Vladimir Sitnikov created CALCITE-7875:
------------------------------------------

             Summary: ORDER BY max(sal) cannot run when a SELECT item max(sal) 
is aliased SAL; PostgreSQL resolves sal inside the aggregate to the input column
                 Key: CALCITE-7875
                 URL: https://issues.apache.org/jira/browse/CALCITE-7875
             Project: Calcite
          Issue Type: Improvement
            Reporter: Vladimir Sitnikov


A query that orders by an aggregate of a column cannot run in Calcite when a 
SELECT item with the same aggregate is aliased with the column's name:

{code:sql}
SELECT max(sal) AS sal, deptno, job
FROM emp
GROUP BY deptno, job
ORDER BY max(sal);
{code}

Calcite resolves {{sal}} inside {{max(...)}} to the SELECT alias {{SAL}}, so 
the ORDER BY item becomes {{max(max(sal))}}. On main (1.43.0-SNAPSHOT, 
6ff13eaccd) the query passes validation and fails during Enumerable code 
generation with {{IllegalStateException: Unable to implement 
EnumerableCalc(...)}}; CALCITE-7744 tracks that failure, and its pull request 
[https://github.com/apache/calcite/pull/5225] rejects the query in the 
validator with {{Aggregate expressions cannot be nested}}. Either way, the 
query does not return rows.

PostgreSQL 17.11 runs the query and orders by the maximum salary of each group, 
because an output-column name in ORDER BY is recognized only when it stands 
alone; inside an expression, {{sal}} is the input column:

{noformat}
 sal | deptno | job
-----+--------+-----
  50 |     20 | C
 200 |     20 | B
 300 |     10 | A
(3 rows)
{noformat}

(Data: {{emp(empno int, deptno int, job text, sal numeric)}} with rows 
(1,10,'A',100), (2,10,'A',300), (3,20,'B',200), (4,20,'C',50).) The grounding 
is another product's behavior, and Calcite deliberately allows SELECT aliases 
inside ORDER BY expressions ({{ORDER BY sal + 0}} is valid in Calcite and an 
error in PostgreSQL), so adopting PostgreSQL's rule wholesale is not the 
request.

*Request.* When an identifier in the argument of a non-windowed aggregate call 
in ORDER BY would resolve to a SELECT alias whose expression is itself an 
aggregate, resolve it to the input column of the same name, if one exists. Such 
an alias can never be valid there: the expansion is always a nested aggregate.

*Acceptance.* The query above validates, converts to a plan with a single 
{{MAX(SAL)}} aggregate call, and returns the rows ordered by {{max(sal)}}. 
{{ORDER BY sal}} and {{ORDER BY sal + 0}} keep resolving {{sal}} to the alias.

*Out of scope.* Changing how aliases resolve outside aggregate arguments, and 
the nested-aggregate rejection that CALCITE-7744 adds for the case where no 
input column of that name exists.

*Prior reports.* A JIRA search for ORDER BY alias resolution found no request 
for this; the nearest is CALCITE-6082, which fixed an alias that equals a 
column name in GROUP BY. The discussion started in 
[https://github.com/apache/calcite/pull/5225#issuecomment-5425585810].




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to