This is an automated email from the ASF dual-hosted git repository.

morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 160d2be0d8 [minimal](Nereids) add more comments for the rewriter 
(#19788)
160d2be0d8 is described below

commit 160d2be0d823496a134ee2031fc4680557c99e9a
Author: Chengpeng Yan <41809508+reminisc...@users.noreply.github.com>
AuthorDate: Thu May 18 14:47:25 2023 +0800

    [minimal](Nereids) add more comments for the rewriter (#19788)
    
    Only add some comments to the rewriter. Because it is fewer comments before 
and it's hard to understand for the newbie.
---
 .../nereids/jobs/rewrite/CustomRewriteJob.java     |  3 ++
 .../jobs/rewrite/PlanTreeRewriteBottomUpJob.java   | 37 +++++++++++++++++++---
 .../jobs/rewrite/PlanTreeRewriteTopDownJob.java    |  7 +++-
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/CustomRewriteJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/CustomRewriteJob.java
index a05ad215a3..cf163010b7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/CustomRewriteJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/CustomRewriteJob.java
@@ -31,6 +31,9 @@ import java.util.function.Supplier;
 
 /**
  * Custom rewrite the plan.
+ * Just pass the plan node to the 'CustomRewriter', and the 'CustomRewriter' 
rule will handle it.
+ * The 'CustomRewriter' rule use the 'Visitor' design pattern to implement the 
rule.
+ * You can check the 'CustomRewriter' interface to see which rules use this 
way to do rewrite.
  */
 public class CustomRewriteJob implements RewriteJob {
     private final RuleType ruleType;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteBottomUpJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteBottomUpJob.java
index 8e625b638d..5652298266 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteBottomUpJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteBottomUpJob.java
@@ -26,31 +26,50 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 
-/** PlanTreeRewriteBottomUpJob */
+/**
+ * PlanTreeRewriteBottomUpJob
+ * The job is used for bottom-up rewrite. If some rewrite rules can take 
effect,
+ * we will process all the rules from the leaf node again. So there are some 
rules that can take effect interactively,
+ * we should use the 'Bottom-Up' job to handle it.
+ */
 public class PlanTreeRewriteBottomUpJob extends PlanTreeRewriteJob {
+    // REWRITE_STATE_KEY represents the key to store the 'RewriteState'. Each 
plan node has their own 'RewriteState'.
+    // Different 'RewriteState' has different actions,
+    // so we will do specified action for each node based on their 
'RewriteState'.
     private static final String REWRITE_STATE_KEY = "rewrite_state";
     private RewriteJobContext rewriteJobContext;
     private List<Rule> rules;
 
     enum RewriteState {
-        ENSURE_CHILDREN_REWRITTEN, REWRITE_THIS, REWRITTEN
+        // 'REWRITE_THIS' means the current plan node can be handled 
immediately. If the plan state is 'REWRITE_THIS',
+        // it means all of its children's state are 'REWRITTEN'. Because we 
handle the plan tree bottom up.
+        REWRITE_THIS,
+        // 'REWRITTEN' means the current plan have been handled already, we 
don't need to do anything else.
+        REWRITTEN,
+        // 'ENSURE_CHILDREN_REWRITTEN' means we need to check the children for 
the current plan node first.
+        // It means some plans have changed after rewrite, so we need traverse 
the plan tree and reset their state.
+        // All the plan nodes need to be handled again.
+        ENSURE_CHILDREN_REWRITTEN
     }
 
     public PlanTreeRewriteBottomUpJob(RewriteJobContext rewriteJobContext, 
JobContext context, List<Rule> rules) {
-        super(JobType.TOP_DOWN_REWRITE, context);
+        super(JobType.BOTTOM_UP_REWRITE, context);
         this.rewriteJobContext = Objects.requireNonNull(rewriteJobContext, 
"rewriteContext cannot be null");
         this.rules = Objects.requireNonNull(rules, "rules cannot be null");
     }
 
     @Override
     public void execute() {
-        // use childrenVisited to judge whether clear the state in the 
previous batch
+        // For the bottom-up rewrite job, we need to reset the state of its 
children
+        // if the plan has changed after the rewrite. So we use the 
'childrenVisited' to check this situation.
         boolean clearStatePhase = !rewriteJobContext.childrenVisited;
         if (clearStatePhase) {
             traverseClearState();
             return;
         }
 
+        // We'll do different actions based on their different states.
+        // You can check the comment in 'RewriteState' structure for more 
details.
         Plan plan = rewriteJobContext.plan;
         RewriteState state = getState(plan);
         switch (state) {
@@ -69,10 +88,13 @@ public class PlanTreeRewriteBottomUpJob extends 
PlanTreeRewriteJob {
     }
 
     private void traverseClearState() {
+        // Reset the state for current node.
         RewriteJobContext clearedStateContext = 
rewriteJobContext.withChildrenVisited(true);
         setState(clearedStateContext.plan, RewriteState.REWRITE_THIS);
         pushJob(new PlanTreeRewriteBottomUpJob(clearedStateContext, context, 
rules));
 
+        // Generate the new rewrite job for its children. Because the 
character of stack is 'first in, last out',
+        // so we can traverse reset the state for the plan node until the leaf 
node.
         List<Plan> children = clearedStateContext.plan.children();
         for (int i = children.size() - 1; i >= 0; i--) {
             Plan child = children.get(i);
@@ -83,25 +105,30 @@ public class PlanTreeRewriteBottomUpJob extends 
PlanTreeRewriteJob {
     }
 
     private void rewriteThis() {
+        // Link the current node with the sub-plan to get the current plan 
which is used in the rewrite phase later.
         Plan plan = linkChildren(rewriteJobContext.plan, 
rewriteJobContext.childrenContext);
         RewriteResult rewriteResult = rewrite(plan, rules, rewriteJobContext);
         if (rewriteResult.hasNewPlan) {
             RewriteJobContext newJobContext = 
rewriteJobContext.withPlan(rewriteResult.plan);
             RewriteState state = getState(rewriteResult.plan);
-            // some eliminate rule will return a rewritten plan
+            // Some eliminate rule will return a rewritten plan, for example 
the current node is eliminated
+            // and return the child plan. So we don't need to handle it again.
             if (state == RewriteState.REWRITTEN) {
                 newJobContext.setResult(rewriteResult.plan);
                 return;
             }
+            // After the rewrite take effect, we should handle the children 
part again.
             pushJob(new PlanTreeRewriteBottomUpJob(newJobContext, context, 
rules));
             setState(rewriteResult.plan, 
RewriteState.ENSURE_CHILDREN_REWRITTEN);
         } else {
+            // No new plan is generated, so just set the state of the current 
plan to 'REWRITTEN'.
             setState(rewriteResult.plan, RewriteState.REWRITTEN);
             rewriteJobContext.setResult(rewriteResult.plan);
         }
     }
 
     private void ensureChildrenRewritten() {
+        // Similar to the function 'traverseClearState'.
         Plan plan = rewriteJobContext.plan;
         setState(plan, RewriteState.REWRITE_THIS);
         pushJob(new PlanTreeRewriteBottomUpJob(rewriteJobContext, context, 
rules));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteTopDownJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteTopDownJob.java
index e92dd15f27..d280159a01 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteTopDownJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/PlanTreeRewriteTopDownJob.java
@@ -25,7 +25,11 @@ import org.apache.doris.nereids.trees.plans.Plan;
 import java.util.List;
 import java.util.Objects;
 
-/** PlanTreeRewriteTopDownJob */
+/**
+ * PlanTreeRewriteTopDownJob
+ * It's easier than the 'BottomUp' job, it handles the plan tree top-down. If 
some new plans generated after rewrite,
+ * it only processes the current node again. Otherwise, it just recursively 
handles its children.
+ */
 public class PlanTreeRewriteTopDownJob extends PlanTreeRewriteJob {
     private RewriteJobContext rewriteJobContext;
     private List<Rule> rules;
@@ -57,6 +61,7 @@ public class PlanTreeRewriteTopDownJob extends 
PlanTreeRewriteJob {
                 pushJob(new PlanTreeRewriteTopDownJob(childRewriteJobContext, 
context, rules));
             }
         } else {
+            // All the children part are already visited. Just link the 
children plan to the current node.
             Plan result = linkChildrenAndParent(rewriteJobContext.plan, 
rewriteJobContext);
             if (rewriteJobContext.parentContext == null) {
                 context.getCascadesContext().setRewritePlan(result);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to