Skip to content

fix: round-trip empty blob values in the 2.1+ structural encoding#7717

Merged
wkalt merged 2 commits into
lance-format:mainfrom
wkalt:ticket/oss-1429/blob-empty-value-read
Jul 10, 2026
Merged

fix: round-trip empty blob values in the 2.1+ structural encoding#7717
wkalt merged 2 commits into
lance-format:mainfrom
wkalt:ticket/oss-1429/blob-empty-value-read

Conversation

@wkalt

@wkalt wkalt commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

A valid empty value is stored as {position: 0, size: 0} while nulls pack their non-zero rep/def levels into position. The page scheduler skips size-0 rows when scheduling reads, but the load task assigned read results to every def == 0 blob, so an empty value consumed the next blob's payload and the last consumer crashed on an exhausted iterator ("Expected option to have value"). Give empty values their zero-length bytes at scheduling time and only assign read results to blobs that scheduled a read.

Fixes #7716

Summary by CodeRabbit

  • Bug Fixes
    • Fixed decoding/round-trip handling for empty blob (LargeBinary) values so they’re preserved and remain correctly aligned when mixed with non-empty payloads and nulls.
    • Prevented empty blob byte data from being overwritten during page loading and ensured empty values are treated as present during decoding.
  • Tests
    • Added an async round-trip test covering empty (LargeBinary) values interleaved with nulls when blob metadata is enabled.

A valid empty value is stored as {position: 0, size: 0} while nulls pack
their non-zero rep/def levels into position. The page scheduler skips
size-0 rows when scheduling reads, but the load task assigned read
results to every def == 0 blob, so an empty value consumed the next
blob's payload and the last consumer crashed on an exhausted iterator
("Expected option to have value"). Give empty values their zero-length
bytes at scheduling time and only assign read results to blobs that
scheduled a read.

Fixes lance-format#7716
@github-actions github-actions Bot added A-encoding Encoding, IO, file reader/writer bug Something isn't working labels Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c878edca-e81b-4633-bb18-7ae08798ab59

📥 Commits

Reviewing files that changed from the base of the PR and between 3e2f1e9 and 17c4b06.

📒 Files selected for processing (1)
  • rust/lance-encoding/src/encodings/logical/blob.rs

📝 Walkthrough

Walkthrough

Blob page scheduling now preserves zero-length values as loaded empty bytes instead of treating them as unread data. A Tokio test covers round-tripping empty, non-empty, and null LargeBinary blob values.

Changes

Empty blob value handling

Layer / File(s) Summary
Preserve scheduled empty blob bytes
rust/lance-encoding/src/encodings/logical/primitive/blob.rs
Zero-size descriptors with definition level zero are assigned empty bytes during scheduling, and page loading no longer overwrites bytes already assigned.
Validate empty blob round trips
rust/lance-encoding/src/encodings/logical/blob.rs
Adds coverage for LargeBinary blob values containing empty payloads, non-empty values, and nulls with blob metadata enabled.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The changes fix empty-value round-tripping in the scheduler/load path, but the summary doesn't show the dataset-level null/empty descriptor leak being addressed. Add or describe a test for dataset-level blob descriptor reads to verify null rows don't expose packed rep/def levels.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main change: fixing empty blob round-tripping in 2.1+ structural encoding.
Out of Scope Changes check ✅ Passed Only blob-encoding logic and a targeted test were changed, with no obvious unrelated edits.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rust/lance-encoding/src/encodings/logical/blob.rs`:
- Around line 561-564: Extend the regression test using
check_round_trip_encoding_of_data to cover LanceFileVersion::V2_2 in addition to
V2_1, either by raising the configured maximum file version or adding an
explicit V2.2 test case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e06feede-1187-47bb-83d2-1bc7cb938dce

📥 Commits

Reviewing files that changed from the base of the PR and between 9d24be1 and b3e2186.

📒 Files selected for processing (2)
  • rust/lance-encoding/src/encodings/logical/blob.rs
  • rust/lance-encoding/src/encodings/logical/primitive/blob.rs

Comment thread rust/lance-encoding/src/encodings/logical/blob.rs Outdated
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@wkalt
wkalt force-pushed the ticket/oss-1429/blob-empty-value-read branch from 3e2f1e9 to 5f33e1b Compare July 9, 2026 23:50
The uncapped TestCases default iterates every version iter_non_legacy()
yields, so new file versions are covered automatically as they are
added.
@wkalt
wkalt force-pushed the ticket/oss-1429/blob-empty-value-read branch from 5f33e1b to 17c4b06 Compare July 9, 2026 23:50
@wkalt
wkalt merged commit 5ba1e20 into lance-format:main Jul 10, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-encoding Encoding, IO, file reader/writer bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blob column with an empty value written via LanceFileWriter at 2.1+ is unreadable; null descriptors leak packed rep/def levels

3 participants