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 2015/10/16 19:30:36 UTC

[2/2] incubator-calcite git commit: [CALCITE-923] Type mismatch when converting LEFT join to INNER

[CALCITE-923] Type mismatch when converting LEFT join to INNER

We were not fixing up nullability of the ON clause. Test case is as for [CALCITE-666].


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

Branch: refs/heads/master
Commit: a6f65dc97ac578c886544b961cb4db40e90bcccf
Parents: 4f415b2
Author: Julian Hyde <jh...@apache.org>
Authored: Fri Oct 16 09:06:17 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Fri Oct 16 09:09:34 2015 -0700

----------------------------------------------------------------------
 .../calcite/rel/rules/FilterJoinRule.java       | 12 ++++-
 .../java/org/apache/calcite/rex/RexUtil.java    | 56 +++++++++++++-------
 2 files changed, 47 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a6f65dc9/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
index e2ec169..0a45a43 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.core.Filter;
 import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexUtil;
@@ -224,8 +225,14 @@ public abstract class FilterJoinRule extends RelOptRule {
 
     // create the new join node referencing the new children and
     // containing its new join filters (if there are any)
+    final ImmutableList<RelDataType> fieldTypes =
+        ImmutableList.<RelDataType>builder()
+            .addAll(RelOptUtil.getFieldTypeList(leftRel.getRowType()))
+            .addAll(RelOptUtil.getFieldTypeList(rightRel.getRowType())).build();
     final RexNode joinFilter =
-        RexUtil.composeConjunction(rexBuilder, joinFilters, false);
+        RexUtil.composeConjunction(rexBuilder,
+            RexUtil.fixUp(rexBuilder, joinFilters, fieldTypes),
+            false);
 
     // If nothing actually got pushed and there is nothing leftover,
     // then this rule is a no-op
@@ -260,7 +267,8 @@ public abstract class FilterJoinRule extends RelOptRule {
 
     // create a FilterRel on top of the join if needed
     relBuilder.filter(
-        RexUtil.fixUp(rexBuilder, aboveFilters, newJoinRel.getRowType()));
+        RexUtil.fixUp(rexBuilder, aboveFilters,
+            RelOptUtil.getFieldTypeList(newJoinRel.getRowType())));
 
     call.transformTo(relBuilder.build());
   }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/a6f65dc9/core/src/main/java/org/apache/calcite/rex/RexUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index f7e6a9e..d65d9be 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -1147,6 +1147,13 @@ public class RexUtil {
     return new CnfHelper(rexBuilder).pull(node);
   }
 
+  @Deprecated // to be removed before 2.0
+  public static List<RexNode> fixUp(final RexBuilder rexBuilder,
+      List<RexNode> nodes, final RelDataType rowType) {
+    final List<RelDataType> typeList = RelOptUtil.getFieldTypeList(rowType);
+    return fixUp(rexBuilder, nodes, typeList);
+  }
+
   /** Fixes up the type of all {@link RexInputRef}s in an
    * expression to match differences in nullability.
    *
@@ -1155,25 +1162,8 @@ public class RexUtil {
    *
    * <p>Throws if there any greater inconsistencies of type. */
   public static List<RexNode> fixUp(final RexBuilder rexBuilder,
-      List<RexNode> nodes, final RelDataType rowType) {
-    final List<RelDataType> typeList = RelOptUtil.getFieldTypeList(rowType);
-    return new RexShuttle() {
-      @Override public RexNode visitInputRef(RexInputRef ref) {
-        final RelDataType rightType = typeList.get(ref.getIndex());
-        final RelDataType refType = ref.getType();
-        if (refType == rightType) {
-          return ref;
-        }
-        final RelDataType refType2 =
-            rexBuilder.getTypeFactory().createTypeWithNullability(refType,
-                rightType.isNullable());
-        if (refType2 == rightType) {
-          return new RexInputRef(ref.getIndex(), refType2);
-        }
-        throw new AssertionError("mismatched type " + ref + " " + rightType);
-      }
-      // CHECKSTYLE: IGNORE 1
-    }.apply(nodes);
+      List<RexNode> nodes, final List<RelDataType> fieldTypes) {
+    return new FixNullabilityShuttle(rexBuilder, fieldTypes).apply(nodes);
   }
 
   /** Transforms a list of expressions into a list of their types. */
@@ -1861,6 +1851,34 @@ public class RexUtil {
       throw Util.FoundOne.NULL;
     }
   }
+
+  /** Shuttle that fixes up an expression to match changes in nullability of
+   * input fields. */
+  public static class FixNullabilityShuttle extends RexShuttle {
+    private final List<RelDataType> typeList;
+    private final RexBuilder rexBuilder;
+
+    public FixNullabilityShuttle(RexBuilder rexBuilder,
+        List<RelDataType> typeList) {
+      this.typeList = typeList;
+      this.rexBuilder = rexBuilder;
+    }
+
+    @Override public RexNode visitInputRef(RexInputRef ref) {
+      final RelDataType rightType = typeList.get(ref.getIndex());
+      final RelDataType refType = ref.getType();
+      if (refType == rightType) {
+        return ref;
+      }
+      final RelDataType refType2 =
+          rexBuilder.getTypeFactory().createTypeWithNullability(refType,
+              rightType.isNullable());
+      if (refType2 == rightType) {
+        return new RexInputRef(ref.getIndex(), refType2);
+      }
+      throw new AssertionError("mismatched type " + ref + " " + rightType);
+    }
+  }
 }
 
 // End RexUtil.java