Skip to content

fix: avoid materializing constant scalar into null slots in constant page decoder - #12

Merged
devin-ai-integration[bot] merged 1 commit into
exa/v9.0.1-txn-perffrom
devin/1787162683-fix-constant-page-null-materialization
Aug 20, 2026
Merged

fix: avoid materializing constant scalar into null slots in constant page decoder#12
devin-ai-integration[bot] merged 1 commit into
exa/v9.0.1-txn-perffrom
devin/1787162683-fix-constant-page-null-materialization

Conversation

@tanish-exa

Copy link
Copy Markdown

Summary

Fixes the SEV-1271 Offset overflow error when reading Lance 2.2 files with null-padded constant pages (the poisoned Silk Node crawl_output fragments in the DLQ).

Root cause: 2.2's constant encoding stores a repeated value once, and on decode ConstantDecodeTask::materialize_values repeated the scalar for every visible slot — including null slots — via take(scalar, [0,0,...]), applying validity only afterwards. Real DLQ fragments hold one large (2–63 MB) utf8/binary value plus ~1000 nulls in the same column chunk; repeating the scalar for the null slots overflows Arrow's i32 utf8/binary offsets (>2 GiB) even though the actual data is tiny.

Fix (in constant.rs): when definition levels are present, build a 2-slot source [scalar, null] and take with per-row indices from the def levels, so null slots contribute zero bytes:

fn materialize_values(&self, def: Option<&[u16]>, num_values: u64) -> Result<ArrayRef> {
    // def-level-aware path: take from [scalar, null] instead of
    // repeating the scalar for every slot including nulls
}

The all-non-null path is unchanged (a genuinely constant 2 GiB+ column still errors, same as before).

Validation

  • New regression tests test_constant_layout_null_padded_large_value_v2_2 (utf8) and test_constant_layout_null_padded_binary_v2_2 mirror the DLQ shape (32 MiB value + ~1000 nulls); both fail with Offset overflow error: 2147483648 on the old code and pass with the fix.
  • cargo test -p lance-encoding: 461 passed. cargo fmt --all --check and cargo clippy --all --tests --benches -- -D warnings clean.
  • Real production data: built the patched pylance wheel and read all 41 poisoned crawl_output fragments downloaded from the production DLQ — stock v9.0.1-exa.1 decodes 0/41 (all fail with Offset overflow error at constant.rs:473), patched build decodes 41/41 (full scans at batch_size=8192 plus take_rows).

Link to Devin session: https://app.devin.ai/sessions/ef2caed0e6614c15974a46d1e764e730
Requested by: @tanish-exa

…page decoder

Null-padded constant pages (one repeated non-null value plus many nulls)
previously repeated the scalar for every visible slot, including nulls,
before validity was applied. With large utf8/binary scalars this
overflowed i32 offsets (Offset overflow error) even though the decoded
data fits comfortably once nulls contribute zero bytes.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@tanish-exa tanish-exa self-assigned this Aug 19, 2026
@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions github-actions Bot added the bug Something isn't working label Aug 19, 2026
@devin-ai-integration
devin-ai-integration Bot merged commit 5254993 into exa/v9.0.1-txn-perf Aug 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant