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: 谢健 <[email protected]>
AuthorDate: Tue Feb 14 17:03:21 2023 +0800
avoid contruct groupExpr in graph-simplifier (#16436)
Signed-off-by: xiejiann <[email protected]>
---
.../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: [email protected]
For additional commands, e-mail: [email protected]