You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2017/02/21 08:59:54 UTC

calcite git commit: [CALCITE-1649] Data type mismatch in EnumerableMergeJoin

Repository: calcite
Updated Branches:
  refs/heads/master bbb7eaa93 -> b74d3b13e


[CALCITE-1649] Data type mismatch in EnumerableMergeJoin

Also, update some plans for [CALCITE-1633].


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/b74d3b13
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/b74d3b13
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/b74d3b13

Branch: refs/heads/master
Commit: b74d3b13eb98e71633a724e8f2d1a7ceadaf9352
Parents: bbb7eaa
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Feb 20 16:57:16 2017 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Feb 20 23:23:27 2017 -0800

----------------------------------------------------------------------
 .../adapter/enumerable/EnumerableMergeJoin.java | 54 +++++++++++++++-----
 core/src/test/resources/sql/sub-query.iq        | 12 +++--
 2 files changed, 48 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/b74d3b13/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
index fd492cb..95d6239 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeJoin.java
@@ -16,9 +16,12 @@
  */
 package org.apache.calcite.adapter.enumerable;
 
+import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.linq4j.tree.BlockBuilder;
 import org.apache.calcite.linq4j.tree.Expression;
 import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.linq4j.tree.Types;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptCost;
 import org.apache.calcite.plan.RelOptPlanner;
@@ -34,14 +37,18 @@ import org.apache.calcite.rel.core.JoinInfo;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.metadata.RelMdCollation;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.util.BuiltInMethod;
 import org.apache.calcite.util.ImmutableIntList;
+import org.apache.calcite.util.Pair;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
+import java.lang.reflect.Type;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
@@ -124,20 +131,39 @@ public class EnumerableMergeJoin extends EquiJoin implements EnumerableRel {
     BlockBuilder builder = new BlockBuilder();
     final Result leftResult =
         implementor.visitChild(this, 0, (EnumerableRel) left, pref);
-    Expression leftExpression =
-        builder.append(
-            "left", leftResult.block);
+    final Expression leftExpression =
+        builder.append("left", leftResult.block);
+    final ParameterExpression left_ =
+        Expressions.parameter(leftResult.physType.getJavaRowType(), "left");
     final Result rightResult =
         implementor.visitChild(this, 1, (EnumerableRel) right, pref);
-    Expression rightExpression =
-        builder.append(
-            "right", rightResult.block);
+    final Expression rightExpression =
+        builder.append("right", rightResult.block);
+    final ParameterExpression right_ =
+        Expressions.parameter(rightResult.physType.getJavaRowType(), "right");
+    final JavaTypeFactory typeFactory = implementor.getTypeFactory();
     final PhysType physType =
-        PhysTypeImpl.of(
-            implementor.getTypeFactory(), getRowType(), pref.preferArray());
-    final PhysType keyPhysType =
-        leftResult.physType.project(
-            leftKeys, JavaRowFormat.LIST);
+        PhysTypeImpl.of(typeFactory, getRowType(), pref.preferArray());
+    final List<Expression> leftExpressions = new ArrayList<>();
+    final List<Expression> rightExpressions = new ArrayList<>();
+    for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) {
+      final RelDataType keyType =
+          typeFactory.leastRestrictive(
+              ImmutableList.of(
+                  left.getRowType().getFieldList().get(pair.left).getType(),
+                  right.getRowType().getFieldList().get(pair.right).getType()));
+      final Type keyClass = typeFactory.getJavaClass(keyType);
+      leftExpressions.add(
+         Types.castIfNecessary(keyClass,
+             leftResult.physType.fieldReference(left_, pair.left)));
+      rightExpressions.add(
+         Types.castIfNecessary(keyClass,
+             rightResult.physType.fieldReference(right_, pair.right)));
+    }
+    final PhysType leftKeyPhysType =
+        leftResult.physType.project(leftKeys, JavaRowFormat.LIST);
+    final PhysType rightKeyPhysType =
+        rightResult.physType.project(rightKeys, JavaRowFormat.LIST);
     return implementor.result(
         physType,
         builder.append(
@@ -146,8 +172,10 @@ public class EnumerableMergeJoin extends EquiJoin implements EnumerableRel {
                 Expressions.list(
                     leftExpression,
                     rightExpression,
-                    leftResult.physType.generateAccessor(leftKeys),
-                    rightResult.physType.generateAccessor(rightKeys),
+                    Expressions.lambda(
+                        leftKeyPhysType.record(leftExpressions), left_),
+                    Expressions.lambda(
+                        rightKeyPhysType.record(rightExpressions), right_),
                     EnumUtils.joinSelector(joinType,
                         physType,
                         ImmutableList.of(

http://git-wip-us.apache.org/repos/asf/calcite/blob/b74d3b13/core/src/test/resources/sql/sub-query.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sub-query.iq b/core/src/test/resources/sql/sub-query.iq
index a545af5..26329ec 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -442,7 +442,7 @@ where sal + 100 not in (
 with t (a, b) as (select * from (values (1, 2)))
 select * from t where exists (select 1 from "scott".emp where deptno = t.a);
 EnumerableCalc(expr#0..2=[{inputs}], proj#0..1=[{exprs}])
-  EnumerableCorrelate(correlation=[$cor0], joinType=[INNER], requiredColumns=[{0}])
+  EnumerableCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{0}])
     EnumerableValues(tuples=[[{ 1, 2 }]])
     EnumerableAggregate(group=[{0}])
       EnumerableCalc(expr#0..7=[{inputs}], expr#8=[true], expr#9=[CAST($t7):INTEGER], expr#10=[$cor0], expr#11=[$t10.A], expr#12=[=($t9, $t11)], i=[$t8], $condition=[$t12])
@@ -453,7 +453,7 @@ EnumerableCalc(expr#0..2=[{inputs}], proj#0..1=[{exprs}])
 with t as (select * from (values (1, 2)) as t(a, b))
 select * from t where exists (select 1 from "scott".emp where deptno = t.a);
 EnumerableCalc(expr#0..2=[{inputs}], proj#0..1=[{exprs}])
-  EnumerableCorrelate(correlation=[$cor0], joinType=[INNER], requiredColumns=[{0}])
+  EnumerableCorrelate(correlation=[$cor0], joinType=[inner], requiredColumns=[{0}])
     EnumerableValues(tuples=[[{ 1, 2 }]])
     EnumerableAggregate(group=[{0}])
       EnumerableCalc(expr#0..7=[{inputs}], expr#8=[true], expr#9=[CAST($t7):INTEGER], expr#10=[$cor0], expr#11=[$t10.A], expr#12=[=($t9, $t11)], i=[$t8], $condition=[$t12])
@@ -463,9 +463,11 @@ EnumerableCalc(expr#0..2=[{inputs}], proj#0..1=[{exprs}])
 # Uncorrelated
 with t (a, b) as (select * from (values (60, 'b')))
 select * from t where a in (select deptno from "scott".dept);
-EnumerableSemiJoin(condition=[=($0, $2)], joinType=[inner])
-  EnumerableValues(tuples=[[{ 60, 'b' }]])
-  EnumerableTableScan(table=[[scott, DEPT]])
+EnumerableCalc(expr#0..2=[{inputs}], EXPR$0=[$t1], EXPR$1=[$t2])
+  EnumerableMergeJoin(condition=[=($0, $1)], joinType=[inner])
+    EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+      EnumerableTableScan(table=[[scott, DEPT]])
+    EnumerableValues(tuples=[[{ 60, 'b' }]])
 !plan
 +---+---+
 | A | B |