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