You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ru...@apache.org on 2020/06/04 15:22:29 UTC

[calcite] branch master updated: [CALCITE-4042] JoinCommuteRule must not match SEMI / ANTI join

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

rubenql 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 721ac8c  [CALCITE-4042] JoinCommuteRule must not match SEMI / ANTI join
721ac8c is described below

commit 721ac8c21fb3a33dc85e677434ec7d716f9aa509
Author: rubenada <ru...@gmail.com>
AuthorDate: Thu Jun 4 11:05:02 2020 +0200

    [CALCITE-4042] JoinCommuteRule must not match SEMI / ANTI join
---
 .../apache/calcite/rel/rules/JoinCommuteRule.java  |  6 +++
 .../org/apache/calcite/test/RelOptRulesTest.java   | 49 ++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java b/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java
index b7c8c4e..7ef422c 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/JoinCommuteRule.java
@@ -145,6 +145,12 @@ public class JoinCommuteRule extends RelOptRule implements TransformationRule {
         .build();
   }
 
+  public boolean matches(RelOptRuleCall call) {
+    Join join = call.rel(0);
+    // SEMI and ANTI join cannot be swapped.
+    return join.getJoinType().projectsRight();
+  }
+
   public void onMatch(final RelOptRuleCall call) {
     Join join = call.rel(0);
 
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 7472d8d..2a867eb 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -5624,6 +5624,55 @@ class RelOptRulesTest extends RelOptTestBase {
     sql(sql).with(program).check();
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-4042">[CALCITE-4042]
+   * JoinCommuteRule must not match SEMI / ANTI join</a>. */
+  @Test void testSwapSemiJoin() {
+    final RelBuilder relBuilder = RelBuilder.create(RelBuilderTest.config().build());
+    final RelNode input = relBuilder
+        .scan("EMP")
+        .scan("DEPT")
+        .semiJoin(relBuilder
+            .equals(
+                relBuilder.field(2, 0, "DEPTNO"),
+                relBuilder.field(2, 1, "DEPTNO")))
+        .project(relBuilder.field("EMPNO"))
+        .build();
+    testSwapJoinShouldNotMatch(input);
+  }
+
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-4042">[CALCITE-4042]
+   * JoinCommuteRule must not match SEMI / ANTI join</a>. */
+  @Test void testSwapAntiJoin() {
+    final RelBuilder relBuilder = RelBuilder.create(RelBuilderTest.config().build());
+    final RelNode input = relBuilder
+        .scan("EMP")
+        .scan("DEPT")
+        .antiJoin(relBuilder
+            .equals(
+                relBuilder.field(2, 0, "DEPTNO"),
+                relBuilder.field(2, 1, "DEPTNO")))
+        .project(relBuilder.field("EMPNO"))
+        .build();
+    testSwapJoinShouldNotMatch(input);
+  }
+
+  private void testSwapJoinShouldNotMatch(RelNode input) {
+    final HepProgram program = new HepProgramBuilder()
+        .addMatchLimit(1)
+        .addRuleInstance(JoinCommuteRule.SWAP_OUTER)
+        .build();
+
+    final HepPlanner hepPlanner = new HepPlanner(program);
+    hepPlanner.setRoot(input);
+    final RelNode output = hepPlanner.findBestExp();
+
+    final String planBefore = RelOptUtil.toString(input);
+    final String planAfter = RelOptUtil.toString(output);
+    assertEquals(planBefore, planAfter);
+  }
+
   @Test void testPushJoinCondDownToProject() {
     final String sql = "select d.deptno, e.deptno from sales.dept d, sales.emp e\n"
         + " where d.deptno + 10 = e.deptno * 2";