[
https://issues.apache.org/jira/browse/CALCITE-3087?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16855345#comment-16855345
]
Feng Zhu commented on CALCITE-3087:
-----------------------------------
For the pattern: *Query(Aggregate)->Project->Child1* &
*Target(Aggregate)->Child2*, When
(1)Child1==Child2;
(2)Project can generate Mapping, i.e., all project expressions are RexInputRef,
e.g., ([$0], [$1]), ([$1], [$0])
AggregateOnProjectToAggregateUnifyRule will generate another Aggregate through
mapping reverse, i.e., {color:#FF0000}Aggregate2=(Query+Project){color}.
This mapping reverse transformation can guarantee the correctness no matter
what the GroupSets(ROLLUP/CUBE) is. Under such conditions, we can safely ignore
it.
Then, the rule _unifyAggregate({color:#FF0000}Aggregate2{color}, target)_ as
that in AggregateToAggregateUnifyRule.
However, Aggregate derives RowType according to its input. When the Project
mapping breaks the initial field order, what we need to do is just adding a
Project for re-maping the result's RowType back.
AggregateOnProjectToAggregateUnifyRule is designed to (according to rule name
and description) ignore Project and reuse the logic in
AggregateToAggregateUnifyRule. As for keeping the Project immediately on top of
target Aggregate, I think it is a more general and complex MV reuse pattern.
> AggregateOnProjectToAggregateUnifyRule cannot ignore Project when its Mapping
> breaks ordering
> ---------------------------------------------------------------------------------------------
>
> Key: CALCITE-3087
> URL: https://issues.apache.org/jira/browse/CALCITE-3087
> Project: Calcite
> Issue Type: Bug
> Components: core
> Reporter: Haisheng Yuan
> Assignee: Feng Zhu
> Priority: Major
> Labels: pull-request-available
> Time Spent: 20m
> Remaining Estimate: 0h
>
> Add the following test to MaterializationTest:
> {code:java}
> @Test public void testAggregateGroupSetsRollUp0() {
> checkMaterialize(
> "select \"empid\", \"deptno\", count(*) as c, sum(\"salary\") as s
> from \"emps\" "
> + "group by \"empid\", \"deptno\"",
> "select count(*) + 1 as c, \"deptno\" from \"emps\" group by
> cube(\"deptno\", \"empid\")",
> HR_FKUK_MODEL,
> CalciteAssert.checkResultContains(
> "EnumerableCalc(expr#0..2=[{inputs}], expr#3=[1], "
> + "expr#4=[+($t2, $t3)], C=[$t4], deptno=[$t1])\n"
> + " EnumerableAggregate(group=[{0, 1}], groups=[[{0, 1},
> {0}, {1}, {}]], agg#0=[$SUM0($2)])\n"
> + " EnumerableTableScan(table=[[hr, m0]])"));
> }
> {code}
> We got error:
> {code:java}
> Caused by: java.lang.IllegalArgumentException: must be sorted: [{0, 1}, {1},
> {0}, {}]
> at
> org.apache.calcite.rel.core.Aggregate$Group.induce(Aggregate.java:472)
> at
> org.apache.calcite.rel.mutable.MutableAggregate.getGroupType(MutableAggregate.java:83)
> at
> org.apache.calcite.plan.SubstitutionVisitor.unifyAggregates(SubstitutionVisitor.java:1281)
> at
> org.apache.calcite.plan.SubstitutionVisitor$AggregateOnProjectToAggregateUnifyRule.apply(SubstitutionVisitor.java:1345)
> at
> org.apache.calcite.plan.SubstitutionVisitor.go(SubstitutionVisitor.java:531)
> at
> org.apache.calcite.plan.SubstitutionVisitor.go(SubstitutionVisitor.java:466)
> at
> org.apache.calcite.plan.MaterializedViewSubstitutionVisitor.go(MaterializedViewSubstitutionVisitor.java:56)
> at
> org.apache.calcite.plan.RelOptMaterializations.substitute(RelOptMaterializations.java:200)
> at
> org.apache.calcite.plan.RelOptMaterializations.useMaterializedViews(RelOptMaterializations.java:72)
> at
> org.apache.calcite.plan.volcano.VolcanoPlanner.registerMaterializations(VolcanoPlanner.java:348)
> at
> org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:584)
> {code}
> The reason is that Mappings.apply2 doesn't sort.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)