diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/parser/parse_agg.c | 37 | ||||
-rw-r--r-- | src/test/regress/expected/tsrf.out | 14 | ||||
-rw-r--r-- | src/test/regress/sql/tsrf.sql | 6 |
3 files changed, 42 insertions, 15 deletions
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index 613bdabd520..64111f315e3 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -705,21 +705,28 @@ check_agg_arguments_walker(Node *node, } /* Continue and descend into subtree */ } - /* We can throw error on sight for a set-returning function */ - if ((IsA(node, FuncExpr) &&((FuncExpr *) node)->funcretset) || - (IsA(node, OpExpr) &&((OpExpr *) node)->opretset)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("aggregate function calls cannot contain set-returning function calls"), - errhint("You might be able to move the set-returning function into a LATERAL FROM item."), - parser_errposition(context->pstate, exprLocation(node)))); - /* We can throw error on sight for a window function */ - if (IsA(node, WindowFunc)) - ereport(ERROR, - (errcode(ERRCODE_GROUPING_ERROR), - errmsg("aggregate function calls cannot contain window function calls"), - parser_errposition(context->pstate, - ((WindowFunc *) node)->location))); + + /* + * SRFs and window functions can be rejected immediately, unless we are + * within a sub-select within the aggregate's arguments; in that case + * they're OK. + */ + if (context->sublevels_up == 0) + { + if ((IsA(node, FuncExpr) &&((FuncExpr *) node)->funcretset) || + (IsA(node, OpExpr) &&((OpExpr *) node)->opretset)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("aggregate function calls cannot contain set-returning function calls"), + errhint("You might be able to move the set-returning function into a LATERAL FROM item."), + parser_errposition(context->pstate, exprLocation(node)))); + if (IsA(node, WindowFunc)) + ereport(ERROR, + (errcode(ERRCODE_GROUPING_ERROR), + errmsg("aggregate function calls cannot contain window function calls"), + parser_errposition(context->pstate, + ((WindowFunc *) node)->location))); + } if (IsA(node, Query)) { /* Recurse into subselects */ diff --git a/src/test/regress/expected/tsrf.out b/src/test/regress/expected/tsrf.out index b691abe7146..6d33fbd3c8b 100644 --- a/src/test/regress/expected/tsrf.out +++ b/src/test/regress/expected/tsrf.out @@ -212,6 +212,20 @@ ERROR: aggregate function calls cannot contain set-returning function calls LINE 1: SELECT min(generate_series(1, 3)) FROM few; ^ HINT: You might be able to move the set-returning function into a LATERAL FROM item. +-- ... unless they're within a sub-select +SELECT sum((3 = ANY(SELECT generate_series(1,4)))::int); + sum +----- + 1 +(1 row) + +SELECT sum((3 = ANY(SELECT lag(x) over(order by x) + FROM generate_series(1,4) x))::int); + sum +----- + 1 +(1 row) + -- SRFs are not allowed in window function arguments, either SELECT min(generate_series(1, 3)) OVER() FROM few; ERROR: window function calls cannot contain set-returning function calls diff --git a/src/test/regress/sql/tsrf.sql b/src/test/regress/sql/tsrf.sql index 0be7530beb4..ae1900bce12 100644 --- a/src/test/regress/sql/tsrf.sql +++ b/src/test/regress/sql/tsrf.sql @@ -61,6 +61,12 @@ SELECT q1, coalesce(generate_series(1,3), 0) FROM int8_tbl; -- SRFs are not allowed in aggregate arguments SELECT min(generate_series(1, 3)) FROM few; +-- ... unless they're within a sub-select +SELECT sum((3 = ANY(SELECT generate_series(1,4)))::int); + +SELECT sum((3 = ANY(SELECT lag(x) over(order by x) + FROM generate_series(1,4) x))::int); + -- SRFs are not allowed in window function arguments, either SELECT min(generate_series(1, 3)) OVER() FROM few; |