[ 
https://issues.apache.org/jira/browse/CALCITE-3618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Li Xian updated CALCITE-3618:
-----------------------------
    Description: 
WindowedAggRelSplitter isDependent is incorrect
{code:java}
      while (!dfs.isEmpty()) {
        int source = dfs.pop();
        if (visited.contains(source)) {
          continue;
        }

        if (source == ordinal1) {
          return true;
        }

        visited.add(source);
        for (DefaultEdge e : graph.getOutwardEdges(source)) {
          int target = (int) e.target;
          if (rank.get(target) < rank.get(ordinal1)) {
            dfs.push(target);
          }
        }
      }
{code}
It only pushes target into dfs queue if target rank is smaller than ordinal1's 
rank, which makes it impossible to find the dependency.

For SQL like
{code:sql}
select 
 lag(a2, 1, 0) over (partition by "deptno" order by a1) as lagx 
from 
 (
  select 
   "deptno", 
   "salary" / "commission" as a1, 
   sum("commission") over ( partition by "deptno" order by "salary" / 
"commission") / sum("commission") over (partition by "deptno") as a2 
  from 
   "hr"."emps"
 )
{code}
It generates levels of exprs like the attached picture below which is incorrect.

If I execute the SQL in the CsvTest
{code:sql}
"SELECT 
     LAG(A2, 1, 0) OVER (PARTITION BY "GENDER" ORDER BY A1) AS LAGX 
    FROM 
     (
      SELECT 
       "GENDER", 
       "EMPNO" / "DEPTNO" AS A1, 
       SUM("DEPTNO") OVER ( PARTITION BY "GENDER" ORDER BY "EMPNO" / "DEPTNO") 
/ SUM("DEPTNO") OVER (PARTITION BY "GENDER") AS A2 
      FROM 
       "EMPS"
     ) {code}
Calcite will throw the below error
{code:sql}
Error while applying rule ProjectToWindowRule:project, args 
[rel#12:LogicalProject.NONE.[](input=RelSubset#11,LAGX=LAG(/(CASE(>(COUNT($2) 
OVER (PARTITION BY $3 ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW), 0), $SUM0($2) OVER (PARTITION BY $3 ORDER BY /($0, $2) RANGE 
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), null:INTEGER), CASE(>(COUNT($2) 
OVER (PARTITION BY $3 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED 
FOLLOWING), 0), $SUM0($2) OVER (PARTITION BY $3 RANGE BETWEEN UNBOUNDED 
PRECEDING AND UNBOUNDED FOLLOWING), null:INTEGER)), 1, 0) OVER (PARTITION BY $3 
ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW))]
        at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
        at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
        at 
org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:163)
        at 
org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:227)
        at org.apache.calcite.test.CsvTest.checkSql(CsvTest.java:408)
        at org.apache.calcite.test.CsvTest.access$300(CsvTest.java:71)
        at org.apache.calcite.test.CsvTest$Fluent.ok(CsvTest.java:1066)
        at org.apache.calcite.test.CsvTest.testSelect(CsvTest.java:192)
        Caused by:
        java.lang.RuntimeException: Error while applying rule 
ProjectToWindowRule:project, args 
[rel#12:LogicalProject.NONE.[](input=RelSubset#11,LAGX=LAG(/(CASE(>(COUNT($2) 
OVER (PARTITION BY $3 ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW), 0), $SUM0($2) OVER (PARTITION BY $3 ORDER BY /($0, $2) RANGE 
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), null:INTEGER), CASE(>(COUNT($2) 
OVER (PARTITION BY $3 RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED 
FOLLOWING), 0), $SUM0($2) OVER (PARTITION BY $3 RANGE BETWEEN UNBOUNDED 
PRECEDING AND UNBOUNDED FOLLOWING), null:INTEGER)), 1, 0) OVER (PARTITION BY $3 
ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW))]
            at 
org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:238)
            at 
org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:632)
            at 
org.apache.calcite.tools.Programs.lambda$standard$3(Programs.java:287)
            at 
org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:347)
            at org.apache.calcite.prepare.Prepare.optimize(Prepare.java:189)
            at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:320)
            at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:231)
            at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:638)
            at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:502)
            at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:472)
            at 
org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:231)
            at 
org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:550)
            at 
org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:675)
            at 
org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:156)
            ... 5 more
            Caused by:
            java.lang.IllegalArgumentException
                at 
org.apache.calcite.rex.RexSlot$SelfPopulatingList.get(RexSlot.java:90)
                at 
org.apache.calcite.rex.RexSlot$SelfPopulatingList.get(RexSlot.java:60)
                at 
org.apache.calcite.rex.RexLocalRef.createName(RexLocalRef.java:83)
                at 
org.apache.calcite.rex.RexLocalRef.<init>(RexLocalRef.java:52)
                at 
org.apache.calcite.rel.rules.CalcRelSplitter$InputToCommonExprConverter.visitLocalRef(CalcRelSplitter.java:921)
                at 
