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/05/21 22:02:36 UTC

incubator-calcite git commit: [CALCITE-688] splitCondition does not behave correctly when one side of the condition references columns from different inputs

Repository: incubator-calcite
Updated Branches:
  refs/heads/master 9475b2d33 -> 53b4b0960


[CALCITE-688] splitCondition does not behave correctly when one side of the condition references columns from different inputs

Close apache/incubator-calcite#78


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

Branch: refs/heads/master
Commit: 53b4b09606de5fe14f49e65a6d5b4346ec930a62
Parents: 9475b2d
Author: Jesus Camacho Rodriguez <jc...@hortonworks.com>
Authored: Fri May 8 14:54:33 2015 +0200
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon May 18 11:58:11 2015 -0700

----------------------------------------------------------------------
 .../org/apache/calcite/plan/RelOptUtil.java     | 31 ++++++++----------
 core/src/test/resources/sql/join.oq             | 34 ++++++++++++++++++++
 2 files changed, 47 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/53b4b096/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index 6090dd2..8289524 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -959,21 +959,20 @@ public abstract class RelOptUtil {
     final RexBuilder rexBuilder = cluster.getRexBuilder();
     final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
 
-    int[] firstFieldInputs = new int[inputs.size()];
+    final ImmutableBitSet[] inputsRange = new ImmutableBitSet[inputs.size()];
     int totalFieldCount = 0;
     for (int i = 0; i < inputs.size(); i++) {
-      firstFieldInputs[i] = totalFieldCount + sysFieldCount;
-      totalFieldCount += sysFieldCount
-              + inputs.get(i).getRowType().getFieldCount();
+      final int firstField = totalFieldCount + sysFieldCount;
+      totalFieldCount = firstField + inputs.get(i).getRowType().getFieldCount();
+      inputsRange[i] = ImmutableBitSet.range(firstField, totalFieldCount);
     }
 
     // adjustment array
     int[] adjustments = new int[totalFieldCount];
     for (int i = 0; i < inputs.size(); i++) {
-      int limit = i == inputs.size() - 1
-              ? totalFieldCount : firstFieldInputs[i + 1];
-      for (int j = firstFieldInputs[i]; j < limit; j++) {
-        adjustments[j] = -firstFieldInputs[i];
+      final int adjustment = inputsRange[i].nextSetBit(0);
+      for (int j = adjustment; j < inputsRange[i].length(); j++) {
+        adjustments[j] = -adjustment;
       }
     }
 
@@ -1022,11 +1021,8 @@ public abstract class RelOptUtil {
 
         boolean foundBothInputs = false;
         for (int i = 0; i < inputs.size() && !foundBothInputs; i++) {
-          final int lowerLimit = firstFieldInputs[i];
-          final int upperLimit = i == inputs.size() - 1
-                  ? totalFieldCount : firstFieldInputs[i + 1];
-          if (projRefs0.nextSetBit(lowerLimit) < upperLimit
-                  && projRefs0.nextSetBit(lowerLimit) != -1) {
+          if (projRefs0.intersects(inputsRange[i])
+                  && projRefs0.union(inputsRange[i]).equals(inputsRange[i])) {
             if (leftKey == null) {
               leftKey = op0;
               leftInput = i;
@@ -1038,8 +1034,8 @@ public abstract class RelOptUtil {
               reverse = true;
               foundBothInputs = true;
             }
-          } else if (projRefs1.nextSetBit(lowerLimit) < upperLimit
-                  && projRefs1.nextSetBit(lowerLimit) != -1) {
+          } else if (projRefs1.intersects(inputsRange[i])
+                  && projRefs1.union(inputsRange[i]).equals(inputsRange[i])) {
             if (leftKey == null) {
               leftKey = op1;
               leftInput = i;
@@ -1116,9 +1112,8 @@ public abstract class RelOptUtil {
 
         boolean foundInput = false;
         for (int i = 0; i < inputs.size() && !foundInput; i++) {
-          final int lowerLimit = firstFieldInputs[i];
-          final int upperLimit = i == inputs.size() - 1
-                  ? totalFieldCount : firstFieldInputs[i + 1];
+          final int lowerLimit = inputsRange[i].nextSetBit(0);
+          final int upperLimit = inputsRange[i].length();
           if (projRefs.nextSetBit(lowerLimit) < upperLimit) {
             leftInput = i;
             leftFields = inputs.get(leftInput).getRowType().getFieldList();

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/53b4b096/core/src/test/resources/sql/join.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/join.oq b/core/src/test/resources/sql/join.oq
index a840f19..c98effd 100644
--- a/core/src/test/resources/sql/join.oq
+++ b/core/src/test/resources/sql/join.oq
@@ -174,4 +174,38 @@ group by cube(emp.deptno, dept.deptno);
 
 !ok
 
+# [CALCITE-688] splitCondition does not behave correctly
+# when one side of the condition references columns from
+# different inputs
+select distinct emp1.deptno, emp3.ename
+from "scott".emp emp1 join "scott".emp emp2 on (emp1.deptno = emp2.deptno)
+join "scott".emp emp3 on (emp1.deptno + emp2.deptno = emp3.deptno + 10);
++--------+--------+
+| DEPTNO | ENAME  |
++--------+--------+
+|     10 | CLARK  |
+|     10 | KING   |
+|     10 | MILLER |
+|     20 | ALLEN  |
+|     20 | BLAKE  |
+|     20 | JAMES  |
+|     20 | MARTIN |
+|     20 | TURNER |
+|     20 | WARD   |
++--------+--------+
+(9 rows)
+
+!ok
+
+EnumerableCalc(expr#0..1=[{inputs}], DEPTNO0=[$t1], ENAME=[$t0])
+  EnumerableAggregate(group=[{1, 16}])
+    EnumerableJoin(condition=[=($8, $25)], joinType=[inner])
+      EnumerableCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[+($t7, $t8)], proj#0..7=[{exprs}], $f8=[$t9])
+        EnumerableTableScan(table=[[scott, EMP]])
+      EnumerableCalc(expr#0..15=[{inputs}], expr#16=[+($t7, $t15)], expr#17=[CAST($t16):INTEGER], proj#0..15=[{exprs}], $f16=[$t17])
+        EnumerableJoin(condition=[=($7, $15)], joinType=[inner])
+          EnumerableTableScan(table=[[scott, EMP]])
+          EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
 # End join.oq