ulysses-you commented on code in PR #58659:
URL: https://github.com/apache/spark/pull/58659#discussion_r4012377678
##########
sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/GroupPartitionsExec.scala:
##########
@@ -64,70 +72,15 @@ import org.apache.spark.sql.vectorized.ColumnarBatch
*/
case class GroupPartitionsExec(
child: SparkPlan,
- @transient joinKeyPositions: Option[Seq[Int]] = None,
- @transient expectedPartitionKeys:
Option[Seq[(InternalRowComparableWrapper, Int)]] = None,
- @transient reducers: Option[Seq[Option[KeyReducer]]] = None,
- @transient distributePartitions: Boolean = false,
- @transient enableSortedMerge: Boolean = false
+ @transient grouping: PartitionGrouping,
Review Comment:
grouping and outputPartitioning are carried over a child rewrite (:302-303),
and the factory doc (:404-415) states the invariant that nothing in the tree
hands this node a child reporting a different partitioning. I verified it for
the codegen and columnar wrappers (ColumnarToRowExec, RowToColumnarExec,
InputAdapter, WholeStageCodegenExec all report child.outputPartitioning), but
not for AQE, and I could not settle it by reading.
A probe at this head shows what the carried fields do once the invariant is
broken:
- withNewChildren(Seq(childReportingOnePartition)) still reports
numPartitions 2 and groups the two old input partitions, silently, while
child.outputPartitioning reports 1.
- A Java serialization round trip leaves grouping == null (NPE on
groupedPartitions) and an outputPartitioning whose KeyLayout.partitionKeys is
null (KeyLayout:493 is `@transient`) while numPartitions still reports the old
count, so toString and equals change across the wire.
The base held all three of these as `@transient` ... lazy val (base :77,
:226, :309), so a rewritten or deserialized node recomputed them from its new
child and could not be stale.
The rewriter I could not rule out is an AQEShuffleReadExec landing between
this node and a keyed shuffle child: CoalesceShufflePartitions.isSupported
accepts a keyed ENSURE_REQUIREMENTS shuffle (CoalesceShufflePartitions:38-44),
and AQEShuffleReadExec reports UnknownPartitioning for a keyed shuffle
(AQEShuffleReadExec:100-105). With the stale keyed claim the join above still
satisfies its distribution, so ValidateRequirements.validate
(AdaptiveSparkPlanExec:205-213) would accept the coalesced plan, where the base
rejects it and reverts the rewrite.
Since I could not build a plan with a GroupPartitionsExec directly over a
keyed ShuffleExchangeExec, I am not calling this blocking. Could we either
re-derive in withNewChildInternal when newChild.outputPartitioning ne
child.outputPartitioning, or name in the doc the rules that guarantee the
invariant? Either way a future child-rewriting rule fails loudly instead of
reading a layout its child no longer has.
--
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]