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

   ### What changes were proposed in this pull request?
   
   Dynamic partition pruning (DPP) builds a subquery that collects the distinct 
build-side join keys. Both `PlanDynamicPruningFilters` and 
`PlanAdaptiveDynamicPruningFilters` constructed it as `Aggregate(aliases, 
aliases, buildPlan)`, i.e. the grouping expressions were aliases of the join 
keys.
   
   This PR moves those aliases into a `Project` below the aggregate and groups 
by the attributes that projection produces:
   
   ```scala
   val groupingAttrs = aliases.map(_.toAttribute)
   val aggregate = Aggregate(groupingAttrs, groupingAttrs, Project(aliases, 
buildPlan))
   ```
   
   The subquery's output schema is unchanged; only where the alias is evaluated 
changes.
   
   Grouping by attributes produced by a lower `Project` is the shape that 
`PullOutGroupingExpressions` establishes for complex grouping expressions. DPP 
builds its subquery after logical optimization, so that rule never sees it; 
this change applies the same shape when the subquery is constructed.
   
   ### Why are the changes needed?
   
   When the build side is a storage-partitioned-join scan, it reports a 
`KeyedPartitioning`. Physical planning splits the aggregate into partial and 
final. The partial aggregate's `resultExpressions` use the grouping attributes 
(`groupingExpressions.map(_.toAttribute)`), so the `Alias` object is no longer 
part of `outputExpressions`. `BaseAggregateExec` extends 
`PartitioningPreservingUnaryExecNode`, whose alias map is built from the 
`Alias` nodes in `outputExpressions`, so it cannot project the scan's keyed 
expressions onto the aggregate's output attribute, drops the 
`KeyedPartitioning` and reports `UnknownPartitioning`. `EnsureRequirements` 
then inserts an `Exchange hashpartitioning(...)` between the partial and final 
aggregate.
   
   With a plain attribute as the grouping expression the partial aggregate 
keeps the keyed partitioning, and `EnsureRequirements` coalesces duplicate keys 
with `GroupPartitionsExec` instead of shuffling:
   
   ```
   Before
   HashAggregate (Final)
   +- Exchange hashpartitioning(id, 5)
      +- HashAggregate (Partial)
         +- Project / Filter / BatchScan (KeyedPartitioning)
   
   After
   HashAggregate (Final)
   +- GroupPartitionsExec
      +- HashAggregate (Partial)
         +- Project [id AS id]
            +- Filter
               +- BatchScan (KeyedPartitioning)
   ```
   
   JIRA: https://issues.apache.org/jira/browse/SPARK-60741
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. Query results are unchanged. The physical plan of the DPP build-side 
subquery no longer contains a shuffle when the build side reports 
`KeyedPartitioning`.
   
   ### How was this patch tested?
   
   A new test, `SPARK-60741: dynamic partition filtering keeps the build side's 
keyed partitioning`, in `KeyGroupedPartitioningRuntimeFilterTests` (it runs 
against both the `SupportsRuntimeFiltering` and the 
`SupportsRuntimeCatalystFiltering` fixtures), with `ADAPTIVE_EXECUTION_ENABLED` 
both off and on, covering `PlanDynamicPruningFilters` and 
`PlanAdaptiveDynamicPruningFilters` respectively. It asserts that the DPP 
subquery exists, that its plan has no `ShuffleExchangeLike` and contains a 
`GroupPartitionsExec`, that the outer storage-partitioned join adds no shuffle, 
and that the result is correct.
   
   Regression:
   
   * All 8 concrete `DynamicPartitionPruning*` suites: 341 passed, 11 ignored, 
0 failed.
   * `KeyGroupedPartitioningRuntimeFilterSuite` and its Catalyst variant, full 
run: 10 passed, 0 failed.
   
   ```bash
   build/sbt 'sql/testOnly *DynamicPartitionPruningV1SuiteAEOff 
*DynamicPartitionPruningV1SuiteAEOn *DynamicPartitionPruningV2SuiteAEOff 
*DynamicPartitionPruningV2SuiteAEOn *DynamicPartitionPruningV2FilterSuiteAEOff 
*DynamicPartitionPruningV2FilterSuiteAEOn 
*DynamicPartitionPruningV2CatalystFilterSuiteAEOff 
*DynamicPartitionPruningV2CatalystFilterSuiteAEOn'
   build/sbt 'sql/testOnly 
org.apache.spark.sql.connector.KeyGroupedPartitioningRuntimeFilterSuite 
org.apache.spark.sql.connector.KeyGroupedPartitioningCatalystRuntimeFilterSuite'
   ```
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (deepseek-flash[1m])
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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