1919
2020import org .apache .doris .common .Pair ;
2121import org .apache .doris .nereids .CascadesContext ;
22+ import org .apache .doris .nereids .StatementContext ;
2223import org .apache .doris .nereids .cost .Cost ;
2324import org .apache .doris .nereids .hint .Hint ;
2425import org .apache .doris .nereids .hint .UseCboRuleHint ;
2829import org .apache .doris .nereids .memo .GroupExpression ;
2930import org .apache .doris .nereids .rules .Rule ;
3031import org .apache .doris .nereids .rules .RuleType ;
32+ import org .apache .doris .nereids .trees .expressions .CTEId ;
33+ import org .apache .doris .nereids .trees .plans .Plan ;
3134import org .apache .doris .nereids .trees .plans .logical .LogicalCTEAnchor ;
3235import org .apache .doris .nereids .trees .plans .logical .LogicalPlan ;
3336import org .apache .doris .qe .ConnectContext ;
3437
3538import com .google .common .collect .ImmutableList ;
39+ import com .google .common .collect .Maps ;
3640import org .apache .logging .log4j .LogManager ;
3741import org .apache .logging .log4j .Logger ;
3842
3943import java .util .ArrayList ;
4044import java .util .Arrays ;
4145import java .util .List ;
46+ import java .util .Map ;
4247import java .util .Optional ;
4348
4449/**
@@ -56,6 +61,11 @@ public CostBasedRewriteJob(List<RewriteJob> rewriteJobs) {
5661 // need to generate real rewrite job list
5762 }
5863
64+ private void restoreCteProducerMap (StatementContext context , Map <CTEId , LogicalPlan > currentCteProducers ) {
65+ context .getRewrittenCteProducer ().clear ();
66+ currentCteProducers .forEach (context .getRewrittenCteProducer ()::put );
67+ }
68+
5969 @ Override
6070 public void execute (JobContext jobContext ) {
6171 // checkHint.first means whether it use hint and checkHint.second means what kind of hint it used
@@ -69,14 +79,21 @@ public void execute(JobContext jobContext) {
6979 CascadesContext applyCboRuleCtx = CascadesContext .newCurrentTreeContext (currentCtx );
7080 // execute cbo rule on one candidate
7181 Rewriter .getCteChildrenRewriter (applyCboRuleCtx , rewriteJobs ).execute ();
82+ Plan applyCboPlan = applyCboRuleCtx .getRewritePlan ();
7283 if (skipCboRuleCtx .getRewritePlan ().deepEquals (applyCboRuleCtx .getRewritePlan ())) {
7384 // this means rewrite do not do anything
7485 return ;
7586 }
7687
88+ Map <CTEId , LogicalPlan > currentCteProducers = Maps .newHashMap ();
89+ // cost based rewrite job may contaminate StatementContext.rewrittenCteProducer
90+ // clone current rewrittenCteProducer, and restore it after getCost(.).
91+ currentCtx .getStatementContext ().getRewrittenCteProducer ().forEach (currentCteProducers ::put );
7792 // compare two candidates
7893 Optional <Pair <Cost , GroupExpression >> skipCboRuleCost = getCost (currentCtx , skipCboRuleCtx , jobContext );
94+ restoreCteProducerMap (currentCtx .getStatementContext (), currentCteProducers );
7995 Optional <Pair <Cost , GroupExpression >> appliedCboRuleCost = getCost (currentCtx , applyCboRuleCtx , jobContext );
96+ restoreCteProducerMap (currentCtx .getStatementContext (), currentCteProducers );
8097 // If one of them optimize failed, just return
8198 if (!skipCboRuleCost .isPresent () || !appliedCboRuleCost .isPresent ()) {
8299 LOG .warn ("Cbo rewrite execute failed on sql: {}, jobs are {}, plan is {}." ,
@@ -94,8 +111,7 @@ public void execute(JobContext jobContext) {
94111 }
95112 // If the candidate applied cbo rule is better, replace the original plan with it.
96113 if (appliedCboRuleCost .get ().first .getValue () < skipCboRuleCost .get ().first .getValue ()) {
97- currentCtx .addPlanProcesses (applyCboRuleCtx .getPlanProcesses ());
98- currentCtx .setRewritePlan (applyCboRuleCtx .getRewritePlan ());
114+ currentCtx .setRewritePlan (applyCboPlan );
99115 }
100116 }
101117
0 commit comments