[ 
https://issues.apache.org/jira/browse/CALCITE-2223?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16735127#comment-16735127
 ] 

Vladimir Sitnikov commented on CALCITE-2223:
--------------------------------------------

{quote}Also, rule FilterSetOpTransposeRule is also affected by the same bug.
 Will try to specify the test cases for this.
{quote}
[~vvysotskyi], have you had a chance to find a test case?

I've looked into MaterializationTest failure (infinite planning), and the case 
there is as follows.

I think the issue is more materialization-induced rather than 
FilterSetOpTransposeRule and/or UnionMergeRule.
{code:java}
  @Test public void testJoinMaterializationX() {
    checkMaterialize(
        "select \"depts\".\"deptno\"\n"
            + "from \"depts\"\n"
            + "join \"dependents\" on (\"depts\".\"name\" = 
\"dependents\".\"name\")\n"
            + "where \"depts\".\"deptno\" > 30",
        "select \"depts\".\"deptno\"\n"
            + "from \"depts\"\n"
            + "join \"dependents\" on (\"depts\".\"name\" = 
\"dependents\".\"name\")\n"
            + "where \"depts\".\"deptno\" > 10",
        HR_FKUK_MODEL,
        CalciteAssert.checkResultContains(
            "EnumerableUnion(all=[true])"
        ));
  }
{code}
Let's call the original join with X (the join without where).
 Then materialization replaces X with
{code:sql}
(select * from X where deptno>10 and deptno<=30)
union all select * from m0
{code}
So far so good.
 However, later it happens to apply materialization again:
{code:sql}
(select * from (
  (select * from X where deptno>10 and deptno<=30)
  union all select * from m0
) where deptno>10 and deptno<=30)
union all select * from m0
{code}
Then it pushes WHERE into UNION:
{code:sql}
(select * from (
  (select * from X where deptno>10 and deptno<=30)
  union all select * from m0 where deptno>10 and deptno<=30)
) 
union all select * from m0
{code}
Then it merges unions:
{code:sql}
(select * from X where deptno>10 and deptno<=30)
union all select * from m0 where deptno>10 and deptno<=30)
union all select * from m0
{code}
The full plan after "merge union" looks like
{noformat}
LogicalUnion(all=[true])
  LogicalFilter(subset=[rel#352:Subset#21.NONE.[]], condition=[>=(30, $0)])
    LogicalFilter(subset=[rel#317:Subset#19.NONE.[]], condition=[>($0, 10)])
      LogicalProject(subset=[rel#312:Subset#18.NONE.[]], deptno=[$0])
        LogicalFilter(subset=[rel#310:Subset#17.NONE.[]], condition=[>=(30, 
$0)])
          LogicalJoin(subset=[rel#216:Subset#4.NONE.[]], condition=[=($1, $2)], 
joinType=[inner])
            LogicalProject(subset=[rel#211:Subset#1.NONE.[]], deptno=[$0], 
name0=[CAST($1):VARCHAR CHARACTER SET "ISO-8859-1" COLLATE 
"ISO-8859-1$en_US$primary"])
              EnumerableTableScan(subset=[rel#209:Subset#0.ENUMERABLE.[]], 
table=[[hr, depts]])
            LogicalProject(subset=[rel#214:Subset#3.NONE.[]], 
name0=[CAST($1):VARCHAR CHARACTER SET "ISO-8859-1" COLLATE 
"ISO-8859-1$en_US$primary"])
              EnumerableTableScan(subset=[rel#212:Subset#2.ENUMERABLE.[]], 
table=[[hr, dependents]])
  LogicalFilter(subset=[rel#353:Subset#22.NONE.[]], condition=[>=(30, $0)])
    LogicalFilter(subset=[rel#318:Subset#20.NONE.[]], condition=[>($0, 10)])
      EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], 
table=[[hr, m0]])
  EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], table=[[hr, 
m0]])
{noformat}
Then the process continues, and it just keeps adding forever
{noformat}
union all select * from m0 where deptno>10 and deptno<=30){noformat}
{noformat}
LogicalUnion(all=[true])
  LogicalFilter(subset=[rel#363:Subset#23.NONE.[]], condition=[>=(30, $0)])
    LogicalFilter(subset=[rel#352:Subset#21.NONE.[]], condition=[>=(30, $0)])
      LogicalFilter(subset=[rel#317:Subset#19.NONE.[]], condition=[>($0, 10)])
        LogicalProject(subset=[rel#312:Subset#18.NONE.[]], deptno=[$0])
          LogicalFilter(subset=[rel#310:Subset#17.NONE.[]], condition=[>=(30, 
$0)])
            LogicalJoin(subset=[rel#216:Subset#4.NONE.[]], condition=[=($1, 
$2)], joinType=[inner])
              LogicalProject(subset=[rel#211:Subset#1.NONE.[]], deptno=[$0], 
name0=[CAST($1):VARCHAR CHARACTER SET "ISO-8859-1" COLLATE 
"ISO-8859-1$en_US$primary"])
                EnumerableTableScan(subset=[rel#209:Subset#0.ENUMERABLE.[]], 
table=[[hr, depts]])
              LogicalProject(subset=[rel#214:Subset#3.NONE.[]], 
name0=[CAST($1):VARCHAR CHARACTER SET "ISO-8859-1" COLLATE 
"ISO-8859-1$en_US$primary"])
                EnumerableTableScan(subset=[rel#212:Subset#2.ENUMERABLE.[]], 
table=[[hr, dependents]])
  LogicalFilter(subset=[rel#364:Subset#24.NONE.[]], condition=[>=(30, $0)])
    LogicalFilter(subset=[rel#353:Subset#22.NONE.[]], condition=[>=(30, $0)])
      LogicalFilter(subset=[rel#318:Subset#20.NONE.[]], condition=[>($0, 10)])
        EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], 
table=[[hr, m0]])
  LogicalFilter(subset=[rel#365:Subset#25.NONE.[]], condition=[>=(30, $0)])
    EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], table=[[hr, 
m0]])
  EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], table=[[hr, 
m0]])
{noformat}
{noformat}
LogicalUnion(all=[true])
  LogicalFilter(subset=[rel#409:Subset#27.NONE.[]], condition=[>=(30, $0)])
    LogicalFilter(subset=[rel#363:Subset#23.NONE.[]], condition=[>=(30, $0)])
      LogicalFilter(subset=[rel#352:Subset#21.NONE.[]], condition=[>=(30, $0)])
        LogicalFilter(subset=[rel#317:Subset#19.NONE.[]], condition=[>($0, 10)])
          LogicalProject(subset=[rel#312:Subset#18.NONE.[]], deptno=[$0])
            LogicalFilter(subset=[rel#310:Subset#17.NONE.[]], condition=[>=(30, 
$0)])
              LogicalJoin(subset=[rel#216:Subset#4.NONE.[]], condition=[=($1, 
$2)], joinType=[inner])
                LogicalProject(subset=[rel#211:Subset#1.NONE.[]], deptno=[$0], 
name0=[CAST($1):VARCHAR CHARACTER SET "ISO-8859-1" COLLATE 
"ISO-8859-1$en_US$primary"])
                  EnumerableTableScan(subset=[rel#209:Subset#0.ENUMERABLE.[]], 
table=[[hr, depts]])
                LogicalProject(subset=[rel#214:Subset#3.NONE.[]], 
name0=[CAST($1):VARCHAR CHARACTER SET "ISO-8859-1" COLLATE 
"ISO-8859-1$en_US$primary"])
                  EnumerableTableScan(subset=[rel#212:Subset#2.ENUMERABLE.[]], 
table=[[hr, dependents]])
  LogicalFilter(subset=[rel#410:Subset#28.NONE.[]], condition=[>=(30, $0)])
    LogicalFilter(subset=[rel#364:Subset#24.NONE.[]], condition=[>=(30, $0)])
      LogicalFilter(subset=[rel#353:Subset#22.NONE.[]], condition=[>=(30, $0)])
        LogicalFilter(subset=[rel#318:Subset#20.NONE.[]], condition=[>($0, 10)])
          EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], 
table=[[hr, m0]])
  LogicalFilter(subset=[rel#411:Subset#29.NONE.[]], condition=[>=(30, $0)])
    LogicalFilter(subset=[rel#365:Subset#25.NONE.[]], condition=[>=(30, $0)])
      EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], 
table=[[hr, m0]])
  LogicalFilter(subset=[rel#365:Subset#25.NONE.[]], condition=[>=(30, $0)])
    EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], table=[[hr, 
m0]])
  EnumerableTableScan(subset=[rel#276:Subset#12.ENUMERABLE.[0]], table=[[hr, 
m0]])
{noformat}
and so on.

> ProjectMergeRule is infinitely matched when is applied after 
> ProjectReduceExpressionsRule
> -----------------------------------------------------------------------------------------
>
>                 Key: CALCITE-2223
>                 URL: https://issues.apache.org/jira/browse/CALCITE-2223
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: Volodymyr Vysotskyi
>            Assignee: Julian Hyde
>            Priority: Critical
>         Attachments: heap_overview.png, provenance_contents.png
>
>
> For queries like this:
> {code:sql}
> select t1.f from (select cast(f as int) f, f from (select cast(f as int) f 
> from (values('1')) t(f))) as t1
> {code}
> OOM is thrown when {{ProjectMergeRule}} is applied before applying 
> {{ProjectReduceExpressionsRule}} in VolcanoPlanner.
>  A simple test to reproduce this issue (in {{RelOptRulesTest}}):
> {code:java}
>   @Test public void testOomProjectMergeRule() {
>     RelBuilder relBuilder = 
> RelBuilder.create(RelBuilderTest.config().build());
>     RelNode relNode = relBuilder
>         .values(new String[]{"f"}, "1")
>         .project(
>             relBuilder.alias(
>                 relBuilder.cast(relBuilder.field(0), SqlTypeName.INTEGER),
>                 "f"))
>         .project(
>             relBuilder.alias(
>                 relBuilder.cast(relBuilder.field(0), SqlTypeName.INTEGER),
>                 "f0"),
>             relBuilder.alias(relBuilder.field(0), "f"))
>         .project(
>             relBuilder.alias(relBuilder.field(0), "f"))
>         .build();
>     RelOptPlanner planner = relNode.getCluster().getPlanner();
>     RuleSet ruleSet =
>         RuleSets.ofList(
>             ReduceExpressionsRule.PROJECT_INSTANCE,
>             new ProjectMergeRuleWithLongerName(),
>             EnumerableRules.ENUMERABLE_PROJECT_RULE,
>             EnumerableRules.ENUMERABLE_VALUES_RULE);
>     Program program = Programs.of(ruleSet);
>     RelTraitSet toTraits =
>         relNode.getCluster().traitSet()
>             .replace(0, EnumerableConvention.INSTANCE);
>     RelNode output = program.run(planner, relNode, toTraits,
>         ImmutableList.<RelOptMaterialization>of(), 
> ImmutableList.<RelOptLattice>of());
>     // check for output
>   }
>   /**
>    * ProjectMergeRule inheritor which has
>    * class name greater than ProjectReduceExpressionsRule class name 
> (String.compareTo()).
>    *
>    * It is needed for RuleQueue.popMatch() method
>    * to apply this rule before ProjectReduceExpressionsRule.
>    */
>   private static class ProjectMergeRuleWithLongerName extends 
> ProjectMergeRule {
>     public ProjectMergeRuleWithLongerName() {
>       super(true, RelFactories.LOGICAL_BUILDER);
>     }
>   }
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to