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

hyuan 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 d3286ad  [CALCITE-3948] RelSubset matching is not properly handled in 
VolcanoRuleCall (Botong Huang)
d3286ad is described below

commit d3286ad4725fa97aae35c70f73ab768fabd409d8
Author: botong.huang <[email protected]>
AuthorDate: Sat Apr 18 17:27:34 2020 -0700

    [CALCITE-3948] RelSubset matching is not properly handled in 
VolcanoRuleCall (Botong Huang)
    
    Close #1935
---
 .../org/apache/calcite/plan/volcano/RelSubset.java | 22 +++++++++++++++
 .../calcite/plan/volcano/VolcanoRuleCall.java      | 31 ++++++++++++++--------
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java 
b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
index a48cd13..eb401d3 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RelSubset.java
@@ -37,6 +37,7 @@ import org.apache.calcite.util.Pair;
 import org.apache.calcite.util.Util;
 import org.apache.calcite.util.trace.CalciteTrace;
 
+import org.apiguardian.api.API;
 import org.slf4j.Logger;
 
 import java.io.PrintWriter;
@@ -53,6 +54,7 @@ import java.util.Queue;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Subset of an equivalence class where all relational expressions have the
@@ -438,6 +440,26 @@ public class RelSubset extends AbstractRelNode {
     return list;
   }
 
+  /**
+   * Returns stream of subsets whose traitset satisfies
+   * current subset's traitset.
+   */
+  @API(since = "1.23", status = API.Status.EXPERIMENTAL)
+  public Stream<RelSubset> getSubsetsSatisfyingThis() {
+    return set.subsets.stream()
+      .filter(s -> s.getTraitSet().satisfies(traitSet));
+  }
+
+  /**
+   * Returns stream of subsets whose traitset is satisfied
+   * by current subset's traitset.
+   */
+  @API(since = "1.23", status = API.Status.EXPERIMENTAL)
+  public Stream<RelSubset> getSatisfyingSubsets() {
+    return set.subsets.stream()
+      .filter(s -> traitSet.satisfies(s.getTraitSet()));
+  }
+
   //~ Inner Classes ----------------------------------------------------------
 
   /**
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 88d40cf..a099fd8 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
@@ -294,6 +294,7 @@ public class VolcanoRuleCall extends RelOptRuleCall {
       final Collection<? extends RelNode> successors;
       if (ascending) {
         assert previousOperand.getParent() == operand;
+        assert operand.getMatchedClass() != RelSubset.class;
         if (previousOperand.getMatchedClass() != RelSubset.class
             && previous instanceof RelSubset) {
           throw new RuntimeException("RelSubset should not match with "
@@ -303,15 +304,17 @@ public class VolcanoRuleCall extends RelOptRuleCall {
         final RelSubset subset = volcanoPlanner.getSubset(previous);
         successors = subset.getParentRels();
       } else {
-        parentOperand = previousOperand;
-        final int parentOrdinal = operand.getParent().ordinalInRule;
-        final RelNode parentRel = rels[parentOrdinal];
+        parentOperand = operand.getParent();
+        final RelNode parentRel = rels[parentOperand.ordinalInRule];
         final List<RelNode> inputs = parentRel.getInputs();
         // if the child is unordered, then add all rels in all input subsets 
to the successors list
         // because unordered can match child in any ordinal
         if (parentOperand.childPolicy == 
RelOptRuleOperandChildPolicy.UNORDERED) {
           if (operand.getMatchedClass() == RelSubset.class) {
-            successors = inputs;
+            // Find all the sibling subsets that satisfy this subset's traitSet
+            successors = inputs.stream()
+              .flatMap(subset -> ((RelSubset) 
subset).getSubsetsSatisfyingThis())
+              .collect(Collectors.toList());
           } else {
             List<RelNode> allRelsInAllSubsets = new ArrayList<>();
             Set<RelNode> duplicates = new HashSet<>();
@@ -337,10 +340,9 @@ public class VolcanoRuleCall extends RelOptRuleCall {
           final RelSubset subset =
               (RelSubset) inputs.get(operand.ordinalInParent);
           if (operand.getMatchedClass() == RelSubset.class) {
-            // Find all the sibling subsets that satisfy the traitSet of 
current subset.
-            successors = subset.set.subsets.stream()
-                .filter(s -> s.getTraitSet().satisfies(subset.getTraitSet()))
-                .collect(Collectors.toList());
+            // Find all the sibling subsets that satisfy this subset'straitSet
+            successors =
+              subset.getSubsetsSatisfyingThis().collect(Collectors.toList());
           } else {
             successors = subset.getRelList();
           }
@@ -363,9 +365,16 @@ public class VolcanoRuleCall extends RelOptRuleCall {
           }
           final RelSubset input =
               (RelSubset) rel.getInput(previousOperand.ordinalInParent);
-          List<RelNode> inputRels = input.getRelList();
-          if (!(previous instanceof RelSubset) && 
!inputRels.contains(previous)) {
-            continue;
+          if (previousOperand.getMatchedClass() == RelSubset.class) {
+            // The matched subset (previous) should satisfy our input subset 
(input)
+            if (input.getSubsetsSatisfyingThis().noneMatch(previous::equals)) {
+              continue;
+            }
+          } else {
+            List<RelNode> inputRels = input.getRelList();
+            if (!inputRels.contains(previous)) {
+              continue;
+            }
           }
         }
 

Reply via email to