You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by hy...@apache.org on 2019/06/30 20:02:35 UTC
[calcite] branch master updated: [CALCITE-2801] Check input type in
AggregateUnionAggregateRule when remove the bottom Aggregate (Hequn Cheng)
This is an automated email from the ASF dual-hosted git repository.
hyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 78251a1 [CALCITE-2801] Check input type in AggregateUnionAggregateRule when remove the bottom Aggregate (Hequn Cheng)
78251a1 is described below
commit 78251a196543a51b67f43b21f484ffcc8a8aa3f9
Author: hequn8128 <ch...@gmail.com>
AuthorDate: Sun Jan 27 15:19:22 2019 +0800
[CALCITE-2801] Check input type in AggregateUnionAggregateRule when remove the bottom Aggregate (Hequn Cheng)
Updated code to make sure to preserve the alias of Union, and add 1 more test
case for coverage by Haisheng Yuan.
Closes #1017
---
.../rel/rules/AggregateUnionAggregateRule.java | 23 +++++++-
.../org/apache/calcite/test/RelOptRulesTest.java | 40 ++++++++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 61 ++++++++++++++++++++++
3 files changed, 122 insertions(+), 2 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java
index 5f1e22d..349c578 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionAggregateRule.java
@@ -18,6 +18,7 @@ package org.apache.calcite.rel.rules;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.RelFactories;
@@ -96,6 +97,23 @@ public class AggregateUnionAggregateRule extends RelOptRule {
//~ Methods ----------------------------------------------------------------
+ /**
+ * Returns an input with the same row type with the input Aggregate,
+ * create a Project node if needed.
+ */
+ private RelNode getInputWithSameRowType(Aggregate bottomAggRel) {
+ if (RelOptUtil.areRowTypesEqual(
+ bottomAggRel.getRowType(),
+ bottomAggRel.getInput(0).getRowType(),
+ false)) {
+ return bottomAggRel.getInput(0);
+ } else {
+ return RelOptUtil.createProject(
+ bottomAggRel.getInput(),
+ bottomAggRel.getGroupSet().asList());
+ }
+ }
+
public void onMatch(RelOptRuleCall call) {
final Aggregate topAggRel = call.rel(0);
final Union union = call.rel(1);
@@ -111,11 +129,11 @@ public class AggregateUnionAggregateRule extends RelOptRule {
// Aggregate is the second input
bottomAggRel = call.rel(3);
relBuilder.push(call.rel(2))
- .push(call.rel(3).getInput(0));
+ .push(getInputWithSameRowType(bottomAggRel));
} else if (call.rel(2) instanceof Aggregate) {
// Aggregate is the first input
bottomAggRel = call.rel(2);
- relBuilder.push(call.rel(2).getInput(0))
+ relBuilder.push(getInputWithSameRowType(bottomAggRel))
.push(call.rel(3));
} else {
return;
@@ -128,6 +146,7 @@ public class AggregateUnionAggregateRule extends RelOptRule {
}
relBuilder.union(true);
+ relBuilder.rename(union.getRowType().getFieldNames());
relBuilder.aggregate(relBuilder.groupKey(topAggRel.getGroupSet()),
topAggRel.getAggCallList());
call.transformTo(relBuilder.build());
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 bc3ca18..2e33132 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -3215,6 +3215,46 @@ public class RelOptRulesTest extends RelOptTestBase {
sql(sql).with(program).check();
}
+ /**
+ * Once the bottom aggregate pulled through union, we need to add a Project
+ * if the new input contains a different type from the union.
+ */
+ @Test public void testPullAggregateThroughUnionAndAddProjects() {
+ HepProgram program = new HepProgramBuilder()
+ .addRuleInstance(AggregateProjectMergeRule.INSTANCE)
+ .addRuleInstance(AggregateUnionAggregateRule.INSTANCE)
+ .build();
+
+ final String sql = "select job, deptno from"
+ + " (select job, deptno from emp as e1"
+ + " group by job, deptno"
+ + " union all"
+ + " select job, deptno from emp as e2"
+ + " group by job, deptno)"
+ + " group by job, deptno";
+ sql(sql).with(program).check();
+ }
+
+ /**
+ * Make sure the union alias is preserved when the bottom aggregate is
+ * pulled up through union.
+ */
+ @Test public void testPullAggregateThroughUnionWithAlias() {
+ HepProgram program = new HepProgramBuilder()
+ .addRuleInstance(AggregateProjectMergeRule.INSTANCE)
+ .addRuleInstance(AggregateUnionAggregateRule.INSTANCE)
+ .build();
+
+ final String sql = "select job, c from"
+ + " (select job, deptno c from emp as e1"
+ + " group by job, deptno"
+ + " union all"
+ + " select job, deptno from emp as e2"
+ + " group by job, deptno)"
+ + " group by job, c";
+ sql(sql).with(program).check();
+ }
+
private void transitiveInference(RelOptRule... extraRules) throws Exception {
final DiffRepository diffRepos = getDiffRepos();
final String sql = diffRepos.expand(null, "${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 0d78880..0453f4a 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -6174,6 +6174,67 @@ LogicalAggregate(group=[{0, 1}])
]]>
</Resource>
</TestCase>
+ <TestCase name="testPullAggregateThroughUnionAndAddProjects">
+ <Resource name="sql">
+ <![CDATA[select job, deptno from
+ (select job, deptno from emp as e1 group by job, deptno
+ union all select job, deptno from emp as e2 group by job, deptno)
+ group by job, deptno]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalAggregate(group=[{0, 1}])
+ LogicalUnion(all=[true])
+ LogicalAggregate(group=[{0, 1}])
+ LogicalProject(JOB=[$2], DEPTNO=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalAggregate(group=[{0, 1}])
+ LogicalProject(JOB=[$2], DEPTNO=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalAggregate(group=[{0, 1}])
+ LogicalUnion(all=[true])
+ LogicalProject(JOB=[$2], DEPTNO=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalProject(JOB=[$2], DEPTNO=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testPullAggregateThroughUnionWithAlias">
+ <Resource name="sql">
+ <![CDATA[select job, c from
+ (select job, deptno c from emp as e1 group by job, deptno
+ union all select job, deptno from emp as e2 group by job, deptno)
+ group by job, c]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalAggregate(group=[{0, 1}])
+ LogicalUnion(all=[true])
+ LogicalAggregate(group=[{0, 1}])
+ LogicalProject(JOB=[$2], C=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalAggregate(group=[{0, 1}])
+ LogicalProject(JOB=[$2], DEPTNO=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalAggregate(group=[{0, 1}])
+ LogicalProject(JOB=[$0], C=[$1])
+ LogicalUnion(all=[true])
+ LogicalAggregate(group=[{2, 7}])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalProject(JOB=[$2], DEPTNO=[$7])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testProjectWindowTransposeRule">
<Resource name="sql">
<![CDATA[select count(empno) over(), deptno from emp]]>