[CALCITE-2105] AggregateJoinTransposeRule incorrectly makes a SUM call NOT NULL when Aggregate has no group keys (jingzhang)
Close apache/calcite#590 Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/a609b473 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/a609b473 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/a609b473 Branch: refs/heads/master Commit: a609b4732f545b7a17006728f0d36587b2babc95 Parents: f496d68 Author: beyond1920 <[email protected]> Authored: Fri Dec 22 12:15:40 2017 +0800 Committer: Julian Hyde <[email protected]> Committed: Sun Dec 24 21:09:35 2017 -0800 ---------------------------------------------------------------------- .../rel/rules/AggregateJoinTransposeRule.java | 6 +++- .../apache/calcite/test/RelOptRulesTest.java | 37 ++++++++++++++------ .../org/apache/calcite/test/RelOptRulesTest.xml | 31 ++++++++++++++++ 3 files changed, 63 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/a609b473/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 3806f07..d7c86aa 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 @@ -235,6 +235,8 @@ public class AggregateJoinTransposeRule extends RelOptRule { ? Mappings.createIdentity(fieldCount) : Mappings.createShiftMapping(fieldCount + offset, 0, offset, fieldCount); + final int oldGroupKeyCount = aggregate.getGroupCount(); + final int newGroupKeyCount = belowAggregateKey.cardinality(); for (Ord<AggregateCall> aggCall : Ord.zip(aggregate.getAggCallList())) { final SqlAggFunction aggregation = aggCall.e.getAggregation(); final SqlSplittableAggFunction splitter = @@ -242,7 +244,9 @@ public class AggregateJoinTransposeRule extends RelOptRule { aggregation.unwrap(SqlSplittableAggFunction.class)); final AggregateCall call1; if (fieldSet.contains(ImmutableBitSet.of(aggCall.e.getArgList()))) { - call1 = splitter.split(aggCall.e, mapping); + final AggregateCall splitCall = splitter.split(aggCall.e, mapping); + call1 = splitCall.adaptTo(joinInput, splitCall.getArgList(), + splitCall.filterArg, oldGroupKeyCount, newGroupKeyCount); } else { call1 = splitter.other(rexBuilder.getTypeFactory(), aggCall.e); } http://git-wip-us.apache.org/repos/asf/calcite/blob/a609b473/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 b711ec8..9ec3918 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java @@ -2810,7 +2810,7 @@ public class RelOptRulesTest extends RelOptTestBase { checkPlanning(program, sql); } - @Test public void testPushAggregateThroughJoin1() throws Exception { + @Test public void testPushAggregateThroughJoin1() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2824,7 +2824,7 @@ public class RelOptRulesTest extends RelOptTestBase { checkPlanning(tester, preProgram, new HepPlanner(program), sql); } - @Test public void testPushAggregateThroughJoin2() throws Exception { + @Test public void testPushAggregateThroughJoin2() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2839,7 +2839,7 @@ public class RelOptRulesTest extends RelOptTestBase { checkPlanning(tester, preProgram, new HepPlanner(program), sql); } - @Test public void testPushAggregateThroughJoin3() throws Exception { + @Test public void testPushAggregateThroughJoin3() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2856,7 +2856,7 @@ public class RelOptRulesTest extends RelOptTestBase { /** Test case for * <a href="https://issues.apache.org/jira/browse/CALCITE-1544">[CALCITE-1544] * AggregateJoinTransposeRule fails to preserve row type</a>. */ - @Test public void testPushAggregateThroughJoin4() throws Exception { + @Test public void testPushAggregateThroughJoin4() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2869,7 +2869,7 @@ public class RelOptRulesTest extends RelOptTestBase { sql(sql).withPre(preProgram).with(program).check(); } - @Test public void testPushAggregateThroughJoin5() throws Exception { + @Test public void testPushAggregateThroughJoin5() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2883,7 +2883,7 @@ public class RelOptRulesTest extends RelOptTestBase { } /** SUM is the easiest aggregate function to split. */ - @Test public void testPushAggregateSumThroughJoin() throws Exception { + @Test public void testPushAggregateSumThroughJoin() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2897,8 +2897,25 @@ public class RelOptRulesTest extends RelOptTestBase { checkPlanning(tester, preProgram, new HepPlanner(program), sql); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-2105">[CALCITE-2105] + * AggregateJoinTransposeRule incorrectly makes a SUM NOT NULL when Aggregate + * has no group keys</a>. */ + @Test public void testPushAggregateSumWithoutGroupKeyThroughJoin() { + final HepProgram preProgram = new HepProgramBuilder() + .addRuleInstance(AggregateProjectMergeRule.INSTANCE) + .build(); + final HepProgram program = new HepProgramBuilder() + .addRuleInstance(AggregateJoinTransposeRule.EXTENDED) + .build(); + final String sql = "select sum(sal)\n" + + "from (select * from sales.emp where empno = 10) as e\n" + + "join sales.dept as d on e.job = d.name"; + checkPlanning(tester, preProgram, new HepPlanner(program), sql); + } + /** Push a variety of aggregate functions. */ - @Test public void testPushAggregateFunctionsThroughJoin() throws Exception { + @Test public void testPushAggregateFunctionsThroughJoin() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2918,7 +2935,7 @@ public class RelOptRulesTest extends RelOptTestBase { /** Push a aggregate functions into a relation that is unique on the join * key. */ - @Test public void testPushAggregateThroughJoinDistinct() throws Exception { + @Test public void testPushAggregateThroughJoinDistinct() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2935,7 +2952,7 @@ public class RelOptRulesTest extends RelOptTestBase { } /** Push count(*) through join, no GROUP BY. */ - @Test public void testPushAggregateSumNoGroup() throws Exception { + @Test public void testPushAggregateSumNoGroup() { final HepProgram preProgram = new HepProgramBuilder() .addRuleInstance(AggregateProjectMergeRule.INSTANCE) .build(); @@ -2947,7 +2964,7 @@ public class RelOptRulesTest extends RelOptTestBase { checkPlanning(tester, preProgram, new HepPlanner(program), sql); } - @Test public void testSwapOuterJoin() throws Exception { + @Test public void testSwapOuterJoin() { final HepProgram program = new HepProgramBuilder() .addMatchLimit(1) .addRuleInstance(JoinCommuteRule.SWAP_OUTER) http://git-wip-us.apache.org/repos/asf/calcite/blob/a609b473/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 1b2287b..fa4a2a5 100644 --- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml @@ -5723,6 +5723,37 @@ LogicalProject(JOB=[$0], EXPR$1=[$2]) ]]> </Resource> </TestCase> + <TestCase name="testPushAggregateSumWithoutGroupKeyThroughJoin"> + <Resource name="sql"> + <![CDATA[select e.job,sum(sal) +from (select * from sales.emp where empno = 10) as e +join sales.dept as d on e.job = d.name +group by e.job,d.name]]> + </Resource> + <Resource name="planBefore"> + <![CDATA[ +LogicalAggregate(group=[{}], EXPR$0=[SUM($5)]) + LogicalJoin(condition=[=($2, $10)], joinType=[inner]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8]) + LogicalFilter(condition=[=($0, 10)]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) + LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) +]]> + </Resource> + <Resource name="planAfter"> + <![CDATA[ +LogicalAggregate(group=[{}], EXPR$0=[SUM($4)]) + LogicalProject(JOB=[$0], EXPR$0=[$1], NAME=[$2], $f1=[$3], $f4=[CAST(*($1, $3)):INTEGER]) + LogicalJoin(condition=[=($0, $2)], joinType=[inner]) + LogicalAggregate(group=[{2}], EXPR$0=[SUM($5)]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8]) + LogicalFilter(condition=[=($0, 10)]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) + LogicalAggregate(group=[{1}], agg#0=[COUNT()]) + LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) +]]> + </Resource> + </TestCase> <TestCase name="testReduceConstantsIsNotNull"> <Resource name="sql"> <