[CALCITE-5289] Assertion failure in MultiJoinOptimizeBushyRule
Signed-off-by: Mihai Budiu <mbudiu@feldera.com>
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinOptimizeBushyRule.java b/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinOptimizeBushyRule.java
index 755df10..e502e8c 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinOptimizeBushyRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinOptimizeBushyRule.java
@@ -107,6 +107,17 @@
final RelMetadataQuery mq = call.getMetadataQuery();
final LoptMultiJoin multiJoin = new LoptMultiJoin(multiJoinRel);
+ for (int i = 0; i < multiJoin.getNumJoinFactors(); i++) {
+ ImmutableBitSet outerJoinFactors = multiJoin.getOuterJoinFactors(i);
+ if (outerJoinFactors == null) {
+ continue;
+ }
+ if (!outerJoinFactors.isEmpty()) {
+ // Refuse to apply this rule to a multijoin with outer joins,
+ // since this rule cannot handle outer joins.
+ return;
+ }
+ }
final List<Vertex> vertexes = new ArrayList<>();
int x = 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 7e58a5b..ab80c1b 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -3383,6 +3383,15 @@
.check();
}
+ /** Test case for <a href="https://issues.apache.org/jira/browse/CALCITE-5289">
+ * [CALCITE-5289] Assertion failure in MultiJoinOptimizeBushyRule</a>. */
+ @Test void testBushyJoinRule() {
+ final String sql = "select emp.ename from emp LEFT JOIN emp AS emp1 on emp.ename = emp1.ename";
+ sql(sql).withPreRule(CoreRules.JOIN_TO_MULTI_JOIN)
+ .withRule(CoreRules.MULTI_JOIN_OPTIMIZE_BUSHY)
+ .checkUnchanged();
+ }
+
@Test void testConvertMultiJoinRule() {
final String sql = "select e1.ename from emp e1, dept d, emp e2\n"
+ "where e1.deptno = d.deptno and d.deptno = e2.deptno";
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 855a6d5..237305a 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -1377,6 +1377,19 @@
]]>
</Resource>
</TestCase>
+ <TestCase name="testBushyJoinRule">
+ <Resource name="sql">
+ <![CDATA[select emp.ename from emp LEFT JOIN emp AS emp1 on emp.ename = emp1.ename]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(ENAME=[$1])
+ MultiJoin(joinFilter=[true], isFullOuterJoin=[false], joinTypes=[[INNER, LEFT]], outerJoinConditions=[[NULL, =($1, $10)]], projFields=[[ALL, ALL]])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testCallOverCorrelationVariableIsNotFlattened">
<Resource name="sql">
<![CDATA[select * from emp e1 where exists (select * from emp e2 where (e1.deptno+30) = e2.deptno)]]>