Skip to content

Commit ed18e58

Browse files
committed
[CALCITE-6600] AggregateJoinTransposeRule can throw ArrayIndexOutOfBoundsException when applied on a SemiJoin
1 parent f325fa6 commit ed18e58

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

core/src/main/java/org/apache/calcite/rel/rules/AggregateJoinTransposeRule.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,10 @@ private static boolean isJoinSupported(final Join join, final Aggregate aggregat
320320
// Update condition
321321
final Mapping mapping =
322322
(Mapping) Mappings.target(map::get,
323-
join.getRowType().getFieldCount(),
323+
join.getJoinType().projectsRight()
324+
? join.getRowType().getFieldCount()
325+
: join.getLeft().getRowType().getFieldCount()
326+
+ join.getRight().getRowType().getFieldCount(),
324327
belowOffset);
325328
final RexNode newCondition =
326329
RexUtil.apply(mapping, join.getCondition());

core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6627,6 +6627,25 @@ private HepProgram getTransitiveProgram() {
66276627
.check();
66286628
}
66296629

6630+
/** Test case for
6631+
* <a href="https://issues.apache.org/jira/browse/CALCITE-6600">[CALCITE-6600]
6632+
* AggregateJoinTransposeRule can throw ArrayIndexOutOfBoundsException when applied
6633+
* on a SemiJoin</a>.*/
6634+
@Test void testPushAggregateThroughSemiJoin() {
6635+
final String sql = "select distinct sal\n"
6636+
+ "from (select * from sales.emp e where e.job in\n"
6637+
+ "(select d.name from sales.dept d))";
6638+
sql(sql)
6639+
.withLateDecorrelate(true)
6640+
.withTrim(true)
6641+
.withPreRule(CoreRules.FILTER_SUB_QUERY_TO_CORRELATE)
6642+
.withRule(CoreRules.PROJECT_MERGE,
6643+
CoreRules.PROJECT_TO_SEMI_JOIN,
6644+
CoreRules.AGGREGATE_PROJECT_MERGE,
6645+
CoreRules.AGGREGATE_JOIN_TRANSPOSE_EXTENDED)
6646+
.check();
6647+
}
6648+
66306649
/** Push count(*) through join, no GROUP BY. */
66316650
@Test void testPushAggregateSumNoGroup() {
66326651
final String sql =

core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10110,6 +10110,50 @@ LogicalAggregate(group=[{0, 2}])
1011010110
LogicalAggregate(group=[{1, 2}])
1011110111
LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
1011210112
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
10113+
]]>
10114+
</Resource>
10115+
</TestCase>
10116+
<TestCase name="testPushAggregateThroughSemiJoin">
10117+
<Resource name="sql">
10118+
<![CDATA[select distinct sal
10119+
from (select * from sales.emp e where e.job in
10120+
(select d.name from sales.dept d))]]>
10121+
</Resource>
10122+
<Resource name="planBefore">
10123+
<![CDATA[
10124+
LogicalAggregate(group=[{0}])
10125+
LogicalProject(SAL=[$1])
10126+
LogicalProject(JOB=[$0], SAL=[$1])
10127+
LogicalJoin(condition=[=($0, $2)], joinType=[inner])
10128+
LogicalProject(JOB=[$2], SAL=[$5])
10129+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
10130+
LogicalAggregate(group=[{0}])
10131+
LogicalProject(NAME=[$1])
10132+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
10133+
]]>
10134+
</Resource>
10135+
<Resource name="planMid">
10136+
<![CDATA[
10137+
LogicalAggregate(group=[{1}])
10138+
LogicalJoin(condition=[=($0, $2)], joinType=[semi])
10139+
LogicalAggregate(group=[{0, 1}])
10140+
LogicalProject(JOB=[$2], SAL=[$5])
10141+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
10142+
LogicalAggregate(group=[{0}])
10143+
LogicalProject(NAME=[$1])
10144+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
10145+
]]>
10146+
</Resource>
10147+
<Resource name="planAfter">
10148+
<![CDATA[
10149+
LogicalAggregate(group=[{1}])
10150+
LogicalJoin(condition=[=($0, $2)], joinType=[semi])
10151+
LogicalAggregate(group=[{0, 1}])
10152+
LogicalProject(JOB=[$2], SAL=[$5])
10153+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
10154+
LogicalAggregate(group=[{0}])
10155+
LogicalProject(NAME=[$1])
10156+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
1011310157
]]>
1011410158
</Resource>
1011510159
</TestCase>

0 commit comments

Comments
 (0)