feat(fts): add cross-column scorer composition - #8685
Merged
Conversation
BubbleCal
force-pushed
the
yang/oss-1603-03-row-address-scorers
branch
from
August 21, 2026 06:08
ff56378 to
5e75e5b
Compare
BubbleCal
force-pushed
the
yang/oss-1603-03-row-address-scorers
branch
from
August 21, 2026 06:15
5e75e5b to
f9ceabd
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
BubbleCal
force-pushed
the
yang/oss-1603-03-row-address-scorers
branch
from
August 21, 2026 06:51
f9ceabd to
c5beb0f
Compare
Contributor
There was a problem hiding this comment.
The document-granularity mismatch is fixed at the row-only boundary, with Match, Phrase, and MultiMatch validation coverage. The remaining risk is regression coverage: supported cross-column scoring has strong component/property evidence and a successful index-backed end-to-end probe, but the repository still lacks a committed test through the full orchestration path. A staged-versus-eager differential test in the consumer integration would close that gap.
Xuanwo
approved these changes
Aug 21, 2026
sbrunk
added a commit
to sbrunk/lance
that referenced
this pull request
Aug 22, 2026
Merge worker tail partitions in row_id order (stable sort + consistent doc-id remap of docs and posting lists) so each partition's row_ids come out strictly ascending. Internal doc-id relabel only: BM25 scores/results unchanged, no format or metadata change, old unordered indexes stay valid. This makes the cross-column scorer added in lance-format#8685 take its ordered path. `ResidentAddressProjection::select_sorted_addresses` resolves staged candidates either through `OrderedRowAddressProjection`, when live row addresses ascend strictly with doc id, or by building and holding the `AddressDocIdLookup` reverse index when they do not. Indexes written before this commit take the fallback for no reason other than the order the merge happened to emit; indexes written after it validate as ordered and skip that structure entirely. Also enables row_id block-skipping for combined_fields read pruning.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Feature
Each FTS index source scores in its own partition-local DocId domain. Cross-column compound queries need to compose those scorers in one globally ordered row-address domain without assuming independently built indices share local document layouts.
This PR adds the cross-column scorer core:
The dataset Scanner does not call this core yet; that integration remains in the final consumer PR.
API and compatibility
There is no file-format change.
This PR exports the low-level async Rust entry point used by the later
lanceplanner integration:The API requires a bounded limit, preserves exact
(score DESC, row_address ASC)ordering, and returns an error for unsupported or internally inconsistent scorer state.Existing
PartitionDocuments::resolve_addressesandestimated_address_read_bytesbehavior remains unchanged frommain, so current production cache and I/O behavior is not altered before Scanner integration.CI failure addressed
The previous head split scorer foundations from their production consumer, leaving 43 groups of private items unused under
-D dead-code. This revision folds the cross-column core into the same PR so those components have real production call paths.Unused leaf-role metadata was deleted. No
allow(dead_code), test-only gating, or visibility workaround was added.Scope boundary
This is PR 3 of the OSS-1603 stack and builds on #8666 and #8667, both merged.
It does not include the previously deferred same-column delayed
MUST_NOTprobing work from OSS-1705. Cross-column prohibited clauses are supported as ordinary query semantics, but this PR does not change the same-columnBooleanScoreror its probing strategy.Validation
cargo fmt --all -- --checkgit diff --check origin/main...HEADPer project workflow, GitHub CI is the authoritative Cargo test and Clippy run for this revised head.
Performance validation
No end-to-end performance benefit is claimed yet because the dataset Scanner does not call this entry point in this PR. A main-vs-this-PR dataset benchmark would execute the existing fallback path and measure noise.
The final consumer PR will enable this core and report independent warm/cold ABBA results with latency, throughput, CPU, bytes, requests, cache metrics, and exact result digests.
Stack
Part of OSS-1603.