fix(encoding): normalize out-of-range null dictionary keys - #8827
fix(encoding): normalize out-of-range null dictionary keys#8827lance-gatefixer[bot] wants to merge 2 commits into
Conversation
|
Blocked: PR #8827 remains blocked at current remote head b855eca by three non-attributable stochastic vector-index checks: Rust linux-build job 98532150495 missed the randomized HNSW-PQ recall threshold at 117/256, while Python Linux 3.13 x86_64 job 98534008079 and Python Linux 3.14 ARM job 98532150478 failed residual-sample initialization with StopIteration on opposite index-version parameters. Current main 0ac7d22 is an ancestor of this head; the exact Rust failing test passes locally, both dictionary regression cases pass, and this PR changes only dictionary encoding. Rerun the three failed checks; alternatively, stabilize the unseeded vector tests in a separate change and then rerun this head. |
|
These test failures look unrelated. |
There was a problem hiding this comment.
✅ Gate recommendation: approve.
The base merge leaves the dictionary normalization patch unchanged. The current head still repairs unsafe null-slot keys at the validity-removal boundary, and the hand-built and Arrow-concatenated round trips remain covered without changing the encoded format or safe-array allocation path.
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
Summary
Root cause
Arrow permits arbitrary physical keys in null dictionary slots. The structural encoder records the key validity in rep-def and then removes the Arrow null buffer, which makes those previously meaningless keys appear valid and triggers dictionary bounds validation.
Fix
When a non-empty dictionary has an out-of-range key in a null slot, rebuild only its keys from the logical iterator. This writes key zero into null slots while preserving logical nullness and dictionary values. Dictionaries without the defect remain untouched.
Validation
Fixes #8826