Weihua Zhang created CALCITE-7744:
-------------------------------------

             Summary: ORDER BY agg(col) on a query where an alias shadows col 
produces an invalid plan containing an aggregate call in a Project
                 Key: CALCITE-7744
                 URL: https://issues.apache.org/jira/browse/CALCITE-7744
             Project: Calcite
          Issue Type: Bug
    Affects Versions: 1.43.0
            Reporter: Weihua Zhang
            Assignee: Weihua Zhang


When a SELECT list defines an alias that shadows a base column, referencing an 
aggregate over that column in ORDER BY causes SqlToRelConverter to emit an 
illegal relational plan: a LogicalProject whose projection list contains a 
RexCall wrapping a SqlAggFunction. This violates the fundamental Calcite 
invariant that aggregate functions may appear only inside Aggregate.aggCalls.
The plan is silently accepted by rel-level validation but crashes during 
Enumerable code generation with:

in dummy.iq
{code:sql}
!use scott
SELECT max(sal) AS sal, deptno, job
FROM emp
GROUP BY deptno, job
ORDER BY max(sal);

java.sql.SQLException: Error while executing SQL "SELECT max(sal) AS sal, 
deptno, job FROM emp GROUP BY deptno, job ORDER BY max(sal)": Unable to 
implement EnumerableCalc(expr#0..3=[{inputs}], proj#0..2=[{exprs}]): rowcount = 
1.4, cumulative cost = {33.949999999999996 rows, 257.2 cpu, 0.0 io}, id = 90
  EnumerableSort(sort0=[$3], dir0=[ASC]): rowcount = 1.4, cumulative cost = 
{32.55 rows, 247.39999999999998 cpu, 0.0 io}, id = 84
    EnumerableCalc(expr#0..3=[{inputs}], SAL=[$t2], DEPTNO=[$t0], JOB=[$t1], 
EXPR$3=[$t3]): rowcount = 1.4, cumulative cost = {31.15 rows, 208.2 cpu, 0.0 
io}, id = 86
      EnumerableAggregate(group=[{0, 1}], SAL=[MAX($2)], agg#1=[MAX($3)]): 
rowcount = 1.4, cumulative cost = {29.75 rows, 197.0 cpu, 0.0 io}, id = 80
        EnumerableCalc(expr#0..7=[{inputs}], expr#8=[MAX($t5)], DEPTNO=[$t7], 
JOB=[$t2], SAL=[$t5], $f3=[$t8]): rowcount = 14.0, cumulative cost = {28.0 
rows, 197.0 cpu, 0.0 io}, id = 88
          EnumerableTableScan(table=[[scott, EMP]]): rowcount = 14.0, 
cumulative cost = {14.0 rows, 15.0 cpu, 0.0 io}, id = 47

        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:164)
        at 
org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:228)
        at net.hydromatic.quidem.Quidem.checkResult(Quidem.java:317)
        at net.hydromatic.quidem.Quidem.access$2600(Quidem.java:54)
        at 
net.hydromatic.quidem.Quidem$ContextImpl.checkResult(Quidem.java:1778)
        at 
net.hydromatic.quidem.Quidem$CheckResultCommand.execute(Quidem.java:985)
        at 
net.hydromatic.quidem.Quidem$CompositeCommand.execute(Quidem.java:1522)
        at net.hydromatic.quidem.Quidem.execute(Quidem.java:204)
        at org.apache.calcite.test.QuidemTest.checkRun(QuidemTest.java:353)
        at org.apache.calcite.test.QuidemTest.test(QuidemTest.java:543)
        at org.apache.calcite.test.CoreQuidemTest.main(CoreQuidemTest.java:54)
