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/01/28 23:44:59 UTC

[6/7] incubator-calcite git commit: [CALCITE-571] ReduceExpressionsRule tries to reduce SemiJoin condition to non-equi condition

[CALCITE-571] ReduceExpressionsRule tries to reduce SemiJoin condition to non-equi condition


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

Branch: refs/heads/branch-1.0
Commit: f036de876064f51e5271cd1d5de342b431299e91
Parents: 1b15939
Author: Julian Hyde <jh...@apache.org>
Authored: Tue Jan 27 13:21:42 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Jan 28 11:32:21 2015 -0800

----------------------------------------------------------------------
 .../rel/rules/ReduceExpressionsRule.java        | 35 +++++++++++++-------
 .../apache/calcite/test/RelOptRulesTest.java    | 19 +++++++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml | 33 ++++++++++++++++++
 3 files changed, 75 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f036de87/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index e033df9..16c5e82 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -23,6 +23,7 @@ import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.core.Join;
+import org.apache.calcite.rel.core.JoinInfo;
 import org.apache.calcite.rel.logical.LogicalCalc;
 import org.apache.calcite.rel.logical.LogicalFilter;
 import org.apache.calcite.rel.logical.LogicalProject;
@@ -221,19 +222,29 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
               RelMetadataQuery.getPulledUpPredicates(join.getRight());
           final RelOptPredicateList predicates =
               leftPredicates.union(rightPredicates.shift(fieldCount));
-          if (reduceExpressions(join, expList, predicates)) {
-            call.transformTo(
-                join.copy(
-                    join.getTraitSet(),
-                    expList.get(0),
-                    join.getLeft(),
-                    join.getRight(),
-                    join.getJoinType(),
-                    join.isSemiJoinDone()));
-
-            // New plan is absolutely better than old plan.
-            call.getPlanner().setImportance(join, 0.0);
+          if (!reduceExpressions(join, expList, predicates)) {
+            return;
           }
+          if (join instanceof EquiJoin) {
+            final JoinInfo joinInfo =
+                JoinInfo.of(join.getLeft(), join.getRight(), expList.get(0));
+            if (!joinInfo.isEqui()) {
+              // This kind of join must be an equi-join, and the condition is
+              // no longer an equi-join. SemiJoin is an example of this.
+              return;
+            }
+          }
+          call.transformTo(
+              join.copy(
+                  join.getTraitSet(),
+                  expList.get(0),
+                  join.getLeft(),
+                  join.getRight(),
+                  join.getJoinType(),
+                  join.isSemiJoinDone()));
+
+          // New plan is absolutely better than old plan.
+          call.getPlanner().setImportance(join, 0.0);
         }
       };
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f036de87/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 3144976..fdc0779 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -327,6 +327,25 @@ public class RelOptRulesTest extends RelOptTestBase {
             + "  ))R where R.deptno <=10 ");
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-571">[CALCITE-571],
+   * ReduceExpressionsRule tries to reduce SemiJoin condition to non-equi
+   * condition</a>. */
+  @Test public void testSemiJoinReduceConstants() {
+    final HepProgram preProgram = HepProgram.builder().addRuleInstance(
+        SemiJoinRule.INSTANCE)
+            .build();
+
+    final HepProgram program = HepProgram.builder().addRuleInstance(
+        ReduceExpressionsRule.JOIN_INSTANCE)
+            .build();
+    checkPlanning(tester.withDecorrelation(false).withTrim(true), preProgram,
+        new HepPlanner(program),
+        "select e1.sal from (select * from emp where deptno = 200) as e1\n"
+            + "where e1.deptno in (\n"
+            + "  select e2.deptno from emp e2 where e2.sal = 100)");
+  }
+
   protected void semiJoinTrim() {
     final DiffRepository diffRepos = getDiffRepos();
     String sql = diffRepos.expand(null, "${sql}");

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f036de87/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 1468adf..a3b2c67 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -108,6 +108,39 @@ ProjectRel(EXPR$0=[1])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testSemiJoinReduceConstants">
+        <Resource name="sql">
+            <![CDATA[select e1.sal from (select * from emp where deptno = 200) as e1
+where e1.deptno in (
+  select e2.deptno from emp e2 where e2.sal = 100)]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+LogicalProject(SAL=[$0])
+  SemiJoin(condition=[=($1, $2)], joinType=[inner])
+    LogicalFilter(condition=[=($1, 200)])
+      LogicalProject(SAL=[$5], DEPTNO=[$7])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+    LogicalProject(DEPTNO=[$1])
+      LogicalFilter(condition=[=($0, 100)])
+        LogicalProject(SAL=[$5], DEPTNO=[$7])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+LogicalProject(SAL=[$0])
+  SemiJoin(condition=[=($1, $2)], joinType=[inner])
+    LogicalFilter(condition=[=($1, 200)])
+      LogicalProject(SAL=[$5], DEPTNO=[$7])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+    LogicalProject(DEPTNO=[$1])
+      LogicalFilter(condition=[=($0, 100)])
+        LogicalProject(SAL=[$5], DEPTNO=[$7])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testFullOuterJoinSimplificationToLeftOuter">
         <Resource name="sql">
             <![CDATA[select 1 from sales.dept d full outer join sales.emp e on d.deptno = e.deptno where d.name = 'Charlie']]>