Skip to content

merge_insert reports zero updated rows for a matching partial upsert #8280

Description

@mmatczuk

Description

A merge_insert with WhenMatched::UpdateAll reports num_updated_rows: 0 when its source contains one key that is present in the dataset. The expected count is 1.

The failure occurs on storage version 2.1 with stable row IDs disabled, max_rows_per_group: 1, and max_rows_per_file: 8. The dataset's only value column has Arrow Null type. Before the failing merge, the dataset undergoes UpsertIf, UpsertFull, ZoneMap index creation, another UpsertFull, and an append. The failing partial upsert supplies key 166 and the value column, using WhenNotMatched::DoNothing and WhenNotMatchedBySource::Keep. A full-scan oracle verifies the dataset after each preceding operation, including the presence of key 166 before this merge.

The merge implementation assigns UpdateAll when both the source and target contribute a row to the join, and the write path increments num_updated_rows for every UpdateAll action. The root cause of the missing count has not yet been isolated.

It is not yet clear whether this is only an incorrect statistic or a dropped update. Continuing after the statistics mismatch produces no scan divergence, but a Null-typed column has the same value before and after every update, so the data oracle cannot distinguish a successful write from a lost one.

A deterministic 158-byte harness input reproduces the failure, but no standalone public-API reproducer has been found. Simpler cases all report num_updated_rows: 1, including a partial source schema, a Null-typed value column, a scalar index with and without a preceding update, stable row IDs on and off, and small row-group and file limits. The longer mutation history appears to be required.

Expected behavior

num_updated_rows should be 1 when the source key matches one live target row and WhenMatched::UpdateAll is configured. The row should also be updated.

Lance version

v10.1.0-beta.2 (94cca93d13b1c731afd6660d46ad2f8d4b4345c4)

Language binding

Rust

Environment

Fedora Linux 44, x86_64, in-memory object store, rustc 1.97.1

Logs / traceback

thread 'main' panicked at src/dataset_ops.rs:1667:21:
assertion `left == right` failed: step 4, candidate 5: op UpsertPartial { keys: [166], mask: 0, rotate: 255, data: DataParams { len: Big, nulls: None, nans: true } }: updated_rows
  left: 0
 right: 1

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