Skip to content

Commit 4971d2a

Browse files
committed
Remove the obsolete WITH clause of CREATE FUNCTION.
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
1 parent b0313f9 commit 4971d2a

File tree

6 files changed

+38
-132
lines changed

6 files changed

+38
-132
lines changed

doc/src/sgml/ref/create_function.sgml

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ CREATE [ OR REPLACE ] FUNCTION
3737
| AS '<replaceable class="parameter">definition</replaceable>'
3838
| AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
3939
} ...
40-
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
4140
</synopsis>
4241
</refsynopsisdiv>
4342

@@ -560,41 +559,6 @@ CREATE [ OR REPLACE ] FUNCTION
560559
</listitem>
561560
</varlistentry>
562561

563-
<varlistentry>
564-
<term><replaceable class="parameter">attribute</replaceable></term>
565-
566-
<listitem>
567-
<para>
568-
The historical way to specify optional pieces of information
569-
about the function. The following attributes can appear here:
570-
571-
<variablelist>
572-
<varlistentry>
573-
<term><literal>isStrict</literal></term>
574-
<listitem>
575-
<para>
576-
Equivalent to <literal>STRICT</literal> or <literal>RETURNS NULL ON NULL INPUT</literal>.
577-
</para>
578-
</listitem>
579-
</varlistentry>
580-
581-
<varlistentry>
582-
<term><literal>isCachable</literal></term>
583-
<listitem>
584-
<para><literal>isCachable</literal> is an obsolete equivalent of
585-
<literal>IMMUTABLE</literal>; it's still accepted for
586-
backwards-compatibility reasons.
587-
</para>
588-
</listitem>
589-
</varlistentry>
590-
591-
</variablelist>
592-
593-
Attribute names are not case-sensitive.
594-
</para>
595-
</listitem>
596-
</varlistentry>
597-
598562
</variablelist>
599563

600564
<para>

src/backend/commands/functioncmds.c

Lines changed: 27 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -637,21 +637,21 @@ update_proconfig_value(ArrayType *a, List *set_items)
637637
* attributes.
638638
*/
639639
static void
640-
compute_attributes_sql_style(ParseState *pstate,
641-
bool is_procedure,
642-
List *options,
643-
List **as,
644-
char **language,
645-
Node **transform,
646-
bool *windowfunc_p,
647-
char *volatility_p,
648-
bool *strict_p,
649-
bool *security_definer,
650-
bool *leakproof_p,
651-
ArrayType **proconfig,
652-
float4 *procost,
653-
float4 *prorows,
654-
char *parallel_p)
640+
compute_function_attributes(ParseState *pstate,
641+
bool is_procedure,
642+
List *options,
643+
List **as,
644+
char **language,
645+
Node **transform,
646+
bool *windowfunc_p,
647+
char *volatility_p,
648+
bool *strict_p,
649+
bool *security_definer,
650+
bool *leakproof_p,
651+
ArrayType **proconfig,
652+
float4 *procost,
653+
float4 *prorows,
654+
char *parallel_p)
655655
{
656656
ListCell *option;
657657
DefElem *as_item = NULL;
@@ -789,59 +789,6 @@ compute_attributes_sql_style(ParseState *pstate,
789789
}
790790

791791

792-
/*-------------
793-
* Interpret the parameters *parameters and return their contents via
794-
* *isStrict_p and *volatility_p.
795-
*
796-
* These parameters supply optional information about a function.
797-
* All have defaults if not specified. Parameters:
798-
*
799-
* * isStrict means the function should not be called when any NULL
800-
* inputs are present; instead a NULL result value should be assumed.
801-
*
802-
* * volatility tells the optimizer whether the function's result can
803-
* be assumed to be repeatable over multiple evaluations.
804-
*------------
805-
*/
806-
static void
807-
compute_attributes_with_style(ParseState *pstate, bool is_procedure, List *parameters, bool *isStrict_p, char *volatility_p)
808-
{
809-
ListCell *pl;
810-
811-
foreach(pl, parameters)
812-
{
813-
DefElem *param = (DefElem *) lfirst(pl);
814-
815-
if (pg_strcasecmp(param->defname, "isstrict") == 0)
816-
{
817-
if (is_procedure)
818-
ereport(ERROR,
819-
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
820-
errmsg("invalid attribute in procedure definition"),
821-
parser_errposition(pstate, param->location)));
822-
*isStrict_p = defGetBoolean(param);
823-
}
824-
else if (pg_strcasecmp(param->defname, "iscachable") == 0)
825-
{
826-
/* obsolete spelling of isImmutable */
827-
if (is_procedure)
828-
ereport(ERROR,
829-
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
830-
errmsg("invalid attribute in procedure definition"),
831-
parser_errposition(pstate, param->location)));
832-
if (defGetBoolean(param))
833-
*volatility_p = PROVOLATILE_IMMUTABLE;
834-
}
835-
else
836-
ereport(WARNING,
837-
(errcode(ERRCODE_SYNTAX_ERROR),
838-
errmsg("unrecognized function attribute \"%s\" ignored",
839-
param->defname),
840-
parser_errposition(pstate, param->location)));
841-
}
842-
}
843-
844-
845792
/*
846793
* For a dynamically linked C language object, the form of the clause is
847794
*
@@ -909,7 +856,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName,
909856

910857
/*
911858
* CreateFunction
912-
* Execute a CREATE FUNCTION utility statement.
859+
* Execute a CREATE FUNCTION (or CREATE PROCEDURE) utility statement.
913860
*/
914861
ObjectAddress
915862
CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
@@ -957,7 +904,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
957904
aclcheck_error(aclresult, OBJECT_SCHEMA,
958905
get_namespace_name(namespaceId));
959906

