You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/12/02 09:47:48 UTC

calcite git commit: [CALCITE-990] In Volcano, Populate RelOptRuleCall.nodeInputs for operands of type "any"

Repository: calcite
Updated Branches:
  refs/heads/master 24b074715 -> 81b487684


[CALCITE-990] In Volcano, Populate RelOptRuleCall.nodeInputs for operands of type "any"


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/81b48768
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/81b48768
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/81b48768

Branch: refs/heads/master
Commit: 81b487684f9a0781d6e58494cba1b690ff42c028
Parents: 24b0747
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Nov 23 19:21:48 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Dec 2 00:15:56 2015 -0800

----------------------------------------------------------------------
 .../org/apache/calcite/plan/RelOptRuleCall.java | 15 +++-
 .../calcite/plan/volcano/VolcanoPlanner.java    |  3 +-
 .../calcite/plan/volcano/VolcanoRuleCall.java   | 75 +++++++++++++-------
 .../calcite/plan/volcano/VolcanoRuleMatch.java  | 18 ++---
 4 files changed, 72 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/81b48768/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java b/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java
index 788549b..f8df61f 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptRuleCall.java
@@ -24,6 +24,7 @@ import org.apache.calcite.util.trace.CalciteTrace;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
@@ -45,8 +46,8 @@ public abstract class RelOptRuleCall {
   //~ Instance fields --------------------------------------------------------
 
   public final int id;
-  private final RelOptRuleOperand operand0;
-  private final Map<RelNode, List<RelNode>> nodeInputs;
+  protected final RelOptRuleOperand operand0;
+  protected Map<RelNode, List<RelNode>> nodeInputs;
   public final RelOptRule rule;
   public final RelNode[] rels;
   private final RelOptPlanner planner;
@@ -169,6 +170,16 @@ public abstract class RelOptRuleCall {
     return nodeInputs.get(rel);
   }
 
+  /** Assigns the input relational expressions of a given relational expression,
+   * as seen by this particular call. Is only called when the operand is
+   * {@link RelOptRule#any()}. */
+  protected void setChildRels(RelNode rel, List<RelNode> inputs) {
+    if (nodeInputs.isEmpty()) {
+      nodeInputs = new HashMap<>();
+    }
+    nodeInputs.put(rel, inputs);
+  }
+
   /**
    * Returns the planner.
    *

http://git-wip-us.apache.org/repos/asf/calcite/blob/81b48768/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
----------------------------------------------------------------------
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 10ea16d..c87115f 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
@@ -1983,7 +1983,8 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
           new VolcanoRuleMatch(
               volcanoPlanner,
               getOperand0(),
-              rels);
+              rels,
+              nodeInputs);
       volcanoPlanner.ruleQueue.addMatch(match);
     }
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/81b48768/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleCall.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleCall.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleCall.java
index 273a4da..aa4e8ae 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleCall.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleCall.java
@@ -25,11 +25,12 @@ import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.util.Util;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
@@ -56,16 +57,15 @@ public class VolcanoRuleCall extends RelOptRuleCall {
    * @param planner Planner
    * @param operand First operand of the rule
    * @param rels    Array which will hold the matched relational expressions
+   * @param nodeInputs For each node which matched with {@code matchAnyChildren}
+   *                   = true, a list of the node's inputs
    */
   protected VolcanoRuleCall(
       VolcanoPlanner planner,
       RelOptRuleOperand operand,
-      RelNode[] rels) {
-    super(
-        planner,
-        operand,
-        rels,
-        Collections.<RelNode, List<RelNode>>emptyMap());
+      RelNode[] rels,
+      Map<RelNode, List<RelNode>> nodeInputs) {
+    super(planner, operand, rels, nodeInputs);
     this.volcanoPlanner = planner;
   }
 
@@ -81,7 +81,8 @@ public class VolcanoRuleCall extends RelOptRuleCall {
     this(
         planner,
         operand,
-        new RelNode[operand.getRule().operands.size()]);
+        new RelNode[operand.getRule().operands.size()],
+        ImmutableMap.<RelNode, List<RelNode>>of());
   }
 
   //~ Methods ----------------------------------------------------------------
@@ -222,7 +223,7 @@ public class VolcanoRuleCall extends RelOptRuleCall {
       }
 
       if (LOGGER.isLoggable(Level.FINE)) {
-        this.generatedRelList = new ArrayList<RelNode>();
+        this.generatedRelList = new ArrayList<>();
       }
 
       getRule().onMatch(this);
