[
https://issues.apache.org/jira/browse/CALCITE-7641?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ruben Q L resolved CALCITE-7641.
--------------------------------
Fix Version/s: 1.43.0
Resolution: Fixed
Fixed via
https://github.com/apache/calcite/commit/010259914397860c07c0e481e407ff4c51cbafb2
> Materialize view rules with UnionRewritingPullProgram on a HepPlanner throws
> IllegalArgumentException
> -----------------------------------------------------------------------------------------------------
>
> Key: CALCITE-7641
> URL: https://issues.apache.org/jira/browse/CALCITE-7641
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.42.0
> Reporter: Ruben Q L
> Assignee: Ruben Q L
> Priority: Major
> Labels: pull-request-available
> Fix For: 1.43.0
>
>
> It seems all the tests on MaterializedView rules:
> - Run with the default UnionRewritingPullProgram (null, i.e. none) for all
> the rules.
> - Run using Volcano planner.
> However, if we try these rules with a certain UnionRewritingPullProgram, and
> apply them using a HepPlanner, for example forcing the situation with this
> test to be added to MaterializedViewRelOptRulesTest:
> {code:java}
> @Test void testJoinAggregateMaterializationNoAggregateFuncs9Hep() {
> final MaterializedViewTester hepTester =
> new MaterializedViewTester() {
> @Override protected List<RelNode> optimize(RelNode queryRel,
> List<RelOptMaterialization> materializationList) {
> final HepProgram unionRewritingPullProgram = new
> HepProgramBuilder()
> .addRuleInstance(ProjectRemoveRule.Config.DEFAULT.toRule())
> .build();
> final HepProgram mainProgram = new HepProgramBuilder()
>
> .addRuleInstance(MaterializedViewOnlyAggregateRule.Config.DEFAULT
>
> .withUnionRewritingPullProgram(unionRewritingPullProgram).toRule())
> .build();
> final HepPlanner hepPlanner = new HepPlanner(mainProgram);
> final Program program =
> (planner, rel, requiredOutputTraits, materializations,
> lattices) -> {
> for (RelOptMaterialization materialization :
> materializations) {
> planner.addMaterialization(materialization);
> }
> planner.setRoot(rel);
> final RelNode rootRel = planner.findBestExp();
> return requireNonNull(rootRel, "could not implement exp");
> };
> return ImmutableList.of(
> program.run(hepPlanner, queryRel,
> queryRel.getCluster().traitSet(),
> materializationList, ImmutableList.of()));
> }
> };
> String materialize = "select \"depts\".\"deptno\",
> \"dependents\".\"empid\"\n"
> + "from \"depts\"\n"
> + "join \"dependents\" on (\"depts\".\"name\" =
> \"dependents\".\"name\")\n"
> + "join \"locations\" on (\"locations\".\"name\" =
> \"dependents\".\"name\")\n"
> + "join \"emps\" on (\"emps\".\"deptno\" = \"depts\".\"deptno\")\n"
> + "where \"depts\".\"deptno\" > 11 and \"depts\".\"deptno\" < 19\n"
> + "group by \"depts\".\"deptno\", \"dependents\".\"empid\"";
> String query = "select \"dependents\".\"empid\"\n"
> + "from \"depts\"\n"
> + "join \"dependents\" on (\"depts\".\"name\" =
> \"dependents\".\"name\")\n"
> + "join \"locations\" on (\"locations\".\"name\" =
> \"dependents\".\"name\")\n"
> + "join \"emps\" on (\"emps\".\"deptno\" = \"depts\".\"deptno\")\n"
> + "where \"depts\".\"deptno\" > 10 and \"depts\".\"deptno\" < 20\n"
> + "group by \"dependents\".\"empid\"";
> MaterializedViewFixture.create(query, hepTester)
> .withMaterializations(ImmutableList.of(Pair.of(materialize, "MV0")))
> .checkingThatResultContains("EnumerableTableScan(table=[[hr, MV0]])")
> .ok();
> }
> {code}
> It fails with:
> {noformat}
> java.lang.IllegalArgumentException
> at
> com.google.common.base.Preconditions.checkArgument(Preconditions.java:127)
> at org.apache.calcite.plan.hep.HepRelVertex.<init>(HepRelVertex.java:54)
> at
> org.apache.calcite.plan.hep.HepPlanner.addRelToGraph(HepPlanner.java:981)
> at org.apache.calcite.plan.hep.HepPlanner.setRoot(HepPlanner.java:242)
> at
> org.apache.calcite.rel.rules.materialize.MaterializedViewAggregateRule.rewriteQuery(MaterializedViewAggregateRule.java:279)
> at
> org.apache.calcite.rel.rules.materialize.MaterializedViewRule.perform(MaterializedViewRule.java:390)
> at
> org.apache.calcite.rel.rules.materialize.MaterializedViewOnlyAggregateRule.onMatch(MaterializedViewOnlyAggregateRule.java:71)
> at
> org.apache.calcite.plan.AbstractRelOptPlanner.fireRule(AbstractRelOptPlanner.java:380)
> {noformat}
> The reason is that UnionRewritingPullProgram (used inside {{rewriteQuery}})
> will try to apply this HepProgram (using of course a HepPlanner):
> {code:java}
> ...
> if (unionRewritingPullProgram != null) {
> final HepPlanner tmpPlanner = new HepPlanner(unionRewritingPullProgram);
> tmpPlanner.setRoot(newNode);
> newNode = tmpPlanner.findBestExp();
> target = newNode.getInput(0);
> }
> {code}
> Since the MaterializedViewRule is applied using a HepPlanner, the RelNode
> that fires the rule contains HepRelVertex as "wrappers" on its inputs (the
> whole subtree nodes are wrapped in HepRelVertex instances). If
> UnionRewritingPullProgram is non-null, a new HepPlanner is created, and we
> tried to apply said program on that subtree. However, when setting the root
> on that second HepPlanner, and initializing the graph, when trying to create
> the "new" HepRelVertex, there's a precondition violation, because the RelNode
> that we are trying to add is also a HepRelVertex (from the subtree that fired
> the MaterializedViewRule):
> {code:java}
> HepRelVertex(RelNode rel) {
> super(rel.getCluster(), rel.getTraitSet());
> currentRel = requireNonNull(rel, "rel");
> checkArgument(!(rel instanceof HepRelVertex)); // fails here
> }
> {code}
> Basically, we cannot apply a HepProgram on a tree containing already
> HepVertex, and this is violated on this scenario.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)