Skip to content

bug: AddRowOffsetExec computes wrong _rowoffset for unsorted addresses in fragments with deletions #8250

Description

@wjones127

`AddRowOffsetExec::compute_row_offsets` (rust/lance/src/io/exec/rowids.rs:470-484) adjusts each row's offset by the number of deleted rows below it using a peekable iterator over the fragment's deletion vector. The iterator only advances forward, so it assumes addresses within a fragment run arrive in ascending order. For an out-of-order address the delete count is stuck at the previous (higher) offset's value, producing a wrong `_rowoffset`.

Example: fragment with deletions at offsets 10 and 60; addresses arrive as [offset 100, offset 50]. Offset 100 correctly subtracts 2, but offset 50 also subtracts 2 (iterator already consumed both entries) instead of 1.

This is fed unsorted user-ordered addresses by the take path (rust/lance/src/dataset/take.rs:376-379, `compute_row_offset_array` on the original request-order `row_addrs`). Stable row ids make it much more reachable: after updates/compaction, taking by sorted row ids yields unsorted addresses within a fragment.

Fix options: pre-sort per fragment and map results back, or use `DeletionVector`'s rank support (count of deleted offsets < x) per address instead of a forward-only iterator.

Only affects `_rowoffset` output, not row content.

Metadata

Metadata

Assignees

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