[
https://issues.apache.org/jira/browse/CALCITE-6193?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mou Wu updated CALCITE-6193:
----------------------------
Description:
{code:java}
@Test void testStopTryIncorrectSubtree() {
final String mv = ""
+ "select \"empid\", \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "group by \"empid\", \"deptno\"";
final String query = ""
+ "select t1.\"deptno\"\n"
+ "from (\n"
+ "select \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "union all\n"
+ "select \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "group by \"deptno\"\n"
+ ") as t1 inner join (\n"
+ "select \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "group by \"deptno\"\n"
+ ") as t2 on t1.\"deptno\" = t2.\"deptno\"\n";
sql(mv, query)
.checkingThatResultContains(""
+ "LogicalCalc(expr#0..1=[{inputs}], deptno=[$t0])\n"
+ " LogicalJoin(condition=[=($0, $1)], joinType=[inner])\n"
+ " LogicalUnion(all=[true])\n"
+ " LogicalCalc(expr#0..4=[{inputs}], expr#5=[1000],
expr#6=[>($t3, $t5)], deptno=[$t1], $condition=[$t6])\n"
+ " LogicalTableScan(table=[[hr, emps]])\n"
+ " LogicalAggregate(group=[{1}])\n"
+ " EnumerableTableScan(table=[[hr, MV0]])\n"
+ " LogicalAggregate(group=[{1}])\n"
+ " EnumerableTableScan(table=[[hr, MV0]])"
).ok();
}{code}
The test case above will fail because the second mv0 not be matched.
Two conditions these kind of bug matchs:
(a) There is a third expression, earlier in the view, that has a subexpression
in common with the matching fragments but does not match the view.
(b) The matching fragments require some compensation.
The root cause is that SubstitutionVisitor replace child nodes with
targetDescendant node itself, not a deep-copy replica, so they may share the
same node and the same parent node, thus the incorrect parent relationship may
occur, it will make stopTrying be wrong.
was:
{code:java}
@Test void testStopTryIncorrectSubtree() {
final String mv = ""
+ "select \"empid\", \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "group by \"empid\", \"deptno\"";
final String query = ""
+ "select t1.\"deptno\"\n"
+ "from (\n"
+ "select \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "union all\n"
+ "select \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "group by \"deptno\"\n"
+ ") as t1 inner join (\n"
+ "select \"deptno\"\n"
+ "from \"emps\"\n"
+ "where \"salary\" > 1000\n"
+ "group by \"deptno\"\n"
+ ") as t2 on t1.\"deptno\" = t2.\"deptno\"\n";
sql(mv, query)
.checkingThatResultContains(""
+ "LogicalCalc(expr#0..1=[{inputs}], deptno=[$t0])\n"
+ " LogicalJoin(condition=[=($0, $1)], joinType=[inner])\n"
+ " LogicalUnion(all=[true])\n"
+ " LogicalCalc(expr#0..4=[{inputs}], expr#5=[1000],
expr#6=[>($t3, $t5)], deptno=[$t1], $condition=[$t6])\n"
+ " LogicalTableScan(table=[[hr, emps]])\n"
+ " LogicalAggregate(group=[{1}])\n"
+ " EnumerableTableScan(table=[[hr, MV0]])\n"
+ " LogicalAggregate(group=[{1}])\n"
+ " EnumerableTableScan(table=[[hr, MV0]])"
).ok();
}{code}
The test case above will fail because the second mv0 not be matched.
The root cause is that SubstitutionVisitor replace child nodes with
targetDescendant node itself, not a deep-copy replica, so they may share the
same node and the same parent node, thus the incorrect parent relationship may
occur, it will make stopTrying be wrong.
> If a query has more than one subexpression that matches a materialized view,
> only the first is substituted
> ----------------------------------------------------------------------------------------------------------
>
> Key: CALCITE-6193
> URL: https://issues.apache.org/jira/browse/CALCITE-6193
> Project: Calcite
> Issue Type: Bug
> Reporter: Mou Wu
> Assignee: Mou Wu
> Priority: Major
> Labels: pull-request-available
> Fix For: 1.37.0
>
>
> {code:java}
> @Test void testStopTryIncorrectSubtree() {
> final String mv = ""
> + "select \"empid\", \"deptno\"\n"
> + "from \"emps\"\n"
> + "where \"salary\" > 1000\n"
> + "group by \"empid\", \"deptno\"";
> final String query = ""
> + "select t1.\"deptno\"\n"
> + "from (\n"
> + "select \"deptno\"\n"
> + "from \"emps\"\n"
> + "where \"salary\" > 1000\n"
> + "union all\n"
> + "select \"deptno\"\n"
> + "from \"emps\"\n"
> + "where \"salary\" > 1000\n"
> + "group by \"deptno\"\n"
> + ") as t1 inner join (\n"
> + "select \"deptno\"\n"
> + "from \"emps\"\n"
> + "where \"salary\" > 1000\n"
> + "group by \"deptno\"\n"
> + ") as t2 on t1.\"deptno\" = t2.\"deptno\"\n";
> sql(mv, query)
> .checkingThatResultContains(""
> + "LogicalCalc(expr#0..1=[{inputs}], deptno=[$t0])\n"
> + " LogicalJoin(condition=[=($0, $1)], joinType=[inner])\n"
> + " LogicalUnion(all=[true])\n"
> + " LogicalCalc(expr#0..4=[{inputs}], expr#5=[1000],
> expr#6=[>($t3, $t5)], deptno=[$t1], $condition=[$t6])\n"
> + " LogicalTableScan(table=[[hr, emps]])\n"
> + " LogicalAggregate(group=[{1}])\n"
> + " EnumerableTableScan(table=[[hr, MV0]])\n"
> + " LogicalAggregate(group=[{1}])\n"
> + " EnumerableTableScan(table=[[hr, MV0]])"
> ).ok();
> }{code}
> The test case above will fail because the second mv0 not be matched.
> Two conditions these kind of bug matchs:
> (a) There is a third expression, earlier in the view, that has a
> subexpression in common with the matching fragments but does not match the
> view.
> (b) The matching fragments require some compensation.
> The root cause is that SubstitutionVisitor replace child nodes with
> targetDescendant node itself, not a deep-copy replica, so they may share the
> same node and the same parent node, thus the incorrect parent relationship
> may occur, it will make stopTrying be wrong.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)