You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ch...@apache.org on 2020/11/06 02:59:09 UTC

[calcite] branch master updated: Fix grammatical errors in TopDownRuleDriver/TopDownRuleQueue/RuleDriver/VolcanoPlanner

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

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


The following commit(s) were added to refs/heads/master by this push:
     new fdcb195  Fix grammatical errors in TopDownRuleDriver/TopDownRuleQueue/RuleDriver/VolcanoPlanner
fdcb195 is described below

commit fdcb195b829fdc4f52d777ae09630ee65eb0a977
Author: Chunwei Lei <ch...@gmail.com>
AuthorDate: Mon Nov 2 17:53:56 2020 +0800

    Fix grammatical errors in TopDownRuleDriver/TopDownRuleQueue/RuleDriver/VolcanoPlanner
---
 .../apache/calcite/plan/volcano/RuleDriver.java    |   6 +-
 .../calcite/plan/volcano/TopDownRuleDriver.java    | 137 +++++++++++----------
 .../calcite/plan/volcano/TopDownRuleQueue.java     |   9 +-
 .../calcite/plan/volcano/VolcanoPlanner.java       |   9 +-
 4 files changed, 91 insertions(+), 70 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RuleDriver.java b/core/src/main/java/org/apache/calcite/plan/volcano/RuleDriver.java
