Skip to content

feat: expose scanner blob handling - #81

Merged
jja725 merged 2 commits into
lance-format:mainfrom
MisterRaindrop:feat/scanner-blob-handling
Sep 17, 2026
Merged

jja725 merged 2 commits into
lance-format:mainfrom
MisterRaindrop:feat/scanner-blob-handling

Conversation

@MisterRaindrop

Copy link
Copy Markdown
Contributor

Adds LanceBlobHandling and lance_scanner_set_blob_handling() so a scan can return Blob v2 columns as bytes (ALL_BINARY) instead of the descriptor struct (#76). The value is applied in build_scanner() right after project(); values outside the enum and calls after the scan has started are rejected. lance.hpp gets Scanner::blob_handling().

Note: on lance v11.0.0 ALL_DESCRIPTIONS only affects columns that carry blob metadata, so a plain Binary column keeps its bytes and values 0 and 2 currently give the same schema. Documented in the header and pinned by a test.

Tests: two-fragment v2.2 fixture (inline / packed / dedicated / empty / null blobs), six Rust tests, and the C and C++ smoke programs.

lance-gatekeeper[bot]

This comment was marked as outdated.

@lance-gatekeeper lance-gatekeeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gate recommendation: approve.

This implements the scan-mode follow-up accepted in #76, preserves descriptor-by-default behavior, and keeps validation in Rust behind thin C/C++ wrappers. For bulk scans, the opt-in scanner policy is a smaller fit than a per-blob handle API, and its materialized-byte path covers inline, packed, dedicated, empty, null, and multi-fragment Blob v2 data.

@lance-gatekeeper lance-gatekeeper Bot added the K-approved Latest Gatekeeper recommendation permits acceptance. label Sep 10, 2026

@jja725 jja725 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, can you resolve the conflict

@MisterRaindrop
MisterRaindrop force-pushed the feat/scanner-blob-handling branch from c1ec76d to 4a1dc17 Compare September 17, 2026 04:01
@lance-gatekeeper lance-gatekeeper Bot removed the K-approved Latest Gatekeeper recommendation permits acceptance. label Sep 17, 2026
Adds LanceBlobHandling and lance_scanner_set_blob_handling(), applied in
build_scanner() right after project(). Values outside the enum and calls
after the scan has started are rejected.
Two-fragment Blob v2 fixture (inline, packed, dedicated, empty and null
rows) and six tests. The C and C++ smoke programs get a blob dataset as a
third argument and check the setter too.
@MisterRaindrop
MisterRaindrop force-pushed the feat/scanner-blob-handling branch from 4a1dc17 to be21568 Compare September 17, 2026 04:13
@MisterRaindrop

Copy link
Copy Markdown
Contributor Author

LGTM, can you resolve the conflict

I’ve updated it

@jja725
jja725 merged commit 45741f6 into lance-format:main Sep 17, 2026
10 checks passed
jja725 pushed a commit that referenced this pull request Sep 18, 2026
Builds on #81; the first two commits are that PR.

Adds the row-addressed blob API from #76:
`lance_dataset_take_blobs` (by `_rowid`) and
`lance_dataset_take_blobs_by_indices` (by row offset) fill a caller
array of `LanceBlobFile*`, NULL for a null value; the handle has `size`,
`read`, `read_up_to`, `read_range`, `seek`, `tell` and `close`. Reads
copy into caller buffers and return 0 / -1 with the thread-local error
set.

The handle wraps upstream `BlobFile` only, so it outlives the dataset.
Take is all-or-nothing (`out` untouched on error), `read` rejects a
buffer smaller than the remaining bytes instead of truncating, and an
unknown column is an invalid argument rather than `LANCE_ERR_INTERNAL`.
`lance.hpp` gets an RAII `BlobFile` and `Dataset::take_blobs*()`
returning `std::vector<std::optional<BlobFile>>`.

Tests: sixteen `test_blob_*` cases (both entry points over every storage
layout, with and without stable row ids, cursor semantics, bounds and
overflow, handles outliving the dataset, NULL and invalid arguments with
`out` untouched) plus the C and C++ smoke programs.

Open: `read` goes from the cursor to the end like the Rust and Java
`read()`, and `seek` is not bounds-checked, like upstream.
`take_blobs_by_addresses` and `kind` / `uri` accessors are not included.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants