ulysses-you commented on code in PR #59317:
URL: https://github.com/apache/spark/pull/59317#discussion_r4269575803


##########
sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/GroupPartitionsExec.scala:
##########
@@ -667,6 +667,14 @@ private[sql] object GroupPartitionsExec {
       val splits = keyMap.getOrElse(key, Seq.empty)
       numMatchedPartitions += splits.size
       if (distributePartitions) {
+        // `padTo` only pads, never truncates, so a key holding more splits 
than its expected
+        // count would be emitted more times than the count says, while 
`isGrouped` can still read
+        // as grouped. A join split would then fail the `committed` gate in 
`EnsureRequirements`
+        // and silently fall back to a shuffle, and an ordering split would 
report duplicate keys
+        // as grouped. Fail fast here, where the alignment is owned, instead 
of either.
+        assert(splits.size <= numSplits,

Review Comment:
   The precondition here needs a condition attached. The counts compared 
against come from `EnsureRequirements.scala:898-903`, which groups the spread 
side's keys projected but not reduced, while `mergedPartitionKeys` (`:799-802`) 
and this node's grouping (`:706-715`) are in the reduced key space. A reducer 
that merges key values is reachable with partial clustering on: a same-function 
pair is admitted at `partitioning.scala:2309` without consulting 
`canReduceKeys`, and `reducersBothWays` runs unconditionally at 
`EnsureRequirements.scala:774`. Then a reduced key's count is read off an 
unrelated raw key.
   
   Two tables of four rows partitioned by a self-reducing transform reproduce 
it. On master the query returns the right rows after a silent shuffle (the 
planner logs `Not storage-partitioning this join after all: the two sides no 
longer declare the same partition keys once regrouped onto the merged partition 
values`, and both sides get `Exchange hashpartitioning(id, 5), 
ENSURE_REQUIREMENTS` with no `GroupPartitionsExec` left); with this patch it 
fails at planning with `more splits (2) than its expected count (1)`.
   
   Reducing the spread side's keys with the same reducers before that `groupBy` 
puts the counts in this node's space, keeps the pairing, and makes the 
precondition hold by construction. Otherwise the comment should say what the 
guard trades: for that input, a correct-but-shuffled plan becomes a failed 
query.



##########
sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/GroupPartitionsExec.scala:
##########
@@ -667,6 +667,14 @@ private[sql] object GroupPartitionsExec {
       val splits = keyMap.getOrElse(key, Seq.empty)
       numMatchedPartitions += splits.size
       if (distributePartitions) {
+        // `padTo` only pads, never truncates, so a key holding more splits 
than its expected
+        // count would be emitted more times than the count says, while 
`isGrouped` can still read
+        // as grouped. A join split would then fail the `committed` gate in 
`EnsureRequirements`
+        // and silently fall back to a shuffle, and an ordering split would 
report duplicate keys

Review Comment:
   The `ordering split` half of this sentence describes a state its producer 
cannot reach. `EnsureRequirements.scala:153-155` derives the expected counts by 
grouping the same `partitionKeys` this node groups at `:706-715`, so there is 
no independent count a repeated key could survive, and a repeated key already 
sets `isGrouped` false at `:666`. The join half is accurate; suggest dropping 
the ordering half or stating the two producers' counts directly.



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