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