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]]>