peter-toth commented on code in PR #58335:
URL: https://github.com/apache/spark/pull/58335#discussion_r3880264752


##########
sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/GroupPartitionsExec.scala:
##########
@@ -59,7 +58,7 @@ case class GroupPartitionsExec(
     child: SparkPlan,
     @transient joinKeyPositions: Option[Seq[Int]] = None,
     @transient expectedPartitionKeys: 
Option[Seq[(InternalRowComparableWrapper, Int)]] = None,
-    @transient reducers: Option[Seq[Option[Reducer[_, _]]]] = None,
+    @transient reducers: Option[Seq[Option[KeyReducer]]] = None,

Review Comment:
   **Finding 8** (my numbering) — an addition to this, measured on 
`c01535cc6ed`.
   
   The normalization does not fire in the two shapes this PR fixes. Since the 
third commit stores the raw target transform, `reducedExpression` is the 
*other* join side's expression: `t` for the identity-vs-transform reducer, `e2` 
for the single-side-transform one. `QueryPlan.normalizeExpressions(expr, 
child.output)` rewrites an attribute only when `child.output` contains its 
exprId, and this node's child is the reduced side, so the other side's 
attribute is left untouched. It fires only for the both-sides-reduce shape, 
where `reducedExpression` is this side's own `e1` — the one shape whose 
expression is stale anyway.
   
   Measured with two `GroupPartitionsExec`s over `LocalTableScanExec(id#1)` and 
`LocalTableScanExec(id#2)`, a value-equal `BucketReducer(2)`, and 
`reducedExpression` built over a third attribute standing in for the other side 
(`oid#11` / `oid#12`):
   
   ```
   PROBE other-side attribute in reducedExpression, canonical equal = false
   ```
   
   The same pair with `reducedExpression` over the node's own attribute — the 
shape the new test builds — gives `true`.
   
   There is a second, independent cause. The synthesized identity reducer is 
`new Reducer[Any, Any] {...}`, so `KeyReducer.equals` compares it by reference. 
Taking the reducer from `reducersBothWays` for an `identity(id)` / `bucket(2, 
id)` pair, with everything else structurally identical:
   
   ```
   PROBE identity-derived reducer, canonical equal = false
   ```
   
   That half is pre-existing — the anonymous reducer was already a constructor 
field of `GroupPartitionsExec` before this PR — so "with value-equal reducers" 
in the commit message is accurate. It does mean the identity-vs-transform 
shape, this PR's headline case, still does not deduplicate.
   
   Fix shape: normalize `reducedExpression` against its own references instead 
of the child's output — the scaladoc already says the attribute it carries is 
not load-bearing, so a positional canonical form is enough — and make the 
synthesized reducer a named case class over the target transform so it compares 
by value, normalizing that expression too, or the exprId problem you just fixed 
reappears inside the reducer. Extending the new test with an identity-derived 
reducer, and with a `reducedExpression` over an attribute the child does not 
output, would pin both.
   



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