Repository: calcite Updated Branches: refs/heads/master 561c6427e -> fce3966b2
[CALCITE-2605] Support left outer join via EnumerableCorrelate Test by Ruben Quesada Lopez closes #874 closes #901 Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/fce3966b Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/fce3966b Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/fce3966b Branch: refs/heads/master Commit: fce3966b29673a835b2a21b714d107eb4aa56e47 Parents: 561c642 Author: Vladimir Sitnikov <[email protected]> Authored: Mon Nov 5 16:34:54 2018 +0300 Committer: Vladimir Sitnikov <[email protected]> Committed: Mon Nov 5 23:34:09 2018 +0300 ---------------------------------------------------------------------- .../adapter/enumerable/EnumerableCorrelate.java | 15 ++++++--- .../enumerable/EnumerableCorrelateTest.java | 32 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/fce3966b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCorrelate.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCorrelate.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCorrelate.java index 6085520..f8205c3 100644 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCorrelate.java +++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableCorrelate.java @@ -98,11 +98,16 @@ public class EnumerableCorrelate extends Correlate getRowType(), pref.prefer(JavaRowFormat.CUSTOM)); - Expression selector = - EnumUtils.joinSelector( - joinType.returnsJustFirstInput() ? joinType.toJoinType() - : JoinRelType.INNER, physType, - ImmutableList.of(leftResult.physType, rightResult.physType)); + Expression selector; + if (joinType.returnsJustFirstInput()) { + // SEMI, ANTI + selector = EnumUtils.joinSelector(JoinRelType.INNER, physType, + ImmutableList.of(leftResult.physType)); + } else { + // INNER, LEFT + selector = EnumUtils.joinSelector(joinType.toJoinType(), physType, + ImmutableList.of(leftResult.physType, rightResult.physType)); + } builder.append( Expressions.call(leftExpression, BuiltInMethod.CORRELATE_JOIN.method, http://git-wip-us.apache.org/repos/asf/calcite/blob/fce3966b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java index 08d5ead..2edc6b9 100644 --- a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java +++ b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java @@ -16,19 +16,51 @@ */ package org.apache.calcite.test.enumerable; +import org.apache.calcite.adapter.enumerable.EnumerableRules; import org.apache.calcite.adapter.java.ReflectiveSchema; import org.apache.calcite.config.CalciteConnectionProperty; import org.apache.calcite.config.Lex; +import org.apache.calcite.plan.RelOptPlanner; +import org.apache.calcite.rel.rules.JoinToCorrelateRule; +import org.apache.calcite.runtime.Hook; import org.apache.calcite.test.CalciteAssert; import org.apache.calcite.test.JdbcTest; import org.junit.Test; +import java.util.function.Consumer; + /** * Unit test for * {@link org.apache.calcite.adapter.enumerable.EnumerableCorrelate}. */ public class EnumerableCorrelateTest { + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-2605">[CALCITE-2605] + * NullPointerException when left outer join implemented with EnumerableCorrelate</a> */ + @Test public void leftOuterJoinCorrelate() { + tester(false, new JdbcTest.HrSchema()) + .query( + "select e.empid, e.name, d.name as dept from emps e left outer join depts d on e.deptno=d.deptno") + .withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> { + // force the left outer join to run via EnumerableCorrelate instead of EnumerableJoin + planner.addRule(JoinToCorrelateRule.INSTANCE); + planner.removeRule(EnumerableRules.ENUMERABLE_JOIN_RULE); + }) + .explainContains("" + + "EnumerableCalc(expr#0..4=[{inputs}], empid=[$t0], name=[$t2], dept=[$t4])\n" + + " EnumerableCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{1}])\n" + + " EnumerableCalc(expr#0..4=[{inputs}], proj#0..2=[{exprs}])\n" + + " EnumerableTableScan(table=[[s, emps]])\n" + + " EnumerableCalc(expr#0..3=[{inputs}], expr#4=[$cor0], expr#5=[$t4.deptno], expr#6=[=($t5, $t0)], proj#0..1=[{exprs}], $condition=[$t6])\n" + + " EnumerableTableScan(table=[[s, depts]])") + .returnsUnordered( + "empid=100; name=Bill; dept=Sales", + "empid=110; name=Theodore; dept=Sales", + "empid=150; name=Sebastian; dept=Sales", + "empid=200; name=Eric; dept=null"); + } + @Test public void simpleCorrelateDecorrelated() { tester(true, new JdbcTest.HrSchema()) .query(
