Skip to content

test(mem_wal): cover vector/FTS search correctness under row updates#6844

Open
hamersaw wants to merge 1 commit into
lance-format:mainfrom
hamersaw:feat/mem-wal-override-tests
Open

test(mem_wal): cover vector/FTS search correctness under row updates#6844
hamersaw wants to merge 1 commit into
lance-format:mainfrom
hamersaw:feat/mem-wal-override-tests

Conversation

@hamersaw
Copy link
Copy Markdown
Contributor

What

Tests validating that mem_wal vector and FTS search return newest-wins results when a primary key is updated (re-inserted with new content).

Findings

Row-override resolution in the search paths is only implemented across LSM generations, and only for vector search:

  • LsmVectorSearchPlanner + FilterStaleExec drop a candidate from generation G when its PK appears in a strictly newer generation's PK bloom filter.
  • There is no intra-generation (same active-memtable / "L0") resolution: FilterStaleExec breaks as soon as bf.generation <= row_generation, and the active vector arm carries no _rowaddr insert-order tiebreak — unlike the full-scan path, where DeduplicateExec sorts (pk ASC, _memtable_gen DESC, _rowaddr DESC) and keeps the newest.
  • FTS has no LSM staleness path at all; the FTS mem index is append-only with no PK tombstone/dedup. Only MVCC WAL-flush visibility applies.

Tests added (test-only; no production changes)

Test Result Purpose
test_vector_search_cross_generation_override_excludes_stale ✅ passes Proves the implemented algorithm: PK written to the base table, then re-inserted with a different vector in a newer generation — the stale (and closer) vector is dropped via the generation PK bloom filter. Includes a no-bloom negative control so the assertion can't pass vacuously.
test_vector_search_same_l0_override_newest_wins fails (intentional spec) Same PK inserted twice within one active memtable. Got [(1, 0.0), (2, 0.04), (1, 384.16)] — id=1 returned twice, no newest-wins resolution.
test_fts_same_l0_override_newest_wins fails (intentional spec) PK id=1 doc "apple" then re-inserted as "banana" in a later batch; searching "apple" still returns the stale document.

The two failing tests are an executable spec for the intra-generation override gap, kept failing (not #[ignore]d) so the gap is visible in CI. They encode the intended contract for whoever implements same-L0 newest-wins resolution in the vector/FTS search path.

Note

This PR is intentionally red on the two spec tests. Merging requires either implementing the same-L0 resolution or deciding how to track the gap.

🤖 Generated with Claude Code

Adds tests validating newest-wins behavior for vector and FTS search
when a primary key is re-inserted (an update).

- test_vector_search_cross_generation_override_excludes_stale (passing):
  proves the implemented algorithm — a row written to the base table and
  then re-inserted with a different vector in a newer generation has its
  stale (closer) vector dropped by FilterStaleExec via the generation PK
  bloom filter, even when it would otherwise rank first by distance.

- test_vector_search_same_l0_override_newest_wins (failing spec):
  same primary key inserted twice within one active memtable (same
  generation). FilterStaleExec only consults bloom filters of strictly
  newer generations and the active arm carries no _rowaddr tiebreak, so
  both versions are returned with no newest-wins resolution — unlike the
  full-scan path's DeduplicateExec.

- test_fts_same_l0_override_newest_wins (failing spec):
  FTS has no LSM staleness path and the mem index is append-only with no
  PK tombstone/dedup, so an overridden document is still matched.

The two failing tests are an executable spec for the intra-generation
override gap; only test additions, no production code changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions github-actions Bot added the chore label May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant