mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Fix window functions that sort by expressions involving aggregates.
In commit c1d9579dd8bf3c921ca6bc2b62c40da6d25372e5, I changed things so that the output of the Agg node that feeds the window functions would not list any ungrouped Vars directly. Formerly, for example, the Agg tlist might have included both "x" and "sum(x)", which is not really valid if "x" isn't a grouping column. If we then had a window function ordering on something like "sum(x) + 1", prepare_sort_from_pathkeys would find no exact match for this in the Agg tlist, and would conclude that it must recompute the expression. But it would break the expression down to just the Var "x", which it would find in the tlist, and then rebuild the ORDER BY expression using a reference to the subplan's "x" output. Now, after the above-referenced changes, "x" isn't in the Agg tlist if it's not a grouping column, so that prepare_sort_from_pathkeys fails with "could not find pathkey item to sort", as reported by Bricklen Anderson. The fix is to not break down Aggrefs into their component parts, but just treat them as irreducible expressions to be sought in the subplan tlist. This is definitely OK for the use with respect to window functions in grouping_planner, since it just built the tlist being used on the same basis. AFAICT it is safe for other uses too; most of the other call sites couldn't encounter Aggrefs anyway.
This commit is contained in:
parent
be64ba6230
commit
1679e9fedd
@ -3539,7 +3539,13 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
|
||||
|
||||
if (!tle)
|
||||
{
|
||||
/* No matching tlist item; look for a computable expression */
|
||||
/*
|
||||
* No matching tlist item; look for a computable expression.
|
||||
* Note that we treat Aggrefs as if they were variables; this
|
||||
* is necessary when attempting to sort the output from an Agg
|
||||
* node for use in a WindowFunc (since grouping_planner will
|
||||
* have treated the Aggrefs as variables, too).
|
||||
*/
|
||||
Expr *sortexpr = NULL;
|
||||
|
||||
foreach(j, ec->ec_members)
|
||||
@ -3552,7 +3558,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
|
||||
continue;
|
||||
sortexpr = em->em_expr;
|
||||
exprvars = pull_var_clause((Node *) sortexpr,
|
||||
PVC_RECURSE_AGGREGATES,
|
||||
PVC_INCLUDE_AGGREGATES,
|
||||
PVC_INCLUDE_PLACEHOLDERS);
|
||||
foreach(k, exprvars)
|
||||
{
|
||||
|
@ -594,6 +594,26 @@ SELECT SUM(COUNT(f1)) OVER () FROM int4_tbl WHERE f1=42;
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-- window function with ORDER BY an expression involving aggregates (9.1 bug)
|
||||
select ten,
|
||||
sum(unique1) + sum(unique2) as res,
|
||||
rank() over (order by sum(unique1) + sum(unique2)) as rank
|
||||
from tenk1
|
||||
group by ten order by ten;
|
||||
ten | res | rank
|
||||
-----+----------+------
|
||||
0 | 9976146 | 4
|
||||
1 | 10114187 | 9
|
||||
2 | 10059554 | 8
|
||||
3 | 9878541 | 1
|
||||
4 | 9881005 | 2
|
||||
5 | 9981670 | 5
|
||||
6 | 9947099 | 3
|
||||
7 | 10120309 | 10
|
||||
8 | 9991305 | 6
|
||||
9 | 10040184 | 7
|
||||
(10 rows)
|
||||
|
||||
-- test non-default frame specifications
|
||||
SELECT four, ten,
|
||||
sum(ten) over (partition by four order by ten),
|
||||
|
@ -138,6 +138,13 @@ SELECT empno, depname, salary, bonus, depadj, MIN(bonus) OVER (ORDER BY empno),
|
||||
-- window function over ungrouped agg over empty row set (bug before 9.1)
|
||||
SELECT SUM(COUNT(f1)) OVER () FROM int4_tbl WHERE f1=42;
|
||||
|
||||
-- window function with ORDER BY an expression involving aggregates (9.1 bug)
|
||||
select ten,
|
||||
sum(unique1) + sum(unique2) as res,
|
||||
rank() over (order by sum(unique1) + sum(unique2)) as rank
|
||||
from tenk1
|
||||
group by ten order by ten;
|
||||
|
||||
-- test non-default frame specifications
|
||||
SELECT four, ten,
|
||||
sum(ten) over (partition by four order by ten),
|
||||
|
Loading…
x
Reference in New Issue
Block a user