ulysses-you opened a new pull request, #57603:
URL: https://github.com/apache/spark/pull/57603

   ### What changes were proposed in this pull request?
   
   This PR adds a new logical optimizer rule `PullUpProjectAliasThroughWindow`.
   
   When a window function's partition/order key is an alias of an underlying
   column, the rename lives in a `Project` *below* the window, while the
   analyzer-inserted `Project` *above* the window references the renamed column
   as a bare `Attribute` (empty alias map). Since `Window.outputPartitioning`
   /`outputOrdering` are pure pass-throughs of the child, the upper project
   cannot translate the child's `HashPartitioning(k)`/`SortOrder(k)` into the
   renamed attribute a downstream operator requires.
   
   The new rule pulls such aliases up from the bottom `Project` into the top
   `Project`, across a chain of one or more adjacent `Window` operators
   (`Project - Window+ - Project`), reusing the same exprId. After the rewrite,
   the top project's alias map maps `k -> a`, so the existing
   `PartitioningPreservingUnaryExecNode`/`OrderPreservingUnaryExecNode`
   machinery that `ProjectExec` mixes in projects the window's partitioning and
   ordering up through the alias. The `Window` operators themselves are left
   untouched.
   
   Example:
   ```sql
   SELECT userid, count(*), sum(size(vset))
   FROM (
     SELECT key AS userid, collect_set(value) OVER (PARTITION BY key) AS vset
     FROM testData
   ) u
   GROUP BY 1
   ```
   Before: the window shuffles on `key`, then a second, redundant shuffle on
   `userid` is inserted for the aggregate. After: a single shuffle.
   
   An entry of the bottom project is pulled up only when: it is an `Alias`; no
   window in the chain references it; all of its input attributes remain
   produced by the pruned bottom project; and the top project consumes its
   output solely as a bare pass-through attribute.
   
   Besides removing the redundant shuffle/sort, this also narrows the data
   crossing the window's shuffle: the alias no longer flows through the window
   as a separate column and is recomputed cheaply above the exchange.
   
   ### Why are the changes needed?
   
   To avoid a redundant shuffle (and possibly a redundant sort) whenever a
   downstream consumer (aggregate, repartition, chained window, ...) requires
   distribution/ordering on an alias of a window partition/order key. The window
   has already shuffled/sorted on the underlying key; the second exchange is
   pure overhead.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. It is a plan optimization; results are unchanged.
   
   ### How was this patch tested?
   
   New unit tests:
   - `PullUpProjectAliasThroughWindowSuite` (catalyst): 14 tests covering 
pull-up
     of partition/order key renames, multi-key windows, computed aliases whose
     inputs are all window keys, window chains, and the negative/idempotency/
     schema-preservation cases.
   - `ProjectedOrderingAndPartitioningSuite` (sql/core): 4 end-to-end tests
     asserting a single shuffle (and single sort where applicable) plus
     `checkAnswer` correctness, for aggregate/repartition/stacked-window/
     window-chain consumers.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Opus 4.8
   


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