You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by hy...@apache.org on 2020/05/05 22:11:57 UTC

[calcite] branch master updated: [CALCITE-3718] Support Intersect and Minus in Bindables (xzh)

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 0cdb7a8  [CALCITE-3718] Support Intersect and Minus in Bindables (xzh)
0cdb7a8 is described below

commit 0cdb7a8a520eabdf103519a399c148b0df3ba20b
Author: dz <95...@qq.com>
AuthorDate: Tue Dec 24 14:07:26 2019 +0800

    [CALCITE-3718] Support Intersect and Minus in Bindables (xzh)
    
    Close #1737
---
 .../org/apache/calcite/interpreter/Bindables.java  | 103 ++++++++++++++++++---
 .../java/org/apache/calcite/test/JdbcTest.java     |  36 +++++++
 2 files changed, 125 insertions(+), 14 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/interpreter/Bindables.java b/core/src/main/java/org/apache/calcite/interpreter/Bindables.java
index c190d28..8490405 100644
--- a/core/src/main/java/org/apache/calcite/interpreter/Bindables.java
+++ b/core/src/main/java/org/apache/calcite/interpreter/Bindables.java
@@ -39,11 +39,14 @@ import org.apache.calcite.rel.core.Aggregate;
 import org.apache.calcite.rel.core.AggregateCall;
 import org.apache.calcite.rel.core.CorrelationId;
 import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Intersect;
 import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.core.Match;
+import org.apache.calcite.rel.core.Minus;
 import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.core.SetOp;
 import org.apache.calcite.rel.core.Sort;
 import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.core.Union;
@@ -51,6 +54,7 @@ import org.apache.calcite.rel.core.Values;
 import org.apache.calcite.rel.core.Window;
 import org.apache.calcite.rel.logical.LogicalAggregate;
 import org.apache.calcite.rel.logical.LogicalFilter;
+import org.apache.calcite.rel.logical.LogicalIntersect;
 import org.apache.calcite.rel.logical.LogicalJoin;
 import org.apache.calcite.rel.logical.LogicalMatch;
 import org.apache.calcite.rel.logical.LogicalProject;
