Repository navigation
Write Parquet NUMERIC with precision up to 76 and name the array column in overflow messages - #90
Open
huiliang-liu wants to merge 2 commits into
Open
huiliang-liu wants to merge 2 commits into
huiliang-liu wants to merge 2 commits into
Conversation
PXF rejected any NUMERIC column with a precision above 38 when writing Parquet, because values were converted through HiveDecimal. Parquet's DECIMAL has no such limit, and Arrow-based readers such as PyArrow read precision up to 76 as decimal256. Columns with a precision from 39 to 76 are now parsed with BigDecimal and written as a FIXED_LEN_BYTE_ARRAY wide enough for the precision. The pxf.parquet.write.decimal.overflow option keeps its error, round and ignore behavior for these columns. Precision up to 38 still goes through HiveDecimal, and NUMERIC without a precision still maps to DECIMAL(38,18), so existing files and readers limited to 38 digits are unaffected.
When a NUMERIC[] element did not fit the Parquet decimal type, ParquetResolver looked up the column name with the element's index inside the repeated group (always 0), so the overflow error, or the warning with pxf.parquet.write.decimal.overflow=ignore, named the table's first column instead of the array column. Pass the column name down from fillGroup instead of deriving it from the primitive's index. Add tests for how the scale of a NUMERIC[] column is chosen on write, from a field report where values with more than 18 decimal places were rounded. The scale comes from the writable table column: NUMERIC[] falls back to DECIMAL(38,18), NUMERIC(38,20)[] and NUMERIC(38,37)[] keep their scale, NUMERIC(76,61)[] and TEXT[] keep every digit, and NUMERIC(77,61)[] is rejected. Unit tests cover the resolver; the automation test covers the same cases end to end.
huiliang-liu
force-pushed
the
feat/parquet-decimal-precision-76
branch
from
October 15, 2026 07:51
eefcc59 to
9dbd712
Compare
Contributor
Author
adam8157
approved these changes
Oct 19, 2026
Contributor
|
One small thing: PG allows |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
JIRA: PTT-1957
Summary
Writing a
NUMERICvalue with more than 38 digits to Parquet loses digits or fails. In a field report,numeric[]values with more than 18 decimal places came back rounded (0.1234567890123456789→0.123456789012345679, and a value with 61 decimal places →0), and declaring a precision above 38 was rejected. The customer needs these values asdecimal256on the Parquet side.This PR has two commits.
1. Write Parquet NUMERIC columns with precision up to 76
NUMERIC(p,s)withp > 38because values went throughHiveDecimal. Parquet'sDECIMALhas no such limit, and Arrow readers (PyArrow) read precision up to 76 asdecimal256.ParquetFileAccessor.MAX_DECIMAL_PRECISION). For precision 39–76, values are parsed withBigDecimal(DecimalUtilities.parseDecimalStringWithBigDecimal) and written as aFIXED_LEN_BYTE_ARRAYsized for the precision (32 bytes at 76).pxf.parquet.write.decimal.overflowkeeps itserror/round(half-up) /ignore(NULL) behavior for these columns.HiveDecimal, so those files are byte-for-byte the same.NUMERICwithout a typmod still maps toDECIMAL(38,18). Spark, Hive and Trino only read precision ≤ 38, so wider columns are opt-in by declaring the precision.BigDecimal. No change was needed there.hdfs_parquet,cfg_server) and CHANGELOG are updated.2. Name the array column in Parquet numeric overflow messages (from #89)
NUMERIC[]element that overflowed, the error (or theignore-mode warning) named the table's first column instead of the array column. The column name is now passed down fromfillGroup.NUMERIC[]column's scale is chosen on write.NUMERIC[]→DECIMAL(38,18).(38,20)and(38,37)keep their scale.(76,61)andTEXT[]keep every digit.(77,61)is rejected.NUMERIC(45,25)[]to be rejected now checks a(76,61)round trip instead.Testing
pxf-hdfsunit tests: 539 passed. New tests are inParquetWriteTestandDecimalUtilitiesTest.file:parquet:numeric(76,61)andnumeric(76,61)[]write and read back exactly, including 61-decimal-place and 15-integer-digit values, negatives and NULLs.decimal256(76, 61)with the correct values.decimal256(76, 61)file written by PyArrow reads through PXF exactly.parquetWriteNumericWithMaxPrecision(numeric_max_precision).parquetWriteNumericArrayScale(numeric_array_scale).numeric_with_large_precisionchanged from 38 to 76.numeric_max_precisionandnumeric_array_scalepass underpxf_regresslocally.numeric_with_large_precisionwas not re-run.mvn test-compilepasses. The full HDFS automation suite was not run.