This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new 74e1a1e5b6b branch-4.0: [fix](nereids) Fix aggregate source repeat
output is different from child repeat #57840 (#58088)
74e1a1e5b6b is described below
commit 74e1a1e5b6b059bf28b20fc27787e7481480dceb
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Nov 18 14:07:49 2025 +0800
branch-4.0: [fix](nereids) Fix aggregate source repeat output is different
from child repeat #57840 (#58088)
Cherry-picked from #57840
Co-authored-by: seawinde <[email protected]>
---
.../trees/copier/LogicalPlanDeepCopier.java | 8 ++-
.../trees/plans/logical/LogicalAggregate.java | 7 ++
.../trees/copier/LogicalPlanDeepCopierTest.java | 76 +++++++++++++++++++++-
3 files changed, 89 insertions(+), 2 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
index e85c6eb8dae..5c5b98b26d7 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
@@ -186,7 +186,13 @@ public class LogicalPlanDeepCopier extends
DefaultPlanRewriter<DeepCopierContext
List<NamedExpression> outputExpressions =
aggregate.getOutputExpressions().stream()
.map(o -> (NamedExpression)
ExpressionDeepCopier.INSTANCE.deepCopy(o, context))
.collect(ImmutableList.toImmutableList());
- return aggregate.withChildGroupByAndOutput(groupByExpressions,
outputExpressions, child);
+ LogicalAggregate<Plan> copiedAggregate =
aggregate.withChildGroupByAndOutput(groupByExpressions,
+ outputExpressions, child);
+ Optional<LogicalRepeat<? extends Plan>> childRepeat =
+ copiedAggregate.collectFirst(LogicalRepeat.class::isInstance);
+ return childRepeat.isPresent() ?
aggregate.withChildGroupByAndOutputAndSourceRepeat(
+ groupByExpressions, outputExpressions, child, childRepeat)
+ : aggregate.withChildGroupByAndOutput(groupByExpressions,
outputExpressions, child);
}
@Override
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
index 7401dbbaea7..07a2d1b7d97 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalAggregate.java
@@ -352,6 +352,13 @@ public class LogicalAggregate<CHILD_TYPE extends Plan>
hasPushed, withInProjection, sourceRepeat, Optional.empty(),
Optional.empty(), newChild);
}
+ public LogicalAggregate<Plan>
withChildGroupByAndOutputAndSourceRepeat(List<Expression> groupByExprList,
+
List<NamedExpression> outputExpressionList, Plan newChild,
+
Optional<LogicalRepeat<?>> sourceRepeat) {
+ return new LogicalAggregate<>(groupByExprList, outputExpressionList,
normalized, ordinalIsResolved, generated,
+ hasPushed, withInProjection, sourceRepeat, Optional.empty(),
Optional.empty(), newChild);
+ }
+
public LogicalAggregate<Plan> withChildAndOutput(CHILD_TYPE child,
List<NamedExpression>
outputExpressionList) {
return new LogicalAggregate<>(groupByExpressions,
outputExpressionList, normalized, ordinalIsResolved,
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java
index fcbb4fbc0c2..bc2dbe097f0 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopierTest.java
@@ -17,22 +17,96 @@
package org.apache.doris.nereids.trees.copier;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat;
import org.apache.doris.nereids.util.PlanConstructor;
+import com.google.common.collect.ImmutableList;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
public class LogicalPlanDeepCopierTest {
@Test
public void testDeepCopyOlapScan() {
LogicalOlapScan relationPlan = PlanConstructor.newLogicalOlapScan(0,
"a", 0);
relationPlan = (LogicalOlapScan)
relationPlan.withOperativeSlots(relationPlan.getOutput());
- LogicalOlapScan aCopy = (LogicalOlapScan)
relationPlan.accept(LogicalPlanDeepCopier.INSTANCE, new DeepCopierContext());
+ LogicalOlapScan aCopy =
+ (LogicalOlapScan)
relationPlan.accept(LogicalPlanDeepCopier.INSTANCE, new DeepCopierContext());
for (Slot opSlot : aCopy.getOperativeSlots()) {
Assertions.assertTrue(aCopy.getOutputSet().contains(opSlot));
}
}
+
+ @Test
+ public void testDeepCopyAggregateWithSourceRepeat() {
+ LogicalOlapScan scan = PlanConstructor.newLogicalOlapScan(0, "t", 0);
+ List<? extends NamedExpression> groupingKeys =
scan.getOutput().subList(0, 1);
+ List<List<Expression>> groupingSets = ImmutableList.of(
+ ImmutableList.of(groupingKeys.get(0)),
+ ImmutableList.of()
+ );
+ LogicalRepeat<Plan> repeat = new LogicalRepeat<>(
+ groupingSets,
+
scan.getOutput().stream().map(NamedExpression.class::cast).collect(Collectors.toList()),
+ scan
+ );
+ List<? extends NamedExpression> groupByExprs =
repeat.getOutput().subList(0, 1).stream()
+ .map(e -> (NamedExpression) e)
+ .collect(ImmutableList.toImmutableList());
+ List<? extends NamedExpression> outputExprs = repeat.getOutput();
+ LogicalAggregate aggregate = new LogicalAggregate(
+ groupByExprs,
+ outputExprs,
+ repeat
+ );
+ aggregate = aggregate.withSourceRepeat(repeat);
+ DeepCopierContext context = new DeepCopierContext();
+ LogicalAggregate<? extends Plan> copiedAggregate = (LogicalAggregate<?
extends Plan>) aggregate.accept(
+ LogicalPlanDeepCopier.INSTANCE,
+ context
+ );
+ Assertions.assertTrue(copiedAggregate.getSourceRepeat().isPresent());
+
+ Optional<LogicalRepeat<? extends Plan>> copiedRepeat =
+ copiedAggregate.collectFirst(LogicalRepeat.class::isInstance);
+ Assertions.assertTrue(copiedRepeat.isPresent());
+ Assertions.assertSame(copiedAggregate.getSourceRepeat().get(),
copiedRepeat.get());
+
+ Assertions.assertNotSame(aggregate, copiedAggregate);
+ Assertions.assertNotSame(repeat, copiedRepeat.get());
+ }
+
+ @Test
+ public void testDeepCopyAggregateWithoutSourceRepeat() {
+ LogicalOlapScan scan = PlanConstructor.newLogicalOlapScan(0, "t", 0);
+ List<Expression> groupByExprs = scan.getOutput().subList(0, 1).stream()
+ .map(e -> (Expression) e)
+ .collect(ImmutableList.toImmutableList());
+ List<? extends NamedExpression> outputExprs = scan.getOutput();
+
+ LogicalAggregate aggregate = new LogicalAggregate(
+ groupByExprs,
+ outputExprs,
+ scan
+ );
+ DeepCopierContext context = new DeepCopierContext();
+ LogicalAggregate<? extends Plan> copiedAggregate = (LogicalAggregate<?
extends Plan>) aggregate.accept(
+ LogicalPlanDeepCopier.INSTANCE,
+ context
+ );
+ Assertions.assertFalse(copiedAggregate.getSourceRepeat().isPresent());
+ Assertions.assertNotSame(aggregate, copiedAggregate);
+ Assertions.assertEquals(aggregate.getGroupByExpressions().size(),
+ copiedAggregate.getGroupByExpressions().size());
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]