Fix oversight in CALL argument handling, and do some minor cleanup.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 10 Feb 2018 18:05:14 +0000 (13:05 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 10 Feb 2018 18:05:14 +0000 (13:05 -0500)
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

src/backend/commands/functioncmds.c
src/backend/parser/parse_agg.c
src/backend/parser/parse_clause.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_func.c
src/include/parser/parse_node.h
src/test/regress/expected/create_table.out

index a483714766df0cffa0c143af99828050d14f05d1..5d94c1ca27cfa63b8932df379eb64efce1fb040a 100644 (file)
@@ -2225,7 +2225,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
    {
        targs = lappend(targs, transformExpr(pstate,
                                             (Node *) lfirst(lc),
-                                            EXPR_KIND_CALL));
+                                            EXPR_KIND_CALL_ARGUMENT));
    }
 
    node = ParseFuncOrColumn(pstate,
index 747139489a0db743a3c3eff8db6cef18aa57f662..377a7ed6d0ae81ccd67732f2ea8d8e8dc0b6c2e7 100644 (file)
@@ -509,13 +509,13 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr)
            break;
        case EXPR_KIND_PARTITION_EXPRESSION:
            if (isAgg)
-               err = _("aggregate functions are not allowed in partition key expression");
+               err = _("aggregate functions are not allowed in partition key expressions");
            else
-               err = _("grouping operations are not allowed in partition key expression");
+               err = _("grouping operations are not allowed in partition key expressions");
 
            break;
 
-       case EXPR_KIND_CALL:
+       case EXPR_KIND_CALL_ARGUMENT:
            if (isAgg)
                err = _("aggregate functions are not allowed in CALL arguments");
            else
@@ -897,9 +897,9 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
            err = _("window functions are not allowed in trigger WHEN conditions");
            break;
        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;
-       case EXPR_KIND_CALL:
+       case EXPR_KIND_CALL_ARGUMENT:
            err = _("window functions are not allowed in CALL arguments");
            break;
 
index 9bafc24083b2a36d8da38aca52f88a55ed9686f9..3a02307bd996f12f54b1f743f55ac4e1b64b8c20 100644 (file)
@@ -3106,12 +3106,11 @@ resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
        }
 
        /*
-        * transformExpr() should have already rejected subqueries,
-        * aggregates, and window functions, based on the EXPR_KIND_ for an
-        * index expression.  Expressions returning sets won't have been
-        * rejected, but don't bother doing so here; there should be no
-        * available expression unique index to match any such expression
-        * against anyway.
+        * transformExpr() will reject subqueries, aggregates, window
+        * functions, and SRFs, based on being passed
+        * EXPR_KIND_INDEX_EXPRESSION.  So we needn't worry about those
+        * further ... not that they would match any available index
+        * expression anyway.
         */
        pInfer->expr = transformExpr(pstate, parse, EXPR_KIND_INDEX_EXPRESSION);
 
index d45926f27fd4f59cf05c96bb443460d386641735..385e54a9b69b5a7b37fabb7bb8ef13f0c4cf7549 100644 (file)
@@ -1818,7 +1818,6 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
        case EXPR_KIND_RETURNING:
        case EXPR_KIND_VALUES:
        case EXPR_KIND_VALUES_SINGLE:
-       case EXPR_KIND_CALL:
            /* okay */
            break;
        case EXPR_KIND_CHECK_CONSTRAINT:
@@ -1847,6 +1846,9 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
        case EXPR_KIND_PARTITION_EXPRESSION:
            err = _("cannot use subquery in partition key expression");
            break;
+       case EXPR_KIND_CALL_ARGUMENT:
+           err = _("cannot use subquery in CALL argument");
+           break;
 
            /*
             * There is intentionally no default: case here, so that the
@@ -3471,7 +3473,7 @@ ParseExprKindName(ParseExprKind exprKind)
            return "WHEN";
        case EXPR_KIND_PARTITION_EXPRESSION:
            return "PARTITION BY";
-       case EXPR_KIND_CALL:
+       case EXPR_KIND_CALL_ARGUMENT:
            return "CALL";
 
            /*
index 4a7bc77c0f74fc7d779e62df92d972739d380daa..2a4ac09d5c9444cded8bf54d4d9dea2aff65ce0d 100644 (file)
@@ -2290,7 +2290,7 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
        case EXPR_KIND_PARTITION_EXPRESSION:
            err = _("set-returning functions are not allowed in partition key expressions");
            break;
-       case EXPR_KIND_CALL:
+       case EXPR_KIND_CALL_ARGUMENT:
            err = _("set-returning functions are not allowed in CALL arguments");
            break;
 
index 2e0792d60b01625623f4f73646ec72fbbaf5fcac..0230543810f04752d0519fa17a06e0b6b5949576 100644 (file)
@@ -69,7 +69,7 @@ typedef enum ParseExprKind
    EXPR_KIND_TRIGGER_WHEN,     /* WHEN condition in CREATE TRIGGER */
    EXPR_KIND_POLICY,           /* USING or WITH CHECK expr in policy */
    EXPR_KIND_PARTITION_EXPRESSION, /* PARTITION BY expression */
-   EXPR_KIND_CALL              /* CALL argument */
+   EXPR_KIND_CALL_ARGUMENT     /* procedure argument in CALL */
 } ParseExprKind;
 
 
index f5e56365f58809a679f3d7550d55daeeef876153..bef5463bab5c4b6021fb189c45d70c1b385946cb 100644 (file)
@@ -325,12 +325,12 @@ DROP FUNCTION retset(int);
 CREATE TABLE partitioned (
    a int
 ) 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 (
    a int,
    b int
 ) 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 (
    a int
 ) PARTITION BY LIST ((a LIKE (SELECT 1)));