zhuqi-lucas opened a new pull request, #25050:
URL: https://github.com/apache/datafusion/pull/25050

   ## Which issue does this PR close?
   
   Closes #24771.
   
   ## Rationale for this change
   
   `OptimizeAggregateOrder` already proves, via `with_beneficial_ordering`, 
when the input
   ordering satisfies the group-by prefix followed by a 
`first_value`/`last_value` ordering
   requirement, and the single-group accumulators consume that flag 
(`first_last.rs`,
   `get_first_idx`/`get_last_idx`). The grouped path never did: 
`create_groups_accumulator`
   dropped the flag, and `FirstLastGroupsAccumulator` ran the full per-row 
lexicographic
   tournament, per-winner ordering-key materialization, and cross-batch 
`compare_rows` on
   every batch even though the winner was already determined by position.
   
   The motivating workload (a materialized `GROUP BY date, ticker` with three
   `LAST_VALUE(... ORDER BY ts, seq)` over an NBBO table whose file sort order 
is exactly
   `(ticker, ts, seq)`, ~1.5B rows/day, ~1.8M groups) spends ~20% of on-CPU 
time inside
   `get_filtered_extreme_of_each_group` — all of it avoidable comparisons. The 
same
   ordering evidence is cashed twice by the planner but only once by the 
executor.
   
   ## What changes are included in this PR?
   
   - `is_input_pre_ordered` is threaded through `create_groups_accumulator` into
     `FirstLastGroupsAccumulator`.
   - When set, `update_batch` takes a comparison-free path: one pass over 
`group_indices`
     records each group's first (FIRST_VALUE) or last (LAST_VALUE) qualifying 
row; later
     batches unconditionally overwrite for LAST_VALUE and never overwrite for 
FIRST_VALUE.
     No `LexicographicalComparator` is built and `compare_rows` never runs on 
this path.
   - The winner's ordering values are still materialized into the partial 
state: the final
     stage merges states from partitions whose relative arrival order is not 
guaranteed, so
     `merge_batch` keeps comparing and is intentionally untouched, as are
     `convert_to_state` and the skip-partial `is_set` handling.
   - Drive-by: three stale comments still referring to the field's old name
     (`min_of_each_group_buf`) are updated.
   
   **Tie semantics note:** among rows whose ordering keys compare equal, this 
path picks
   the physically last qualifying row for LAST_VALUE (first for FIRST_VALUE), 
matching the
   single-group pre-ordered accumulator and `Iterator::max_by`. The tournament 
path keeps
   the first-seen row of a tie (its comparisons are strict), so the two paths 
may pick
   different — equally valid — rows on tied keys. Documented on the method and 
pinned by a
   dedicated test.
   
   ## Are these changes tested?
   
   - 9 new unit tests: fast-vs-tournament full-state equivalence 
(LAST/FIRST/DESC/FILTER
     incl. null predicates/IGNORE NULLS/RESPECT NULLS with a null winner), 
explicit
     expected values, `EmitTo::First(n)` mid-stream draining with index 
shifting, and a
     partial→final merge in both arrival orders proving the emitted state 
carries the
     winning ordering keys.
   - A new end-to-end `first_last_ordered.slt`: requirement proven through 
declared
     orderings, through a projection-alias equivalence, and through a 
filter-induced
     constant; FILTER interaction; and the reverse branch (FIRST over DESC).
   - Existing suites pass: 215 crate tests, `aggregate.slt`, 
`first_last_nested.slt`,
     `group_by.slt`, `distinct_on.slt`, `array_agg.slt`, `subquery_sort.slt`.
   
   ## Are there any user-facing changes?
   
   No API changes. Queries whose input ordering already satisfies a grouped
   first_value/last_value requirement get faster; on the motivating workload the
   aggregation stage improved by ~20% end-to-end wall time.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to