andygrove opened a new issue, #7208:
URL: https://github.com/apache/datafusion-comet/issues/7208

   ### Describe the bug
   
   With AQE on (the default), a `REBALANCE(k)` hint followed by `GROUP BY k` 
returns duplicate groups when the data is skewed. Spark returns one row per 
key. Comet returns several rows for the skewed keys, each with a partial sum 
and count. A `PARTITION BY k` window above the rebalance has the same problem, 
so `row_number()` restarts inside a key.
   
   Spark's `OptimizeSkewInRebalancePartitions` splits the skewed shuffle 
partition (`AQEShuffleRead coalesced and skewed`). In plain Spark that is safe, 
because `ValidateRequirements` rejects the split when an operator above needs 
`ClusteredDistribution(k)`. Comet's aggregate and window operators declare no 
`requiredChildDistribution`, so the check passes. The native `Partial` and 
`Final` aggregates then run directly over the split partitions, and each piece 
of a key gets its own output row.
   
   - It reproduces with native shuffle, with JVM shuffle, and with 
`spark.comet.shuffle.directRead.enabled=false`.
   - It goes away with `spark.comet.exec.aggregate.enabled=false` or 
`spark.sql.adaptive.optimizeSkewsInRebalancePartitions.enabled=false`.
   
   The 1.1.0 release has the bug too. With the 1.1.0 jar on Spark 3.5.7, the 
query below returns 2000 rows; branch-1.2 on Spark 4.1 returns 1357. No release 
so far has declared a required distribution on these operators.
   
   ### Steps to reproduce
   
   Default configs except the two below, which make the skew split happen on a 
small input:
   
   ```scala
   spark.conf.set("spark.sql.shuffle.partitions", "200")
   spark.conf.set("spark.sql.adaptive.advisoryPartitionSizeInBytes", "2k")
   
   spark.range(0, 40000, 1, 8)
     .selectExpr("CASE WHEN id % 10 = 0 THEN 0L ELSE id % 1000 END AS k", "id 
AS v")
     .write.parquet("/tmp/rebal_t1")
   spark.read.parquet("/tmp/rebal_t1").createOrReplaceTempView("t1")
   
   spark.sql("""SELECT k, sum(v), count(*)
     FROM (SELECT /*+ REBALANCE(k) */ * FROM t1) GROUP BY k""").collect().length
   ```
   
   - Spark: 901 rows. Key 0 is one row, `(79980000, 4000)`.
   - Comet (branch-1.2, Spark 4.1): 1357 rows. Key 0 is four rows: `(17495000, 
1000)`, `(19995000, 1000)`, `(34995000, 1000)` and `(7495000, 1000)`.
   - Comet 1.1.0 (Spark 3.5.7): 2000 rows.
   
   Calling `.count()` on the DataFrame instead hides the bug, because the extra 
aggregate changes the plan.
   
   The plan:
   
   ```
   CometHashAggregate [k], [Final]
   +- CometHashAggregate [k], [Partial]
      +- AQEShuffleRead coalesced and skewed
         +- ShuffleQueryStage 0
            +- CometExchange hashpartitioning(k, 200), 
REBALANCE_PARTITIONS_BY_COL, CometNativeShuffle
               +- CometNativeScan parquet [k, v]
   ```
   
   The window case: `SELECT k, row_number() OVER (PARTITION BY k ORDER BY v) rn 
FROM (SELECT /*+ REBALANCE(k) */ * FROM t1)` has 1357 rows with `rn = 1` in 
Comet and 901 in Spark. The plan is `CometWindowExec` over `CometSort` over the 
same `AQEShuffleRead coalesced and skewed`.
   
   ### Expected behavior
   
   The same rows as Spark. Comet's operators that need their input clustered 
(aggregates with grouping keys, windows with a partition spec, joins) declare 
the same `requiredChildDistribution` as the Spark operators they replace, so 
AQE does not split partitions under them.
   
   ### Additional context
   
   Found in the branch-1.2 release audit (#7204). It is not a 1.2 regression. 
Searches for rebalance, skew and `requiredChildDistribution` found no existing 
issue.
   


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