Repository: calcite Updated Branches: refs/heads/master b4d9246ee -> c1ffe0bad
[CALCITE-2316] AggregateJoinTransposeRule fails to split aggregate call if input contains an aggregate call and has distinct rows (Haisheng Yuan) Close apache/calcite#676 Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/c1ffe0ba Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/c1ffe0ba Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/c1ffe0ba Branch: refs/heads/master Commit: c1ffe0bad1abcde60741a21207ae4de80e8ac057 Parents: b4d9246 Author: Haisheng Yuan <[email protected]> Authored: Tue Apr 24 17:28:31 2018 -0500 Committer: Julian Hyde <[email protected]> Committed: Mon May 21 13:24:02 2018 -0700 ---------------------------------------------------------------------- .../rel/rules/AggregateJoinTransposeRule.java | 7 +++- .../apache/calcite/test/RelOptRulesTest.java | 21 ++++++++++++ .../org/apache/calcite/test/RelOptRulesTest.xml | 34 ++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/c1ffe0ba/core/src/main/java/org/apache/calcite/rel/rules/AggregateJoinTransposeRule.java ---------------------------------------------------------------------- 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 1068702..28c58f3 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 @@ -243,8 +243,13 @@ public class AggregateJoinTransposeRule extends RelOptRule { && fieldSet.contains(ImmutableBitSet.of(aggCall.e.getArgList()))) { final RexNode singleton = splitter.singleton(rexBuilder, joinInput.getRowType(), aggCall.e.transform(mapping)); + if (singleton instanceof RexInputRef) { - side.split.put(aggCall.i, ((RexInputRef) singleton).getIndex()); + final int index = ((RexInputRef) singleton).getIndex(); + if (!belowAggregateKey.get(index)) { + projects.add(singleton); + } + side.split.put(aggCall.i, index); } else { projects.add(singleton); side.split.put(aggCall.i, projects.size() - 1); http://git-wip-us.apache.org/repos/asf/calcite/blob/c1ffe0ba/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java ---------------------------------------------------------------------- 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 e86ecdc..182b26e 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java @@ -3104,6 +3104,27 @@ public class RelOptRulesTest extends RelOptTestBase { sql(sql).withPre(preProgram).with(program).check(); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-2278">[CALCITE-2278] + * AggregateJoinTransposeRule fails to split aggregate call if input contains + * an aggregate call and has distinct rows</a>. */ + @Test public void testPushAggregateThroughJoinWithUniqueInput() { + final HepProgram preProgram = new HepProgramBuilder() + .addRuleInstance(AggregateProjectMergeRule.INSTANCE) + .build(); + final HepProgram program = new HepProgramBuilder() + .addRuleInstance(AggregateJoinTransposeRule.EXTENDED) + .build(); + final String sql = "select A.job, B.mgr, A.deptno,\n" + + "max(B.hiredate1) as hiredate1, sum(B.comm1) as comm1\n" + + "from sales.emp as A\n" + + "join (select mgr, sal, max(hiredate) as hiredate1,\n" + + " sum(comm) as comm1 from sales.emp group by mgr, sal) as B\n" + + "on A.sal=B.sal\n" + + "group by A.job, B.mgr, A.deptno"; + checkPlanning(tester, preProgram, new HepPlanner(program), sql); + } + /** SUM is the easiest aggregate function to split. */ @Test public void testPushAggregateSumThroughJoin() { final HepProgram preProgram = new HepProgramBuilder() http://git-wip-us.apache.org/repos/asf/calcite/blob/c1ffe0ba/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml ---------------------------------------------------------------------- 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 abecad9..7754b5c 100644 --- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml @@ -5995,6 +5995,40 @@ LogicalAggregate(group=[{}], EXPR$0=[SUM($3)]) ]]> </Resource> </TestCase> + <TestCase name="testPushAggregateThroughJoinWithUniqueInput"> + <Resource name="sql"> + <![CDATA[select A.job, B.mgr, A.deptno, +max(B.hiredate1) as hiredate1, sum(B.comm1) as comm1 +from sales.emp as A +join (select mgr, sal, max(hiredate) as hiredate1, + sum(comm) as comm1 from sales.emp group by mgr, sal) as B +on A.sal=B.sal +group by A.job, B.mgr, A.deptno +]]> + </Resource> + <Resource name="planBefore"> + <![CDATA[ +LogicalProject(JOB=[$0], MGR0=[$2], DEPTNO=[$1], HIREDATE1=[$3], COMM1=[$4]) + LogicalAggregate(group=[{2, 7, 9}], HIREDATE1=[MAX($11)], COMM1=[SUM($12)]) + LogicalJoin(condition=[=($5, $10)], joinType=[inner]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) + LogicalAggregate(group=[{3, 5}], HIREDATE1=[MAX($4)], COMM1=[SUM($6)]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) +]]> + </Resource> + <Resource name="planAfter"> + <![CDATA[ +LogicalProject(JOB=[$0], MGR0=[$2], DEPTNO=[$1], HIREDATE1=[$3], COMM1=[$4]) + LogicalAggregate(group=[{0, 2, 4}], HIREDATE1=[MAX($6)], COMM1=[SUM($8)]) + LogicalProject(JOB=[$0], SAL=[$1], DEPTNO=[$2], $f3=[$3], MGR=[$4], SAL0=[$5], HIREDATE1=[$6], COMM1=[$7], $f8=[CAST(*($3, $7)):INTEGER NOT NULL]) + LogicalJoin(condition=[=($1, $5)], joinType=[inner]) + LogicalAggregate(group=[{2, 5, 7}], agg#0=[COUNT()]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) + LogicalAggregate(group=[{3, 5}], HIREDATE1=[MAX($4)], COMM1=[SUM($6)]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) +]]> + </Resource> + </TestCase> <TestCase name="testPushAggregateSumThroughJoin"> <Resource name="sql"> <