Repository navigation
feat(parquet): opt-in dictionary fallback to the column's encoding - #54
Draft
tobias-fire wants to merge 1 commit into
Draft
tobias-fire wants to merge 1 commit into
tobias-fire wants to merge 1 commit into
Conversation
A column chunk whose dictionary grows past dictionary_pagesize_limit continues in PLAIN, hard-coded, and a column's configured encoding only applies with dictionary encoding disabled. parquet-rs instead continues in the column's encoding, which lets a writer get dictionary pages where a dictionary pays off and a better encoding than PLAIN where it does not, without knowing a column's cardinality up front. WriterProperties::Builder::enable_dictionary_fallback_encoding() asks for the same: with it, the fallback is the column's encoding. Only PLAIN and DELTA_LENGTH_BYTE_ARRAY are accepted as that encoding, the latter for BYTE_ARRAY columns, and a column writer for any other combination fails to open rather than mid-write. The delta encodings are format 2.0 encodings, so they are written to 2.x files with V2 data pages only, as RLE for booleans is; a 1.0 file or V1 pages keep PLAIN. Off by default: nothing changes without the option. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011hhJuKWxLQsA1Mgyh4Ni9d
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.
Background
A column chunk whose dictionary grows past
dictionary_pagesize_limitcontinues in PLAIN, hard-coded (FallbackToPlainEncoding), and a column's configuredencodingonly applies with dictionary encoding disabled. parquet-rs instead continues in the column's encoding, so a writer gets dictionary pages where a dictionary pays off and a better encoding than PLAIN where it does not, without knowing a column's cardinality up front. PackDB's native Parquet reader decodes DELTA_LENGTH_BYTE_ARRAY 1–6× faster than PLAIN (firebolt-analytics/packdb#27086), so that is what its tablet writer wants to fall back to.Summary
WriterProperties::Builder::enable_dictionary_fallback_encoding(): with it, the fallback is the column'sencoding. Only PLAIN and DELTA_LENGTH_BYTE_ARRAY are accepted there, the latter for BYTE_ARRAY columns; a column writer for any other combination throws when it opens rather than mid-write. The delta encodings are format 2.0 encodings, so they are written to 2.x files with V2 data pages only, as RLE for booleans is (ColumnWriter::Make); a 1.0 file or V1 pages keep PLAIN. Off by default: nothing changes without the option.UNKNOWN, the column default thatColumnWriter::Makeresolves to PLAIN, resolves to PLAIN here too.Test Plan
column_writer_test.cc:DictionaryFallbackToDeltaLengthByteArraywrites a BYTE_ARRAY column that outgrows its dictionary with the option on and reads every row back; the chunk's data pages are RLE_DICTIONARY and then DELTA_LENGTH_BYTE_ARRAY, with PLAIN only on the dictionary page.DictionaryFallbackEncodingNeedsVersion2AndV2Pageskeeps PLAIN for 1.0 files and for V1 pages.DictionaryFallbackEncodingIsValidatedandDeltaLengthByteArrayIsNoDictionaryFallbackForInt32reject DELTA_BYTE_ARRAY and a DELTA_LENGTH_BYTE_ARRAY fallback on an INT32 column at writer creation. The existingDictionaryFallbackVersion*tests cover the default (option off).ParquetFormatTest.AColumnThatOutgrowsItsDictionaryContinuesInDeltaLengthByteArray(firebolt-analytics/packdb PR to follow), which writes a tablet through this code and checks the chunk's page encodings and the read-back; the 682 Parquet and ManagedV2 tests pass with this tree.🤖 Generated with Claude Code
https://claude.ai/code/session_011hhJuKWxLQsA1Mgyh4Ni9d
Note
Medium Risk
Opt-in writer behavior change affects on-disk page encodings when dictionaries overflow; misconfiguration is caught at writer open, but enabled paths must be readable by consumers expecting PLAIN fallback.
Overview
Adds an opt-in
WriterProperties::Builder::enable_dictionary_fallback_encoding()so that when a column’s dictionary hitsdictionary_pagesize_limit, later data pages use the column’s configuredencoding(parquet-rs-style) instead of always PLAIN. Default behavior is unchanged.DictionaryFallbackEncodingpicks the fallback at writer construction: PLAIN unless the option is on, dictionary encoding is used, the file is 2.x with V2 data pages, and the column encoding is PLAIN or DELTA_LENGTH_BYTE_ARRAY (BYTE_ARRAY only). Other encodings or type mismatches throwParquetExceptionat open time.FallbackToNonDictionaryEncoding(renamed from plain-only fallback) switches encoders to that storedfallback_encoding_when the dictionary limit is hit or dictionary writes must stop.Tests cover DELTA_LENGTH_BYTE_ARRAY fallback after dictionary overflow, version/page gating, and validation errors.
Reviewed by Cursor Bugbot for commit a71dc73. Bugbot is set up for automated code reviews on this repo. Configure here.