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.
*/