GH-51626: [C++][Parquet] Fix statistics of dictionary-encoded leaves under null parents - #51627
Open
kita-renji wants to merge 1 commit into
Open
kita-renji wants to merge 1 commit into
kita-renji wants to merge 1 commit into
Conversation
…eaves under null parents WriteArrowDictionary computed page statistics from the raw leaf indices, before MaybeReplaceValidity applied the validity derived from the def levels. An index slot under a null parent (e.g. a null struct row) could be valid in the leaf array, so it was counted as a value and its dictionary entry went into min/max. Also, Unique() returns a null entry when the chunk has null indices, so the dictionary re-use shortcut fired when exactly one dictionary entry was unreferenced, putting that entry into min/max (flagged as exact). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
|
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.
Rationale for this change
WriteArrowDictionarycan write wrong Parquet statistics fordictionary<*, string|binary>columns (see #51626):Unique()returns one null entry when a batch has null indices, so the shortcut that re-uses the whole dictionary for min/max fires when exactly one dictionary entry is unreferenced, and that entry can become min/max.min/max are marked exact, and readers use them: DuckDB drops rows for
s.x IS NULLand miscountscount(s.x), DataFusion returns a value that isn't in the data formin(c), max(c).What changes are included in this PR?
MaybeReplaceValiditybeforeupdate_statsinWriteIndicesChunk, so statistics see the same validity as the encoded data. This is the orderWriteArrowDensealready uses.Unique()when checking whether all dictionary entries are referenced.Both are needed: with only the first change, the slots under null parents become null indices and case 2 puts the hidden value back into min/max.
Are these changes tested?
Yes. Two cases added to the
NoNullCountWrittenForRepeatedFields(PARQUET-2067) suite inarrow_statistics_test.cc: astruct<dictionary<int32, utf8>>with null rows over valid child slots, and a top-level dictionary with a null and one unreferenced entry. Both fail without the change. All parquet C++ test binaries pass.I also ran a randomized check (not included) that writes dictionary<string/binary> leaves nested in struct/list/large_list/fixed_size_list (up to two levels), with nulls at every level, values hidden under null parents, slices, several batches, small pages and row groups, dictionary fallback and V1/V2 pages, and compares the written statistics with ones computed from the logical values. On main it finds wrong statistics in most nested shapes (and trips the V2 DCHECK); with this change 4500 random cases match.
Are there any user-facing changes?
Files written with dictionary encoding get correct
null_countand min/max for these columns. No API changes.This PR contains a "Critical Fix". It fixes a bug that writes incorrect statistics, which makes other readers return wrong results. The data itself was always written correctly.
Was AI used for this PR?
In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.
PR code and description written by:
Reviewed before submission by:
🤖 Generated with Claude Code