Skip to content

Commit d44b653

Browse files
branch-4.0: [fix](hint)should pull up subquery alias with hint for all kind of root nodes #58767 (#58853)
Cherry-picked from #58767 Co-authored-by: starocean999 <lichi@selectdb.com>
1 parent 0b5a732 commit d44b653

File tree

2 files changed

+210
-22
lines changed

2 files changed

+210
-22
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/processor/pre/PullUpSubqueryAliasToCTE.java

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@
2020
import org.apache.doris.nereids.StatementContext;
2121
import org.apache.doris.nereids.analyzer.UnboundRelation;
2222
import org.apache.doris.nereids.analyzer.UnboundResultSink;
23+
import org.apache.doris.nereids.analyzer.UnboundTableSink;
2324
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
2425
import org.apache.doris.nereids.trees.plans.Plan;
2526
import org.apache.doris.nereids.trees.plans.logical.LogicalCTE;
27+
import org.apache.doris.nereids.trees.plans.logical.LogicalFileSink;
28+
import org.apache.doris.nereids.trees.plans.logical.LogicalLimit;
2629
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
2730
import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint;
31+
import org.apache.doris.nereids.trees.plans.logical.LogicalSort;
2832
import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
2933

3034
import java.util.ArrayList;
@@ -39,27 +43,25 @@ public class PullUpSubqueryAliasToCTE extends PlanPreprocessor {
3943
@Override
4044
public Plan visitUnboundResultSink(UnboundResultSink<? extends Plan> unboundResultSink,
4145
StatementContext context) {
42-
Plan topPlan = visitChildren(this, unboundResultSink, context);
43-
if (!aliasQueries.isEmpty()) {
44-
if (((UnboundResultSink) topPlan).child() instanceof LogicalCTE) {
45-
LogicalCTE logicalCTE = (LogicalCTE) ((UnboundResultSink) topPlan).child();
46-
List<LogicalSubQueryAlias<Plan>> subQueryAliases = new ArrayList<>();
47-
subQueryAliases.addAll(logicalCTE.getAliasQueries());
48-
subQueryAliases.addAll(aliasQueries);
49-
return topPlan.withChildren(
50-
new LogicalCTE<>(subQueryAliases, (LogicalPlan) ((UnboundResultSink) topPlan).child()));
51-
}
52-
return topPlan.withChildren(
53-
new LogicalCTE<>(aliasQueries, (LogicalPlan) ((UnboundResultSink) topPlan).child()));
54-
}
55-
return topPlan;
46+
return createCteForRootNode(unboundResultSink, context);
47+
}
48+
49+
@Override
50+
public Plan visitUnboundTableSink(UnboundTableSink<? extends Plan> unboundTableSink,
51+
StatementContext context) {
52+
return createCteForRootNode(unboundTableSink, context);
53+
}
54+
55+
@Override
56+
public Plan visitLogicalFileSink(LogicalFileSink<? extends Plan> logicalFileSink,
57+
StatementContext context) {
58+
return createCteForRootNode(logicalFileSink, context);
5659
}
5760

5861
@Override
5962
public Plan visitLogicalSubQueryAlias(LogicalSubQueryAlias<? extends Plan> alias,
6063
StatementContext context) {
61-
if (alias.child() instanceof LogicalSelectHint
62-
&& ((LogicalSelectHint) alias.child()).isIncludeHint("Leading")) {
64+
if (findLeadingHintIgnoreSortAndLimit(alias.child())) {
6365
aliasQueries.add((LogicalSubQueryAlias<Plan>) alias);
6466
List<String> tableName = new ArrayList<>();
6567
tableName.add(alias.getAlias());
@@ -72,12 +74,7 @@ public Plan visitLogicalSubQueryAlias(LogicalSubQueryAlias<? extends Plan> alias
7274
public Plan visitLogicalCTE(LogicalCTE<? extends Plan> logicalCTE, StatementContext context) {
7375
List<LogicalSubQueryAlias<Plan>> subQueryAliases = logicalCTE.getAliasQueries();
7476
for (LogicalSubQueryAlias<Plan> subQueryAlias : subQueryAliases) {
75-
Plan newSubQueryAlias = subQueryAlias.accept(new PullUpSubqueryAliasToCTE(), context);
76-
if (newSubQueryAlias instanceof LogicalSubQueryAlias) {
77-
subQueryAlias = (LogicalSubQueryAlias<Plan>) newSubQueryAlias;
78-
} else {
79-
subQueryAlias = new LogicalSubQueryAlias<>(subQueryAlias.getAlias(), newSubQueryAlias);
80-
}
77+
subQueryAlias.accept(new PullUpSubqueryAliasToCTE(), context);
8178
}
8279
Plan cte = visitChildren(this, logicalCTE, context);
8380
if (!aliasQueries.isEmpty()) {
@@ -90,4 +87,32 @@ public Plan visitLogicalCTE(LogicalCTE<? extends Plan> logicalCTE, StatementCont
9087
}
9188
return cte;
9289
}
90+
91+
private Plan createCteForRootNode(Plan plan, StatementContext context) {
92+
Plan topPlan = visitChildren(this, plan, context);
93+
if (!aliasQueries.isEmpty()) {
94+
if (topPlan.child(0) instanceof LogicalCTE) {
95+
LogicalCTE logicalCTE = (LogicalCTE) topPlan.child(0);
96+
List<LogicalSubQueryAlias<Plan>> subQueryAliases = new ArrayList<>();
97+
subQueryAliases.addAll(logicalCTE.getAliasQueries());
98+
subQueryAliases.addAll(aliasQueries);
99+
return topPlan.withChildren(
100+
new LogicalCTE<>(subQueryAliases, (LogicalPlan) topPlan.child(0)));
101+
}
102+
return topPlan.withChildren(
103+
new LogicalCTE<>(aliasQueries, (LogicalPlan) topPlan.child(0)));
104+
}
105+
return topPlan;
106+
}
107+
108+
private boolean findLeadingHintIgnoreSortAndLimit(Plan plan) {
109+
if (plan instanceof LogicalSelectHint
110+
&& ((LogicalSelectHint) plan).isIncludeHint("Leading")) {
111+
return true;
112+
} else if (plan instanceof LogicalLimit || plan instanceof LogicalSort) {
113+
return findLeadingHintIgnoreSortAndLimit(plan.child(0));
114+
} else {
115+
return false;
116+
}
117+
}
93118
}

0 commit comments

Comments
 (0)