index f32279a..48c8d25 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RuleDriver.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RuleDriver.java
@@ -29,12 +29,13 @@ interface RuleDriver {
   RuleQueue getRuleQueue();
 
   /**
-   * Apply rules.
+   * Applies rules.
    */
   void drive();
 
   /**
    * Callback when new RelNodes are added into RelSet.
+   *
    * @param rel the new RelNode
    * @param subset subset to add
    */
@@ -42,12 +43,13 @@ interface RuleDriver {
 
   /**
    * Callback when RelSets are merged.
+   *
    * @param set the merged result set
    */
   void onSetMerged(RelSet set);
 
   /**
-   * Clear this RuleDriver.
+   * Clears this RuleDriver.
    */
   void clear();
 }
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleDriver.java b/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleDriver.java
index ce42d03..d4a43b9 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleDriver.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleDriver.java
@@ -36,13 +36,13 @@ import java.util.Stack;
 import java.util.function.Predicate;
 
 /**
- * A rule driver that apply rules in a Top-Down manner.
+ * A rule driver that applies rules in a Top-Down manner.
  * By ensuring rule applying orders, there could be ways for
  * space pruning and rule mutual exclusivity check.
  *
- * <p>This implementation use tasks to manage rule matches.
+ * <p>This implementation uses tasks to manage rule matches.
  * A Task is a piece of work to be executed, it may apply some rules
- * or schedule other tasks</p>
+ * or schedule other tasks.</p>
  */
 @SuppressWarnings("JdkObsolete")
 class TopDownRuleDriver implements RuleDriver {
@@ -69,8 +69,9 @@ class TopDownRuleDriver implements RuleDriver {
   private GeneratorTask applying = null;
 
   /**
-   * RelNodes that are generated by passThrough or derive
-   * these nodes will not takes part in another passThrough or derive.
+   * RelNodes that are generated by {@link org.apache.calcite.rel.PhysicalNode#passThrough}
+   * or {@link org.apache.calcite.rel.PhysicalNode#derive}. These nodes will not take part
+   * in another passThrough or derive.
    */
   private Set<RelNode> passThroughCache = new HashSet<>();
 
@@ -89,13 +90,13 @@ class TopDownRuleDriver implements RuleDriver {
     // Starting from the root's OptimizeGroup task.
     tasks.push(new OptimizeGroup(planner.root, planner.infCost));
 
-    // ensure materialized view roots get explored.
+    // Ensure materialized view roots get explored.
     // Note that implementation rules or enforcement rules are not applied
-    // unless the mv is matched
+    // unless the mv is matched.
     exploreMaterializationRoots();
 
     try {
-      // Iterates until the root is fully optimized
+      // Iterates until the root is fully optimized.
       while (!tasks.isEmpty()) {
         Task task = tasks.pop();
         description.log(task);
@@ -148,8 +149,8 @@ class TopDownRuleDriver implements RuleDriver {
 
   @Override public void onSetMerged(RelSet set) {
     // When RelSets get merged, an optimized group may get extra opportunities.
-    // Clear the OPTIMISED state for the RelSubsets and all theirs ancestors
-    // so that they will be optimized again
+    // Clear the OPTIMIZED state for the RelSubsets and all their ancestors,
+    // so that they will be optimized again.
     applyGenerator(null, () -> clearProcessed(set));
   }
 
@@ -170,27 +171,27 @@ class TopDownRuleDriver implements RuleDriver {
     }
   }
 
-  // a callback invoked when a RelNode is going to be added into a RelSubset,
-  // either by Register or Reregister. The task driver should need to schedule
-  // tasks for the new nodes.
+  // A callback invoked when a RelNode is going to be added into a RelSubset,
+  // either by Register or Reregister. The task driver should schedule tasks
+  // for the new nodes.
   @Override public void onProduce(RelNode node, RelSubset subset) {
 
-    // if the RelNode is added to another RelSubset, just ignore it.
-    // It should be schedule in the later OptimizeGroup task
+    // If the RelNode is added to another RelSubset, just ignore it.
+    // It should be scheduled in the later OptimizeGroup task.
     if (applying == null || subset.set
         != VolcanoPlanner.equivRoot(applying.group().set)) {
       return;
     }
 
-    // extra callback from each task
+    // Extra callback from each task.
     if (!applying.onProduce(node)) {
       return;
     }
 
     if (!planner.isLogical(node)) {
       // For a physical node, schedule tasks to optimize its inputs.
-      // The upper bound depends on all optimizing RelSubsets that this Rel belongs to.
-      // If there are optimizing subsets that comes from the same RelSet,
+      // The upper bound depends on all optimizing RelSubsets that this RelNode belongs to.
+      // If there are optimizing subsets that come from the same RelSet,
       // invoke the passThrough method to generate a candidate for that Subset.
       RelSubset optimizingGroup = null;
       boolean canPassThrough = node instanceof PhysicalNode
@@ -267,7 +268,7 @@ class TopDownRuleDriver implements RuleDriver {
         builder.append(")");
       }
 
-      LOGGER.info(builder.toString());
+      LOGGER.debug(builder.toString());
     }
 
     TaskDescriptor item(String name, Object value) {
@@ -292,8 +293,8 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Optimize a RelSubset.
-   * It schedule optimization tasks for RelNodes in the RelSet.
+   * Optimizes a RelSubset.
+   * It schedules optimization tasks for RelNodes in the RelSet.
    */
   private class OptimizeGroup implements Task {
     private final RelSubset group;
@@ -311,31 +312,31 @@ class TopDownRuleDriver implements RuleDriver {
       }
 
       if (group.taskState != null && upperBound.isLe(group.upperBound)) {
-        // either this group failed to optimize before or it is a ring
+        // Either this group failed to optimize before or it is a ring.
         return;
       }
 
       group.startOptimize(upperBound);
 
-      // cannot decide an actual lower bound before MExpr are fully explored
-      // so delay the lower bound checking
+      // Cannot decide an actual lower bound before MExpr are fully explored.
+      // So delay the lower bound check.
 
-      // a gate keeper to update context
+      // A gate keeper to update context.
       tasks.push(new GroupOptimized(group));
 
-      // optimize mExprs in group
+      // Optimize mExprs in group.
       List<RelNode> physicals = new ArrayList<>();
       for (RelNode rel : group.set.rels) {
         if (planner.isLogical(rel)) {
           tasks.push(new OptimizeMExpr(rel, group, false));
         } else if (rel.isEnforcer()) {
-          // Enforcers have lower priority than other physical nodes
+          // Enforcers have lower priority than other physical nodes.
           physicals.add(0, rel);
         } else {
           physicals.add(rel);
         }
       }
-      // always apply O_INPUTS first so as to get an valid upper bound
+      // Always apply O_INPUTS first so as to get a valid upper bound.
       for (RelNode rel : physicals) {
         Task task = getOptimizeInputTask(rel, group);
         if (task != null) {
@@ -350,9 +351,9 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Mark the RelSubset optimized.
+   * Marks the RelSubset optimized.
    * When GroupOptimized returns, the group is either fully
-   * optimized and has a winner or failed to optimized
+   * optimized and has a winner or failed to be optimized.
    */
   private static class GroupOptimized implements Task {
     private final RelSubset group;
@@ -366,18 +367,19 @@ class TopDownRuleDriver implements RuleDriver {
     }
 
     @Override public void describe(TaskDescriptor desc) {
-      desc.item("group", group);
+      desc.item("group", group)
+          .item("upperBound", group.upperBound);
     }
   }
 
   /**
-   * Optimize a logical node, including exploring its input and applying rules for it.
+   * Optimizes a logical node, including exploring its input and applying rules for it.
    */
   private class OptimizeMExpr implements Task {
     private final RelNode mExpr;
     private final RelSubset group;
 
-    // when true, only apply transformation rules for mExpr
+    // When true, only apply transformation rules for mExpr.
     private final boolean explore;
 
     OptimizeMExpr(RelNode mExpr,
@@ -391,8 +393,8 @@ class TopDownRuleDriver implements RuleDriver {
       if (explore && group.isExplored()) {
         return;
       }
-      // 1. explode input
-      // 2. apply other rules
+      // 1. explore input.
+      // 2. apply other rules.
       tasks.push(new ApplyRules(mExpr, group, explore));
       for (int i = mExpr.getInputs().size() - 1; i >= 0; --i) {
         tasks.push(new ExploreInput(mExpr, i));
@@ -405,8 +407,8 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Ensure that ExploreInputs are working on the correct input group.
-   * Currently, a RelNode's input may change since calcite may merge RelSets.
+   * Ensures that ExploreInputs are working on the correct input group.
+   * Currently, a RelNode's input may change since Calcite may merge RelSets.
    */
   private class EnsureGroupExplored implements Task {
 
@@ -427,7 +429,7 @@ class TopDownRuleDriver implements RuleDriver {
       }
       input.setExplored();
       for (RelSubset subset : input.getSet().subsets) {
-        // clear the LB cache as exploring state have changed
+        // Clear the LB cache as exploring state has changed.
         input.getCluster().getMetadataQuery().clearCache(subset);
       }
     }
@@ -438,7 +440,7 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Explore an input for a RelNode.
+   * Explores an input for a RelNode.
    */
   private class ExploreInput implements Task {
     private final RelSubset group;
@@ -469,7 +471,7 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Extract rule matches from rule queue and add them to task stack.
+   * Extracts rule matches from rule queue and adds them to task stack.
    */
   private class ApplyRules implements Task {
     private final RelNode mExpr;
@@ -499,7 +501,7 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Apply a rule match.
+   * Applies a rule match.
    */
   private class ApplyRule implements GeneratorTask {
     private final VolcanoRuleMatch match;
@@ -529,7 +531,9 @@ class TopDownRuleDriver implements RuleDriver {
     }
   }
 
-  // Decide how to optimize a physical node.
+  /**
+   *  Decides how to optimize a physical node.
+   */
   private Task getOptimizeInputTask(RelNode rel, RelSubset group) {
     // If the physical does not in current optimizing RelSubset, it firstly tries to
     // convert the physical node either by converter rule or traits pass though.
@@ -564,8 +568,10 @@ class TopDownRuleDriver implements RuleDriver {
     return new OptimizeInputs(rel, group);
   }
 
-  // Try to convert the physical node to another trait sets,
-  // either by converter rule or traits pass through.
+  /**
+   * Tries to convert the physical node to another trait sets, either by converter rule
+   * or traits pass through.
+   */
   private RelNode convert(RelNode rel, RelSubset group) {
     if (!passThroughCache.contains(rel)) {
       if (checkLowerBound(rel, group)) {
@@ -590,7 +596,9 @@ class TopDownRuleDriver implements RuleDriver {
     return null;
   }
 
-  // check whether a node's lower bound is less than a RelSubset's upper bound
+  /**
+   * Checks whether a node's lower bound is less than a RelSubset's upper bound.
+   */
   private boolean checkLowerBound(RelNode rel, RelSubset group) {
     RelOptCost upperBound = group.upperBound;
     if (upperBound.isInfinite()) {
@@ -601,8 +609,8 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * A task that optimize input for physical nodes who has only one input.
-   * This task can be replaced by OptimizeInputs but simplify lots of logic.
+   * A task that optimizes input for physical nodes who has only one input.
+   * This task can be replaced by OptimizeInputs but simplifies lots of logic.
    */
   private class OptimizeInput1 implements Task {
 
@@ -630,7 +638,7 @@ class TopDownRuleDriver implements RuleDriver {
 
       RelSubset input = (RelSubset) mExpr.getInput(0);
 
-      // Apply enforcing rules
+      // Apply enforcing rules.
       tasks.push(new DeriveTrait(mExpr, group));
 
       tasks.push(new CheckInput(null, mExpr, input, 0, upperForInput));
@@ -639,8 +647,8 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Optimize a physical node's inputs.
-   * This task calculates a proper upper bound for the input and invoke
+   * Optimizes a physical node's inputs.
+   * This task calculates a proper upper bound for the input and invokes
    * the OptimizeGroup task. Group pruning mainly happens here when
    * the upper bound for an input is less than the input's lower bound
    */
@@ -652,6 +660,8 @@ class TopDownRuleDriver implements RuleDriver {
     private RelOptCost upperBound;
     private RelOptCost upperForInput;
     private int processingChild;
+    private List<RelOptCost> lowerBounds;
+    private RelOptCost lowerBoundSum;
 
     OptimizeInputs(RelNode rel, RelSubset group) {
       this.mExpr = rel;
@@ -667,12 +677,10 @@ class TopDownRuleDriver implements RuleDriver {
           .item("processingChild", processingChild);
     }
 
-    private List<RelOptCost> lowerBounds;
-    private RelOptCost lowerBoundSum;
     @Override public void perform() {
       RelOptCost bestCost = group.bestCost;
       if (!bestCost.isInfinite()) {
-        // calculate the upper bound for inputs
+        // Calculate the upper bound for inputs.
         if (bestCost.isLt(upperBound)) {
           upperBound = bestCost;
           upperForInput = planner.upperBoundForInputs(mExpr, upperBound);
@@ -693,7 +701,8 @@ class TopDownRuleDriver implements RuleDriver {
           LOGGER.debug(
               "Skip O_INPUT because of lower bound. LB = {}, UP = {}",
               lowerBoundSum, upperForInput);
-          return; // group pruned
+          // Group is pruned.
+          return;
         }
       }
 
@@ -703,7 +712,7 @@ class TopDownRuleDriver implements RuleDriver {
       }
 
       if (processingChild == 0) {
-        // derive traits after all inputs are optimized successfully
+        // Derive traits after all inputs are optimized successfully.
         tasks.push(new DeriveTrait(mExpr, group));
       }
 
@@ -743,7 +752,7 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Ensure input is optimized correctly and modify context.
+   * Ensures input is optimized correctly and modify context.
    */
   private class CheckInput implements Task {
 
@@ -768,22 +777,22 @@ class TopDownRuleDriver implements RuleDriver {
 
     @Override public void perform() {
       if (input != parent.getInput(i)) {
-        // The input has chnaged. So reschedule the optimize task.
+        // The input has changed. So reschedule the optimize task.
         input = (RelSubset) parent.getInput(i);
         tasks.push(this);
         tasks.push(new OptimizeGroup(input, upper));
         return;
       }
 
-      // Optimize input completed. Update the context for other inputs
+      // Optimizing input completed. Update the context for other inputs.
       if (context == null) {
-        // If there is no other input, just return (no need to optimize other inputs)
+        // If there is no other input, just return (no need to optimize other inputs).
         return;
       }
 
       RelOptCost winner = input.getWinnerCost();
       if (winner == null) {
-        // The input fail to optimize due to group pruning
+        // The input fails to optimize due to group pruning.
         // Then there's no need to optimize other inputs.
         context.lowerBoundSum = planner.infCost;
         return;
@@ -800,7 +809,7 @@ class TopDownRuleDriver implements RuleDriver {
   }
 
   /**
-   * Derive traits for already optimized physical nodes.
+   * Derives traits for already optimized physical nodes.
    */
   private class DeriveTrait implements GeneratorTask {
 
@@ -816,7 +825,7 @@ class TopDownRuleDriver implements RuleDriver {
       List<RelNode> inputs = mExpr.getInputs();
       for (RelNode input : inputs) {
         if (((RelSubset) input).getWinnerCost() == null) {
-          // fail to optimize input, then no need to deliver traits
+          // Fail to optimize input, then no need to deliver traits.
           return;
         }
       }
@@ -825,7 +834,7 @@ class TopDownRuleDriver implements RuleDriver {
       // Note that this is deprecated and will be removed in the future.
       tasks.push(new ApplyRules(mExpr, group, false));
 
-      // Derive traits from inputs
+      // Derive traits from inputs.
       if (!passThroughCache.contains(mExpr)) {
         applyGenerator(this, this::derive);
       }
@@ -840,7 +849,7 @@ class TopDownRuleDriver implements RuleDriver {
       PhysicalNode rel = (PhysicalNode) mExpr;
       DeriveMode mode = rel.getDeriveMode();
       int arity = rel.getInputs().size();
-      // for OMAKASE
+      // For OMAKASE.
       List<List<RelTraitSet>> inputTraits = new ArrayList<>(arity);
 
       for (int i = 0; i < arity; i++) {
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleQueue.java b/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleQueue.java
index f4a6119..e93c511 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleQueue.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/TopDownRuleQueue.java
@@ -29,7 +29,7 @@ import java.util.Set;
 import java.util.function.Predicate;
 
 /**
- * A rule queue that manage rule matches for cascade planner.
+ * A rule queue that manages rule matches for cascades planner.
  */
 class TopDownRuleQueue extends RuleQueue {
 
@@ -53,6 +53,13 @@ class TopDownRuleQueue extends RuleQueue {
       return;
     }
 
+    // The substitution rule would be applied first though it is added at the end of the queue.
+    // The process looks like:
+    //   1) put the non-substitution rule at the front and substitution rule at the end of the queue
+    //   2) get each rule from the queue in order from first to last and generate an ApplyRule task
+    //   3) push each ApplyRule task into the task stack
+    // As a result, substitution rule is executed first since the ApplyRule(substitution) task is
+    // popped earlier than the ApplyRule(non-substitution) task from the stack.
     if (!planner.isSubstituteRule(match)) {
       queue.addFirst(match);
     } else {
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
index 32d647d..4f8d3c2 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
@@ -1442,9 +1442,10 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
   }
 
   /**
-   * Check whether a rule match is a substitute rule match.
+   * Checks whether a rule match is a substitution rule match.
+   *
    * @param match The rule match to check
-   * @return True if the rule match is a substitute rule match
+   * @return True if the rule match is a substitution rule match
    */
   @API(since = "1.24", status = API.Status.EXPERIMENTAL)
   protected boolean isSubstituteRule(VolcanoRuleCall match) {
@@ -1452,7 +1453,8 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
   }
 
   /**
-   * Check whether a rule match is a transformation rule match.
+   * Checks whether a rule match is a transformation rule match.
+   *
    * @param match The rule match to check
    * @return True if the rule match is a transformation rule match
    */
@@ -1472,6 +1474,7 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
 
   /**
    * Gets the lower bound cost of a relational operator.
+   *
    * @param rel The rel node
    * @return The lower bound cost of the given rel. The value is ensured NOT NULL.
    */