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/09/03 00:15:54 UTC

[06/50] incubator-calcite git commit: [CALCITE-390] Infer predicates for semi-join

[CALCITE-390] Infer predicates for semi-join


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

Branch: refs/heads/branch-release
Commit: 23396f0637724205ae35a89972bb61bc60d3e946
Parents: 464fd36
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jul 9 21:23:00 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 9 21:26:49 2015 -0700

----------------------------------------------------------------------
 .../calcite/rel/metadata/RelMdPredicates.java   |  8 ++-
 .../apache/calcite/test/RelMetadataTest.java    | 67 ++++++++++++++++++++
 2 files changed, 72 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/23396f06/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
index 05e6b4f..5e14ba7 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
@@ -193,9 +193,11 @@ public class RelMdPredicates {
 
   /** Infers predicates for a {@link org.apache.calcite.rel.core.SemiJoin}. */
   public RelOptPredicateList getPredicates(SemiJoin semiJoin) {
-    // Workaround, pending [CALCITE-390] "Transitive inference (RelMdPredicate)
-    // doesn't handle semi-join"
-    return RelOptPredicateList.EMPTY;
+    final RelNode left = semiJoin.getInput(0);
+    final RelOptPredicateList leftInfo =
+        RelMetadataQuery.getPulledUpPredicates(left);
+    return RelOptPredicateList.of(leftInfo.pulledUpPredicates,
+        leftInfo.pulledUpPredicates, ImmutableList.<RexNode>of());
   }
 
   /** Infers predicates for a {@link org.apache.calcite.rel.core.Join}. */

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/23396f06/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 2c46a9f..ddb116f 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -19,6 +19,7 @@ package org.apache.calcite.test;
 import org.apache.calcite.adapter.enumerable.EnumerableMergeJoin;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptPredicateList;
 import org.apache.calcite.plan.RelOptSchema;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.rel.InvalidRelException;
@@ -32,6 +33,7 @@ import org.apache.calcite.rel.core.AggregateCall;
 import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.SemiJoin;
 import org.apache.calcite.rel.core.Sort;
 import org.apache.calcite.rel.logical.LogicalAggregate;
 import org.apache.calcite.rel.logical.LogicalFilter;
@@ -51,6 +53,7 @@ import org.apache.calcite.rel.metadata.RelMdCollation;
 import org.apache.calcite.rel.metadata.RelMetadataProvider;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
@@ -1011,6 +1014,70 @@ public class RelMetadataTest extends SqlToRelTestBase {
     assertThat(RelMetadataQuery.splitCount(aggregate), is(1));
   }
 
+  /** Unit test for
+   * {@link org.apache.calcite.rel.metadata.RelMdPredicates#getPredicates(SemiJoin)}. */
+  @Test public void testPredicates() {
+    final Project rel = (Project) convertSql("select * from emp, dept");
+    final Join join = (Join) rel.getInput();
+    final RelOptTable empTable = join.getInput(0).getTable();
+    final RelOptTable deptTable = join.getInput(1).getTable();
+    Frameworks.withPlanner(
+        new Frameworks.PlannerAction<Void>() {
+          public Void apply(RelOptCluster cluster,
+              RelOptSchema relOptSchema,
+              SchemaPlus rootSchema) {
+            checkPredicates(cluster, empTable, deptTable);
+            return null;
+          }
+        });
+  }
+
+  private void checkPredicates(RelOptCluster cluster, RelOptTable empTable,
+      RelOptTable deptTable) {
+    final RexBuilder rexBuilder = cluster.getRexBuilder();
+    final LogicalTableScan empScan = LogicalTableScan.create(cluster, empTable);
+
+    RelOptPredicateList predicates =
+        RelMetadataQuery.getPulledUpPredicates(empScan);
+    assertThat(predicates.pulledUpPredicates.isEmpty(), is(true));
+
+    final LogicalFilter filter =
+        LogicalFilter.create(empScan,
+            rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+                rexBuilder.makeInputRef(empScan,
+                    empScan.getRowType().getFieldNames().indexOf("EMPNO")),
+                rexBuilder.makeExactLiteral(BigDecimal.ONE)));
+
+    predicates = RelMetadataQuery.getPulledUpPredicates(filter);
+    assertThat(predicates.pulledUpPredicates.toString(), is("[=($0, 1)]"));
+
+    final LogicalTableScan deptScan =
+        LogicalTableScan.create(cluster, deptTable);
+
+    final RelDataTypeField leftDeptnoField =
+        empScan.getRowType().getFieldList().get(
+            empScan.getRowType().getFieldNames().indexOf("DEPTNO"));
+    final RelDataTypeField rightDeptnoField =
+        deptScan.getRowType().getFieldList().get(
+            deptScan.getRowType().getFieldNames().indexOf("DEPTNO"));
+    final SemiJoin semiJoin =
+        SemiJoin.create(filter, deptScan,
+            rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+                rexBuilder.makeInputRef(leftDeptnoField.getType(),
+                    leftDeptnoField.getIndex()),
+                rexBuilder.makeInputRef(rightDeptnoField.getType(),
+                    rightDeptnoField.getIndex()
+                        + empScan.getRowType().getFieldCount())),
+            ImmutableIntList.of(leftDeptnoField.getIndex()),
+            ImmutableIntList.of(rightDeptnoField.getIndex()
+                    + empScan.getRowType().getFieldCount()));
+
+    predicates = RelMetadataQuery.getPulledUpPredicates(semiJoin);
+    assertThat(predicates.pulledUpPredicates.toString(), is("[=($0, 1)]"));
+    assertThat(predicates.leftInferredPredicates.toString(), is("[=($0, 1)]"));
+    assertThat(predicates.rightInferredPredicates.isEmpty(), is(true));
+  }
+
   /** Custom metadata interface. */
   public interface ColType extends Metadata {
     String getColType(int column);