]> granicus.if.org Git - postgresql/commitdiff
Remove the obsolete WITH clause of CREATE FUNCTION.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 26 Jan 2018 17:25:44 +0000 (12:25 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 26 Jan 2018 17:25:44 +0000 (12:25 -0500)
This clause was superseded by SQL-standard syntax back in 7.3.
We've kept it around for backwards-compatibility purposes ever since;
but 15 years seems like long enough for that, especially seeing that
there are undocumented weirdnesses in how it interacts with the
SQL-standard syntax for specifying the same options.

Michael Paquier, per an observation by Daniel Gustafsson;
some small cosmetic adjustments to nearby code by me.

Discussion: https://postgr.es/m/20180115022748.GB1724@paquier.xyz

doc/src/sgml/ref/create_function.sgml
src/backend/commands/functioncmds.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/include/nodes/parsenodes.h

index fd229d1193733194c9c1191be7b3faad5dfb0e9c..c0adb8cf1e63427958c608ffcc3f1f0e23376b39 100644 (file)
@@ -37,7 +37,6 @@ CREATE [ OR REPLACE ] FUNCTION
     | AS '<replaceable class="parameter">definition</replaceable>'
     | AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
   } ...
-    [ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -560,41 +559,6 @@ CREATE [ OR REPLACE ] FUNCTION
      </listitem>
     </varlistentry>
 
-    <varlistentry>
-     <term><replaceable class="parameter">attribute</replaceable></term>
-
-     <listitem>
-      <para>
-       The historical way to specify optional pieces of information
-       about the function.  The following attributes can appear here:
-
-      <variablelist>
-       <varlistentry>
-        <term><literal>isStrict</literal></term>
-        <listitem>
-         <para>
-          Equivalent to <literal>STRICT</literal> or <literal>RETURNS NULL ON NULL INPUT</literal>.
-         </para>
-        </listitem>
-       </varlistentry>
-
-       <varlistentry>
-        <term><literal>isCachable</literal></term>
-        <listitem>
-         <para><literal>isCachable</literal> is an obsolete equivalent of
-          <literal>IMMUTABLE</literal>; it's still accepted for
-          backwards-compatibility reasons.
-         </para>
-        </listitem>
-       </varlistentry>
-
-      </variablelist>
-
-      Attribute names are not case-sensitive.
-     </para>
-    </listitem>
-   </varlistentry>
-
    </variablelist>
 
    <para>
index df87dfeb5433f4198c300087acc626ee2b913420..a483714766df0cffa0c143af99828050d14f05d1 100644 (file)
@@ -637,21 +637,21 @@ update_proconfig_value(ArrayType *a, List *set_items)
  * attributes.
  */
 static void
-compute_attributes_sql_style(ParseState *pstate,
-                                                        bool is_procedure,
-                                                        List *options,
-                                                        List **as,
-                                                        char **language,
-                                                        Node **transform,
-                                                        bool *windowfunc_p,
-                                                        char *volatility_p,
-                                                        bool *strict_p,
-                                                        bool *security_definer,
-                                                        bool *leakproof_p,
-                                                        ArrayType **proconfig,
-                                                        float4 *procost,
-                                                        float4 *prorows,
-                                                        char *parallel_p)
+compute_function_attributes(ParseState *pstate,
+                                                       bool is_procedure,
+                                                       List *options,
+                                                       List **as,
+                                                       char **language,
+                                                       Node **transform,
+                                                       bool *windowfunc_p,
+                                                       char *volatility_p,
+                                                       bool *strict_p,
+                                                       bool *security_definer,
+                                                       bool *leakproof_p,
+                                                       ArrayType **proconfig,
+                                                       float4 *procost,
+                                                       float4 *prorows,
+                                                       char *parallel_p)
 {
        ListCell   *option;
        DefElem    *as_item = NULL;
@@ -789,59 +789,6 @@ compute_attributes_sql_style(ParseState *pstate,
 }
 
 
-/*-------------
- *      Interpret the parameters *parameters and return their contents via
- *      *isStrict_p and *volatility_p.
- *
- *     These parameters supply optional information about a function.
- *     All have defaults if not specified. Parameters:
- *
- *      * isStrict means the function should not be called when any NULL
- *        inputs are present; instead a NULL result value should be assumed.
- *
- *      * volatility tells the optimizer whether the function's result can
- *        be assumed to be repeatable over multiple evaluations.
- *------------
- */
-static void
-compute_attributes_with_style(ParseState *pstate, bool is_procedure, List *parameters, bool *isStrict_p, char *volatility_p)
-{
-       ListCell   *pl;
-
-       foreach(pl, parameters)
-       {
-               DefElem    *param = (DefElem *) lfirst(pl);
-
-               if (pg_strcasecmp(param->defname, "isstrict") == 0)
-               {
-                       if (is_procedure)
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-                                                errmsg("invalid attribute in procedure definition"),
-                                                parser_errposition(pstate, param->location)));
-                       *isStrict_p = defGetBoolean(param);
-               }
-               else if (pg_strcasecmp(param->defname, "iscachable") == 0)
-               {
-                       /* obsolete spelling of isImmutable */
-                       if (is_procedure)
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
-                                                errmsg("invalid attribute in procedure definition"),
-                                                parser_errposition(pstate, param->location)));
-                       if (defGetBoolean(param))
-                               *volatility_p = PROVOLATILE_IMMUTABLE;
-               }
-               else
-                       ereport(WARNING,
-                                       (errcode(ERRCODE_SYNTAX_ERROR),
-                                        errmsg("unrecognized function attribute \"%s\" ignored",
-                                                       param->defname),
-                                        parser_errposition(pstate, param->location)));
-       }
-}
-
-
 /*
  * For a dynamically linked C language object, the form of the clause is
  *
@@ -909,7 +856,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName,
 
 /*
  * CreateFunction
- *      Execute a CREATE FUNCTION utility statement.
+ *      Execute a CREATE FUNCTION (or CREATE PROCEDURE) utility statement.
  */
 ObjectAddress
 CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
