Skip to content

feat(mem_wal): tombstone-preserving point lookup#7482

Merged
jackye1995 merged 1 commit into
lance-format:mainfrom
hamersaw:feat/mem-wal-lookup-keep-tombstone
Jun 26, 2026
Merged

feat(mem_wal): tombstone-preserving point lookup#7482
jackye1995 merged 1 commit into
lance-format:mainfrom
hamersaw:feat/mem-wal-lookup-keep-tombstone

Conversation

@hamersaw

Copy link
Copy Markdown
Contributor

What

Adds LsmPointLookupPlanner::lookup_keep_tombstone and lookup_many_keep_tombstone — point-lookup variants that carry the _tombstone marker through instead of filtering deleted keys out.

Why

The existing lookup / lookup_many collapse two distinct states — deleted in the fresh tier and never written — into a single None. That's correct for a normal reader, but a caller doing a read-on-write merge needs to tell them apart: a fresh-deleted PK must be treated as absent (so a later partial update resurrects it from carried columns + NULLs), while a never-written PK falls back to the base row.

These variants return the deleted row with _tombstone = true; absent keys still return None. Implemented by refactoring plan_lookup to share a plan_lookup_coalesced helper and skipping the post-coalesce tombstone filter, so the hot read path is unchanged.

Tests

  • test_lookup_keep_tombstone_returns_deleted_row_with_marker
  • test_lookup_many_keep_tombstone_includes_tombstoned_keys

Context

Prerequisite for a downstream WAL partial-column-update resurrection fix: a partial update arriving after a delete must resurrect carried columns + NULL untouched, never stale pre-delete base data.

🤖 Generated with Claude Code

Add `LsmPointLookupPlanner::lookup_keep_tombstone` and
`lookup_many_keep_tombstone`: point-lookup variants that carry the
`_tombstone` marker through instead of filtering deleted keys out. The
existing `lookup` collapses "deleted in the fresh tier" and "absent" into a
single `None`; these variants distinguish them by returning the deleted row
with `_tombstone = true` (absent keys still return `None`).

Refactors `plan_lookup` to share `plan_lookup_coalesced`, leaving the hot
read path unchanged. The sophon WAL partial-column-update merge uses this to
treat a fresh-deleted PK as absent rather than resurrecting stale base columns.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@github-actions github-actions Bot added the enhancement New feature or request label Jun 25, 2026
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.69072% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../lance/src/dataset/mem_wal/scanner/point_lookup.rs 89.69% 4 Missing and 6 partials ⚠️

📢 Thoughts on this report? Let us know!

@jackye1995 jackye1995 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks good to me!

@jackye1995
jackye1995 merged commit b2673c8 into lance-format:main Jun 26, 2026
30 checks passed
@hamersaw
hamersaw deleted the feat/mem-wal-lookup-keep-tombstone branch June 26, 2026 15:37
BubbleCal pushed a commit that referenced this pull request Jun 30, 2026
## What

Adds `LsmPointLookupPlanner::lookup_keep_tombstone` and
`lookup_many_keep_tombstone` — point-lookup variants that carry the
`_tombstone` marker through instead of filtering deleted keys out.

## Why

The existing `lookup` / `lookup_many` collapse two distinct states —
**deleted in the fresh tier** and **never written** — into a single
`None`. That's correct for a normal reader, but a caller doing a
read-on-write merge needs to tell them apart: a fresh-deleted PK must be
treated as *absent* (so a later partial update resurrects it from
carried columns + NULLs), while a never-written PK falls back to the
base row.

These variants return the deleted row with `_tombstone = true`; absent
keys still return `None`. Implemented by refactoring `plan_lookup` to
share a `plan_lookup_coalesced` helper and skipping the post-coalesce
tombstone filter, so the hot read path is unchanged.

## Tests

- `test_lookup_keep_tombstone_returns_deleted_row_with_marker`
- `test_lookup_many_keep_tombstone_includes_tombstoned_keys`

## Context

Prerequisite for a downstream WAL partial-column-update resurrection
fix: a partial update arriving after a delete must resurrect carried
columns + NULL untouched, never stale pre-delete base data.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
BubbleCal pushed a commit that referenced this pull request Jun 30, 2026
Backport of the following PRs:
- #7362
- #7417
- #7482
- #7483
- #7489

This PR backports the changes from the original PRs to the release/v8.0
branch.

---------

Co-authored-by: Dan Rammer <[email protected]>
Co-authored-by: Lance Release Bot <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants