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

Danny Chen updated CALCITE-3618:
--------------------------------
    Fix Version/s: 1.22.0

> 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
>             Fix For: 1.22.0
>
>         Attachments: Screen Shot 2019-12-20 at 3.49.09 PM.png
>
>          Time Spent: 50m
>  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.
> To reproduce the error, you can execute the below 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}
> And 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