fix(encoding): normalize out-of-range null dictionary keys - #2
Merged
valkum merged 1 commit intoAug 28, 2026
Conversation
Arrow permits an arbitrary physical key in a null dictionary slot. The structural encoder records the key validity in rep-def and then removes the null buffer, which makes such a key look valid and fails the dictionary bounds check. Rebuild the keys from the logical iterator when a non-empty dictionary holds an out-of-range key in a null slot. A dictionary without the defect stays untouched. Backport of lance-format#8827 (head b855eca). Adaptation for 6.x: the round trip test selects the structural encoder with with_min_file_version(LanceFileVersion::V2_1). This branch has no TestEncoding selector. (cherry picked from commit b855eca) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116qdBmoaQpMLZAWoi6evmA
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.
Summary
Backport of upstream lance-format/lance#8827 (head
b855eca8), which fixes #8826: the encoder rejects a dictionary array that holds an out-of-range physical key in a null slot.Root cause. Arrow permits an arbitrary physical key in a null dictionary slot. The structural encoder records the key validity in rep-def and then removes the null buffer (
extract_validity_buf). The meaningless key then looks valid and fails the dictionary bounds check.arrow_select::concatmakes such keys when it merges a chunk that has values with an all-null chunk.Fix. Before validity extraction, rebuild the keys from the logical iterator when a non-empty dictionary holds an out-of-range key in a null slot. This writes key zero into every null slot and keeps the logical values and the validity bitmap. A dictionary without the defect returns unchanged, so the no-allocation path stays.
Backport notes
clear_out_of_range_null_keysindict.rs, plus one call inPrimitiveStructuralEncoder::extract_validity.git cherry-pick -xapplied with no conflict..with_encoding(TestEncoding::StructuralU32). This branch has noTestEncodingselector, so the test uses.with_min_file_version(LanceFileVersion::V2_1), the same as the dictionary tests next to it.rebuild_empty_dictionary_chunks, fix(encoding): align all-null dictionary handling with upstream #1). The new function skips an empty dictionary (num_values == 0), whichdo_flushcontinues to handle.Tests
test_dictionary_out_of_range_null_keys_round_tripcovers two sources of the defect: a hand-built dictionary, and one thatarrow_select::concatproduces from a valued chunk and an all-null chunk.The test is not vacuous on this branch. With the call in
extract_validityremoved, both cases fail:cargo test -p lance-encoding— 382 passed, 0 failed, 5 ignoredcargo fmt --all -- --check— cleancargo clippy --all --tests --benches -- -D warnings— clean🤖 Generated with Claude Code
https://claude.ai/code/session_0116qdBmoaQpMLZAWoi6evmA