Skip to content

Commit c7f134a

Browse files
committed
fix
1 parent 91ca4dc commit c7f134a

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/LimitAggToTopNAgg.java

+36-16
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.google.common.collect.Lists;
3535

3636
import java.util.List;
37+
import java.util.Optional;
3738
import java.util.stream.Collectors;
3839

3940
/**
@@ -55,7 +56,11 @@ public List<Rule> buildRules() {
5556
>= limit.getLimit() + limit.getOffset())
5657
.then(limit -> {
5758
LogicalAggregate<? extends Plan> agg = limit.child();
58-
List<OrderKey> orderKeys = generateOrderKeyByGroupKey(agg);
59+
Optional<OrderKey> orderKeysOpt = tryGenerateOrderKeyByTheFirstGroupKey(agg);
60+
if (!orderKeysOpt.isPresent()) {
61+
return null;
62+
}
63+
List<OrderKey> orderKeys = Lists.newArrayList(orderKeysOpt.get());
5964
return new LogicalTopN<>(orderKeys, limit.getLimit(), limit.getOffset(), agg);
6065
}).toRule(RuleType.LIMIT_AGG_TO_TOPN_AGG),
6166
//limit->project->agg to topn->project->agg
@@ -68,7 +73,11 @@ public List<Rule> buildRules() {
6873
LogicalProject<? extends Plan> project = limit.child();
6974
LogicalAggregate<? extends Plan> agg
7075
= (LogicalAggregate<? extends Plan>) project.child();
71-
List<OrderKey> orderKeys = generateOrderKeyByGroupKey(agg);
76+
Optional<OrderKey> orderKeysOpt = tryGenerateOrderKeyByTheFirstGroupKey(agg);
77+
if (!orderKeysOpt.isPresent()) {
78+
return null;
79+
}
80+
List<OrderKey> orderKeys = Lists.newArrayList(orderKeysOpt.get());
7281
Plan result;
7382

7483
if (outputAllGroupKeys(limit, agg)) {
@@ -78,21 +87,27 @@ public List<Rule> buildRules() {
7887
// add the first group by key to topn, and prune this key by upper project
7988
// topn order keys are prefix of group by keys
8089
// refer to PushTopnToAgg.tryGenerateOrderKeyByGroupKeyAndTopnKey()
81-
List<NamedExpression> bottomProjections = Lists.newArrayList(project.getProjects());
82-
if (agg.getGroupByExpressions().isEmpty()) {
83-
return null;
84-
}
8590
Expression firstGroupByKey = agg.getGroupByExpressions().get(0);
8691
if (!(firstGroupByKey instanceof SlotReference)) {
8792
return null;
8893
}
89-
bottomProjections.add((SlotReference) firstGroupByKey);
90-
LogicalProject<Plan> bottomProject = project.withProjects(bottomProjections);
94+
boolean shouldPruneFirstGroupByKey = true;
95+
if (project.getOutputs().contains(firstGroupByKey)) {
96+
shouldPruneFirstGroupByKey = false;
97+
} else {
98+
List<NamedExpression> bottomProjections = Lists.newArrayList(project.getProjects());
99+
bottomProjections.add((SlotReference) firstGroupByKey);
100+
project = project.withProjects(bottomProjections);
101+
}
91102
LogicalTopN topn = new LogicalTopN<>(orderKeys, limit.getLimit(),
92-
limit.getOffset(), bottomProject);
93-
List<NamedExpression> limitOutput = limit.getOutput().stream()
94-
.map(e -> (NamedExpression) e).collect(Collectors.toList());
95-
result = new LogicalProject<>(limitOutput, topn);
103+
limit.getOffset(), project);
104+
if (shouldPruneFirstGroupByKey) {
105+
List<NamedExpression> limitOutput = limit.getOutput().stream()
106+
.map(e -> (NamedExpression) e).collect(Collectors.toList());
107+
result = new LogicalProject<>(limitOutput, topn);
108+
} else {
109+
result = topn;
110+
}
96111
}
97112
return result;
98113
}).toRule(RuleType.LIMIT_AGG_TO_TOPN_AGG),
@@ -138,9 +153,14 @@ private boolean outputAllGroupKeys(LogicalLimit limit, LogicalAggregate agg) {
138153
return limit.getOutputSet().containsAll(agg.getGroupByExpressions());
139154
}
140155

141-
private List<OrderKey> generateOrderKeyByGroupKey(LogicalAggregate<? extends Plan> agg) {
142-
return agg.getGroupByExpressions().stream()
143-
.map(key -> new OrderKey(key, true, false))
144-
.collect(Collectors.toList());
156+
private Optional<OrderKey> tryGenerateOrderKeyByTheFirstGroupKey(LogicalAggregate<? extends Plan> agg) {
157+
if (agg.getGroupByExpressions().isEmpty()) {
158+
return Optional.empty();
159+
}
160+
if (agg.getGroupByExpressions().get(0) instanceof SlotReference) {
161+
// agg normalize projects the expression under agg. we cannot use it as order key above agg
162+
return Optional.of(new OrderKey(agg.getGroupByExpressions().get(0), true, false));
163+
}
164+
return Optional.empty();
145165
}
146166
}

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalHashAggregate.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ public String toString() {
206206
"groupByExpr", groupByExpressions,
207207
"outputExpr", outputExpressions,
208208
"partitionExpr", partitionExpressions,
209-
"requireProperties", requireProperties,
210-
"topnOpt", topnPushInfo != null
209+
"topnFilter", topnPushInfo != null,
210+
"topnPushDown", getMutableState(MutableState.KEY_PUSH_TOPN_TO_AGG).isPresent()
211211
);
212212
}
213213

0 commit comments

Comments
 (0)