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);