fix(index): keep address-domain indices off replaced fragments - #8084
Merged
wjones127 merged 1 commit intoJul 31, 2026
Merged
Conversation
A zone map or bloom filter index reports matches as physical row addresses, which a rewrite invalidates, and neither supports remap. Under stable row ids compaction skipped remapping entirely and simply pointed each index's fragment bitmap at the fragments it had just written, so the index answered queries with addresses into fragments that no longer existed. That surfaced as an internal error from translate_addr_treemap_to_row_ids or, with the addresses pruned, as a silently empty result. Compaction now drops the rewritten fragments from an address-domain index's coverage instead of forwarding it, leaving those fragments to a full scan. Translation also tolerates a reference to a fragment that is gone: an update that replaces every row of a fragment removes it while the index keeps the addresses it held, and those rows have no live counterpart to translate to. Fixes lance-format#8076 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Contributor
Author
|
I think this is a short-term fix. In the long term we should do: #8085 |
wjones127
marked this pull request as ready for review
July 29, 2026 20:47
westonpace
approved these changes
Jul 29, 2026
westonpace
left a comment
Member
There was a problem hiding this comment.
I think this is probably even fine as a long-term fix. With seeds it should be really fast to update zone map & bloom filter indexes after the compaction has run. The indexes themselves should also remain reasonably small. So dropping them from the bitmap is probably ok.
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.
Zone map and bloom filter indices report their matches as physical row addresses (a fragment plus an offset) rather than as row ids, and neither can be remapped when a fragment is rewritten. Under stable row ids, compaction skipped index remapping altogether and just pointed each index's fragment coverage at the fragments it had written. An address-domain index would then be asked to answer queries about data whose addresses it never knew, and the addresses it did return named fragments that compaction had deleted. A filtered scan after compaction failed with
fragment 0 referenced by an address-domain index result was not found in the dataset.The same error site was reachable a second way: an update that replaces every row of a fragment removes that fragment, while the index keeps the addresses it held for it.
This PR makes compaction drop the rewritten fragments from an address-domain index's coverage instead of forwarding the coverage to the new fragments — the index keeps serving whatever the rewrite left alone, and the rewritten data falls back to a full scan. Address-to-row-id translation now also skips a reference to a fragment that is no longer in the dataset, the same way it already skips an address that points at a deleted row: in both cases the row has no live counterpart, so it is not part of any answer.
Both behaviors are specific to stable row ids. Without them an address is the row id, remapping runs (and drops these indices outright), and the sequences above already worked.
Fixes #8076