960-
/* default attributes */
907+
/* Set default attributes */
961908
isWindowFunc = false;
962909
isStrict = false;
963910
security = false;
@@ -968,14 +915,14 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
968915
prorows = -1; /* indicates not set */
969916
parallel = PROPARALLEL_UNSAFE;
970917

971-
/* override attributes from explicit list */
972-
compute_attributes_sql_style(pstate,
973-
stmt->is_procedure,
974-
stmt->options,
975-
&as_clause, &language, &transformDefElem,
976-
&isWindowFunc, &volatility,
977-
&isStrict, &security, &isLeakProof,
978-
&proconfig, &procost, &prorows, &parallel);
918+
/* Extract non-default attributes from stmt->options list */
919+
compute_function_attributes(pstate,
920+
stmt->is_procedure,
921+
stmt->options,
922+
&as_clause, &language, &transformDefElem,
923+
&isWindowFunc, &volatility,
924+
&isStrict, &security, &isLeakProof,
925+
&proconfig, &procost, &prorows, &parallel);
979926

980927
/* Look up the language and validate permissions */
981928
languageTuple = SearchSysCache1(LANGNAME, PointerGetDatum(language));
@@ -1107,8 +1054,6 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
11071054
trftypes = NULL;
11081055
}
11091056

1110-
compute_attributes_with_style(pstate, stmt->is_procedure, stmt->withClause, &isStrict, &volatility);
1111-
11121057
interpret_AS_clause(languageOid, language, funcname, as_clause,
11131058
&prosrc_str, &probin_str);
11141059

@@ -2269,7 +2214,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
22692214
FuncExpr *fexpr;
22702215
int nargs;
22712216
int i;
2272-
AclResult aclresult;
2217+
AclResult aclresult;
22732218
FmgrInfo flinfo;
22742219
FunctionCallInfoData fcinfo;
22752220
CallContext *callcontext;
@@ -2329,7 +2274,7 @@ ExecuteCallStmt(ParseState *pstate, CallStmt *stmt, bool atomic)
23292274
InitFunctionCallInfoData(fcinfo, &flinfo, nargs, fexpr->inputcollid, (Node *) callcontext, NULL);
23302275