@@ -275,7 +276,8 @@ public class VolcanoRuleCall extends RelOptRuleCall {
    * @pre solve &lt;= rule.operands.length
    */
   private void matchRecurse(int solve) {
-    if (solve == getRule().operands.size()) {
+    final List<RelOptRuleOperand> operands = getRule().operands;
+    if (solve == operands.size()) {
       // We have matched all operands. Now ask the rule whether it
       // matches; this gives the rule chance to apply side-conditions.
       // If the side-conditions are satisfied, we have a match.
@@ -283,25 +285,28 @@ public class VolcanoRuleCall extends RelOptRuleCall {
         onMatch();
       }
     } else {
-      int operandOrdinal = getOperand0().solveOrder[solve];
-      int previousOperandOrdinal = getOperand0().solveOrder[solve - 1];
+      final int operandOrdinal = operand0.solveOrder[solve];
+      final int previousOperandOrdinal = operand0.solveOrder[solve - 1];
       boolean ascending = operandOrdinal < previousOperandOrdinal;
-      RelOptRuleOperand previousOperand =
-          getRule().operands.get(previousOperandOrdinal);
-      RelOptRuleOperand operand = getRule().operands.get(operandOrdinal);
+      final RelOptRuleOperand previousOperand =
+          operands.get(previousOperandOrdinal);
+      final RelOptRuleOperand operand = operands.get(operandOrdinal);
+      final RelNode previous = rels[previousOperandOrdinal];
 
+      final RelOptRuleOperand parentOperand;
       final Collection<? extends RelNode> successors;
       if (ascending) {
         assert previousOperand.getParent() == operand;
-        final RelNode childRel = rels[previousOperandOrdinal];
-        RelSubset subset = volcanoPlanner.getSubset(childRel);
+        parentOperand = operand;
+        final RelSubset subset = volcanoPlanner.getSubset(previous);
         successors = subset.getParentRels();
       } else {
-        int parentOrdinal = operand.getParent().ordinalInRule;
-        RelNode parentRel = rels[parentOrdinal];
-        List<RelNode> inputs = parentRel.getInputs();
+        parentOperand = previousOperand;
+        final int parentOrdinal = operand.getParent().ordinalInRule;
+        final RelNode parentRel = rels[parentOrdinal];
+        final List<RelNode> inputs = parentRel.getInputs();
         if (operand.ordinalInParent < inputs.size()) {
-          RelSubset subset =
+          final RelSubset subset =
               (RelSubset) inputs.get(operand.ordinalInParent);
           if (operand.getMatchedClass() == RelSubset.class) {
             successors = subset.set.subsets;
@@ -320,17 +325,33 @@ public class VolcanoRuleCall extends RelOptRuleCall {
           continue;
         }
         if (ascending) {
-          // We know that the previous operand was *a* child of
-          // its parent, but now check that it is the *correct*
-          // child
+          // We know that the previous operand was *a* child of its parent,
+          // but now check that it is the *correct* child.
           final RelSubset input =
-              (RelSubset) rel.getInput(
-                  previousOperand.ordinalInParent);
+              (RelSubset) rel.getInput(previousOperand.ordinalInParent);
           List<RelNode> inputRels = input.set.getRelsFromAllSubsets();
-          if (!inputRels.contains(rels[previousOperandOrdinal])) {
+          if (!inputRels.contains(previous)) {
             continue;
           }
         }
+
+        // Assign "childRels" if the operand is UNORDERED.
+        switch (parentOperand.childPolicy) {
+        case UNORDERED:
+          if (ascending) {
+            final List<RelNode> inputs = Lists.newArrayList(rel.getInputs());
+            inputs.set(previousOperand.ordinalInParent, previous);
+            setChildRels(rel, inputs);
+          } else {
+            List<RelNode> inputs = getChildRels(previous);
+            if (inputs == null) {
+              inputs = Lists.newArrayList(previous.getInputs());
+            }
+            inputs.set(operand.ordinalInParent, rel);
+            setChildRels(previous, inputs);
+          }
+        }
+
         rels[operandOrdinal] = rel;
         matchRecurse(solve + 1);
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/81b48768/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleMatch.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleMatch.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleMatch.java
index bc120f8..6a2c8b3 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleMatch.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoRuleMatch.java
@@ -21,6 +21,9 @@ import org.apache.calcite.plan.RelTrait;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelNode;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * A match of a rule to a particular set of target relational expressions,
  * frozen in time.
@@ -31,7 +34,6 @@ class VolcanoRuleMatch extends VolcanoRuleCall {
   private final RelSet targetSet;
   private RelSubset targetSubset;
   private String digest;
-  private final VolcanoPlanner volcanoPlanner;
   private double cachedImportance = Double.NaN;
 
   //~ Constructors -----------------------------------------------------------
@@ -42,16 +44,14 @@ class VolcanoRuleMatch extends VolcanoRuleCall {
    * @param operand0 Primary operand
    * @param rels     List of targets; copied by the constructor, so the client
    *                 can modify it later
+   * @param nodeInputs Map from relational expressions to their inputs
    * @pre rels[i] != null
    */
-  VolcanoRuleMatch(
-      VolcanoPlanner volcanoPlanner,
-      RelOptRuleOperand operand0,
-      RelNode[] rels) {
-    super(volcanoPlanner, operand0, rels.clone());
-    this.volcanoPlanner = volcanoPlanner;
-    for (int i = 0; i < rels.length; i++) {
-      assert rels[i] != null;
+  VolcanoRuleMatch(VolcanoPlanner volcanoPlanner, RelOptRuleOperand operand0,
+      RelNode[] rels, Map<RelNode, List<RelNode>> nodeInputs) {
+    super(volcanoPlanner, operand0, rels.clone(), nodeInputs);
+    for (RelNode rel : rels) {
+      assert rel != null;
     }
 
     // Try to deduce which subset the result will belong to. Assume --