fix(scanner): preserve requested projection in fast search - #9699
lance-gatefixer[bot] wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
| self.fast_search = true; | ||
| self.projection_plan.include_row_id(); // fast search requires _rowid | ||
| // Fast search needs row IDs internally, without adding them to the requested output. | ||
| self.projection_plan.physical_projection.with_row_id = true; |
There was a problem hiding this comment.
The extra _rowid column is gone. However, I'd suggest removing the remaining line as well, rather than keeping it as an internal-only flag:
self.projection_plan.physical_projection.with_row_id = true;
This line isn't needed. The vector and FTS search nodes already output _rowid. When the take step adds the missing columns, take_current also carries over the _rowid that is already in its input (projection.with_row_id |= has_row_id).
It defeats the include_deleted_rows check. During planning, include_deleted_rows is rejected when physical_projection.with_row_id is false, because a NULL _rowid is the only way to identify a deleted row.
It does extra work, and the plan depends on call order. For a scalar-index filtered query, calling fast_search() after project(["id"]) makes the plan read row IDs and then add an extra projection to drop them.
There was a problem hiding this comment.
Addressed in 66a4a99. Removed the physical row-ID flag; fast_search() now leaves projection unchanged while search nodes and take_current preserve internal IDs. Regression tests cover include_deleted_rows() validation and identical scalar plans/results across both call orders. All 38 fast-search tests, formatting, and Clippy pass.
There was a problem hiding this comment.
✅ Gate recommendation: approve.
Removing the projection mutation fixes #9696 while search nodes and materialization retain the row IDs they need. The revision also addresses the deleted-row validation and call-order concerns: explicit row-ID requests still work, deleted-row scans require them, and scalar-query plans are independent of project()/fast_search() order.
|
Blocked: the Head: I inspected the job log and failing call path. This test builds a Torch IVF-PQ index without calling Please rerun the failed Windows job on this head with a fresh runner. If the error repeats, investigate the runner's TorchInductor cache permissions separately and rerun after correcting them. |
fast_search()changed the requested projection, causing FTS and vector queries selecting onlyidto return an extra_rowidcolumn.Remove the row-ID projection mutation from
fast_search(). Search nodes already produce the row IDs needed internally, and the take step preserves them. Explicit_rowidprojections andwith_row_id()continue to return row IDs. This also preserves deleted-row validation and makes scalar-query plans independent of whetherproject()runs before or afterfast_search().Regression coverage includes FTS and vector search, default and explicit projections, requested row IDs, and both row ID modes over two fragments. It checks result equality with normal search and recall 1.0, rejects deleted-row scans without requested row IDs, and compares scalar-query plans and results across both call orders.
Validation:
cargo test -p lance fast_search --lib— 38 passed.cargo fmt --all— passed.cargo clippy --all --tests --benches -- -D warnings— passed.Fixes #9696