[common] Read a shredded variant decimal as the same string as an unshredded one - #9818
Open
zhuxiangyi wants to merge 1 commit into
Open
zhuxiangyi wants to merge 1 commit into
zhuxiangyi wants to merge 1 commit into
Conversation
…hredded one The unshredded leg of a variant extraction casts a decimal after getDecimal() has stripped its trailing zeros, so 10.0 reads as "10". The shredded leg reads the typed_value with the scale of the file schema, e.g. DECIMAL(18, 1), and its string cast keeps that scale: the same value reads as "10.0" from a shredded file, and as "1.50" instead of "1.5" once the inferred scale is 2. With inferred shredding a table mixes both layouts, so one column yields two spellings of the same number, and a pushed-down variant_get(..., 'string') differs from Spark's own evaluation. Move the normalization into a helper shared by both legs and apply it to a typed_value decimal before casting. Numeric targets are unaffected.
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.
Purpose
This is a bug fix. Extracting a decimal as a string returns different text depending on whether the file is shredded:
The unshredded leg (
VariantGet.cast) casts fromgetDecimal(), which strips trailing zeros, so it matches Spark'sVariantGet. The shredded leg (BaseVariantReader.ScalarReader) reads thetyped_valuewith the scale of the file schema and its string cast keeps that scale. Only decimal → string is affected; numeric targets agree on both legs.This matters because the docs promise that "the SQL and result are the same for plain, shredded, and mixed-layout files",
'string'is the one target type a strictvariant_getis pushed into the scan for, and withvariant.inferShreddingSchemaa table routinely mixes plain and shredded files, so a single column yields1.5for some rows and1.50for others.The fix extracts the normalization already used by the unshredded leg (strip trailing zeros, fold a negative scale, keep precision at least the scale) into
VariantGet.normalizedDecimaland applies it to atyped_valuedecimal before it is cast, so both legs cast from the same value.Tests
The new unit and format tests reproduce the bug: on
masterthey fail withexpected: +I(10,1.5,0.05,0,...) but was: +I(10.0,1.50,0.05,0.00,...), and pass with this change.PaimonShreddingUtilsTest#testShreddedDecimalCastsLikeUnshredded: the same extractions through a shredded and an unshreddedVariantSchemayield identical strings, and decimal / double / bigint targets are unchanged.VariantShreddingReadTest#testReadDecimalAsStringConsistently: parameterised over a plain Parquet file and one shredded withprice DECIMAL(18, 1), amount DECIMAL(18, 2).VariantTestBase:variant_get(..., 'string')on values whose inferred scale keeps trailing zeros; runs under all four Spark 4.x configurations (with/without pushdown, with/without inferred shredding). Verified on Spark 4.1.2: 116 tests pass.API and Format
No.
Documentation
No.