@@ -957,7 +904,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
                aclcheck_error(aclresult, OBJECT_SCHEMA,
                                           get_namespace_name(namespaceId));
 
-       /* default attributes */
+       /* Set default attributes */
        isWindowFunc = false;
        isStrict = false;
        security = false;
@@ -968,14 +915,14 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
        prorows = -1;                           /* indicates not set */
        parallel = PROPARALLEL_UNSAFE;
 
-       /* override attributes from explicit list */
-       compute_attributes_sql_style(pstate,
-                                                                stmt->is_procedure,
-                                                                stmt->options,
-                                                                &as_clause, &language, &transformDefElem,
-                                                                &isWindowFunc, &volatility,
-                                                                &isStrict, &security, &isLeakProof,
-                                                                &proconfig, &procost, &prorows, &parallel);
+       /* Extract non-default attributes from stmt->options list */
+       compute_function_attributes(pstate,
+                                                               stmt->is_procedure,
+                                                               stmt->options,
+                                                               &as_clause, &language, &transformDefElem,
+                                                               &isWindowFunc, &volatility,
+                                                               &isStrict, &security, &isLeakProof,
+                                                               &proconfig, &procost, &prorows, &parallel);
 
        /* Look up the language and validate permissions */
        languageTuple = SearchSysCache1(LANGNAME, PointerGetDatum(language));
@@ -1107,8 +1054,6 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
                trftypes = NULL;
        }
 
-       compute_attributes_with_style(pstate, stmt->is_procedure, stmt->withClause, &isStrict, &volatility);
-
        interpret_AS_clause(languageOid, language, funcname, as_clause,
                                                &prosrc_str, &probin_str);
 
@@ -2269,7 +2214,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
        FuncExpr   *fexpr;
        int                     nargs;
        int                     i;
-       AclResult   aclresult;
+       AclResult       aclresult;
        FmgrInfo        flinfo;
        FunctionCallInfoData fcinfo;
        CallContext *callcontext;
@@ -2329,7 +2274,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
        InitFunctionCallInfoData(fcinfo, &flinfo, nargs, fexpr->inputcollid, (Node *) callcontext, NULL);
 
        i = 0;