@@ -104,8 +108,8 @@ public class Bindables {
   public static final RelOptRule BINDABLE_JOIN_RULE =
       new BindableJoinRule(RelFactories.LOGICAL_BUILDER);
 
-  public static final RelOptRule BINDABLE_UNION_RULE =
-      new BindableUnionRule(RelFactories.LOGICAL_BUILDER);
+  public static final RelOptRule BINDABLE_SETOP_RULE =
+      new BindableSetOpRule(RelFactories.LOGICAL_BUILDER);
 
   public static final RelOptRule BINDABLE_VALUES_RULE =
       new BindableValuesRule(RelFactories.LOGICAL_BUILDER);
@@ -128,7 +132,7 @@ public class Bindables {
           BINDABLE_PROJECT_RULE,
           BINDABLE_SORT_RULE,
           BINDABLE_JOIN_RULE,
-          BINDABLE_UNION_RULE,
+          BINDABLE_SETOP_RULE,
           BINDABLE_VALUES_RULE,
           BINDABLE_AGGREGATE_RULE,
           BINDABLE_WINDOW_RULE,
@@ -517,11 +521,8 @@ public class Bindables {
     }
   }
 
-  /**
-   * Rule to convert an {@link org.apache.calcite.rel.logical.LogicalUnion}
-   * to a {@link BindableUnion}.
-   */
-  public static class BindableUnionRule extends ConverterRule {
+  @Deprecated // Use BindableSetOpRule instead, to be removed before 1.24.0
+  public static class BindableUnionRule extends BindableSetOpRule {
 
     /**
      * Creates a BindableUnionRule.
@@ -529,17 +530,41 @@ public class Bindables {
      * @param relBuilderFactory Builder for relational expressions
      */
     public BindableUnionRule(RelBuilderFactory relBuilderFactory) {
-      super(LogicalUnion.class, (Predicate<RelNode>) r -> true,
+      super(relBuilderFactory);
+    }
+  }
+
+  /**
+   * Rule to convert an {@link SetOp} to a {@link BindableUnion}
+   * or {@link BindableIntersect} or {@link BindableMinus}.
+   */
+  public static class BindableSetOpRule extends ConverterRule {
+
+    /**
+     * Creates a BindableSetOpRule.
+     *
+     * @param relBuilderFactory Builder for relational expressions
+     */
+    public BindableSetOpRule(RelBuilderFactory relBuilderFactory) {
+      super(SetOp.class, (Predicate<RelNode>) r -> true,
           Convention.NONE, BindableConvention.INSTANCE, relBuilderFactory,
-          "BindableUnionRule");
+          "BindableSetOpRule");
     }
 
     public RelNode convert(RelNode rel) {
-      final LogicalUnion union = (LogicalUnion) rel;
+      final SetOp setOp = (SetOp) rel;
       final BindableConvention out = BindableConvention.INSTANCE;
-      final RelTraitSet traitSet = union.getTraitSet().replace(out);
-      return new BindableUnion(rel.getCluster(), traitSet,
-          convertList(union.getInputs(), out), union.all);
+      final RelTraitSet traitSet = setOp.getTraitSet().replace(out);
+      if (setOp instanceof LogicalUnion) {
+        return new BindableUnion(rel.getCluster(), traitSet,
+            convertList(setOp.getInputs(), out), setOp.all);
+      } else if (setOp instanceof LogicalIntersect) {
+        return new BindableIntersect(rel.getCluster(), traitSet,
+            convertList(setOp.getInputs(), out), setOp.all);
+      } else {
+        return new BindableMinus(rel.getCluster(), traitSet,
+            convertList(setOp.getInputs(), out), setOp.all);
+      }
     }
   }
 
@@ -569,6 +594,56 @@ public class Bindables {
     }
   }
 
+  /** Implementation of {@link org.apache.calcite.rel.core.Intersect} in
+   * bindable calling convention. */
+  public static class BindableIntersect extends Intersect implements BindableRel {
+    public BindableIntersect(RelOptCluster cluster, RelTraitSet traitSet,
+        List<RelNode> inputs, boolean all) {
+      super(cluster, traitSet, inputs, all);
+    }
+
+    public BindableIntersect copy(RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
+      return new BindableIntersect(getCluster(), traitSet, inputs, all);
+    }
+
+    public Class<Object[]> getElementType() {
+      return Object[].class;
+    }
+
+    public Enumerable<Object[]> bind(DataContext dataContext) {
+      return help(dataContext, this);
+    }
+
+    public Node implement(InterpreterImplementor implementor) {
+      return new SetOpNode(implementor.compiler, this);
+    }
+  }
+
+  /** Implementation of {@link org.apache.calcite.rel.core.Minus} in
+   * bindable calling convention. */
+  public static class BindableMinus extends Minus implements BindableRel {
+    public BindableMinus(RelOptCluster cluster, RelTraitSet traitSet,
+        List<RelNode> inputs, boolean all) {
+      super(cluster, traitSet, inputs, all);
+    }
+
+    public BindableMinus copy(RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
+      return new BindableMinus(getCluster(), traitSet, inputs, all);
+    }
+
+    public Class<Object[]> getElementType() {
+      return Object[].class;
+    }
+
+    public Enumerable<Object[]> bind(DataContext dataContext) {
+      return help(dataContext, this);
+    }
+
+    public Node implement(InterpreterImplementor implementor) {
+      return new SetOpNode(implementor.compiler, this);
+    }
+  }
+
   /** Implementation of {@link org.apache.calcite.rel.core.Values}
    * in bindable calling convention. */
   public static class BindableValues extends Values implements BindableRel {
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 4a4927f..fa5b501 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -7072,6 +7072,42 @@ public class JdbcTest {
     }
   }
 
+  @Test public void testBindableIntersect() {
+    try (Hook.Closeable ignored = Hook.ENABLE_BINDABLE.addThread(Hook.propertyJ(true))) {
+      final String sql0 = "select \"empid\", \"deptno\" from \"hr\".\"emps\"";
+      final String sql = sql0 + " intersect all " + sql0;
+      CalciteAssert.hr()
+          .query(sql)
+          .explainContains(""
+              + "PLAN=BindableIntersect(all=[true])\n"
+              + "  BindableProject(empid=[$0], deptno=[$1])\n"
+              + "    BindableTableScan(table=[[hr, emps]])\n"
+              + "  BindableProject(empid=[$0], deptno=[$1])\n"
+              + "    BindableTableScan(table=[[hr, emps]])")
+          .returns(""
+              + "empid=150; deptno=10\n"
+              + "empid=100; deptno=10\n"
+              + "empid=200; deptno=20\n"
+              + "empid=110; deptno=10\n");
+    }
+  }
+
+  @Test public void testBindableMinus() {
+    try (Hook.Closeable ignored = Hook.ENABLE_BINDABLE.addThread(Hook.propertyJ(true))) {
+      final String sql0 = "select \"empid\", \"deptno\" from \"hr\".\"emps\"";
+      final String sql = sql0 + " except all " + sql0;
+      CalciteAssert.hr()
+          .query(sql)
+          .explainContains(""
+              + "PLAN=BindableMinus(all=[true])\n"
+              + "  BindableProject(empid=[$0], deptno=[$1])\n"
+              + "    BindableTableScan(table=[[hr, emps]])\n"
+              + "  BindableProject(empid=[$0], deptno=[$1])\n"
+              + "    BindableTableScan(table=[[hr, emps]])")
+          .returns("");
+    }
+  }
+
   /** Test case for
    * <a href="https://issues.apache.org/jira/browse/CALCITE-2224">[CALCITE-2224]
    * WITHIN GROUP clause for aggregate functions</a>. */