Skip to content

Commit 1f5edae

Browse files
authored
[fix](Nereids) prune not required window expressions on window operator (#35593)
pick from master #35504 if window expression is not required by its parent, we should prune this column. If all window expressions of window operator are pruned, we remove this window operator directly.
1 parent 8c0c05b commit 1f5edae

File tree

5 files changed

+88
-3
lines changed

5 files changed

+88
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public Plan visitLogicalWindow(LogicalWindow<? extends Plan> window, Map<ExprId,
246246
List<NamedExpression> windowExpressions =
247247
updateExpressions(window.getWindowExpressions(), replaceMap);
248248
windowExpressions.forEach(w -> replaceMap.put(w.getExprId(), w.toSlot()));
249-
return window.withExpression(windowExpressions, window.child());
249+
return window.withExpressionsAndChild(windowExpressions, window.child());
250250
}
251251

252252
@Override

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat;
3838
import org.apache.doris.nereids.trees.plans.logical.LogicalSink;
3939
import org.apache.doris.nereids.trees.plans.logical.LogicalUnion;
40+
import org.apache.doris.nereids.trees.plans.logical.LogicalWindow;
4041
import org.apache.doris.nereids.trees.plans.logical.OutputPrunable;
4142
import org.apache.doris.nereids.trees.plans.visitor.CustomRewriter;
4243
import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanRewriter;
@@ -211,6 +212,30 @@ public Plan visitLogicalCTEConsumer(LogicalCTEConsumer cteConsumer, PruneContext
211212
return super.visitLogicalCTEConsumer(cteConsumer, context);
212213
}
213214

215+
@Override
216+
public Plan visitLogicalWindow(LogicalWindow<? extends Plan> window, PruneContext context) {
217+
boolean pruned = false;
218+
boolean reserved = false;
219+
ImmutableList.Builder<NamedExpression> reservedWindowExpressions = ImmutableList.builder();
220+
for (NamedExpression windowExpression : window.getWindowExpressions()) {
221+
if (context.requiredSlots.contains(windowExpression.toSlot())) {
222+
reservedWindowExpressions.add(windowExpression);
223+
reserved = true;
224+
} else {
225+
pruned = true;
226+
}
227+
}
228+
if (!pruned) {
229+
return pruneChildren(window, context.requiredSlots);
230+
}
231+
if (!reserved) {
232+
return window.child().accept(this, context);
233+
}
234+
LogicalWindow<? extends Plan> prunedWindow
235+
= window.withExpressionsAndChild(reservedWindowExpressions.build(), window.child());
236+
return pruneChildren(prunedWindow, context.requiredSlots);
237+
}
238+
214239
private Plan pruneAggregate(Aggregate<?> agg, PruneContext context) {
215240
// first try to prune group by and aggregate functions
216241
Aggregate<? extends Plan> prunedOutputAgg = pruneOutput(agg, agg.getOutputs(), agg::pruneOutputs, context);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ private Plan simplify(MatchingContext<LogicalWindow<Plan>> ctx) {
120120
}
121121
List<NamedExpression> finalProjections = Lists.newArrayList(projections);
122122
finalProjections.addAll(windowOutputs);
123-
return new LogicalProject(finalProjections, window.withExpression(remainWindows,
123+
return new LogicalProject(finalProjections, window.withExpressionsAndChild(remainWindows,
124124
window.child(0)));
125125
}
126126
}

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalWindow.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public List<? extends Expression> getExpressions() {
8686
return windowExpressions;
8787
}
8888

89-
public LogicalWindow<Plan> withExpression(List<NamedExpression> windowExpressions, Plan child) {
89+
public LogicalWindow<Plan> withExpressionsAndChild(List<NamedExpression> windowExpressions, Plan child) {
9090
return new LogicalWindow<>(windowExpressions, isChecked, child);
9191
}
9292

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
suite("window_column_pruning") {
19+
sql "set disable_nereids_rules=PRUNE_EMPTY_PARTITION"
20+
21+
sql """
22+
DROP TABLE IF EXISTS window_column_pruning
23+
"""
24+
sql """
25+
CREATE TABLE IF NOT EXISTS window_column_pruning(
26+
`id` int NULL,
27+
`c1` int NULL
28+
) ENGINE = OLAP
29+
DISTRIBUTED BY HASH(id) BUCKETS 4
30+
PROPERTIES (
31+
"replication_allocation" = "tag.location.default: 1"
32+
);
33+
"""
34+
35+
// should prune
36+
explain {
37+
sql "select id from (select id, row_number() over (partition by id) as rn from window_column_pruning) tmp where id > 1;"
38+
notContains "row_number"
39+
}
40+
41+
// should not prune
42+
explain {
43+
sql "select id, rn from (select id, row_number() over (partition by id) as rn from window_column_pruning) tmp where id > 1;"
44+
contains "row_number"
45+
}
46+
47+
// should prune rank, but not prune row_number
48+
explain {
49+
sql "select id, rn1 from (select id, row_number() over (partition by id) as rn1, rank() over (partition by id) as rk from window_column_pruning) tmp where id > 1;"
50+
contains "row_number"
51+
notContains "rank"
52+
}
53+
54+
// prune through union all
55+
explain {
56+
sql "select id from (select id, rank() over() px from window_column_pruning union all select id, rank() over() px from window_column_pruning) a"
57+
notContains "rank"
58+
}
59+
}
60+

0 commit comments

Comments
 (0)