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(

Reply via email to