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]

Reply via email to