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 4444abc828 avoid contruct groupExpr in graph-simplifier (#16436)
4444abc828 is described below

commit 4444abc828d3ab05bd31b6a3720eed2013a7877e
Author: 谢健 <jianx...@gmail.com>
AuthorDate: Tue Feb 14 17:03:21 2023 +0800

    avoid contruct groupExpr in graph-simplifier (#16436)
    
    Signed-off-by: xiejiann <jianx...@gmail.com>
---
 .../java/org/apache/doris/nereids/PlanContext.java |  50 ++++---
 .../apache/doris/nereids/cost/CostCalculator.java  |  14 +-
 .../nereids/jobs/joinorder/hypergraph/Edge.java    |   8 --
 .../jobs/joinorder/hypergraph/GraphSimplifier.java | 149 +++++++++++----------
 .../nereids/properties/RequestPropertyDeriver.java |   4 +-
 .../doris/nereids/stats/StatsCalculator.java       |   1 -
 .../doris/nereids/trees/plans/GroupPlan.java       |   6 +
 7 files changed, 118 insertions(+), 114 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/PlanContext.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/PlanContext.java
index 6ad6327291..1d2a1dd343 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/PlanContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/PlanContext.java
@@ -17,15 +17,12 @@
 
 package org.apache.doris.nereids;
 
-import org.apache.doris.common.Id;
 import org.apache.doris.nereids.memo.GroupExpression;
-import org.apache.doris.nereids.properties.LogicalProperties;
-import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.statistics.StatsDeriveResult;
 
-import com.google.common.base.Preconditions;
-
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -35,44 +32,43 @@ import java.util.List;
  * Inspired by GPORCA-CExpressionHandle.
  */
 public class PlanContext {
-    // attached group expression
-    private final GroupExpression groupExpression;
+    private List<StatsDeriveResult> childrenStats = new ArrayList<>();
+    private StatsDeriveResult planStats = new StatsDeriveResult(0);
+    private int arity = 0;
 
     /**
      * Constructor for PlanContext.
      */
     public PlanContext(GroupExpression groupExpression) {
-        this.groupExpression = groupExpression;
-    }
-
-    public GroupExpression getGroupExpression() {
-        return groupExpression;
+        this.arity = groupExpression.arity();
+        if (groupExpression.getOwnerGroup() == null) {
+            return;
+        }
+        planStats = groupExpression.getOwnerGroup().getStatistics();
+        childrenStats = new ArrayList<>();
+        for (int i = 0; i < groupExpression.arity(); i++) {
+            childrenStats.add(groupExpression.childStatistics(i));
+        }
     }
 
-    public StatsDeriveResult getStatisticsWithCheck() {
-        StatsDeriveResult statistics = 
groupExpression.getOwnerGroup().getStatistics();
-        Preconditions.checkNotNull(statistics);
-        return statistics;
+    public PlanContext(StatsDeriveResult planStats, StatsDeriveResult... 
childrenStats) {
+        this.planStats = planStats;
+        this.childrenStats = Arrays.asList(childrenStats);
+        this.arity = this.childrenStats.size();
     }
 
-    public LogicalProperties childLogicalPropertyAt(int index) {
-        return groupExpression.child(index).getLogicalProperties();
+    public int arity() {
+        return arity;
     }
 
-    public List<Slot> getChildOutputSlots(int index) {
-        return childLogicalPropertyAt(index).getOutput();
-    }
-
-    public List<Id> getChildOutputIds(int index) {
-        return childLogicalPropertyAt(index).getOutputExprIds();
+    public StatsDeriveResult getStatisticsWithCheck() {
+        return planStats;
     }
 
     /**
      * Get child statistics.
      */
     public StatsDeriveResult getChildStatistics(int index) {
-        StatsDeriveResult statistics = 
groupExpression.child(index).getStatistics();
-        Preconditions.checkNotNull(statistics);
-        return statistics;
+        return childrenStats.get(index);
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java
index 51fb7076f4..994566362b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java
@@ -90,6 +90,14 @@ public class CostCalculator {
         return costWeight.calculate(costEstimate);
     }
 
+    public static double calculateCost(Plan plan, PlanContext planContext) {
+        CostEstimator costCalculator = new CostEstimator();
+        CostEstimate costEstimate = plan.accept(costCalculator, planContext);
+        CostWeight costWeight = new CostWeight(CPU_WEIGHT, MEMORY_WEIGHT, 
NETWORK_WEIGHT,
+                
ConnectContext.get().getSessionVariable().getNereidsCboPenaltyFactor());
+        return costWeight.calculate(costEstimate);
+    }
+
     private static class CostEstimator extends PlanVisitor<CostEstimate, 
PlanContext> {
         @Override
         public CostEstimate visit(Plan plan, PlanContext context) {
@@ -226,8 +234,8 @@ public class CostCalculator {
         @Override
         public CostEstimate visitPhysicalHashJoin(
                 PhysicalHashJoin<? extends Plan, ? extends Plan> 
physicalHashJoin, PlanContext context) {
-            Preconditions.checkState(context.getGroupExpression().arity() == 
2);
-            StatsDeriveResult outputStats = 
physicalHashJoin.getGroupExpression().get().getOwnerGroup().getStatistics();
+            Preconditions.checkState(context.arity() == 2);
+            StatsDeriveResult outputStats = context.getStatisticsWithCheck();
             double outputRowCount = outputStats.getRowCount();
 
             StatsDeriveResult probeStats = context.getChildStatistics(0);
@@ -268,7 +276,7 @@ public class CostCalculator {
                 PhysicalNestedLoopJoin<? extends Plan, ? extends Plan> 
nestedLoopJoin,
                 PlanContext context) {
             // TODO: copy from physicalHashJoin, should update according to 
physical nested loop join properties.
-            Preconditions.checkState(context.getGroupExpression().arity() == 
2);
+            Preconditions.checkState(context.arity() == 2);
 
             StatsDeriveResult leftStatistics = context.getChildStatistics(0);
             StatsDeriveResult rightStatistics = context.getChildStatistics(1);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
index 87a8876a80..e6c247fdee 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
@@ -19,7 +19,6 @@ package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.plans.GroupPlan;
 import org.apache.doris.nereids.trees.plans.JoinType;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
@@ -126,13 +125,6 @@ public class Edge {
         return join.getExpressions().get(0);
     }
 
-    private double getRowCount(Plan plan) {
-        if (plan instanceof GroupPlan) {
-            return ((GroupPlan) plan).getGroup().getStatistics().getRowCount();
-        }
-        return 
plan.getGroupExpression().get().getOwnerGroup().getStatistics().getRowCount();
-    }
-
     @Override
     public String toString() {
         return String.format("<%s - %s>", LongBitmap.toString(left), 
LongBitmap.toString(right));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
index 9f71e217cd..a0817daf9d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
@@ -17,15 +17,17 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
+import org.apache.doris.common.Pair;
+import org.apache.doris.nereids.PlanContext;
+import org.apache.doris.nereids.cost.CostCalculator;
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.Counter;
-import org.apache.doris.nereids.memo.Group;
-import org.apache.doris.nereids.memo.GroupExpression;
-import org.apache.doris.nereids.properties.PhysicalProperties;
-import org.apache.doris.nereids.stats.StatsCalculator;
-import org.apache.doris.nereids.trees.plans.GroupPlan;
-import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.stats.JoinEstimation;
 import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
+import org.apache.doris.nereids.trees.plans.physical.PhysicalHashJoin;
+import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin;
+import org.apache.doris.nereids.util.JoinUtils;
+import org.apache.doris.statistics.StatsDeriveResult;
 
 import com.google.common.base.Preconditions;
 
@@ -41,8 +43,8 @@ import javax.annotation.Nullable;
  * GraphSimplifier is used to simplify HyperGraph {@link HyperGraph}.
  * <p>
  * Related paper:
- *  - [Neu09] Neumann: “Query Simplification: Graceful Degradation for 
Join-Order Optimization”.
- *  - [Rad19] Radke and Neumann: “LinDP++: Generalizing Linearized DP to 
Crossproducts and Non-Inner Joins”.
+ * - [Neu09] Neumann: “Query Simplification: Graceful Degradation for 
Join-Order Optimization”.
+ * - [Rad19] Radke and Neumann: “LinDP++: Generalizing Linearized DP to 
Crossproducts and Non-Inner Joins”.
  */
 public class GraphSimplifier {
     // Note that each index in the graph simplifier is the half of the actual 
index
@@ -56,10 +58,11 @@ public class GraphSimplifier {
     private final PriorityQueue<BestSimplification> priorityQueue = new 
PriorityQueue<>();
     // The graph we are simplifying
     private final HyperGraph graph;
-    // It cached the plan in simplification. we don't store it in hyper graph,
+    // It cached the plan stats in simplification. we don't store it in hyper 
graph,
     // because it's just used for simulating join. In fact, the graph 
simplifier
     // just generate the partial order of join operator.
-    private final HashMap<Long, Plan> cachePlan = new HashMap<>();
+    private final HashMap<Long, StatsDeriveResult> cacheStats = new 
HashMap<>();
+    private final HashMap<Long, Double> cacheCost = new HashMap<>();
 
     private final Stack<SimplificationStep> appliedSteps = new Stack<>();
     private final Stack<SimplificationStep> unAppliedSteps = new Stack<>();
@@ -77,7 +80,8 @@ public class GraphSimplifier {
             simplifications.add(bestSimplification);
         }
         for (Node node : graph.getNodes()) {
-            cachePlan.put(node.getNodeMap(), node.getPlan());
+            cacheStats.put(node.getNodeMap(), node.getGroup().getStatistics());
+            cacheCost.put(node.getNodeMap(), 
node.getGroup().getStatistics().getRowCount());
         }
         circleDetector = new CircleDetector(edgeSize);
 
@@ -179,7 +183,7 @@ public class GraphSimplifier {
         }
         appliedSteps.push(bestStep);
         Preconditions.checkArgument(
-                cachePlan.containsKey(bestStep.newLeft) && 
cachePlan.containsKey(bestStep.newRight),
+                cacheStats.containsKey(bestStep.newLeft) && 
cacheStats.containsKey(bestStep.newRight),
                 String.format("%s - %s", bestStep.newLeft, bestStep.newRight));
         graph.modifyEdge(bestStep.afterIndex, bestStep.newLeft, 
bestStep.newRight);
         if (needProcessNeighbor) {
@@ -306,8 +310,8 @@ public class GraphSimplifier {
         long right1 = edge1.getRight();
         long left2 = edge2.getLeft();
         long right2 = edge2.getRight();
-        Edge edge1Before2;
-        Edge edge2Before1;
+        Pair<StatsDeriveResult, Edge> edge1Before2;
+        Pair<StatsDeriveResult, Edge> edge2Before1;
         List<Long> superBitset = new ArrayList<>();
         if (tryGetSuperset(left1, left2, superBitset)) {
             // (common Join1 right1) Join2 right2
@@ -337,53 +341,53 @@ public class GraphSimplifier {
         return Optional.of(simplificationStep);
     }
 
-    Edge threeLeftJoin(long bitmap1, Edge edge1, long bitmap2, Edge edge2, 
long bitmap3) {
+    Pair<StatsDeriveResult, Edge> threeLeftJoin(long bitmap1, Edge edge1, long 
bitmap2, Edge edge2, long bitmap3) {
         // (plan1 edge1 plan2) edge2 plan3
         // The join may have redundant table, e.g., t1,t2 join t3 join t2,t4
         // Therefore, the cost is not accurate
         Preconditions.checkArgument(
-                cachePlan.containsKey(bitmap1) && 
cachePlan.containsKey(bitmap2) && cachePlan.containsKey(bitmap3));
-        LogicalJoin leftPlan = simulateJoin(cachePlan.get(bitmap1), 
edge1.getJoin(), cachePlan.get(bitmap2));
-        LogicalJoin join = simulateJoin(leftPlan, edge2.getJoin(), 
cachePlan.get(bitmap3));
-        Edge edge = new Edge(join, -1);
+                cacheStats.containsKey(bitmap1) && 
cacheStats.containsKey(bitmap2) && cacheStats.containsKey(bitmap3));
+        StatsDeriveResult leftStats = 
JoinEstimation.estimate(cacheStats.get(bitmap1), cacheStats.get(bitmap2),
+                edge1.getJoin());
+        StatsDeriveResult joinStats = JoinEstimation.estimate(leftStats, 
cacheStats.get(bitmap3), edge2.getJoin());
+        Edge edge = new Edge(edge2.getJoin(), -1);
         long newLeft = LongBitmap.newBitmapUnion(bitmap1, bitmap2);
         // To avoid overlapping the left and the right, the newLeft is 
calculated, Note the
         // newLeft is not totally include the bitset1 and bitset2, we use 
circle detector to trace the dependency
         newLeft = LongBitmap.andNot(newLeft, bitmap3);
         edge.addLeftNodes(newLeft);
         edge.addRightNode(edge2.getRight());
-        cachePlan.put(newLeft, leftPlan);
-        return edge;
+        cacheStats.put(newLeft, leftStats);
+        cacheCost.put(newLeft, calCost(edge2, leftStats, 
cacheStats.get(bitmap1), cacheStats.get(bitmap2)));
+        return Pair.of(joinStats, edge);
     }
 
-    Edge threeRightJoin(long bitmap1, Edge edge1, long bitmap2, Edge edge2, 
long bitmap3) {
+    Pair<StatsDeriveResult, Edge> threeRightJoin(long bitmap1, Edge edge1, 
long bitmap2, Edge edge2, long bitmap3) {
         Preconditions.checkArgument(
-                cachePlan.containsKey(bitmap1) && 
cachePlan.containsKey(bitmap2) && cachePlan.containsKey(bitmap3));
+                cacheStats.containsKey(bitmap1) && 
cacheStats.containsKey(bitmap2) && cacheStats.containsKey(bitmap3));
         // plan1 edge1 (plan2 edge2 plan3)
-        LogicalJoin rightPlan = simulateJoin(cachePlan.get(bitmap2), 
edge2.getJoin(), cachePlan.get(bitmap3));
-        LogicalJoin join = simulateJoin(cachePlan.get(bitmap1), 
edge1.getJoin(), rightPlan);
-        Edge edge = new Edge(join, -1);
+        StatsDeriveResult rightStats = 
JoinEstimation.estimate(cacheStats.get(bitmap2), cacheStats.get(bitmap3),
+                edge2.getJoin());
+        StatsDeriveResult joinStats = 
JoinEstimation.estimate(cacheStats.get(bitmap1), rightStats, edge1.getJoin());
+        Edge edge = new Edge(edge1.getJoin(), -1);
 
         long newRight = LongBitmap.newBitmapUnion(bitmap2, bitmap3);
         newRight = LongBitmap.andNot(newRight, bitmap1);
         edge.addLeftNode(edge1.getLeft());
         edge.addRightNode(newRight);
-        cachePlan.put(newRight, rightPlan);
-        return edge;
+        cacheStats.put(newRight, rightStats);
+        cacheCost.put(newRight, calCost(edge2, rightStats, 
cacheStats.get(bitmap2), cacheStats.get(bitmap3)));
+        return Pair.of(joinStats, edge);
     }
 
-    private Group getGroup(Plan plan) {
-        if (plan instanceof GroupPlan) {
-            return ((GroupPlan) plan).getGroup();
-        }
-        Preconditions.checkArgument(plan.getGroupExpression().isPresent(),
-                "All plan in GraphSimplifier must have a group");
-        return plan.getGroupExpression().get().getOwnerGroup();
-    }
-
-    private SimplificationStep orderJoin(Edge edge1Before2, Edge edge2Before1, 
int edgeIndex1, int edgeIndex2) {
-        double cost1Before2 = getSimpleCost(edge1Before2.getJoin());
-        double cost2Before1 = getSimpleCost(edge2Before1.getJoin());
+    private SimplificationStep orderJoin(Pair<StatsDeriveResult, Edge> 
edge1Before2,
+            Pair<StatsDeriveResult, Edge> edge2Before1, int edgeIndex1, int 
edgeIndex2) {
+        double cost1Before2 = calCost(edge1Before2.second, edge1Before2.first,
+                cacheStats.get(edge1Before2.second.getLeft()),
+                cacheStats.get(edge1Before2.second.getRight()));
+        double cost2Before1 = calCost(edge2Before1.second, edge1Before2.first,
+                cacheStats.get(edge1Before2.second.getLeft()),
+                cacheStats.get(edge1Before2.second.getRight()));
         double benefit = Double.MAX_VALUE;
         SimplificationStep step;
         // Choose the plan with smaller cost and make the simplification step 
to replace the old edge by it.
@@ -392,15 +396,17 @@ public class GraphSimplifier {
                 benefit = cost2Before1 / cost1Before2;
             }
             // choose edge1Before2
-            step = new SimplificationStep(benefit, edgeIndex1, edgeIndex2, 
edge1Before2.getLeft(),
-                    edge1Before2.getRight(), 
graph.getEdge(edgeIndex2).getLeft(), graph.getEdge(edgeIndex2).getRight());
+            step = new SimplificationStep(benefit, edgeIndex1, edgeIndex2, 
edge1Before2.second.getLeft(),
+                    edge1Before2.second.getRight(), 
graph.getEdge(edgeIndex2).getLeft(),
+                    graph.getEdge(edgeIndex2).getRight());
         } else {
             if (cost2Before1 != 0) {
                 benefit = cost1Before2 / cost2Before1;
             }
             // choose edge2Before1
-            step = new SimplificationStep(benefit, edgeIndex2, edgeIndex1, 
edge2Before1.getLeft(),
-                    edge2Before1.getRight(), 
graph.getEdge(edgeIndex1).getLeft(), graph.getEdge(edgeIndex1).getRight());
+            step = new SimplificationStep(benefit, edgeIndex2, edgeIndex1, 
edge2Before1.second.getLeft(),
+                    edge2Before1.second.getRight(), 
graph.getEdge(edgeIndex1).getLeft(),
+                    graph.getEdge(edgeIndex1).getRight());
         }
         return step;
     }
@@ -416,35 +422,32 @@ public class GraphSimplifier {
         return false;
     }
 
-    private double getSimpleCost(Plan plan) {
-        if (!(plan instanceof LogicalJoin)) {
-            return 
plan.getGroupExpression().get().getOwnerGroup().getStatistics().getRowCount();
-        }
-        return 
plan.getGroupExpression().get().getCostByProperties(PhysicalProperties.ANY);
-    }
-
-    private LogicalJoin simulateJoin(Plan plan1, LogicalJoin join, Plan plan2) 
{
-        // In Graph Simplifier, we use the simple cost model, that is
-        //      Plan.cost = Plan.rowCount + Plan.children1.cost + 
Plan.children2.cost
-        // The reason is that this cost model has ASI (adjacent sequence 
interchange) property.
-        // TODO: consider network, data distribution cost
-        LogicalJoin newJoin = new LogicalJoin<>(join.getJoinType(), plan1, 
plan2);
-        List<Group> children = new ArrayList<>();
-        children.add(getGroup(plan1));
-        children.add(getGroup(plan2));
-        double cost = getSimpleCost(plan1) + getSimpleCost(plan2);
-        GroupExpression groupExpression = new GroupExpression(newJoin, 
children);
-        // FIXME: use wrong constructor
-        Group group = new Group(null, groupExpression, null);
-        StatsCalculator.estimate(groupExpression);
-        cost += group.getStatistics().getRowCount();
-
-        List<PhysicalProperties> inputs = new ArrayList<>();
-        inputs.add(PhysicalProperties.ANY);
-        inputs.add(PhysicalProperties.ANY);
-        groupExpression.updateLowestCostTable(PhysicalProperties.ANY, inputs, 
cost);
-
-        return newJoin.withGroupExpression(Optional.of(groupExpression));
+    private double calCost(Edge edge, StatsDeriveResult stats,
+            StatsDeriveResult leftStats, StatsDeriveResult rightStats) {
+        LogicalJoin join = edge.getJoin();
+        PlanContext planContext = new PlanContext(stats, leftStats, 
rightStats);
+        double cost = 0;
+        if (JoinUtils.shouldNestedLoopJoin(join)) {
+            PhysicalNestedLoopJoin nestedLoopJoin = new 
PhysicalNestedLoopJoin<>(
+                    join.getJoinType(),
+                    join.getHashJoinConjuncts(),
+                    join.getOtherJoinConjuncts(),
+                    join.getLogicalProperties(),
+                    join.left(),
+                    join.right());
+            cost = CostCalculator.calculateCost(nestedLoopJoin, planContext);
+        } else {
+            PhysicalHashJoin hashJoin = new PhysicalHashJoin<>(
+                    join.getJoinType(),
+                    join.getHashJoinConjuncts(),
+                    join.getOtherJoinConjuncts(),
+                    join.getHint(),
+                    join.getLogicalProperties(),
+                    join.left(),
+                    join.right());
+            cost = CostCalculator.calculateCost(hashJoin, planContext);
+        }
+        return cost + cacheCost.get(edge.getLeft()) + 
cacheCost.get(edge.getRight());
     }
 
     /**
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java
index 08f0fe1b8d..d2161cfa9a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/RequestPropertyDeriver.java
@@ -86,8 +86,8 @@ public class RequestPropertyDeriver extends PlanVisitor<Void, 
PlanContext> {
         }
 
         List<PhysicalProperties> requiredPropertyList =
-                
Lists.newArrayListWithCapacity(context.getGroupExpression().arity());
-        for (int i = context.getGroupExpression().arity(); i > 0; --i) {
+                Lists.newArrayListWithCapacity(context.arity());
+        for (int i = context.arity(); i > 0; --i) {
             requiredPropertyList.add(PhysicalProperties.ANY);
         }
         addRequestPropertyToChildren(requiredPropertyList);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java
index a53f1ef82f..c29793238d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java
@@ -101,7 +101,6 @@ import java.util.stream.Collectors;
  * Used to calculate the stats for each plan
  */
 public class StatsCalculator extends DefaultPlanVisitor<StatsDeriveResult, 
Void> {
-
     private final GroupExpression groupExpression;
 
     private StatsCalculator(GroupExpression groupExpression) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/GroupPlan.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/GroupPlan.java
index 8967891521..a47968e1bd 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/GroupPlan.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/GroupPlan.java
@@ -24,6 +24,7 @@ import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.plans.logical.LogicalLeaf;
 import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.statistics.StatsDeriveResult;
 
 import com.google.common.collect.ImmutableList;
 
@@ -58,6 +59,11 @@ public class GroupPlan extends LogicalLeaf {
         return ImmutableList.of();
     }
 
+    @Override
+    public StatsDeriveResult getStats() {
+        throw new IllegalStateException("GroupPlan can not invoke getStats()");
+    }
+
     @Override
     public GroupPlan withOutput(List<Slot> output) {
         throw new IllegalStateException("GroupPlan can not invoke 
withOutput()");


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to