Skip to content

Commit 94bdc48

Browse files
committed
Extend syntax of CREATE FUNCTION to resemble SQL99.
1 parent 97f7cea commit 94bdc48

File tree

13 files changed

+504
-271
lines changed

13 files changed

+504
-271
lines changed

doc/src/sgml/ref/create_function.sgml

Lines changed: 196 additions & 152 deletions
Large diffs are not rendered by default.

doc/src/sgml/release.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.135 2002/05/17 01:19:16 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.136 2002/05/17 18:32:52 petere Exp $
33
-->
44

55
<appendix id="release">
@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
2424
worries about funny characters.
2525
-->
2626
<literallayout><![CDATA[
27+
Syntax of CREATE FUNCTION has been extended to resemble SQL99
2728
Effects of SET within a transaction block now roll back if transaction aborts
2829
New SET LOCAL syntax sets a parameter for the life of the current transaction
2930
Datestyle, timezone, client_encoding can be set in postgresql.conf

src/backend/commands/functioncmds.c

Lines changed: 128 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.3 2002/04/27 03:45:01 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.4 2002/05/17 18:32:52 petere Exp $
1313
*
1414
* DESCRIPTION
1515
* These routines take the parse tree and pick out the
@@ -159,6 +159,104 @@ compute_parameter_types(List *argTypes, Oid languageOid,
159159
return parameterCount;
160160
}
161161

162+
163+
/*
164+
* Dissect the list of options assembled in gram.y into function
165+
* attributes.
166+
*/
167+
168+
static void
169+
compute_attributes_sql_style(const List *options,
170+
List **as,
171+
char **language,
172+
char *volatility_p,
173+
bool *strict_p,
174+
bool *security_definer,
175+
bool *implicit_cast)
176+
{
177+
const List *option;
178+
DefElem *as_item = NULL;
179+
DefElem *language_item = NULL;
180+
DefElem *volatility_item = NULL;
181+
DefElem *strict_item = NULL;
182+
DefElem *security_item = NULL;
183+
DefElem *implicit_item = NULL;
184+
185+
foreach(option, options)
186+
{
187+
DefElem *defel = (DefElem *) lfirst(option);
188+
189+
if (strcmp(defel->defname, "as")==0)
190+
{
191+
if (as_item)
192+
elog(ERROR, "conflicting or redundant options");
193+
as_item = defel;
194+
}
195+
else if (strcmp(defel->defname, "language")==0)
196+
{
197+
if (language_item)
198+
elog(ERROR, "conflicting or redundant options");
199+
language_item = defel;
200+
}
201+
else if (strcmp(defel->defname, "volatility")==0)
202+
{
203+
if (volatility_item)
204+
elog(ERROR, "conflicting or redundant options");
205+
volatility_item = defel;
206+
}
207+
else if (strcmp(defel->defname, "strict")==0)
208+
{
209+
if (strict_item)
210+
elog(ERROR, "conflicting or redundant options");
211+
strict_item = defel;
212+
}
213+
else if (strcmp(defel->defname, "security")==0)
214+
{
215+
if (security_item)
216+
elog(ERROR, "conflicting or redundant options");
217+
security_item = defel;
218+
}
219+
else if (strcmp(defel->defname, "implicit")==0)
220+
{
221+
if (implicit_item)
222+
elog(ERROR, "conflicting or redundant options");
223+
implicit_item = defel;
224+
}
225+
else
226+
elog(ERROR, "invalid CREATE FUNCTION option");
227+
}
228+
229+
if (as_item)
230+
*as = (List *)as_item->arg;
231+
else
232+
elog(ERROR, "no function body specified");
233+
234+
if (language_item)
235+
*language = strVal(language_item->arg);
236+
else
237+
elog(ERROR, "no language specified");
238+
239+
if (volatility_item)
240+
{
241+
if (strcmp(strVal(volatility_item->arg), "immutable")==0)
242+
*volatility_p = PROVOLATILE_IMMUTABLE;
243+
else if (strcmp(strVal(volatility_item->arg), "stable")==0)
244+
*volatility_p = PROVOLATILE_STABLE;
245+
else if (strcmp(strVal(volatility_item->arg), "volatile")==0)
246+
*volatility_p = PROVOLATILE_VOLATILE;
247+
else
248+
elog(ERROR, "invalid volatility");
249+
}
250+
251+
if (strict_item)
252+
*strict_p = intVal(strict_item->arg);
253+
if (security_item)
254+
*security_definer = intVal(security_item->arg);
255+
if (implicit_item)
256+
*implicit_cast = intVal(implicit_item->arg);
257+
}
258+
259+
162260
/*-------------
163261
* Interpret the parameters *parameters and return their contents as
164262
* *byte_pct_p, etc.
@@ -183,23 +281,14 @@ compute_parameter_types(List *argTypes, Oid languageOid,
183281
*------------
184282
*/
185283
static void
186-
compute_full_attributes(List *parameters,
187-
int32 *byte_pct_p, int32 *perbyte_cpu_p,
188-
int32 *percall_cpu_p, int32 *outin_ratio_p,
189-
bool *isImplicit_p, bool *isStrict_p,
190-
char *volatility_p)
284+
compute_attributes_with_style(List *parameters,
285+
int32 *byte_pct_p, int32 *perbyte_cpu_p,
286+
int32 *percall_cpu_p, int32 *outin_ratio_p,
287+
bool *isImplicit_p, bool *isStrict_p,
288+
char *volatility_p)
191289
{
192290
List *pl;
193291

194-
/* the defaults */
195-
*byte_pct_p = BYTE_PCT;
196-
*perbyte_cpu_p = PERBYTE_CPU;
197-
*percall_cpu_p = PERCALL_CPU;
198-
*outin_ratio_p = OUTIN_RATIO;
199-
*isImplicit_p = false;
200-
*isStrict_p = false;
201-
*volatility_p = PROVOLATILE_VOLATILE;
202-
203292
foreach(pl, parameters)
204293
{
205294
DefElem *param = (DefElem *) lfirst(pl);
@@ -290,12 +379,13 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
290379
* Execute a CREATE FUNCTION utility statement.
291380
*/
292381
void
293-
CreateFunction(ProcedureStmt *stmt)
382+
CreateFunction(CreateFunctionStmt *stmt)
294383
{
295384
char *probin_str;
296385
char *prosrc_str;
297386
Oid prorettype;
298387
bool returnsSet;
388+
char *language;
299389
char languageName[NAMEDATALEN];
300390
Oid languageOid;
301391
char *funcname;
@@ -308,10 +398,12 @@ CreateFunction(ProcedureStmt *stmt)
308398
percall_cpu,
309399
outin_ratio;
310400
bool isImplicit,
311-
isStrict;
401+
isStrict,
402+
security;
312403
char volatility;
313404
HeapTuple languageTuple;
314405
Form_pg_language languageStruct;
406+
List *as_clause;
315407

316408
/* Convert list of names to a name and namespace */
317409
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
@@ -322,8 +414,21 @@ CreateFunction(ProcedureStmt *stmt)
322414
if (aclresult != ACLCHECK_OK)
323415
aclcheck_error(aclresult, get_namespace_name(namespaceId));
324416

417+
/* defaults attributes */
418+
byte_pct = BYTE_PCT;
419+
perbyte_cpu = PERBYTE_CPU;
420+
percall_cpu = PERCALL_CPU;
421+
outin_ratio = OUTIN_RATIO;
422+
isImplicit = false;
423+
isStrict = false;
424+
volatility = PROVOLATILE_VOLATILE;
425+
426+
/* override attributes from explicit list */
427+
compute_attributes_sql_style(stmt->options,
428+
&as_clause, &language, &volatility, &isStrict, &security, &isImplicit);
429+
325430
/* Convert language name to canonical case */
326-
case_translate_language_name(stmt->language, languageName);
431+
case_translate_language_name(language, languageName);
327432

328433
/* Look up the language and validate permissions */
329434
languageTuple = SearchSysCache(LANGNAME,
@@ -363,12 +468,12 @@ CreateFunction(ProcedureStmt *stmt)
363468
parameterCount = compute_parameter_types(stmt->argTypes, languageOid,
364469
parameterTypes);
365470

366-
compute_full_attributes(stmt->withClause,
367-
&byte_pct, &perbyte_cpu, &percall_cpu,
368-
&outin_ratio, &isImplicit, &isStrict,
369-
&volatility);
471+
compute_attributes_with_style(stmt->withClause,
472+
&byte_pct, &perbyte_cpu, &percall_cpu,
473+
&outin_ratio, &isImplicit, &isStrict,
474+
&volatility);
370475

371-
interpret_AS_clause(languageOid, languageName, stmt->as,
476+
interpret_AS_clause(languageOid, languageName, as_clause,
372477
&prosrc_str, &probin_str);
373478

374479
/*

src/backend/nodes/copyfuncs.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.186 2002/05/17 01:19:17 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.187 2002/05/17 18:32:52 petere Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -2098,18 +2098,17 @@ _copyIndexStmt(IndexStmt *from)
20982098
return newnode;
20992099
}
21002100

2101-
static ProcedureStmt *
2102-
_copyProcedureStmt(ProcedureStmt *from)
2101+
static CreateFunctionStmt *
2102+
_copyCreateFunctionStmt(CreateFunctionStmt *from)
21032103
{
2104-
ProcedureStmt *newnode = makeNode(ProcedureStmt);
2104+
CreateFunctionStmt *newnode = makeNode(CreateFunctionStmt);
21052105

21062106
newnode->replace = from->replace;
21072107
Node_Copy(from, newnode, funcname);
21082108
Node_Copy(from, newnode, argTypes);
21092109
Node_Copy(from, newnode, returnType);
2110+
Node_Copy(from, newnode, options);
21102111
Node_Copy(from, newnode, withClause);
2111-
Node_Copy(from, newnode, as);
2112-
newnode->language = pstrdup(from->language);
21132112

21142113
return newnode;
21152114
}
@@ -2865,8 +2864,8 @@ copyObject(void *from)
28652864
case T_IndexStmt:
28662865
retval = _copyIndexStmt(from);
28672866
break;
2868-
case T_ProcedureStmt:
2869-
retval = _copyProcedureStmt(from);
2867+
case T_CreateFunctionStmt:
2868+
retval = _copyCreateFunctionStmt(from);
28702869
break;
28712870
case T_RemoveAggrStmt:
28722871
retval = _copyRemoveAggrStmt(from);

src/backend/nodes/equalfuncs.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
2222
* IDENTIFICATION
23-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.133 2002/05/17 01:19:17 tgl Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.134 2002/05/17 18:32:52 petere Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -923,7 +923,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
923923
}
924924

925925
static bool
926-
_equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
926+
_equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
927927
{
928928
if (a->replace != b->replace)
929929
return false;
@@ -933,11 +933,9 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
933933
return false;
934934
if (!equal(a->returnType, b->returnType))
935935
return false;
936-
if (!equal(a->withClause, b->withClause))
937-
return false;
938-
if (!equal(a->as, b->as))
936+
if (!equal(a->options, b->options))
939937
return false;
940-
if (!equalstr(a->language, b->language))
938+
if (!equal(a->withClause, b->withClause))
941939
return false;
942940

943941
return true;
@@ -2020,8 +2018,8 @@ equal(void *a, void *b)
20202018
case T_IndexStmt:
20212019
retval = _equalIndexStmt(a, b);
20222020
break;
2023-
case T_ProcedureStmt:
2024-
retval = _equalProcedureStmt(a, b);
2021+
case T_CreateFunctionStmt:
2022+
retval = _equalCreateFunctionStmt(a, b);
20252023
break;
20262024
case T_RemoveAggrStmt:
20272025
retval = _equalRemoveAggrStmt(a, b);

0 commit comments

Comments
 (0)