KYLIN-2773: fix join condition push down issue caused by type casting

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

Branch: refs/heads/master
Commit: 87f1732b0a26191122788baaa2fc9d97c96210da
Parents: 28ac7d9
Author: Zhong <nju_y...@apache.org>
Authored: Tue Aug 29 17:19:47 2017 +0800
Committer: Roger Shi <rogershijich...@gmail.com>
Committed: Wed Aug 30 16:02:26 2017 +0800

----------------------------------------------------------------------
 .../calcite/sql2rel/SqlToRelConverter.java      | 54 ++++++++++++++++++++
 1 file changed, 54 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/87f1732b/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git 
a/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java 
b/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index f10ba96..3615df7 100644
--- 
a/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ 
b/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -2468,6 +2468,10 @@ public class SqlToRelConverter {
       return corr;
     }
 
+    if (containOnlyCast(joinCond)) {
+      joinCond = convertCastCondition(joinCond);
+    }
+
     final Join originalJoin =
         (Join) RelFactories.DEFAULT_JOIN_FACTORY.createJoin(leftRel, rightRel,
             joinCond, ImmutableSet.<CorrelationId>of(), joinType, false);
@@ -2475,6 +2479,56 @@ public class SqlToRelConverter {
     return RelOptUtil.pushDownJoinConditions(originalJoin);
   }
 
+  private boolean containOnlyCast(RexNode node) {
+    boolean result = true;
+    switch (node.getKind()) {
+      case AND:
+      case EQUALS:
+        final RexCall call = (RexCall) node;
+        List<RexNode> operands = Lists.newArrayList(call.getOperands());
+        for (int i = 0; i < operands.size(); i++) {
+          RexNode operand = operands.get(i);
+          result &= containOnlyCast(operand);
+        }
+        break;
+      case OR:
+      case INPUT_REF:
+      case LITERAL:
+      case CAST:
+        return true;
+      default:
+        return false;
+    }
+    return result;
+  }
+
+  private static RexNode convertCastCondition(RexNode node) {
+    switch (node.getKind()) {
+      case AND:
+      case EQUALS:
+        RexCall call = (RexCall) node;
+        List<RexNode> list = Lists.newArrayList();
+        List<RexNode> operands = Lists.newArrayList(call.getOperands());
+        for (int i = 0; i < operands.size(); i++) {
+          RexNode operand = operands.get(i);
+          final RexNode e =
+                  convertCastCondition(
+                          operand);
+          list.add(e);
+        }
+        if (!list.equals(call.getOperands())) {
+          return call.clone(call.getType(), list);
+        }
+        return call;
+      case CAST:
+        call = (RexCall) node;
+        operands = Lists.newArrayList(call.getOperands());
+        return operands.get(0);
+      default:
+        return node;
+    }
+  }
+
   private CorrelationUse getCorrelationUse(Blackboard bb, final RelNode r0) {
     final Set<CorrelationId> correlatedVariables =
         RelOptUtil.getVariablesUsed(r0);

Reply via email to