[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.
This commit is contained in:
morrySnow
2024-05-29 15:27:27 +08:00
committed by GitHub
parent 8c0c05b9c6
commit 1f5edae090
5 changed files with 88 additions and 3 deletions

View File

@ -246,7 +246,7 @@ public class AdjustNullable extends DefaultPlanRewriter<Map<ExprId, Slot>> imple
List<NamedExpression> windowExpressions =
updateExpressions(window.getWindowExpressions(), replaceMap);
windowExpressions.forEach(w -> replaceMap.put(w.getExprId(), w.toSlot()));
return window.withExpression(windowExpressions, window.child());
return window.withExpressionsAndChild(windowExpressions, window.child());
}
@Override

View File

@ -37,6 +37,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat;
import org.apache.doris.nereids.trees.plans.logical.LogicalSink;
import org.apache.doris.nereids.trees.plans.logical.LogicalUnion;
import org.apache.doris.nereids.trees.plans.logical.LogicalWindow;
import org.apache.doris.nereids.trees.plans.logical.OutputPrunable;
import org.apache.doris.nereids.trees.plans.visitor.CustomRewriter;
import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanRewriter;
@ -211,6 +212,30 @@ public class ColumnPruning extends DefaultPlanRewriter<PruneContext> implements
return super.visitLogicalCTEConsumer(cteConsumer, context);
}
@Override
public Plan visitLogicalWindow(LogicalWindow<? extends Plan> window, PruneContext context) {
boolean pruned = false;
boolean reserved = false;
ImmutableList.Builder<NamedExpression> reservedWindowExpressions = ImmutableList.builder();
for (NamedExpression windowExpression : window.getWindowExpressions()) {
if (context.requiredSlots.contains(windowExpression.toSlot())) {
reservedWindowExpressions.add(windowExpression);
reserved = true;
} else {
pruned = true;
}
}
if (!pruned) {
return pruneChildren(window, context.requiredSlots);
}
if (!reserved) {
return window.child().accept(this, context);
}
LogicalWindow<? extends Plan> prunedWindow
= window.withExpressionsAndChild(reservedWindowExpressions.build(), window.child());
return pruneChildren(prunedWindow, context.requiredSlots);
}
private Plan pruneAggregate(Aggregate<?> agg, PruneContext context) {
// first try to prune group by and aggregate functions
Aggregate<? extends Plan> prunedOutputAgg = pruneOutput(agg, agg.getOutputs(), agg::pruneOutputs, context);

View File

@ -120,7 +120,7 @@ public class SimplifyWindowExpression extends OneRewriteRuleFactory {
}
List<NamedExpression> finalProjections = Lists.newArrayList(projections);
finalProjections.addAll(windowOutputs);
return new LogicalProject(finalProjections, window.withExpression(remainWindows,
return new LogicalProject(finalProjections, window.withExpressionsAndChild(remainWindows,
window.child(0)));
}
}

View File

@ -86,7 +86,7 @@ public class LogicalWindow<CHILD_TYPE extends Plan> extends LogicalUnary<CHILD_T
return windowExpressions;
}
public LogicalWindow<Plan> withExpression(List<NamedExpression> windowExpressions, Plan child) {
public LogicalWindow<Plan> withExpressionsAndChild(List<NamedExpression> windowExpressions, Plan child) {
return new LogicalWindow<>(windowExpressions, isChecked, child);
}