[CORE] Add distinct FILTER boundary coverage for two-phase aggregate merge - #12741
Open
Smallfu666 wants to merge 1 commit into
Open
[CORE] Add distinct FILTER boundary coverage for two-phase aggregate merge#12741Smallfu666 wants to merge 1 commit into
Smallfu666 wants to merge 1 commit into
Conversation
…merge This records a non-merge boundary exposed while reviewing PR 12653. PR 12653 added FILTER-clause support to MergeTwoPhasesHashBaseAggregate. Its code comment used the single-distinct case as rationale for positional alignment over resultId matching. However, single-distinct + FILTER is outside this merge rule's scope: planAggregateWithOneDistinct inserts an exchange between the partial and final stages, breaking the direct parent-child relationship the rule requires. This PR: 1. Corrects the comment — removes the resultId rationale, keeps only the positional-alignment invariant. 2. Adds two boundary characterization tests verifying that distinct + FILTER is not merged into a single aggregate and that FILTER is preserved through the unmerged stages (results match vanilla Spark). Verified on Spark 3.4 + Scala 2.12 (AEOn + AEOff, 6/6 tests pass).
|
Run Gluten Clickhouse CI on x86 |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR clarifies the intended scope/behavior of MergeTwoPhasesHashBaseAggregate around DISTINCT + FILTER by (1) correcting an in-code rationale comment and (2) adding characterization tests that record the non-merge boundary caused by Spark’s planAggregateWithOneDistinct exchange insertion, while also validating results against vanilla Spark.
Changes:
- Update the merge-rule comment to rely only on Spark’s positional alignment invariant (not
resultIdmatching) when restoringFILTERpredicates. - Add two new test cases asserting
DISTINCT + FILTERplans are not merged into a single aggregate and that results match vanilla Spark (no fallback).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| gluten-ut/test/src/test/scala/org/apache/gluten/execution/MergeTwoPhasesHashBaseAggregateSuite.scala | Adds boundary tests for DISTINCT + FILTER ensuring no merge occurs and results match vanilla Spark. |
| gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/MergeTwoPhasesHashBaseAggregate.scala | Refines explanatory comment about how FILTER restoration is matched (positional alignment). |
Suppressed comments (1)
gluten-ut/test/src/test/scala/org/apache/gluten/execution/MergeTwoPhasesHashBaseAggregateSuite.scala:149
compareResultsAgainstVanillaSparkalready runs the query before callingcustomCheck; the extradf.collect()here executes the SQL an additional time. The executed plan can be inspected without re-running the query.
df => {
df.collect()
val plans = collect(df.queryExecution.executedPlan) {
case agg: HashAggregateExecBaseTransformer => agg
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+127
to
+133
| df => { | ||
| df.collect() | ||
| val plans = collect(df.queryExecution.executedPlan) { | ||
| case agg: HashAggregateExecBaseTransformer => agg | ||
| } | ||
| assert(plans.size > 1, "distinct + FILTER should not be merged into a single aggregate") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes are proposed in this pull request?
This records a non-merge boundary exposed while reviewing PR #12653.
PR #12653 added FILTER-clause support to
MergeTwoPhasesHashBaseAggregate. Its code comment used the single-distinct case as rationale for positional alignment overresultIdmatching. However, single-distinct + FILTER is outside this merge rule's scope:planAggregateWithOneDistinctinserts an exchange between the partial and final stages, breaking the direct parent-child relationship the rule requires.This PR:
resultIdrationale, keeps only the positional-alignment invariant.These tests would pass on
mainbefore #12653 was merged — distinct aggregates were never merged because of the exchange. This PR records a non-merge boundary, not a correctness regression fixed by #12653.How was this patch tested?
Verified on Spark 3.4 + Scala 2.12 (AEOn + AEOff, 6/6 tests pass) on the existing
MergeTwoPhasesHashBaseAggregateSuite. Both new cases usecompareResultsAgainstVanillaSpark(which checks Gluten result against vanilla Spark oracle and verifies no fallback).Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 4.8 GPT 5.6 sol