2020import org .apache .doris .nereids .StatementContext ;
2121import org .apache .doris .nereids .analyzer .UnboundRelation ;
2222import org .apache .doris .nereids .analyzer .UnboundResultSink ;
23+ import org .apache .doris .nereids .analyzer .UnboundTableSink ;
2324import org .apache .doris .nereids .trees .expressions .StatementScopeIdGenerator ;
2425import org .apache .doris .nereids .trees .plans .Plan ;
2526import 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 ;
2629import org .apache .doris .nereids .trees .plans .logical .LogicalPlan ;
2730import org .apache .doris .nereids .trees .plans .logical .LogicalSelectHint ;
31+ import org .apache .doris .nereids .trees .plans .logical .LogicalSort ;
2832import org .apache .doris .nereids .trees .plans .logical .LogicalSubQueryAlias ;
2933
3034import 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