-       foreach (lc, fexpr->args)
+       foreach(lc, fexpr->args)
        {
                EState     *estate;
                ExprState  *exprstate;
index e5d2de533061048bc49c31e71ca4f80b4aeddc2f..fd3001c4934d44016cd616edf9257b3c499e85fa 100644 (file)
@@ -3217,7 +3217,7 @@ _copyClosePortalStmt(const ClosePortalStmt *from)
 static CallStmt *
 _copyCallStmt(const CallStmt *from)
 {
-       CallStmt *newnode = makeNode(CallStmt);
+       CallStmt   *newnode = makeNode(CallStmt);
 
        COPY_NODE_FIELD(funccall);
 
@@ -3422,13 +3422,12 @@ _copyCreateFunctionStmt(const CreateFunctionStmt *from)
 {
        CreateFunctionStmt *newnode = makeNode(CreateFunctionStmt);
 
+       COPY_SCALAR_FIELD(is_procedure);
        COPY_SCALAR_FIELD(replace);
        COPY_NODE_FIELD(funcname);
        COPY_NODE_FIELD(parameters);
        COPY_NODE_FIELD(returnType);
-       COPY_SCALAR_FIELD(is_procedure);
        COPY_NODE_FIELD(options);
-       COPY_NODE_FIELD(withClause);
 
        return newnode;
 }
index 785dc54d375cfe9c315baedf04a2f6c1a37bef3b..7d2aa1a2d3a4f945ca40d45fce211a94e2c792c5 100644 (file)
@@ -1370,13 +1370,12 @@ _equalCreateStatsStmt(const CreateStatsStmt *a, const CreateStatsStmt *b)
 static bool
 _equalCreateFunctionStmt(const CreateFunctionStmt *a, const CreateFunctionStmt *b)
 {
+       COMPARE_SCALAR_FIELD(is_procedure);
        COMPARE_SCALAR_FIELD(replace);
        COMPARE_NODE_FIELD(funcname);
        COMPARE_NODE_FIELD(parameters);
        COMPARE_NODE_FIELD(returnType);
-       COMPARE_SCALAR_FIELD(is_procedure);
        COMPARE_NODE_FIELD(options);
-       COMPARE_NODE_FIELD(withClause);
 
        return true;
 }
index 459a227e576d7ce008f8794e5a04f2da27d28e3b..5329432f25cba2d8e2b356b2222366777a5ae76d 100644 (file)
@@ -7506,51 +7506,51 @@ opt_nulls_order: NULLS_LA FIRST_P                       { $$ = SORTBY_NULLS_FIRST; }
 
 CreateFunctionStmt:
                        CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
-                       RETURNS func_return createfunc_opt_list opt_definition
+                       RETURNS func_return createfunc_opt_list
                                {
                                        CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
+                                       n->is_procedure = false;
                                        n->replace = $2;
                                        n->funcname = $4;
                                        n->parameters = $5;
                                        n->returnType = $7;
                                        n->options = $8;
-                                       n->withClause = $9;
                                        $$ = (Node *)n;
                                }
                        | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
-                         RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list opt_definition
+                         RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list
                                {
                                        CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
+                                       n->is_procedure = false;
                                        n->replace = $2;
                                        n->funcname = $4;
                                        n->parameters = mergeTableFuncParameters($5, $9);
                                        n->returnType = TableFuncTypeName($9);
                                        n->returnType->location = @7;
                                        n->options = $11;
-                                       n->withClause = $12;
                                        $$ = (Node *)n;
                                }
                        | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
-                         createfunc_opt_list opt_definition
+                         createfunc_opt_list
                                {
                                        CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
+                                       n->is_procedure = false;
                                        n->replace = $2;
                                        n->funcname = $4;
                                        n->parameters = $5;
                                        n->returnType = NULL;
                                        n->options = $6;
-                                       n->withClause = $7;
                                        $$ = (Node *)n;
                                }
                        | CREATE opt_or_replace PROCEDURE func_name func_args_with_defaults
                          createfunc_opt_list
                                {
                                        CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
+                                       n->is_procedure = true;
                                        n->replace = $2;
                                        n->funcname = $4;
                                        n->parameters = $5;
                                        n->returnType = NULL;
-                                       n->is_procedure = true;
                                        n->options = $6;
                                        $$ = (Node *)n;
                                }
index bbacbe144c88eb631b4bbb0417b938d440a5abc6..76a73b2a377634d98de3ca05f9dfff5d17ca7d64 100644 (file)
@@ -2735,13 +2735,12 @@ typedef struct CreateStatsStmt
 typedef struct CreateFunctionStmt
 {
        NodeTag         type;
+       bool            is_procedure;   /* it's really CREATE PROCEDURE */
        bool            replace;                /* T => replace if already exists */
        List       *funcname;           /* qualified name of function to create */
        List       *parameters;         /* a list of FunctionParameter */
        TypeName   *returnType;         /* the return type */
-       bool            is_procedure;
        List       *options;            /* a list of DefElem */
-       List       *withClause;         /* a list of DefElem */
 } CreateFunctionStmt;
 
 typedef enum FunctionParameterMode