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 2021/12/15 08:31:15 UTC

[calcite] branch master updated: [CALCITE-4941] SemiJoinRule loses hints

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 7d342b3  [CALCITE-4941] SemiJoinRule loses hints
7d342b3 is described below

commit 7d342b3eac92b34a9196a5486e4ebe172d843f2b
Author: rubenada <ru...@gmail.com>
AuthorDate: Tue Dec 14 17:52:37 2021 +0000

    [CALCITE-4941] SemiJoinRule loses hints
---
 .../org/apache/calcite/rel/rules/SemiJoinRule.java |  2 +-
 .../org/apache/calcite/test/RelOptRulesTest.java   | 46 ++++++++++++++++++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml    | 21 ++++++++++
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java
index adf9a2f..fc84206 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/SemiJoinRule.java
@@ -109,7 +109,7 @@ public abstract class SemiJoinRule
           RelOptUtil.createEquiJoinCondition(relBuilder.peek(2, 0),
               joinInfo.leftKeys, relBuilder.peek(2, 1), newRightKeys,
               rexBuilder);
-      relBuilder.semiJoin(newCondition);
+      relBuilder.semiJoin(newCondition).hints(join.getHints());
       break;
 
     case LEFT:
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 a01731a..e2276b5 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -58,6 +58,9 @@ import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.core.Minus;
 import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.Union;
+import org.apache.calcite.rel.hint.HintPredicates;
+import org.apache.calcite.rel.hint.HintStrategyTable;
+import org.apache.calcite.rel.hint.RelHint;
 import org.apache.calcite.rel.logical.LogicalAggregate;
 import org.apache.calcite.rel.logical.LogicalCorrelate;
 import org.apache.calcite.rel.logical.LogicalFilter;
@@ -147,6 +150,7 @@ import java.util.function.Supplier;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
 /**
@@ -1078,6 +1082,48 @@ class RelOptRulesTest extends RelOptTestBase {
   }
 
   /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-4941">[CALCITE-4941]
+   * SemiJoinRule loses hints</a>. */
+  @Test void testSemiJoinRuleWithHint() {
+    final RelHint noHashJoinHint = RelHint.builder("no_hash_join").build();
+    final Function<RelBuilder, RelNode> relFn = b -> {
+      b.getCluster().setHintStrategies(
+          HintStrategyTable.builder()
+              .hintStrategy("no_hash_join", HintPredicates.JOIN)
+              .build());
+      return b
+          .scan("DEPT")
+          .scan("EMP")
+          .project(b.field("DEPTNO"))
+          .distinct()
+          .join(
+              JoinRelType.INNER,
+              b.equals(
+                  b.field(2, 0, "DEPTNO"),
+                  b.field(2, 1, "DEPTNO"))).hints(noHashJoinHint)
+          .project(b.field("DNAME"))
+          .build();
+    };
+
+    // verify plan
+    relFn(relFn)
+        .withRule(CoreRules.PROJECT_TO_SEMI_JOIN)
+        .check();
+
+    // verify hint
+    final RelBuilder relBuilder = RelBuilder.create(RelBuilderTest.config().build());
+    final RelNode input = relFn.apply(relBuilder);
+    final HepProgram program = new HepProgramBuilder()
+        .addRuleInstance(CoreRules.PROJECT_TO_SEMI_JOIN)
+        .build();
+    final HepPlanner hepPlanner = new HepPlanner(program);
+    hepPlanner.setRoot(input);
+    final RelNode output = hepPlanner.findBestExp();
+    final Join join = (Join) output.getInput(0);
+    assertTrue(join.getHints().contains(noHashJoinHint));
+  }
+
+  /** Test case for
    * <a href="https://issues.apache.org/jira/browse/CALCITE-438">[CALCITE-438]
    * Push predicates through SemiJoin</a>. */
   @Test void testPushFilterThroughSemiJoin() {
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 e9a4152..8991b55 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -11450,6 +11450,27 @@ LogicalProject(DEPTNO=[$0], NAME=[$1])
 ]]>
     </Resource>
   </TestCase>
+  <TestCase name="testSemiJoinRuleWithHint">
+    <Resource name="planBefore">
+      <![CDATA[
+LogicalProject(DNAME=[$1])
+  LogicalJoin(condition=[=($0, $3)], joinType=[inner])
+    LogicalTableScan(table=[[scott, DEPT]])
+    LogicalAggregate(group=[{0}])
+      LogicalProject(DEPTNO=[$7])
+        LogicalTableScan(table=[[scott, EMP]])
+]]>
+    </Resource>
+    <Resource name="planAfter">
+      <![CDATA[
+LogicalProject(DNAME=[$1])
+  LogicalJoin(condition=[=($0, $3)], joinType=[semi])
+    LogicalTableScan(table=[[scott, DEPT]])
+    LogicalProject(DEPTNO=[$7])
+      LogicalTableScan(table=[[scott, EMP]])
+]]>
+    </Resource>
+  </TestCase>
   <TestCase name="testSemiJoinTrim">
     <Resource name="sql">
       <![CDATA[select s.deptno from (select * from dept where exists (