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 cac28e9 [CALCITE-4621] SemiJoinRule throws AssertionError on ANTI join cac28e9 is described below commit cac28e95762532538cd3d0dce9e933ef9e4d5228 Author: rubenada <rube...@gmail.com> AuthorDate: Tue May 25 13:51:45 2021 +0100 [CALCITE-4621] SemiJoinRule throws AssertionError on ANTI join --- .../org/apache/calcite/rel/rules/SemiJoinRule.java | 10 +++--- .../org/apache/calcite/test/RelOptRulesTest.java | 39 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) 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 16422d3..60c9f7a 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 @@ -24,6 +24,7 @@ import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.Aggregate; import org.apache.calcite.rel.core.Join; import org.apache.calcite.rel.core.JoinInfo; +import org.apache.calcite.rel.core.JoinRelType; import org.apache.calcite.rel.core.Project; import org.apache.calcite.rex.RexBuilder; import org.apache.calcite.rex.RexNode; @@ -45,8 +46,9 @@ import java.util.List; public abstract class SemiJoinRule extends RelRule<SemiJoinRule.Config> implements TransformationRule { - private static boolean notGenerateNullsOnLeft(Join join) { - return !join.getJoinType().generatesNullsOnLeft(); + private static boolean isJoinTypeSupported(Join join) { + final JoinRelType type = join.getJoinType(); + return type == JoinRelType.INNER || type == JoinRelType.SEMI || type == JoinRelType.LEFT; } /** @@ -170,7 +172,7 @@ public abstract class SemiJoinRule return withOperandSupplier(b -> b.operand(projectClass).oneInput(b2 -> b2.operand(joinClass) - .predicate(SemiJoinRule::notGenerateNullsOnLeft).inputs( + .predicate(SemiJoinRule::isJoinTypeSupported).inputs( b3 -> b3.operand(RelNode.class).anyInputs(), b4 -> b4.operand(aggregateClass).anyInputs()))) .as(Config.class); @@ -219,7 +221,7 @@ public abstract class SemiJoinRule default Config withOperandFor(Class<Join> joinClass, Class<Aggregate> aggregateClass) { return withOperandSupplier(b -> - b.operand(joinClass).predicate(SemiJoinRule::notGenerateNullsOnLeft).inputs( + b.operand(joinClass).predicate(SemiJoinRule::isJoinTypeSupported).inputs( b2 -> b2.operand(RelNode.class).anyInputs(), b3 -> b3.operand(aggregateClass).anyInputs())) .as(Config.class); 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 e23e86f..d988d72 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java @@ -5513,6 +5513,45 @@ class RelOptRulesTest extends RelOptTestBase { assertEquals(planBefore, planAfter); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-4621">[CALCITE-4621] + * SemiJoinRule throws AssertionError on ANTI join</a>. */ + @Test void testJoinToSemiJoinRuleOnAntiJoin() { + testSemiJoinRuleOnAntiJoin(CoreRules.JOIN_TO_SEMI_JOIN); + } + + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-4621">[CALCITE-4621] + * SemiJoinRule throws AssertionError on ANTI join</a>. */ + @Test void testProjectToSemiJoinRuleOnAntiJoin() { + testSemiJoinRuleOnAntiJoin(CoreRules.PROJECT_TO_SEMI_JOIN); + } + + private void testSemiJoinRuleOnAntiJoin(RelOptRule rule) { + final RelBuilder relBuilder = RelBuilder.create(RelBuilderTest.config().build()); + final RelNode input = relBuilder + .scan("DEPT") + .scan("EMP") + .project(relBuilder.field("DEPTNO")) + .distinct() + .antiJoin(relBuilder + .equals( + relBuilder.field(2, 0, "DEPTNO"), + relBuilder.field(2, 1, "DEPTNO"))) + .project(relBuilder.field("DNAME")) + .build(); + + final HepProgram program = new HepProgramBuilder() + .addRuleInstance(rule) + .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";