Caused by: java.lang.IllegalStateException: Unable to implement 
EnumerableCalc(expr#0..3=[{inputs}], proj#0..2=[{exprs}]): rowcount = 1.4, 
cumulative cost = {33.949999999999996 rows, 257.2 cpu, 0.0 io}, id = 90
  EnumerableSort(sort0=[$3], dir0=[ASC]): rowcount = 1.4, cumulative cost = 
{32.55 rows, 247.39999999999998 cpu, 0.0 io}, id = 84
    EnumerableCalc(expr#0..3=[{inputs}], SAL=[$t2], DEPTNO=[$t0], JOB=[$t1], 
EXPR$3=[$t3]): rowcount = 1.4, cumulative cost = {31.15 rows, 208.2 cpu, 0.0 
io}, id = 86
      EnumerableAggregate(group=[{0, 1}], SAL=[MAX($2)], agg#1=[MAX($3)]): 
rowcount = 1.4, cumulative cost = {29.75 rows, 197.0 cpu, 0.0 io}, id = 80
        EnumerableCalc(expr#0..7=[{inputs}], expr#8=[MAX($t5)], DEPTNO=[$t7], 
JOB=[$t2], SAL=[$t5], $f3=[$t8]): rowcount = 14.0, cumulative cost = {28.0 
rows, 197.0 cpu, 0.0 io}, id = 88
          EnumerableTableScan(table=[[scott, EMP]]): rowcount = 14.0, 
cumulative cost = {14.0 rows, 15.0 cpu, 0.0 io}, id = 47

        at 
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.implementRoot(EnumerableRelImplementor.java:120)
        at 
org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:113)
        at 
org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.implement(CalcitePrepareImpl.java:1209)
        at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:343)
        at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:221)
        at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:677)
        at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:528)
        at 
org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:496)
        at 
org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:246)
        at 
org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:654)
        at 
org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:678)
        at 
org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:157)
        ... 10 more
        Suppressed: java.lang.RuntimeException: cannot translate call MAX($t5)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitCall(RexToLixTranslator.java:1632)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitCall(RexToLixTranslator.java:110)
                at org.apache.calcite.rex.RexCall.accept(RexCall.java:208)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitLocalRef(RexToLixTranslator.java:1508)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.visitLocalRef(RexToLixTranslator.java:110)
                at 
org.apache.calcite.rex.RexLocalRef.accept(RexLocalRef.java:78)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate(RexToLixTranslator.java:293)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate(RexToLixTranslator.java:287)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateList(RexToLixTranslator.java:1295)
                at 
org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateProjects(RexToLixTranslator.java:233)
                at 
org.apache.calcite.adapter.enumerable.EnumerableCalc.implement(EnumerableCalc.java:193)
                at 
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:110)
                at 
org.apache.calcite.adapter.enumerable.EnumerableAggregate.implement(EnumerableAggregate.java:99)
                at 
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:110)
                at 
org.apache.calcite.adapter.enumerable.EnumerableCalc.implement(EnumerableCalc.java:118)
                at 
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:110)
                at 
org.apache.calcite.adapter.enumerable.EnumerableSort.implement(EnumerableSort.java:74)
                at 
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.visitChild(EnumerableRelImplementor.java:110)
                at 
org.apache.calcite.adapter.enumerable.EnumerableCalc.implement(EnumerableCalc.java:118)
                at 
org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.implementRoot(EnumerableRelImplementor.java:117)
                ... 21 more
!ok
{code}

plan after sqltorel:
Note the leaf LogicalProject contains $f3=[MAX($5)] where MAX is a 
SqlMinMaxAggFunction (a SqlAggFunction). This is a RexCall(SqlAggFunction) 
inside a Project — a shape that no relational operator should ever produce.

{code:java}
LogicalSort(sort0=[$3], dir0=[ASC])
  LogicalProject(SAL=[$2], DEPTNO=[$0], JOB=[$1], EXPR$3=[$3])
    LogicalAggregate(group=[{0,1}], SAL=[MAX($2)], agg#1=[MAX($3)])
      LogicalProject(DEPTNO=[$7], JOB=[$2], SAL=[$5], $f3=[MAX($5)])
        LogicalTableScan(table=[[scott, EMP]])
{code}






--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to