This is an automated email from the ASF dual-hosted git repository.

rubenql pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new ed18e58d89 [CALCITE-6600] AggregateJoinTransposeRule can throw 
ArrayIndexOutOfBoundsException when applied on a SemiJoin
ed18e58d89 is described below

commit ed18e58d89160bf90db087362737a82980eea7a0
Author: Ruben Quesada Lopez <[email protected]>
AuthorDate: Thu Sep 26 12:28:40 2024 +0100

    [CALCITE-6600] AggregateJoinTransposeRule can throw 
ArrayIndexOutOfBoundsException when applied on a SemiJoin
---
 .../rel/rules/AggregateJoinTransposeRule.java      |  5 ++-
 .../org/apache/calcite/test/RelOptRulesTest.java   | 19 ++++++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml    | 44 ++++++++++++++++++++++
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/AggregateJoinTransposeRule.java
 
b/core/src/main/java/org/apache/calcite/rel/rules/AggregateJoinTransposeRule.java
index 01fd8b7480..146f17c6b1 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/rules/AggregateJoinTransposeRule.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/rules/AggregateJoinTransposeRule.java
@@ -320,7 +320,10 @@ public class AggregateJoinTransposeRule
     // Update condition
     final Mapping mapping =
         (Mapping) Mappings.target(map::get,
-            join.getRowType().getFieldCount(),
+            join.getJoinType().projectsRight()
+                ? join.getRowType().getFieldCount()
+                : join.getLeft().getRowType().getFieldCount()
+                    + join.getRight().getRowType().getFieldCount(),
             belowOffset);
     final RexNode newCondition =
         RexUtil.apply(mapping, join.getCondition());
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java 
b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index bf4071592f..6720625e9a 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -6627,6 +6627,25 @@ class RelOptRulesTest extends RelOptTestBase {
         .check();
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6600";>[CALCITE-6600]
+   * AggregateJoinTransposeRule can throw ArrayIndexOutOfBoundsException when 
applied
+   * on a SemiJoin</a>.*/
+  @Test void testPushAggregateThroughSemiJoin() {
+    final String sql = "select distinct sal\n"
+        + "from (select * from sales.emp e where e.job in\n"
+        + "(select d.name from sales.dept d))";
+    sql(sql)
+        .withLateDecorrelate(true)
+        .withTrim(true)
+        .withPreRule(CoreRules.FILTER_SUB_QUERY_TO_CORRELATE)
+        .withRule(CoreRules.PROJECT_MERGE,
+            CoreRules.PROJECT_TO_SEMI_JOIN,
+            CoreRules.AGGREGATE_PROJECT_MERGE,
+            CoreRules.AGGREGATE_JOIN_TRANSPOSE_EXTENDED)
+        .check();
+  }
+
   /** Push count(*) through join, no GROUP BY. */
   @Test void testPushAggregateSumNoGroup() {
     final String sql =
diff --git 
a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml 
b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index b6e04f0881..eca85f5e4b 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -10110,6 +10110,50 @@ LogicalAggregate(group=[{0, 2}])
     LogicalAggregate(group=[{1, 2}])
       LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[+($0, 5)])
         LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testPushAggregateThroughSemiJoin">
+    <Resource name="sql">
+      <![CDATA[select distinct sal
+from (select * from sales.emp e where e.job in
+(select d.name from sales.dept d))]]>
+    </Resource>
+    <Resource name="planBefore">
+      <![CDATA[
+LogicalAggregate(group=[{0}])
+  LogicalProject(SAL=[$1])
+    LogicalProject(JOB=[$0], SAL=[$1])
+      LogicalJoin(condition=[=($0, $2)], joinType=[inner])
+        LogicalProject(JOB=[$2], SAL=[$5])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+        LogicalAggregate(group=[{0}])
+          LogicalProject(NAME=[$1])
+            LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+    </Resource>
+    <Resource name="planMid">
+      <![CDATA[
+LogicalAggregate(group=[{1}])
+  LogicalJoin(condition=[=($0, $2)], joinType=[semi])
+    LogicalAggregate(group=[{0, 1}])
+      LogicalProject(JOB=[$2], SAL=[$5])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+    LogicalAggregate(group=[{0}])
+      LogicalProject(NAME=[$1])
+        LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+    </Resource>
+    <Resource name="planAfter">
+      <![CDATA[
+LogicalAggregate(group=[{1}])
+  LogicalJoin(condition=[=($0, $2)], joinType=[semi])
+    LogicalAggregate(group=[{0, 1}])
+      LogicalProject(JOB=[$2], SAL=[$5])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+    LogicalAggregate(group=[{0}])
+      LogicalProject(NAME=[$1])
+        LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
 ]]>
     </Resource>
   </TestCase>

Reply via email to