org.apache.calcite.rel.rules.CalcRelSplitter$InputToCommonExprConverter.visitLocalRef(CalcRelSplitter.java:872)
                at 
org.apache.calcite.rex.RexLocalRef.accept(RexLocalRef.java:75)
                at 
org.apache.calcite.rex.RexShuttle.visitList(RexShuttle.java:149)
                at 
org.apache.calcite.rex.RexShuttle.visitCall(RexShuttle.java:101)
                at 
org.apache.calcite.rex.RexShuttle.visitCall(RexShuttle.java:34)
                at org.apache.calcite.rex.RexCall.accept(RexCall.java:191)
                at 
org.apache.calcite.rel.rules.CalcRelSplitter.createProgramForLevel(CalcRelSplitter.java:561)
                at 
org.apache.calcite.rel.rules.CalcRelSplitter.execute(CalcRelSplitter.java:218)
                at 
org.apache.calcite.rel.rules.ProjectToWindowRule$ProjectToLogicalProjectAndWindowRule.onMatch(ProjectToWindowRule.java:187)
                at 
org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:211)
                ... 18 more
{code}

 

I  have submitted a PR to fix this [https://github.com/apache/calcite/pull/1678]

  was:
WindowedAggRelSplitter isDependent is incorrect
{code:java}
      while (!dfs.isEmpty()) {
        int source = dfs.pop();
        if (visited.contains(source)) {
          continue;
        }

        if (source == ordinal1) {
          return true;
        }

        visited.add(source);
        for (DefaultEdge e : graph.getOutwardEdges(source)) {
          int target = (int) e.target;
          if (rank.get(target) < rank.get(ordinal1)) {
            dfs.push(target);
          }
        }
      }
{code}
It only pushes target into dfs queue if target rank is smaller than ordinal1's 
rank, which makes it impossible to find the dependency.

For SQL like
{code:sql}
select 
 lag(a2, 1, 0) over (partition by "deptno" order by a1) as lagx 
from 
 (
  select 
   "deptno", 
   "salary" / "commission" as a1, 
   sum("commission") over ( partition by "deptno" order by "salary" / 
"commission") / sum("commission") over (partition by "deptno") as a2 
  from 
   "hr"."emps"
 )
{code}
It generates levels of exprs like the attached picture below which is 
incorrect. And will cause error `Error while applying rule 
ProjectToWindowRule:project`

 

I  have submitted a PR to fix this [https://github.com/apache/calcite/pull/1678]


> WindowedAggRelSplitter.isDependent is incorrect
> -----------------------------------------------
>
>                 Key: CALCITE-3618
>                 URL: https://issues.apache.org/jira/browse/CALCITE-3618
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.21.0
>            Reporter: Li Xian
>            Priority: Major
>              Labels: pull-request-available
>         Attachments: Screen Shot 2019-12-20 at 3.49.09 PM.png
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> WindowedAggRelSplitter isDependent is incorrect
> {code:java}
>       while (!dfs.isEmpty()) {
>         int source = dfs.pop();
>         if (visited.contains(source)) {
>           continue;
>         }
>         if (source == ordinal1) {
>           return true;
>         }
>         visited.add(source);
>         for (DefaultEdge e : graph.getOutwardEdges(source)) {
>           int target = (int) e.target;
>           if (rank.get(target) < rank.get(ordinal1)) {
>             dfs.push(target);
>           }
>         }
>       }
> {code}
> It only pushes target into dfs queue if target rank is smaller than 
> ordinal1's rank, which makes it impossible to find the dependency.
> For SQL like
> {code:sql}
> select 
>  lag(a2, 1, 0) over (partition by "deptno" order by a1) as lagx 
> from 
>  (
>   select 
>    "deptno", 
>    "salary" / "commission" as a1, 
>    sum("commission") over ( partition by "deptno" order by "salary" / 
> "commission") / sum("commission") over (partition by "deptno") as a2 
>   from 
>    "hr"."emps"
>  )
> {code}
> It generates levels of exprs like the attached picture below which is 
> incorrect.
> If I execute the SQL in the CsvTest
> {code:sql}
> "SELECT 
>      LAG(A2, 1, 0) OVER (PARTITION BY "GENDER" ORDER BY A1) AS LAGX 
>     FROM 
>      (
>       SELECT 
>        "GENDER", 
>        "EMPNO" / "DEPTNO" AS A1, 
>        SUM("DEPTNO") OVER ( PARTITION BY "GENDER" ORDER BY "EMPNO" / 
> "DEPTNO") / SUM("DEPTNO") OVER (PARTITION BY "GENDER") AS A2 
>       FROM 
>        "EMPS"
>      ) {code}
> Calcite will throw the below error
> {code:sql}
> Error while applying rule ProjectToWindowRule:project, args 
> [rel#12:LogicalProject.NONE.[](input=RelSubset#11,LAGX=LAG(/(CASE(>(COUNT($2) 
> OVER (PARTITION BY $3 ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING 
> AND CURRENT ROW), 0), $SUM0($2) OVER (PARTITION BY $3 ORDER BY /($0, $2) 
> RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), null:INTEGER), 
> CASE(>(COUNT($2) OVER (PARTITION BY $3 RANGE BETWEEN UNBOUNDED PRECEDING AND 
> UNBOUNDED FOLLOWING), 0), $SUM0($2) OVER (PARTITION BY $3 RANGE BETWEEN 
> UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), null:INTEGER)), 1, 0) OVER 
> (PARTITION BY $3 ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING AND 
> CURRENT ROW))]
>         at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
>         at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
>         at 
> org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:163)
>         at 
> org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:227)
>         at org.apache.calcite.test.CsvTest.checkSql(CsvTest.java:408)
>         at org.apache.calcite.test.CsvTest.access$300(CsvTest.java:71)
>         at org.apache.calcite.test.CsvTest$Fluent.ok(CsvTest.java:1066)
>         at org.apache.calcite.test.CsvTest.testSelect(CsvTest.java:192)
>         Caused by:
>         java.lang.RuntimeException: Error while applying rule 
> ProjectToWindowRule:project, args 
> [rel#12:LogicalProject.NONE.[](input=RelSubset#11,LAGX=LAG(/(CASE(>(COUNT($2) 
> OVER (PARTITION BY $3 ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING 
> AND CURRENT ROW), 0), $SUM0($2) OVER (PARTITION BY $3 ORDER BY /($0, $2) 
> RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), null:INTEGER), 
> CASE(>(COUNT($2) OVER (PARTITION BY $3 RANGE BETWEEN UNBOUNDED PRECEDING AND 
> UNBOUNDED FOLLOWING), 0), $SUM0($2) OVER (PARTITION BY $3 RANGE BETWEEN 
> UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), null:INTEGER)), 1, 0) OVER 
> (PARTITION BY $3 ORDER BY /($0, $2) RANGE BETWEEN UNBOUNDED PRECEDING AND 
> CURRENT ROW))]
>             at 
> org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:238)
>             at 
> org.apache.calcite.plan.volcano.VolcanoPlanner.findBestExp(VolcanoPlanner.java:632)
>             at 
> org.apache.calcite.tools.Programs.lambda$standard$3(Programs.java:287)
>             at 
> org.apache.calcite.tools.Programs$SequenceProgram.run(Programs.java:347)
>             at org.apache.calcite.prepare.Prepare.optimize(Prepare.java:189)
>             at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:320)
>             at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:231)
>             at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:638)
>             at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:502)
>             at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:472)
>             at 
> org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:231)
>             at 
> org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:550)
>             at 
> org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:675)
>             at 
> org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:156)
>             ... 5 more
>             Caused by:
>             java.lang.IllegalArgumentException
>                 at 
> org.apache.calcite.rex.RexSlot$SelfPopulatingList.get(RexSlot.java:90)
>                 at 
> org.apache.calcite.rex.RexSlot$SelfPopulatingList.get(RexSlot.java:60)
>                 at 
> org.apache.calcite.rex.RexLocalRef.createName(RexLocalRef.java:83)
>                 at 
> org.apache.calcite.rex.RexLocalRef.<init>(RexLocalRef.java:52)
>                 at 
> org.apache.calcite.rel.rules.CalcRelSplitter$InputToCommonExprConverter.visitLocalRef(CalcRelSplitter.java:921)
>                 at 
> org.apache.calcite.rel.rules.CalcRelSplitter$InputToCommonExprConverter.visitLocalRef(CalcRelSplitter.java:872)
>                 at 
> org.apache.calcite.rex.RexLocalRef.accept(RexLocalRef.java:75)
>                 at 
> org.apache.calcite.rex.RexShuttle.visitList(RexShuttle.java:149)
>                 at 
> org.apache.calcite.rex.RexShuttle.visitCall(RexShuttle.java:101)
>                 at 
> org.apache.calcite.rex.RexShuttle.visitCall(RexShuttle.java:34)
>                 at org.apache.calcite.rex.RexCall.accept(RexCall.java:191)
>                 at 
> org.apache.calcite.rel.rules.CalcRelSplitter.createProgramForLevel(CalcRelSplitter.java:561)
>                 at 
> org.apache.calcite.rel.rules.CalcRelSplitter.execute(CalcRelSplitter.java:218)
>                 at 
> org.apache.calcite.rel.rules.ProjectToWindowRule$ProjectToLogicalProjectAndWindowRule.onMatch(ProjectToWindowRule.java:187)
>                 at 
> org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:211)
>                 ... 18 more
> {code}
>  
> I  have submitted a PR to fix this 
> [https://github.com/apache/calcite/pull/1678]



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to