Uh oh!
There was an error while loading. Please reload this page.
[fix](agg) Fix grouping function handling and repeatSlotIdList calculation in DecomposeRepeatWithPreAggregation - #60091
Conversation
hello-stephen
commented
Jan 21, 2026
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
feiniaofeiafei
commented
Jan 21, 2026
run buildall |
doris-robot
commented
Jan 21, 2026
TPC-H: Total hot run time: 31857 ms |
doris-robot
commented
Jan 21, 2026
TPC-DS: Total hot run time: 174145 ms |
doris-robot
commented
Jan 21, 2026
ClickBench: Total hot run time: 26.84 s |
hello-stephen
commented
Jan 21, 2026
FE UT Coverage ReportIncrement line coverage |
hello-stephen
commented
Jan 21, 2026
FE Regression Coverage ReportIncrement line coverage |
ae3ef77 to
43a9454Comparefeiniaofeiafei
commented
Jan 23, 2026
run buildall |
doris-robot
commented
Jan 23, 2026
TPC-H: Total hot run time: 30728 ms |
doris-robot
commented
Jan 23, 2026
TPC-DS: Total hot run time: 173968 ms |
doris-robot
commented
Jan 23, 2026
ClickBench: Total hot run time: 26.83 s |
hello-stephen
commented
Jan 23, 2026
FE Regression Coverage ReportIncrement line coverage |
feiniaofeiafei
commented
Jan 26, 2026
run buildall |
1 similar comment
feiniaofeiafei
commented
Jan 26, 2026
run buildall |
hello-stephen
commented
Jan 26, 2026
FE UT Coverage ReportIncrement line coverage |
doris-robot
commented
Jan 26, 2026
TPC-H: Total hot run time: 30939 ms |
doris-robot
commented
Jan 26, 2026
TPC-DS: Total hot run time: 173439 ms |
doris-robot
commented
Jan 26, 2026
ClickBench: Total hot run time: 27.16 s |
feiniaofeiafei
commented
Jan 26, 2026
run cloud_p0 |
hello-stephen
commented
Jan 26, 2026
FE Regression Coverage ReportIncrement line coverage |
1 similar comment
hello-stephen
commented
Jan 26, 2026
FE Regression Coverage ReportIncrement line coverage |
feiniaofeiafei
commented
Jan 27, 2026
run buildall |
doris-robot
commented
Jan 27, 2026
TPC-H: Total hot run time: 32310 ms |
doris-robot
commented
Jan 27, 2026
ClickBench: Total hot run time: 28.57 s |
feiniaofeiafei
commented
Jan 27, 2026
run p0 |
feiniaofeiafei
commented
Jan 27, 2026
run cloud_p0 |
feiniaofeiafei
commented
Jan 27, 2026
run feut |
feiniaofeiafei
commented
Jan 27, 2026
run p0 |
feiniaofeiafei
commented
Feb 9, 2026
run buildall |
doris-robot
commented
Feb 9, 2026
TPC-H: Total hot run time: 30443 ms |
doris-robot
commented
Feb 9, 2026
TPC-DS: Total hot run time: 190819 ms |
doris-robot
commented
Feb 9, 2026
ClickBench: Total hot run time: 28.31 s |
feiniaofeiafei
commented
Feb 9, 2026
run buildall |
doris-robot
commented
Feb 9, 2026
TPC-H: Total hot run time: 30928 ms |
doris-robot
commented
Feb 9, 2026
ClickBench: Total hot run time: 28.37 s |
hello-stephen
commented
Feb 9, 2026
FE UT Coverage ReportIncrement line coverage |
feiniaofeiafei
commented
Feb 9, 2026
run buildall |
doris-robot
commented
Feb 9, 2026
TPC-H: Total hot run time: 30167 ms |
doris-robot
commented
Feb 9, 2026
ClickBench: Total hot run time: 28.32 s |
hello-stephen
commented
Feb 9, 2026
FE UT Coverage ReportIncrement line coverage |
hello-stephen
commented
Feb 9, 2026
FE Regression Coverage ReportIncrement line coverage |
PR approved by at least one committer and no changes requested. |
PR approved by anyone and no changes requested. |
Uh oh!
There was an error while loading. Please reload this page.
…ation in DecomposeRepeatWithPreAggregation (apache#60091) Related PR: apache#59116apache#60045 **Problem Summary:** There are 2 problems: 1. When `DecomposeRepeatWithPreAggregation` optimization removes the maximum grouping set, grouping functions (e.g., `grouping()`, `grouping_id()`) that reference expressions only existing in the removed grouping set would fail because of index lookup failure: When computing grouping function values, `GroupingSetShapes.indexOf()` would return -1 for expressions not in `flattenGroupingSetExpression`, causing incorrect behavior. Example scenario: ```sql SELECT a, b, c, grouping(c) FROM t1 GROUP BY GROUPING SETS ((a, b, c), (a, b), (a), ()); ``` After optimization removes the maximum grouping set `(a, b, c)`, the expression `c` no longer exists in the remaining grouping sets. When computing `grouping(c)`, the index lookup would fail. 2. The `repeatSlotIdList` calculation was incorrect because it relied on the assumption that the order of `physicalRepeat.getOutputExpressions()` matches the order of `outputTuple`. However, this assumption can be broken during rule rewriting (e.g., in `DecomposeRepeatWithPreAggregation.constructRepeat()` at line 502-503, where `replacedRepeatOutputs` is constructed by `new ArrayList<>(child.getOutput())` and then appends grouping functions, potentially changing the order). This mismatch causes incorrect slot ID mapping and wrong query results. Example scenario: When `DecomposeRepeatWithPreAggregation` rewrites a repeat plan, the output expressions order may differ from the output tuple order, leading to incorrect slot ID mapping in `repeatSlotIdList`. **Solution:** 1. For problem 1: Modified `Repeat.toShapes()` method to ensure all expressions referenced by grouping functions are included in `flattenGroupingSetExpression`, even if they are not in any grouping set. For expressions that only exist in the removed maximum grouping set, they are correctly marked as `shouldBeErasedToNull = true` in all remaining grouping sets, which is the correct SQL semantics. Key changes: - `Repeat.toShapes()`: Enhanced to collect all expressions referenced by grouping functions using `ExpressionUtils.collectToList()` and merge them into `flattenGroupingSetExpression` - For expressions not in any grouping set, they are correctly marked as `shouldBeErasedToNull = true` in all `GroupingSetShape` instances - This ensures `GroupingSetShapes.indexOf()` always returns a valid index for grouping function arguments, preventing index lookup failures 2. For problem 2: Modified `Repeat.computeRepeatSlotIdList()` method to accept an additional `outputSlots` parameter. Instead of relying on the order of `outputExpressions` matching `outputTuple`, the method now uses `outputSlots` to correctly map grouping set expressions to their indices in the output tuple. This ensures correct slot ID calculation even when rule rewriting changes the order of output expressions. Key changes: - `computeRepeatSlotIdList(List<Integer> slotIdList, List<Slot> outputSlots)`: Added `outputSlots` parameter - `getGroupingSetsIndexesInOutput(List<Slot> outputSlots)`: Modified to use `outputSlots` instead of `getOutputExpressions()` - `indexesOfOutput(List<Slot> outputSlots)`: Modified to build index map from `outputSlots` instead of `getOutputExpressions()` - `PhysicalPlanTranslator.visitPhysicalRepeat()`: Updated to pass `outputSlots` to `computeRepeatSlotIdList()` 3. Another task for this pull request is to set the shuffle key for the rewritten bottom aggregation. Choosing a suitable shuffle key can improve the aggregation rate of the top aggregation's local aggregation.
…ation in DecomposeRepeatWithPreAggregation (apache#60091) Related PR: apache#59116apache#60045 **Problem Summary:** There are 2 problems: 1. When `DecomposeRepeatWithPreAggregation` optimization removes the maximum grouping set, grouping functions (e.g., `grouping()`, `grouping_id()`) that reference expressions only existing in the removed grouping set would fail because of index lookup failure: When computing grouping function values, `GroupingSetShapes.indexOf()` would return -1 for expressions not in `flattenGroupingSetExpression`, causing incorrect behavior. Example scenario: ```sql SELECT a, b, c, grouping(c) FROM t1 GROUP BY GROUPING SETS ((a, b, c), (a, b), (a), ()); ``` After optimization removes the maximum grouping set `(a, b, c)`, the expression `c` no longer exists in the remaining grouping sets. When computing `grouping(c)`, the index lookup would fail. 2. The `repeatSlotIdList` calculation was incorrect because it relied on the assumption that the order of `physicalRepeat.getOutputExpressions()` matches the order of `outputTuple`. However, this assumption can be broken during rule rewriting (e.g., in `DecomposeRepeatWithPreAggregation.constructRepeat()` at line 502-503, where `replacedRepeatOutputs` is constructed by `new ArrayList<>(child.getOutput())` and then appends grouping functions, potentially changing the order). This mismatch causes incorrect slot ID mapping and wrong query results. Example scenario: When `DecomposeRepeatWithPreAggregation` rewrites a repeat plan, the output expressions order may differ from the output tuple order, leading to incorrect slot ID mapping in `repeatSlotIdList`. **Solution:** 1. For problem 1: Modified `Repeat.toShapes()` method to ensure all expressions referenced by grouping functions are included in `flattenGroupingSetExpression`, even if they are not in any grouping set. For expressions that only exist in the removed maximum grouping set, they are correctly marked as `shouldBeErasedToNull = true` in all remaining grouping sets, which is the correct SQL semantics. Key changes: - `Repeat.toShapes()`: Enhanced to collect all expressions referenced by grouping functions using `ExpressionUtils.collectToList()` and merge them into `flattenGroupingSetExpression` - For expressions not in any grouping set, they are correctly marked as `shouldBeErasedToNull = true` in all `GroupingSetShape` instances - This ensures `GroupingSetShapes.indexOf()` always returns a valid index for grouping function arguments, preventing index lookup failures 2. For problem 2: Modified `Repeat.computeRepeatSlotIdList()` method to accept an additional `outputSlots` parameter. Instead of relying on the order of `outputExpressions` matching `outputTuple`, the method now uses `outputSlots` to correctly map grouping set expressions to their indices in the output tuple. This ensures correct slot ID calculation even when rule rewriting changes the order of output expressions. Key changes: - `computeRepeatSlotIdList(List<Integer> slotIdList, List<Slot> outputSlots)`: Added `outputSlots` parameter - `getGroupingSetsIndexesInOutput(List<Slot> outputSlots)`: Modified to use `outputSlots` instead of `getOutputExpressions()` - `indexesOfOutput(List<Slot> outputSlots)`: Modified to build index map from `outputSlots` instead of `getOutputExpressions()` - `PhysicalPlanTranslator.visitPhysicalRepeat()`: Updated to pass `outputSlots` to `computeRepeatSlotIdList()` 3. Another task for this pull request is to set the shuffle key for the rewritten bottom aggregation. Choosing a suitable shuffle key can improve the aggregation rate of the top aggregation's local aggregation.
What problem does this PR solve?
Related PR: #59116#60045
Problem Summary:
There are 2 problems:
DecomposeRepeatWithPreAggregationoptimization removes the maximum grouping set, grouping functions (e.g.,grouping(),grouping_id()) that reference expressions only existing in the removed grouping set would fail because of index lookup failure: When computing grouping function values,GroupingSetShapes.indexOf()would return -1 for expressions not inflattenGroupingSetExpression, causing incorrect behavior.Example scenario:
After optimization removes the maximum grouping set
(a, b, c), the expressioncno longer exists in the remaining grouping sets. When computinggrouping(c), the index lookup would fail.2. The
repeatSlotIdListcalculation was incorrect because it relied on the assumption that the order ofphysicalRepeat.getOutputExpressions()matches the order ofoutputTuple. However, this assumption can be broken during rule rewriting (e.g., inDecomposeRepeatWithPreAggregation.constructRepeat()at line 502-503, wherereplacedRepeatOutputsis constructed bynew ArrayList<>(child.getOutput())and then appends grouping functions, potentially changing the order). This mismatch causes incorrect slot ID mapping and wrong query results.Example scenario:
When
DecomposeRepeatWithPreAggregationrewrites a repeat plan, the output expressions order may differ from the output tuple order, leading to incorrect slot ID mapping inrepeatSlotIdList.Solution:
Repeat.toShapes()method to ensure all expressions referenced by grouping functions are included inflattenGroupingSetExpression, even if they are not in any grouping set. For expressions that only exist in the removed maximum grouping set, they are correctly marked asshouldBeErasedToNull = truein all remaining grouping sets, which is the correct SQL semantics.Key changes:
Repeat.toShapes(): Enhanced to collect all expressions referenced by grouping functions usingExpressionUtils.collectToList()and merge them intoflattenGroupingSetExpressionshouldBeErasedToNull = truein allGroupingSetShapeinstancesGroupingSetShapes.indexOf()always returns a valid index for grouping function arguments, preventing index lookup failuresRepeat.computeRepeatSlotIdList()method to accept an additionaloutputSlotsparameter. Instead of relying on the order ofoutputExpressionsmatchingoutputTuple, the method now usesoutputSlotsto correctly map grouping set expressions to their indices in the output tuple. This ensures correct slot ID calculation even when rule rewriting changes the order of output expressions.Key changes:
computeRepeatSlotIdList(List<Integer> slotIdList, List<Slot> outputSlots): AddedoutputSlotsparametergetGroupingSetsIndexesInOutput(List<Slot> outputSlots): Modified to useoutputSlotsinstead ofgetOutputExpressions()indexesOfOutput(List<Slot> outputSlots): Modified to build index map fromoutputSlotsinstead ofgetOutputExpressions()PhysicalPlanTranslator.visitPhysicalRepeat(): Updated to passoutputSlotstocomputeRepeatSlotIdList()Release note
None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)