Commit 65b1d767 authored by Tom Lane's avatar Tom Lane

Fix oversight in CALL argument handling, and do some minor cleanup.

CALL statements cannot support sub-SELECTs in the arguments of the called
procedure, since they just use ExecEvalExpr to evaluate such arguments.
Teach transformSubLink() to reject the case, as it already does for other
contexts in which subqueries are not supported.

In passing, s/EXPR_KIND_CALL/EXPR_KIND_CALL_ARGUMENT/ to make that enum
symbol line up more closely with the phrasing of the error messages it is
associated with.  And fix someone's weak grasp of English grammar in the
preceding EXPR_KIND_PARTITION_EXPRESSION addition.  Also update an
incorrect comment in resolve_unique_index_expr (possibly it was correct
when written, but nowadays transformExpr definitely does reject SRFs here).

Per report from Pavel Stehule --- but this resolves only one of the bugs
he mentions.

Discussion: https://postgr.es/m/CAFj8pRDxOwPPzpA8i+AQeDQFj7bhVw-dR2==rfWZ3zMGkm568Q@mail.gmail.com
parent fad15f4a
...@@ -2225,7 +2225,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic) ...@@ -2225,7 +2225,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
{ {
targs = lappend(targs, transformExpr(pstate, targs = lappend(targs, transformExpr(pstate,
(Node *) lfirst(lc), (Node *) lfirst(lc),
EXPR_KIND_CALL)); EXPR_KIND_CALL_ARGUMENT));
} }
node = ParseFuncOrColumn(pstate, node = ParseFuncOrColumn(pstate,
......
...@@ -509,13 +509,13 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr) ...@@ -509,13 +509,13 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr)
break; break;
case EXPR_KIND_PARTITION_EXPRESSION: case EXPR_KIND_PARTITION_EXPRESSION:
if (isAgg) if (isAgg)
err = _("aggregate functions are not allowed in partition key expression"); err = _("aggregate functions are not allowed in partition key expressions");
else else
err = _("grouping operations are not allowed in partition key expression"); err = _("grouping operations are not allowed in partition key expressions");
break; break;
case EXPR_KIND_CALL: case EXPR_KIND_CALL_ARGUMENT:
if (isAgg) if (isAgg)
err = _("aggregate functions are not allowed in CALL arguments"); err = _("aggregate functions are not allowed in CALL arguments");
else else
...@@ -897,9 +897,9 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, ...@@ -897,9 +897,9 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
err = _("window functions are not allowed in trigger WHEN conditions"); err = _("window functions are not allowed in trigger WHEN conditions");
break; break;
case EXPR_KIND_PARTITION_EXPRESSION: case EXPR_KIND_PARTITION_EXPRESSION:
err = _("window functions are not allowed in partition key expression"); err = _("window functions are not allowed in partition key expressions");
break; break;
case EXPR_KIND_CALL: case EXPR_KIND_CALL_ARGUMENT:
err = _("window functions are not allowed in CALL arguments"); err = _("window functions are not allowed in CALL arguments");
break; break;
......
...@@ -3106,12 +3106,11 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer, ...@@ -3106,12 +3106,11 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
} }
/* /*
* transformExpr() should have already rejected subqueries, * transformExpr() will reject subqueries, aggregates, window
* aggregates, and window functions, based on the EXPR_KIND_ for an * functions, and SRFs, based on being passed
* index expression. Expressions returning sets won't have been * EXPR_KIND_INDEX_EXPRESSION. So we needn't worry about those
* rejected, but don't bother doing so here; there should be no * further ... not that they would match any available index
* available expression unique index to match any such expression * expression anyway.
* against anyway.
*/ */
pInfer->expr = transformExpr(pstate, parse, EXPR_KIND_INDEX_EXPRESSION); pInfer->expr = transformExpr(pstate, parse, EXPR_KIND_INDEX_EXPRESSION);
......
...@@ -1818,7 +1818,6 @@ transformSubLink(ParseState *pstate, SubLink *sublink) ...@@ -1818,7 +1818,6 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
case EXPR_KIND_RETURNING: case EXPR_KIND_RETURNING:
case EXPR_KIND_VALUES: case EXPR_KIND_VALUES:
case EXPR_KIND_VALUES_SINGLE: case EXPR_KIND_VALUES_SINGLE:
case EXPR_KIND_CALL:
/* okay */ /* okay */
break; break;
case EXPR_KIND_CHECK_CONSTRAINT: case EXPR_KIND_CHECK_CONSTRAINT:
...@@ -1847,6 +1846,9 @@ transformSubLink(ParseState *pstate, SubLink *sublink) ...@@ -1847,6 +1846,9 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
case EXPR_KIND_PARTITION_EXPRESSION: case EXPR_KIND_PARTITION_EXPRESSION:
err = _("cannot use subquery in partition key expression"); err = _("cannot use subquery in partition key expression");
break; break;
case EXPR_KIND_CALL_ARGUMENT:
err = _("cannot use subquery in CALL argument");
break;
/* /*
* There is intentionally no default: case here, so that the * There is intentionally no default: case here, so that the
...@@ -3471,7 +3473,7 @@ ParseExprKindName(ParseExprKind exprKind) ...@@ -3471,7 +3473,7 @@ ParseExprKindName(ParseExprKind exprKind)
return "WHEN"; return "WHEN";
case EXPR_KIND_PARTITION_EXPRESSION: case EXPR_KIND_PARTITION_EXPRESSION:
return "PARTITION BY"; return "PARTITION BY";
case EXPR_KIND_CALL: case EXPR_KIND_CALL_ARGUMENT:
return "CALL"; return "CALL";
/* /*
......
...@@ -2290,7 +2290,7 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location) ...@@ -2290,7 +2290,7 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
case EXPR_KIND_PARTITION_EXPRESSION: case EXPR_KIND_PARTITION_EXPRESSION:
err = _("set-returning functions are not allowed in partition key expressions"); err = _("set-returning functions are not allowed in partition key expressions");
break; break;
case EXPR_KIND_CALL: case EXPR_KIND_CALL_ARGUMENT:
err = _("set-returning functions are not allowed in CALL arguments"); err = _("set-returning functions are not allowed in CALL arguments");
break; break;
......
...@@ -69,7 +69,7 @@ typedef enum ParseExprKind ...@@ -69,7 +69,7 @@ typedef enum ParseExprKind
EXPR_KIND_TRIGGER_WHEN, /* WHEN condition in CREATE TRIGGER */ EXPR_KIND_TRIGGER_WHEN, /* WHEN condition in CREATE TRIGGER */
EXPR_KIND_POLICY, /* USING or WITH CHECK expr in policy */ EXPR_KIND_POLICY, /* USING or WITH CHECK expr in policy */
EXPR_KIND_PARTITION_EXPRESSION, /* PARTITION BY expression */ EXPR_KIND_PARTITION_EXPRESSION, /* PARTITION BY expression */
EXPR_KIND_CALL /* CALL argument */ EXPR_KIND_CALL_ARGUMENT /* procedure argument in CALL */
} ParseExprKind; } ParseExprKind;
......
...@@ -325,12 +325,12 @@ DROP FUNCTION retset(int); ...@@ -325,12 +325,12 @@ DROP FUNCTION retset(int);
CREATE TABLE partitioned ( CREATE TABLE partitioned (
a int a int
) PARTITION BY RANGE ((avg(a))); ) PARTITION BY RANGE ((avg(a)));
ERROR: aggregate functions are not allowed in partition key expression ERROR: aggregate functions are not allowed in partition key expressions
CREATE TABLE partitioned ( CREATE TABLE partitioned (
a int, a int,
b int b int
) PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b))); ) PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b)));
ERROR: window functions are not allowed in partition key expression ERROR: window functions are not allowed in partition key expressions
CREATE TABLE partitioned ( CREATE TABLE partitioned (
a int a int
) PARTITION BY LIST ((a LIKE (SELECT 1))); ) PARTITION BY LIST ((a LIKE (SELECT 1)));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment