mirror of
https://github.com/postgres/postgres.git
synced 2026-07-07 08:41:01 -04:00
Disallow set-returning functions within window OVER clauses.
We previously allowed this, but it leads to odd behaviors, basically because putting a SRF there is inconsistent with the principle that a window function doesn't change the number of rows in the query result. There doesn't seem to be a strong reason to try to make such cases behave consistently. Users should put their SRFs in lateral FROM clauses instead. This issue has been sitting on the back burner for multiple years now, partially because it didn't seem wise to back-patch such a change. Let's squeeze it into v19 before it's too late. Bug: #17502 Bug: #19535 Reported-by: Daniel Farkaš <daniel.farkas@datoris.com> Reported-by: Qifan Liu <imchifan@163.com> Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: David Rowley <dgrowleyml@gmail.com> Discussion: https://postgr.es/m/17502-281a7aaacfaa872a@postgresql.org Discussion: https://postgr.es/m/19535-376081d7cc07c86d@postgresql.org Backpatch-through: 19
This commit is contained in:
parent
57f19774d6
commit
1de468099d
3 changed files with 22 additions and 16 deletions
|
|
@ -2700,9 +2700,6 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
|
|||
break;
|
||||
case EXPR_KIND_WINDOW_PARTITION:
|
||||
case EXPR_KIND_WINDOW_ORDER:
|
||||
/* okay, these are effectively GROUP BY/ORDER BY */
|
||||
pstate->p_hasTargetSRFs = true;
|
||||
break;
|
||||
case EXPR_KIND_WINDOW_FRAME_RANGE:
|
||||
case EXPR_KIND_WINDOW_FRAME_ROWS:
|
||||
case EXPR_KIND_WINDOW_FRAME_GROUPS:
|
||||
|
|
|
|||
|
|
@ -267,7 +267,21 @@ ERROR: window function calls cannot contain set-returning function calls
|
|||
LINE 1: SELECT min(generate_series(1, 3)) OVER() FROM few;
|
||||
^
|
||||
HINT: You might be able to move the set-returning function into a LATERAL FROM item.
|
||||
-- SRFs are normally computed after window functions
|
||||
--- ... nor in window definitions
|
||||
SELECT sum(id) OVER (PARTITION BY generate_series(1, 3)) FROM few;
|
||||
ERROR: set-returning functions are not allowed in window definitions
|
||||
LINE 1: SELECT sum(id) OVER (PARTITION BY generate_series(1, 3)) FRO...
|
||||
^
|
||||
SELECT sum(id) OVER (ORDER BY generate_series(1, 3)) FROM few;
|
||||
ERROR: set-returning functions are not allowed in window definitions
|
||||
LINE 1: SELECT sum(id) OVER (ORDER BY generate_series(1, 3)) FROM fe...
|
||||
^
|
||||
SELECT sum(id) OVER (ROWS BETWEEN UNBOUNDED PRECEDING
|
||||
AND generate_series(1, 3) FOLLOWING) FROM few;
|
||||
ERROR: set-returning functions are not allowed in window definitions
|
||||
LINE 2: AND generate_series(1, 3) FOLLOWING) FR...
|
||||
^
|
||||
-- SRFs are computed after window functions
|
||||
SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few;
|
||||
id | lag | count | generate_series
|
||||
----+-----+-------+-----------------
|
||||
|
|
@ -282,15 +296,6 @@ SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few;
|
|||
3 | 2 | 3 | 3
|
||||
(9 rows)
|
||||
|
||||
-- unless referencing SRFs
|
||||
SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g;
|
||||
sum | g
|
||||
-----+---
|
||||
3 | 1
|
||||
3 | 2
|
||||
3 | 3
|
||||
(3 rows)
|
||||
|
||||
-- sorting + grouping
|
||||
SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1;
|
||||
dataa | count | min | max | generate_series
|
||||
|
|
|
|||
|
|
@ -82,10 +82,14 @@ SELECT sum((3 = ANY(SELECT lag(x) over(order by x)
|
|||
-- SRFs are not allowed in window function arguments, either
|
||||
SELECT min(generate_series(1, 3)) OVER() FROM few;
|
||||
|
||||
-- SRFs are normally computed after window functions
|
||||
--- ... nor in window definitions
|
||||
SELECT sum(id) OVER (PARTITION BY generate_series(1, 3)) FROM few;
|
||||
SELECT sum(id) OVER (ORDER BY generate_series(1, 3)) FROM few;
|
||||
SELECT sum(id) OVER (ROWS BETWEEN UNBOUNDED PRECEDING
|
||||
AND generate_series(1, 3) FOLLOWING) FROM few;
|
||||
|
||||
-- SRFs are computed after window functions
|
||||
SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few;
|
||||
-- unless referencing SRFs
|
||||
SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g;
|
||||
|
||||
-- sorting + grouping
|
||||
SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue