This is an automated email from the ASF dual-hosted git repository.

starocean999 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 893a1e92399 [fix](nereids) Fix aggregate source repeat output is 
different from child repeat (#57840)
893a1e92399 is described below

commit 893a1e92399d1cfd17eec4ec09523e4f1d22bf1b
Author: seawinde <[email protected]>
AuthorDate: Mon Nov 17 17:36:47 2025 +0800

    [fix](nereids) Fix aggregate source repeat output is different from child 
repeat (#57840)
    
    if cte def has group sets, after cte inline, the aggregate source repeat
    output is different from child repeat
    the pr fix this
    
    such query as following
    ```sql
                with t as (
                    select t1.l_partkey, t1.l_suppkey, o_orderdate,
                    grouping(t1.l_suppkey),
                    grouping(o_orderdate),
                    grouping_id(t1.l_partkey, t1.l_suppkey),
                    grouping_id(t1.l_partkey, t1.l_suppkey, o_orderdate),
                    sum(o_totalprice),
                    max(o_totalprice),
                    min(o_totalprice),
                    count(*),
                    count(distinct case when o_shippriority > 1 and o_orderkey 
IN (1, 3) then o_custkey else null end)
                    from (select * from lineitem where l_shipdate = 
'2023-12-11') t1
                    left join orders on t1.l_orderkey = orders.o_orderkey and 
t1.l_shipdate = o_orderdate
                    group by
                    GROUPING SETS ((l_shipdate, o_orderdate, l_partkey), 
(l_partkey, l_suppkey), (l_suppkey), ())
                )
                select t1.l_suppkey, t2.o_orderdate
                from
                t t1
                inner join
                t t2 on t1.l_partkey = t2.l_partkey;
    ```
---
 .../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