Skip to content

Structurally eliminate rg_plan / RowSelection drift in the parquet runtime prune path (retain_row_groups) #24358

Description

@zhuqi-lucas

Follow-up to #24352 / #24354 (and the second instance #24355), from @adriangb's review on #24354.

Problem

The parquet runtime row-group prune path in PushDecoderStreamState maintains state parallel to the arrow-rs push decoder and updates it independently of the decoder's own frontier:

  • rg_plan: VecDeque<RgPlanEntry> — a DataFusion-side queue of pending row groups, and
  • a carried flat RowSelection over the concatenation of the remaining row groups (arrow-rs side).

Both must stay aligned with the decoder's row-group frontier, but nothing enforces that structurally, and each drift is a silent wrong-results bug:

The #24354 fix also couples rg_plan's correctness to row_group_pruner.is_some() (it syncs only when a pruner exists) — sound today because the pruner is the only consumer that rebuilds from rg_plan, but fragile: the invariant is enforced only where a pruner happens to be present.

Proposed direction

Give the decoder ownership of the drop so the row-group queue and the RowSelection cannot be updated independently. As @adriangb suggested:

  • arrow-rs: add ParquetPushDecoder::retain_row_groups(impl FnMut(usize) -> bool) (or remaining_row_groups() -> impl ExactSizeIterator<Item = usize>) that filters the frontier in place, slicing the RowSelection alongside the row-group queue.

  • DataFusion: replace rg_plan / RgPlanEntry / sync_rg_plan_to_decoder_frontier / advance_rg_plan_to / the Data-arm pop / and the into_builder() + is_at_row_group_boundary() dance with a single

    decoder.retain_row_groups(|rg| !pruner.should_prune(&[rg]));

This removes the parallel state entirely, so there is no alignment left to drift — closing the whole family (#24352, #24355) at the root and dropping the pruner.is_some() coupling.

Either repo can host the change; the in-place retain really wants to live in arrow-rs, which owns both the queue and the selection.

cc @alamb @adriangb @hhhizzz

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions