You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by xi...@apache.org on 2021/12/18 11:15:20 UTC
[calcite] branch master updated: [CALCITE-4700] AggregateUnionTransposeRule produces wrong group sets for the top Aggregate (Vladimir Ozerov)
This is an automated email from the ASF dual-hosted git repository.
xiong 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 538016e [CALCITE-4700] AggregateUnionTransposeRule produces wrong group sets for the top Aggregate (Vladimir Ozerov)
538016e is described below
commit 538016eec2b174ac159dfc0b8886671670ee555a
Author: Vladimir Ozerov <pp...@gmail.com>
AuthorDate: Mon Jul 26 09:40:49 2021 +0300
[CALCITE-4700] AggregateUnionTransposeRule produces wrong group sets for the top Aggregate (Vladimir Ozerov)
---
.../rel/rules/AggregateUnionTransposeRule.java | 29 ++++++++++++++++++-
.../org/apache/calcite/test/RelOptRulesTest.java | 11 ++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 33 ++++++++++++++++++++++
3 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java
index e67ef89..215b12a 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java
@@ -39,6 +39,10 @@ import org.apache.calcite.sql.fun.SqlSumAggFunction;
import org.apache.calcite.sql.fun.SqlSumEmptyIsZeroAggFunction;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
+import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.mapping.Mapping;
+import org.apache.calcite.util.mapping.MappingType;
+import org.apache.calcite.util.mapping.Mappings;
import com.google.common.collect.ImmutableList;
@@ -156,8 +160,31 @@ public class AggregateUnionTransposeRule
// create a new union whose children are the aggregates created above
relBuilder.union(true, union.getInputs().size());
+
+ // Create the top aggregate. We must adjust group key indexes of the
+ // original aggregate. E.g., if the original tree was:
+ //
+ // Aggregate[groupSet=$1, ...]
+ // Union[...]
+ //
+ // Then the new tree should be:
+ // Aggregate[groupSet=$0, ...]
+ // Union[...]
+ // Aggregate[groupSet=$1, ...]
+ ImmutableBitSet groupSet = aggRel.getGroupSet();
+ Mapping topGroupMapping = Mappings.create(MappingType.INVERSE_SURJECTION,
+ union.getRowType().getFieldCount(),
+ aggRel.getGroupCount());
+ for (int i = 0; i < groupSet.cardinality(); i++) {
+ topGroupMapping.set(groupSet.nth(i), i);
+ }
+
+ ImmutableBitSet topGroupSet = Mappings.apply(topGroupMapping, groupSet);
+ ImmutableList<ImmutableBitSet> topGroupSets =
+ Mappings.apply2(topGroupMapping, aggRel.getGroupSets());
+
relBuilder.aggregate(
- relBuilder.groupKey(aggRel.getGroupSet(), aggRel.getGroupSets()),
+ relBuilder.groupKey(topGroupSet, topGroupSets),
transformedAggCalls);
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 e2276b5..864cb95 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -5405,6 +5405,17 @@ class RelOptRulesTest extends RelOptTestBase {
.checkUnchanged();
}
+ @Test void testAggregateUnionTransposeWithTopLevelGroupSetRemapping() {
+ final String sql = "select count(t1), t2 from (\n"
+ + "select (case when deptno=0 then 1 else null end) as t1, 1 as t2 from sales.emp e1\n"
+ + "union all\n"
+ + "select (case when deptno=0 then 1 else null end) as t1, 2 as t2 from sales.emp e2)\n"
+ + "group by t2";
+ sql(sql)
+ .withPreRule(CoreRules.AGGREGATE_PROJECT_MERGE)
+ .withRule(CoreRules.AGGREGATE_UNION_TRANSPOSE)
+ .check();
+ }
@Test void testSortJoinTranspose1() {
final String sql = "select * from sales.emp e left join (\n"
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 8991b55..b81a3be 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -1097,6 +1097,39 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)])
]]>
</Resource>
</TestCase>
+ <TestCase name="testAggregateUnionTransposeWithTopLevelGroupSetRemapping">
+ <Resource name="sql">
+ <![CDATA[select count(t1), t2 from (
+select (case when deptno=0 then 1 else null end) as t1, 1 as t2 from sales.emp e1
+union all
+select (case when deptno=0 then 1 else null end) as t1, 2 as t2 from sales.emp e2)
+group by t2]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(EXPR$0=[$1], T2=[$0])
+ LogicalAggregate(group=[{1}], EXPR$0=[COUNT($0)])
+ LogicalUnion(all=[true])
+ LogicalProject(T1=[CASE(=($7, 0), 1, null:INTEGER)], T2=[1])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalProject(T1=[CASE(=($7, 0), 1, null:INTEGER)], T2=[2])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(EXPR$0=[$1], T2=[$0])
+ LogicalAggregate(group=[{0}], EXPR$0=[$SUM0($1)])
+ LogicalUnion(all=[true])
+ LogicalAggregate(group=[{1}], EXPR$0=[COUNT($0)])
+ LogicalProject(T1=[CASE(=($7, 0), 1, null:INTEGER)], T2=[1])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalAggregate(group=[{1}], EXPR$0=[COUNT($0)])
+ LogicalProject(T1=[CASE(=($7, 0), 1, null:INTEGER)], T2=[2])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testAggregateWithDynamicParam">
<Resource name="sql">
<![CDATA[SELECT sal, COUNT(1) AS count_val