23312276
i = 0;
2332-
foreach (lc, fexpr->args)
2277+
foreach(lc, fexpr->args)
23332278
{
23342279
EState *estate;
23352280
ExprState *exprstate;

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,7 +3217,7 @@ _copyClosePortalStmt(const ClosePortalStmt *from)
32173217
static CallStmt *
32183218
_copyCallStmt(const CallStmt *from)
32193219
{
3220-
CallStmt *newnode = makeNode(CallStmt);
3220+
CallStmt *newnode = makeNode(CallStmt);
32213221

32223222
COPY_NODE_FIELD(funccall);
32233223

@@ -3422,13 +3422,12 @@ _copyCreateFunctionStmt(const CreateFunctionStmt *from)
34223422
{
34233423
CreateFunctionStmt *newnode = makeNode(CreateFunctionStmt);
34243424

3425+
COPY_SCALAR_FIELD(is_procedure);
34253426
COPY_SCALAR_FIELD(replace);
34263427
COPY_NODE_FIELD(funcname);
34273428
COPY_NODE_FIELD(parameters);
34283429
COPY_NODE_FIELD(returnType);
3429-
COPY_SCALAR_FIELD(is_procedure);
34303430
COPY_NODE_FIELD(options);
3431-
COPY_NODE_FIELD(withClause);
34323431

34333432
return newnode;
34343433
}

src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,13 +1370,12 @@ _equalCreateStatsStmt(const CreateStatsStmt *a, const CreateStatsStmt *b)
13701370
static bool
13711371
_equalCreateFunctionStmt(const CreateFunctionStmt *a, const CreateFunctionStmt *b)
13721372
{
1373+
COMPARE_SCALAR_FIELD(is_procedure);
13731374
COMPARE_SCALAR_FIELD(replace);
13741375
COMPARE_NODE_FIELD(funcname);
13751376
COMPARE_NODE_FIELD(parameters);
13761377
COMPARE_NODE_FIELD(returnType);
1377-
COMPARE_SCALAR_FIELD(is_procedure);
13781378
COMPARE_NODE_FIELD(options);
1379-
COMPARE_NODE_FIELD(withClause);
13801379

13811380
return true;
13821381
}

src/backend/parser/gram.y

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7506,51 +7506,51 @@ opt_nulls_order: NULLS_LA FIRST_P { $$ = SORTBY_NULLS_FIRST; }
75067506

75077507
CreateFunctionStmt:
75087508
CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
7509-
RETURNS func_return createfunc_opt_list opt_definition
7509+
RETURNS func_return createfunc_opt_list
75107510
{
75117511
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
7512+
n->is_procedure = false;
75127513
n->replace = $2;
75137514
n->funcname = $4;
75147515
n->parameters = $5;
75157516
n->returnType = $7;
75167517
n->options = $8;
7517-
n->withClause = $9;
75187518
$$ = (Node *)n;
75197519
}
75207520
| CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
7521-
RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list opt_definition
7521+
RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list
75227522
{
75237523
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
7524+
n->is_procedure = false;
75247525
n->replace = $2;
75257526
n->funcname = $4;
75267527
n->parameters = mergeTableFuncParameters($5, $9);
75277528
n->returnType = TableFuncTypeName($9);
75287529
n->returnType->location = @7;
75297530
n->options = $11;
7530-
n->withClause = $12;
75317531
$$ = (Node *)n;
75327532
}
75337533
| CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
7534-
createfunc_opt_list opt_definition
7534+
createfunc_opt_list
75357535
{
75367536
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
7537+
n->is_procedure = false;
75377538
n->replace = $2;
75387539
n->funcname = $4;
75397540
n->parameters = $5;
75407541
n->returnType = NULL;
75417542
n->options = $6;
7542-
n->withClause = $7;
75437543
$$ = (Node *)n;
75447544
}
75457545
| CREATE opt_or_replace PROCEDURE func_name func_args_with_defaults
75467546
createfunc_opt_list
75477547
{
75487548
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
7549+
n->is_procedure = true;
75497550
n->replace = $2;
75507551
n->funcname = $4;
75517552
n->parameters = $5;
75527553
n->returnType = NULL;
7553-
n->is_procedure = true;
75547554
n->options = $6;
75557555
$$ = (Node *)n;
75567556
}

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,13 +2735,12 @@ typedef struct CreateStatsStmt
27352735
typedef struct CreateFunctionStmt
27362736
{
27372737
NodeTag type;
2738+
bool is_procedure; /* it's really CREATE PROCEDURE */
27382739
bool replace; /* T => replace if already exists */
27392740
List *funcname; /* qualified name of function to create */
27402741
List *parameters; /* a list of FunctionParameter */
27412742
TypeName *returnType; /* the return type */
2742-
bool is_procedure;
27432743
List *options; /* a list of DefElem */
2744-
List *withClause; /* a list of DefElem */
27452744
} CreateFunctionStmt;
27462745

27472746
typedef enum FunctionParameterMode

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy