Conversation
Signed-off-by: 1fanwang <1fannnw@gmail.com>
divjotarora
suggested changes
Sep 18, 2026
divjotarora
left a comment
Contributor
There was a problem hiding this comment.
Seems reasonable, but one possible edge case
| // TODO: the compressed size of a dictionary page is lost in Parquet | ||
| dict.getUncompressedSize(); | ||
| long totalSize = dict.getCompressedSize(); | ||
| long totalSize = getPageCompressedSize(); |
Contributor
There was a problem hiding this comment.
getPageCompressedSize calls columnChunk.hasDictionaryPage() to determine the page offset. This function does:
public boolean hasDictionaryPage() {
EncodingStats stats = getEncodingStats();
if (stats != null) {
// ensure there is a dictionary page and that it is used to encode data pages
return stats.hasDictionaryPages() && stats.hasDictionaryEncodedPages();
}
Set<Encoding> encodings = getEncodings();
return (encodings.contains(PLAIN_DICTIONARY) || encodings.contains(RLE_DICTIONARY));
}
In an edge case where a writer emits a dictionary page followed by no PLAIN_DICTIONARY or RLE_DICTIONARY data pages, we would get wrong results because hasDictionaryPage() returns false.
Realistically, writers wouldn't do this, but I didn't find any wording in the spec explicitly disallowing it. The TestParquetFileWriter code in this repo seems to do exactly this.
Signed-off-by: 1fanwang <1fannnw@gmail.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
parquet pagesreports decoded dictionary sizes instead of the bytes stored in compressed files. It can also fail on a valid file whose dictionary is not used by any data page. The summary now reports the stored page sizes for both layouts.Closes #2870.
What changes are included in this PR?
Read dictionary sizes from the original page headers and start the scan at the column's physical offset. An unused dictionary no longer makes the scan start at the first data page. Files and the core page API are unchanged.
Are these changes tested?
Testing Done
Ran both fixtures with JDK 17.0.5 and Thrift 0.24.0 against the upstream baseline and this PR's head.
java -jar <cli.jar> pages -c color compressed-dictionary.parquetjava -jar <cli.jar> pages unused-dictionary.parquetRequired field 'uncompressed_page_size' was not found in serialized data!java -jar <cli.jar> cat unused-dictionary.parquetFrom this PR's checkout, build the two runtime jars:
Create and inspect the compressed file:
python3 -c 'from pathlib import Path; Path("dictionary_page_input.csv").write_text("color\n" + ("a" * 120 + "\n" + "b" * 120 + "\n") * 100)' java -Xmx512m -XX:ActiveProcessorCount=2 -jar before-cli.jar convert-csv dictionary_page_input.csv --require color --compression-codec GZIP -o compressed-dictionary.parquet java -Xmx512m -XX:ActiveProcessorCount=2 -jar before-cli.jar pages -c color compressed-dictionary.parquet java -Xmx512m -XX:ActiveProcessorCount=2 -jar after-cli.jar pages -c color compressed-dictionary.parquet java -Xmx512m -XX:ActiveProcessorCount=2 -jar after-cli.jar pages --raw -c color compressed-dictionary.parquetSave the writer below as
WriteUnusedDictionary.java, then create a file with a dictionary and only plain-encoded data:Executed fixture writer
Raw result lines
GZIP dictionary before:
GZIP dictionary after:
Unused-dictionary file before:
Unused-dictionary file after:
Decoded rows, unchanged:
The regression also verifies that the unused dictionary has a recorded offset but no dictionary-encoded data pages. Raw headers, decoded rows, and the original GZIP data-page summary remain unchanged.
Are there any user-facing changes?
Dictionary summaries report on-disk bytes, including when no data page uses the dictionary.