Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

-36
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

+27-82
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

+2-3
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

+1-2
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

+7-7
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

+1-2
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)