Repository navigation
Conversation
On Spark 3.4, BatchScanExec reports SinglePartition for a scan of one input partition, and Spark plans no exchange above it. The native Iceberg scan reported UnknownPartitioning(0). Since the aggregates declare their required distribution (apache#7231), EnsureRequirements, which AQE runs again over a DPP subquery's converted plan, inserted an exchange inside a native block that was already serialized, and the native scan lost its tasks. Report SinglePartition when the replaced scan does.
andygrove
left a comment
There was a problem hiding this comment.
Thanks @comphead. This is a tidy fix for the Spark 3.4 [scans] nightly failure.
I read DataSourceV2ScanExecBase and BatchScanExec at v3.4.3, v3.5.8 and v4.1.1. On 3.4, outputPartitioning is SinglePartition when partitions.length == 1, and partitions comes from the unfiltered inputPartitions. So reading it resolves no DPP subquery and the #6268 concern does not return. On 3.5 and later BatchScanExec never reports SinglePartition, so the new branch always falls through to UnknownPartitioning(0). The case where DPP prunes the only split is also covered, because serializePartitions keeps Spark's one empty partition in that case.
The originalPlan != null guard handles canonicalized instances. The SPARK-34637 test reproduces the failure and passes in CI with the Spark 3.4 profile. Looks good to me.
|
Thanks @andygrove for the review. 5fe99d2 drops the Spark 3.4 skip that #7423 added to the SPARK-34637 test, so the test exercises this fix on 3.4 again. The I added |
Which issue does this PR close?
Closes #7422.
Rationale for this change
On Spark 3.4,
DataSourceV2ScanExecBase.outputPartitioningreportsSinglePartitionfor a scan of one input partition. Spark 3.5 dropped that case. In the SPARK-34637 test, the two files that pass theunits_sold = 70filter form one split. Spark therefore plans the final aggregate of the DPP build side directly over the partial one, with no exchange between them. Comet then fuses both aggregates, the project, the filter and the native Iceberg scan into one native block. The scan reportsUnknownPartitioning(0)(#6268).AQE builds the DPP subquery's
AdaptiveSparkPlanExecover that converted build side and runsEnsureRequirementson it again. Since #7231, the finalCometHashAggregatereports Spark'sClusteredDistribution(store_id), while the partial aggregate below passes on the scan'sUnknownPartitioning(0). SoEnsureRequirementsinserts an exchange inside the native block, which is already serialized with the scan inlined.findAllPlanDatano longer reaches the scan through the new exchange, and the nativeIcebergScangets no schema or tasks:Column index 1 is out of bound. This is theSpark 3.4 [scans]failure in the nightly run since #7231 landed.What changes are included in this PR?
CometIcebergNativeScanExec.outputPartitioningreportsSinglePartitionwhen theBatchScanExecit replaces does, andUnknownPartitioning(0)otherwise, as before. RunningEnsureRequirementsagain then finds the requirement satisfied, as Spark did.planInputPartitions(), before runtime filtering, so reading it resolves no DPP subquery, which is the problem fix: do not resolve DPP subqueries when AQE reads a native scan's partitioning #6268 avoided.serializePartitionsalready keeps Spark's one empty partition, so the native block still runs exactly one partition.BatchScanExecnever reportsSinglePartition, so nothing changes there.How are these changes tested?
CometIcebergNativeSuite"AQE DPP - V2 broadcast query stage creation order (SPARK-34637)" reproduces the failure on Spark 3.4 and covers the fix. This PR removes the Spark 3.4 skip that #7423 added to it. Spark 3.4 runs only throughrun-all-spark-profiles, and the Iceberg suites throughrun-iceberg-tests. The Spark 3.4 profile does not build offline in my environment, so I have not run it locally yet. On Spark 4.1, the suite's 25 DPP tests pass.