viirya opened a new issue, #26818:
URL: https://github.com/apache/datafusion/issues/26818

   ### Describe the bug
   
   `AggregateExec` adds `Constraint::Unique(group keys)` to its equivalence 
properties in every mode, including `Partial` and `PartialReduce`. Partial 
state is not unique on the group keys:
   
   - Operators that merge partitions, e.g. `RepartitionExec`, 
`SortPreservingMergeExec` and `CoalescePartitionsExec`, keep constraints, so 
after a merge the same key can come from several input partitions.
   - Even within one partition, a partial stage can emit the same group more 
than once (early emission under memory pressure, skipping partial aggregation, 
clustered partial aggregation emitting incomplete groups under memory pressure).
   
   `EquivalenceProperties::ordering_satisfy` uses `Unique` constraints: an 
ordering on `[k]` plus `Unique(k)` satisfies `[k, x]` for any `x`. With a stale 
`Unique(k)` this removes a sort that is needed.
   
   ### To Reproduce
   
   Two input partitions, each sorted on non-null `k`: `(1, 9), (2, 5)` and `(1, 
1), (2, 7)`. A `Partial` `sum(v)` grouped by `k`, under a parent that requires 
`Hash(k)` and `[k, sum]` within each partition. Run `EnsureRequirements` with 
`target_partitions = 2` and `prefer_existing_sort = true`:
   
   ```
   RepartitionExec: partitioning=Hash([k@0], 2), input_partitions=2, 
preserve_order=true, sort_exprs=k@0 ASC
     AggregateExec: mode=Partial, gby=[k@0 as k], aggr=[sum_v], 
group_clustering_mode=Full
       DataSourceExec: partitions=2, partition_sizes=[1, 1], 
output_ordering=k@0 ASC
   ```
   
   The sort on `[k, sum]` is gone, and the partition for `k = 1` comes out as 
`(1, 9), (1, 1)`. `SanityCheckPlan` accepts the plan because it uses the same 
`ordering_satisfy`. Without `prefer_existing_sort` the optimizer keeps a 
`SortExec(k, sum)` and the output is correct.
   
   The same happens directly in `SortExec`, which skips sorting when its input 
already satisfies the requested ordering. Each of the following under 
`SortExec([k, sum])` returns rows with equal `k` out of order:
   
   - `RepartitionExec(Hash(k)).with_preserve_order()` over the Partial aggregate
   - `SortPreservingMergeExec([k])` over it
   - `CoalescePartitionsExec` then `SortExec([k])` over it
   
   ### Expected behavior
   
   Only aggregation modes that produce final values (`Final`, 
`FinalPartitioned`, `Single`, `SinglePartitioned`) should declare `Unique` on 
the group keys.
   
   ### Additional context
   
   With the default SQL planner, the operator directly above the merge over a 
Partial aggregate is always the Final aggregate. That aggregate's ordering 
requirement covers only the group keys, and it declares its own (correct) 
`Unique`. I couldn't produce wrong results from SQL: I checked plans for `ORDER 
BY k, sum`, window functions ordered by `k, sum`, sort-merge joins of grouped 
subqueries, `DISTINCT` and `LIMIT`, with `prefer_existing_sort` and 
`repartition_sorts` on and off. The bug shows up in plans that put something 
other than an aggregate above Partial output: hand-built plans, custom 
optimizer rules, or planners that split stages between the Partial and Final 
aggregates.
   
   The constraint was added for all modes in #14111.
   


-- 
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