Skip to content

Commit ae47b72

Browse files
committed
[CALCITE-7356] The MARK JOIN generated by TopDownGeneralDecorrelator needs to be adapted to RelFieldTrimmer
1 parent 6de6266 commit ae47b72

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,11 @@ public TrimResult trimFields(
836836
Join join,
837837
ImmutableBitSet fieldsUsed,
838838
Set<RelDataTypeField> extraFields) {
839+
// If the column "mark" is included, it needs to be excluded first.
840+
if (join.getJoinType() == JoinRelType.LEFT_MARK) {
841+
int markIndex = join.getRowType().getFieldCount() - 1;
842+
fieldsUsed = fieldsUsed.except(ImmutableBitSet.of(markIndex));
843+
}
839844
final int fieldCount = join.getSystemFieldList().size()
840845
+ join.getLeft().getRowType().getFieldCount()
841846
+ join.getRight().getRowType().getFieldCount();
@@ -957,17 +962,25 @@ public TrimResult trimFields(
957962
switch (join.getJoinType()) {
958963
case SEMI:
959964
case ANTI:
960-
// For SemiJoins and AntiJoins only map fields from the left-side
965+
case LEFT_MARK:
966+
// For SemiJoins, AntiJoins and LeftMarkJoins only map fields from the left-side.
967+
// For LeftMarkJoins, the mark column is also mapped.
961968
if (join.getJoinType() == JoinRelType.SEMI) {
962969
relBuilder.semiJoin(newConditionExpr);
963-
} else {
970+
} else if (join.getJoinType() == JoinRelType.ANTI) {
964971
relBuilder.antiJoin(newConditionExpr);
972+
} else {
973+
relBuilder.join(join.getJoinType(), newConditionExpr, join.getVariablesSet());
965974
}
966975
Mapping inputMapping = inputMappings.get(0);
976+
int targetCount = newSystemFieldCount + inputMapping.getTargetCount();
977+
if (join.getJoinType() == JoinRelType.LEFT_MARK) {
978+
targetCount++;
979+
}
967980
mapping =
968981
Mappings.create(MappingType.INVERSE_SURJECTION,
969982
join.getRowType().getFieldCount(),
970-
newSystemFieldCount + inputMapping.getTargetCount());
983+
targetCount);
971984
for (int i = 0; i < newSystemFieldCount; ++i) {
972985
mapping.set(i, i);
973986
}
@@ -976,6 +989,9 @@ public TrimResult trimFields(
976989
for (IntPair pair : inputMapping) {
977990
mapping.set(pair.source + offset, pair.target + newOffset);
978991
}
992+
if (join.getJoinType() == JoinRelType.LEFT_MARK) {
993+
mapping.set(join.getRowType().getFieldCount() - 1, targetCount - 1);
994+
}
979995
break;
980996
case ASOF:
981997
case LEFT_ASOF:

core/src/test/resources/sql/new-decorr.iq

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,60 @@ SELECT * FROM t0 WHERE t0a <
4242

4343
!ok
4444

45+
# [CALCITE-7356] The MARK JOIN generated by TopDownGeneralDecorrelator needs to be adapted to RelFieldTrimmer
46+
!use blank
47+
CREATE TABLE emps (
48+
empid INTEGER NOT NULL,
49+
deptno INTEGER NOT NULL,
50+
name VARCHAR(10) NOT NULL,
51+
salary DECIMAL(10, 2) NOT NULL,
52+
commission INTEGER);
53+
(0 rows modified)
54+
55+
!update
56+
57+
INSERT INTO emps (empid, deptno, name, salary, commission) VALUES
58+
(100, 10, 'Bill', 10000.00, 1000),
59+
(200, 20, 'Eric', 8000.00, 500),
60+
(150, 10, 'Sebastian', 7000.00, NULL),
61+
(110, 10, 'Theodore', 11500.00, 250),
62+
(170, 30, 'Theodore', 11500.00, 250),
63+
(140, 10, 'Sebastian', 7000.00, NULL);
64+
(6 rows modified)
65+
66+
!update
67+
68+
SELECT empid, EXISTS(select * from (
69+
SELECT e2.deptno FROM emps e2 where e1.commission = e2.commission) as table3
70+
where table3.deptno <> e1.deptno)
71+
from emps e1 order by empid;
72+
+-------+--------+
73+
| EMPID | EXPR$1 |
74+
+-------+--------+
75+
| 100 | false |
76+
| 110 | true |
77+
| 140 | false |
78+
| 150 | false |
79+
| 170 | true |
80+
| 200 | false |
81+
+-------+--------+
82+
(6 rows)
83+
84+
!ok
85+
86+
!if (use_new_decorr) {
87+
EnumerableSort(sort0=[$0], dir0=[ASC])
88+
EnumerableCalc(expr#0..3=[{inputs}], EMPID=[$t0], EXPR$1=[$t3])
89+
EnumerableHashJoin(condition=[AND(IS NOT DISTINCT FROM($1, $3), IS NOT DISTINCT FROM($2, $4))], joinType=[left_mark])
90+
EnumerableCalc(expr#0..4=[{inputs}], proj#0..1=[{exprs}], COMMISSION=[$t4])
91+
EnumerableTableScan(table=[[BLANK, EMPS]])
92+
EnumerableCalc(expr#0..3=[{inputs}], proj#0..1=[{exprs}])
93+
EnumerableHashJoin(condition=[AND(=($1, $3), <>($2, $0))], joinType=[inner])
94+
EnumerableAggregate(group=[{1, 4}])
95+
EnumerableTableScan(table=[[BLANK, EMPS]])
96+
EnumerableCalc(expr#0..4=[{inputs}], DEPTNO=[$t1], COMMISSION=[$t4])
97+
EnumerableTableScan(table=[[BLANK, EMPS]])
98+
!plan
99+
!}
100+
45101
# End new-decorr.iq

0 commit comments

Comments
 (0)