Skip to content

bug: a legacy Delete reinstates a data file a concurrent Project pruned #9217

Description

@wjones127

A Delete that rebases over a concurrently committed Project reinstates a data file the projection had pruned. The resulting manifest carries a data file none of whose fields are in the schema, and the field-id watermark goes back up over an id the projection retired.

Reproduction

On main (verified at 8cdffd30e), through the public write paths only:

  1. Create a dataset with columns a, b; then add_columns a third column c, so fragment 0 carries two data files — [a, b] and [c]. Call this version v.
  2. Stage a delete against v with DeleteBuilder::execute_uncommitted.
  3. Commit a Project down to {a, b}. It lands at v+1, correctly pruning the [c] data file: fragment 0 now has one file.
  4. Commit the staged delete against v. It rebases over the projection and lands at v+2.

Observed across the three versions:

version schema field ids fragment 0 data files Manifest::max_field_id
v [0, 1, 2] [[0, 1], [2]] 2
v+1 (project) [0, 1] [[0, 1]] 1
v+2 (delete) [0, 1] [[0, 1], [2]] 2

The [2] file is back, and the watermark is non-monotonic — so a later write can mint field id 2 while a data file already claims it.

Cause

Same mechanism as #9216: Operation::Delete's apply replaces the fragment entry wholesale from a post-image built at the read version, which still lists the file the projection dropped. check_delete_txn permits a concurrent Project for the same reason it permits a concurrent DataOverlay.

The scan still succeeds — the orphaned file is simply unreachable — so this does not surface as a read error today. It is a correctness hazard for field-id allocation and leaves a file that cleanup will not collect.

Coverage

A failing test asserting the correct behaviour is committed #[ignore]d as io::commit::conflict_matrix::cases::delete_must_not_reinstate_a_pruned_data_file, pointing at this issue. The (Delete, Project) cell is excluded from that module's matrix until this is fixed.

cargo test -p lance --lib conflict_matrix -- --ignored

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions