Commit 94bdc485 authored by Peter Eisentraut's avatar Peter Eisentraut

Extend syntax of CREATE FUNCTION to resemble SQL99.

parent 97f7ceaa
This diff is collapsed.
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.135 2002/05/17 01:19:16 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.136 2002/05/17 18:32:52 petere Exp $
--> -->
<appendix id="release"> <appendix id="release">
...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without ...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters. worries about funny characters.
--> -->
<literallayout><![CDATA[ <literallayout><![CDATA[
Syntax of CREATE FUNCTION has been extended to resemble SQL99
Effects of SET within a transaction block now roll back if transaction aborts Effects of SET within a transaction block now roll back if transaction aborts
New SET LOCAL syntax sets a parameter for the life of the current transaction New SET LOCAL syntax sets a parameter for the life of the current transaction
Datestyle, timezone, client_encoding can be set in postgresql.conf Datestyle, timezone, client_encoding can be set in postgresql.conf
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.3 2002/04/27 03:45:01 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.4 2002/05/17 18:32:52 petere Exp $
* *
* DESCRIPTION * DESCRIPTION
* These routines take the parse tree and pick out the * These routines take the parse tree and pick out the
...@@ -159,6 +159,104 @@ compute_parameter_types(List *argTypes, Oid languageOid, ...@@ -159,6 +159,104 @@ compute_parameter_types(List *argTypes, Oid languageOid,
return parameterCount; return parameterCount;
} }
/*
* Dissect the list of options assembled in gram.y into function
* attributes.
*/
static void
compute_attributes_sql_style(const List *options,
List **as,
char **language,
char *volatility_p,
bool *strict_p,
bool *security_definer,
bool *implicit_cast)
{
const List *option;
DefElem *as_item = NULL;
DefElem *language_item = NULL;
DefElem *volatility_item = NULL;
DefElem *strict_item = NULL;
DefElem *security_item = NULL;
DefElem *implicit_item = NULL;
foreach(option, options)
{
DefElem *defel = (DefElem *) lfirst(option);
if (strcmp(defel->defname, "as")==0)
{
if (as_item)
elog(ERROR, "conflicting or redundant options");
as_item = defel;
}
else if (strcmp(defel->defname, "language")==0)
{
if (language_item)
elog(ERROR, "conflicting or redundant options");
language_item = defel;
}
else if (strcmp(defel->defname, "volatility")==0)
{
if (volatility_item)
elog(ERROR, "conflicting or redundant options");
volatility_item = defel;
}
else if (strcmp(defel->defname, "strict")==0)
{
if (strict_item)
elog(ERROR, "conflicting or redundant options");
strict_item = defel;
}
else if (strcmp(defel->defname, "security")==0)
{
if (security_item)
elog(ERROR, "conflicting or redundant options");
security_item = defel;
}
else if (strcmp(defel->defname, "implicit")==0)
{
if (implicit_item)
elog(ERROR, "conflicting or redundant options");
implicit_item = defel;
}
else
elog(ERROR, "invalid CREATE FUNCTION option");
}
if (as_item)
*as = (List *)as_item->arg;
else
elog(ERROR, "no function body specified");
if (language_item)
*language = strVal(language_item->arg);
else
elog(ERROR, "no language specified");
if (volatility_item)
{
if (strcmp(strVal(volatility_item->arg), "immutable")==0)
*volatility_p = PROVOLATILE_IMMUTABLE;
else if (strcmp(strVal(volatility_item->arg), "stable")==0)
*volatility_p = PROVOLATILE_STABLE;
else if (strcmp(strVal(volatility_item->arg), "volatile")==0)
*volatility_p = PROVOLATILE_VOLATILE;
else
elog(ERROR, "invalid volatility");
}
if (strict_item)
*strict_p = intVal(strict_item->arg);
if (security_item)
*security_definer = intVal(security_item->arg);
if (implicit_item)
*implicit_cast = intVal(implicit_item->arg);
}
/*------------- /*-------------
* Interpret the parameters *parameters and return their contents as * Interpret the parameters *parameters and return their contents as
* *byte_pct_p, etc. * *byte_pct_p, etc.
...@@ -183,23 +281,14 @@ compute_parameter_types(List *argTypes, Oid languageOid, ...@@ -183,23 +281,14 @@ compute_parameter_types(List *argTypes, Oid languageOid,
*------------ *------------
*/ */
static void static void
compute_full_attributes(List *parameters, compute_attributes_with_style(List *parameters,
int32 *byte_pct_p, int32 *perbyte_cpu_p, int32 *byte_pct_p, int32 *perbyte_cpu_p,
int32 *percall_cpu_p, int32 *outin_ratio_p, int32 *percall_cpu_p, int32 *outin_ratio_p,
bool *isImplicit_p, bool *isStrict_p, bool *isImplicit_p, bool *isStrict_p,
char *volatility_p) char *volatility_p)
{ {
List *pl; List *pl;
/* the defaults */
*byte_pct_p = BYTE_PCT;
*perbyte_cpu_p = PERBYTE_CPU;
*percall_cpu_p = PERCALL_CPU;
*outin_ratio_p = OUTIN_RATIO;
*isImplicit_p = false;
*isStrict_p = false;
*volatility_p = PROVOLATILE_VOLATILE;
foreach(pl, parameters) foreach(pl, parameters)
{ {
DefElem *param = (DefElem *) lfirst(pl); DefElem *param = (DefElem *) lfirst(pl);
...@@ -290,12 +379,13 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as, ...@@ -290,12 +379,13 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
* Execute a CREATE FUNCTION utility statement. * Execute a CREATE FUNCTION utility statement.
*/ */
void void
CreateFunction(ProcedureStmt *stmt) CreateFunction(CreateFunctionStmt *stmt)
{ {
char *probin_str; char *probin_str;
char *prosrc_str; char *prosrc_str;
Oid prorettype; Oid prorettype;
bool returnsSet; bool returnsSet;
char *language;
char languageName[NAMEDATALEN]; char languageName[NAMEDATALEN];
Oid languageOid; Oid languageOid;
char *funcname; char *funcname;
...@@ -308,10 +398,12 @@ CreateFunction(ProcedureStmt *stmt) ...@@ -308,10 +398,12 @@ CreateFunction(ProcedureStmt *stmt)
percall_cpu, percall_cpu,
outin_ratio; outin_ratio;
bool isImplicit, bool isImplicit,
isStrict; isStrict,
security;
char volatility; char volatility;
HeapTuple languageTuple; HeapTuple languageTuple;
Form_pg_language languageStruct; Form_pg_language languageStruct;
List *as_clause;
/* Convert list of names to a name and namespace */ /* Convert list of names to a name and namespace */
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname, namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
...@@ -322,8 +414,21 @@ CreateFunction(ProcedureStmt *stmt) ...@@ -322,8 +414,21 @@ CreateFunction(ProcedureStmt *stmt)
if (aclresult != ACLCHECK_OK) if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, get_namespace_name(namespaceId)); aclcheck_error(aclresult, get_namespace_name(namespaceId));
/* defaults attributes */
byte_pct = BYTE_PCT;
perbyte_cpu = PERBYTE_CPU;
percall_cpu = PERCALL_CPU;
outin_ratio = OUTIN_RATIO;
isImplicit = false;
isStrict = false;
volatility = PROVOLATILE_VOLATILE;
/* override attributes from explicit list */
compute_attributes_sql_style(stmt->options,
&as_clause, &language, &volatility, &isStrict, &security, &isImplicit);
/* Convert language name to canonical case */ /* Convert language name to canonical case */
case_translate_language_name(stmt->language, languageName); case_translate_language_name(language, languageName);
/* Look up the language and validate permissions */ /* Look up the language and validate permissions */
languageTuple = SearchSysCache(LANGNAME, languageTuple = SearchSysCache(LANGNAME,
...@@ -363,12 +468,12 @@ CreateFunction(ProcedureStmt *stmt) ...@@ -363,12 +468,12 @@ CreateFunction(ProcedureStmt *stmt)
parameterCount = compute_parameter_types(stmt->argTypes, languageOid, parameterCount = compute_parameter_types(stmt->argTypes, languageOid,
parameterTypes); parameterTypes);
compute_full_attributes(stmt->withClause, compute_attributes_with_style(stmt->withClause,
&byte_pct, &perbyte_cpu, &percall_cpu, &byte_pct, &perbyte_cpu, &percall_cpu,
&outin_ratio, &isImplicit, &isStrict, &outin_ratio, &isImplicit, &isStrict,
&volatility); &volatility);
interpret_AS_clause(languageOid, languageName, stmt->as, interpret_AS_clause(languageOid, languageName, as_clause,
&prosrc_str, &probin_str); &prosrc_str, &probin_str);
/* /*
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.186 2002/05/17 01:19:17 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.187 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2098,18 +2098,17 @@ _copyIndexStmt(IndexStmt *from) ...@@ -2098,18 +2098,17 @@ _copyIndexStmt(IndexStmt *from)
return newnode; return newnode;
} }
static ProcedureStmt * static CreateFunctionStmt *
_copyProcedureStmt(ProcedureStmt *from) _copyCreateFunctionStmt(CreateFunctionStmt *from)
{ {
ProcedureStmt *newnode = makeNode(ProcedureStmt); CreateFunctionStmt *newnode = makeNode(CreateFunctionStmt);
newnode->replace = from->replace; newnode->replace = from->replace;
Node_Copy(from, newnode, funcname); Node_Copy(from, newnode, funcname);
Node_Copy(from, newnode, argTypes); Node_Copy(from, newnode, argTypes);
Node_Copy(from, newnode, returnType); Node_Copy(from, newnode, returnType);
Node_Copy(from, newnode, options);
Node_Copy(from, newnode, withClause); Node_Copy(from, newnode, withClause);
Node_Copy(from, newnode, as);
newnode->language = pstrdup(from->language);
return newnode; return newnode;
} }
...@@ -2865,8 +2864,8 @@ copyObject(void *from) ...@@ -2865,8 +2864,8 @@ copyObject(void *from)
case T_IndexStmt: case T_IndexStmt:
retval = _copyIndexStmt(from); retval = _copyIndexStmt(from);
break; break;
case T_ProcedureStmt: case T_CreateFunctionStmt:
retval = _copyProcedureStmt(from); retval = _copyCreateFunctionStmt(from);
break; break;
case T_RemoveAggrStmt: case T_RemoveAggrStmt:
retval = _copyRemoveAggrStmt(from); retval = _copyRemoveAggrStmt(from);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.133 2002/05/17 01:19:17 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.134 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -923,7 +923,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b) ...@@ -923,7 +923,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
} }
static bool static bool
_equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b) _equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
{ {
if (a->replace != b->replace) if (a->replace != b->replace)
return false; return false;
...@@ -933,11 +933,9 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b) ...@@ -933,11 +933,9 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
return false; return false;
if (!equal(a->returnType, b->returnType)) if (!equal(a->returnType, b->returnType))
return false; return false;
if (!equal(a->withClause, b->withClause)) if (!equal(a->options, b->options))
return false;
if (!equal(a->as, b->as))
return false; return false;
if (!equalstr(a->language, b->language)) if (!equal(a->withClause, b->withClause))
return false; return false;
return true; return true;
...@@ -2020,8 +2018,8 @@ equal(void *a, void *b) ...@@ -2020,8 +2018,8 @@ equal(void *a, void *b)
case T_IndexStmt: case T_IndexStmt:
retval = _equalIndexStmt(a, b); retval = _equalIndexStmt(a, b);
break; break;
case T_ProcedureStmt: case T_CreateFunctionStmt:
retval = _equalProcedureStmt(a, b); retval = _equalCreateFunctionStmt(a, b);
break; break;
case T_RemoveAggrStmt: case T_RemoveAggrStmt:
retval = _equalRemoveAggrStmt(a, b); retval = _equalRemoveAggrStmt(a, b);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.316 2002/05/17 01:19:17 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.317 2002/05/17 18:32:52 petere Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -141,7 +141,7 @@ static void doNegateFloat(Value *v); ...@@ -141,7 +141,7 @@ static void doNegateFloat(Value *v);
DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropAssertStmt, DropTrigStmt, DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropAssertStmt, DropTrigStmt,
DropRuleStmt, DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt, DropRuleStmt, DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt, GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt, NotifyStmt, OptimizableStmt, CreateFunctionStmt, ReindexStmt,
RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt, RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,
RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty, RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty,
RuleStmt, SelectStmt, TransactionStmt, TruncateStmt, RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
...@@ -201,7 +201,7 @@ static void doNegateFloat(Value *v); ...@@ -201,7 +201,7 @@ static void doNegateFloat(Value *v);
%type <list> stmtblock, stmtmulti, %type <list> stmtblock, stmtmulti,
OptTableElementList, OptInherit, definition, opt_distinct, OptTableElementList, OptInherit, definition, opt_distinct,
opt_with, func_args, func_args_list, func_as, opt_with, func_args, func_args_list, func_as, createfunc_opt_list
oper_argtypes, RuleActionList, RuleActionMulti, oper_argtypes, RuleActionList, RuleActionMulti,
opt_column_list, columnList, opt_name_list, opt_column_list, columnList, opt_name_list,
sort_clause, sortby_list, index_params, index_list, name_list, sort_clause, sortby_list, index_params, index_list, name_list,
...@@ -214,6 +214,7 @@ static void doNegateFloat(Value *v); ...@@ -214,6 +214,7 @@ static void doNegateFloat(Value *v);
%type <range> into_clause, OptTempTableName %type <range> into_clause, OptTempTableName
%type <defelt> createfunc_opt_item
%type <typnam> func_arg, func_return, func_type, aggr_argtype %type <typnam> func_arg, func_return, func_type, aggr_argtype
%type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids %type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids
...@@ -388,6 +389,9 @@ static void doNegateFloat(Value *v); ...@@ -388,6 +389,9 @@ static void doNegateFloat(Value *v);
TEMP, TEMPLATE, TOAST, TRUNCATE, TRUSTED, TEMP, TEMPLATE, TOAST, TRUNCATE, TRUSTED,
UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
%token <keyword> CALLED, DEFINER, EXTERNAL, IMMUTABLE, IMPLICIT, INPUT,
INVOKER, SECURITY, STABLE, STRICT, VOLATILE
/* The grammar thinks these are keywords, but they are not in the keywords.c /* The grammar thinks these are keywords, but they are not in the keywords.c
* list and so can never be entered directly. The filter in parser.c * list and so can never be entered directly. The filter in parser.c
* creates these tokens when required. * creates these tokens when required.
...@@ -467,6 +471,7 @@ stmt : AlterDatabaseSetStmt ...@@ -467,6 +471,7 @@ stmt : AlterDatabaseSetStmt
| CreateStmt | CreateStmt
| CreateAsStmt | CreateAsStmt
| CreateDomainStmt | CreateDomainStmt
| CreateFunctionStmt
| CreateSchemaStmt | CreateSchemaStmt
| CreateGroupStmt | CreateGroupStmt
| CreateSeqStmt | CreateSeqStmt
...@@ -494,7 +499,6 @@ stmt : AlterDatabaseSetStmt ...@@ -494,7 +499,6 @@ stmt : AlterDatabaseSetStmt
| UnlistenStmt | UnlistenStmt
| LockStmt | LockStmt
| NotifyStmt | NotifyStmt
| ProcedureStmt
| ReindexStmt | ReindexStmt
| RemoveAggrStmt | RemoveAggrStmt
| RemoveOperStmt | RemoveOperStmt
...@@ -2769,17 +2773,16 @@ RecipeStmt: EXECUTE RECIPE recipe_name ...@@ -2769,17 +2773,16 @@ RecipeStmt: EXECUTE RECIPE recipe_name
* *
*****************************************************************************/ *****************************************************************************/
ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args CreateFunctionStmt: CREATE opt_or_replace FUNCTION func_name func_args
RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with RETURNS func_return createfunc_opt_list opt_with
{ {
ProcedureStmt *n = makeNode(ProcedureStmt); CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
n->replace = $2; n->replace = $2;
n->funcname = $4; n->funcname = $4;
n->argTypes = $5; n->argTypes = $5;
n->returnType = $7; n->returnType = $7;
n->withClause = $12; n->options = $8;
n->as = $9; n->withClause = $9;
n->language = $11;
$$ = (Node *)n; $$ = (Node *)n;
}; };
...@@ -2787,10 +2790,6 @@ opt_or_replace: OR REPLACE { $$ = TRUE; } ...@@ -2787,10 +2790,6 @@ opt_or_replace: OR REPLACE { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; }
; ;
opt_with: WITH definition { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
func_args: '(' func_args_list ')' { $$ = $2; } func_args: '(' func_args_list ')' { $$ = $2; }
| '(' ')' { $$ = NIL; } | '(' ')' { $$ = NIL; }
; ;
...@@ -2831,12 +2830,6 @@ opt_arg: IN ...@@ -2831,12 +2830,6 @@ opt_arg: IN
} }
; ;
func_as: Sconst
{ $$ = makeList1(makeString($1)); }
| Sconst ',' Sconst
{ $$ = makeList2(makeString($1), makeString($3)); }
;
func_return: func_type func_return: func_type
{ {
/* We can catch over-specified arguments here if we want to, /* We can catch over-specified arguments here if we want to,
...@@ -2864,6 +2857,104 @@ func_type: Typename ...@@ -2864,6 +2857,104 @@ func_type: Typename
} }
; ;
createfunc_opt_list: createfunc_opt_item
{ $$ = makeList1($1); }
| createfunc_opt_list createfunc_opt_item
{ $$ = lappend($1, $2); }
;
createfunc_opt_item: AS func_as
{
$$ = makeNode(DefElem);
$$->defname = "as";
$$->arg = (Node *)$2;
}
| LANGUAGE ColId_or_Sconst
{
$$ = makeNode(DefElem);
$$->defname = "language";
$$->arg = (Node *)makeString($2);
}
| IMMUTABLE
{
$$ = makeNode(DefElem);
$$->defname = "volatility";
$$->arg = (Node *)makeString("immutable");
}
| STABLE
{
$$ = makeNode(DefElem);
$$->defname = "volatility";
$$->arg = (Node *)makeString("stable");
}
| VOLATILE
{
$$ = makeNode(DefElem);
$$->defname = "volatility";
$$->arg = (Node *)makeString("volatile");
}
| CALLED ON NULL_P INPUT
{
$$ = makeNode(DefElem);
$$->defname = "strict";
$$->arg = (Node *)makeInteger(FALSE);
}
| RETURNS NULL_P ON NULL_P INPUT
{
$$ = makeNode(DefElem);
$$->defname = "strict";
$$->arg = (Node *)makeInteger(TRUE);
}
| STRICT
{
$$ = makeNode(DefElem);
$$->defname = "strict";
$$->arg = (Node *)makeInteger(TRUE);
}
| EXTERNAL SECURITY DEFINER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(TRUE);
}
| EXTERNAL SECURITY INVOKER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(FALSE);
}
| SECURITY DEFINER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(TRUE);
}
| SECURITY INVOKER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(FALSE);
}
| IMPLICIT CAST
{
$$ = makeNode(DefElem);
$$->defname = "implicit";
$$->arg = (Node *)makeInteger(TRUE);
}
;
func_as: Sconst
{ $$ = makeList1(makeString($1)); }
| Sconst ',' Sconst
{ $$ = makeList2(makeString($1), makeString($3)); }
;
opt_with: WITH definition { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
/***************************************************************************** /*****************************************************************************
* *
* QUERY: * QUERY:
...@@ -6137,6 +6228,7 @@ unreserved_keyword: ...@@ -6137,6 +6228,7 @@ unreserved_keyword:
| BEGIN_TRANS | BEGIN_TRANS
| BY | BY
| CACHE | CACHE
| CALLED
| CASCADE | CASCADE
| CHAIN | CHAIN
| CHARACTERISTICS | CHARACTERISTICS
...@@ -6156,6 +6248,7 @@ unreserved_keyword: ...@@ -6156,6 +6248,7 @@ unreserved_keyword:
| DAY_P | DAY_P
| DECLARE | DECLARE
| DEFERRED | DEFERRED
| DEFINER
| DELETE | DELETE
| DELIMITERS | DELIMITERS
| DOMAIN_P | DOMAIN_P
...@@ -6168,6 +6261,7 @@ unreserved_keyword: ...@@ -6168,6 +6261,7 @@ unreserved_keyword:
| EXCLUSIVE | EXCLUSIVE
| EXECUTE | EXECUTE
| EXPLAIN | EXPLAIN
| EXTERNAL
| FETCH | FETCH
| FORCE | FORCE
| FORWARD | FORWARD
...@@ -6176,13 +6270,17 @@ unreserved_keyword: ...@@ -6176,13 +6270,17 @@ unreserved_keyword:
| HANDLER | HANDLER
| HOUR_P | HOUR_P
| IMMEDIATE | IMMEDIATE
| IMMUTABLE
| IMPLICIT
| INCREMENT | INCREMENT
| INDEX | INDEX
| INHERITS | INHERITS
| INOUT | INOUT
| INPUT
| INSENSITIVE | INSENSITIVE
| INSERT | INSERT
| INSTEAD | INSTEAD
| INVOKER
| ISOLATION | ISOLATION
| KEY | KEY
| LANGUAGE | LANGUAGE
...@@ -6238,18 +6336,21 @@ unreserved_keyword: ...@@ -6238,18 +6336,21 @@ unreserved_keyword:
| SCHEMA | SCHEMA
| SCROLL | SCROLL
| SECOND_P | SECOND_P
| SECURITY
| SESSION | SESSION
| SEQUENCE | SEQUENCE
| SERIALIZABLE | SERIALIZABLE
| SET | SET
| SHARE | SHARE
| SHOW | SHOW
| STABLE
| START | START
| STATEMENT | STATEMENT
| STATISTICS | STATISTICS
| STDIN | STDIN
| STDOUT | STDOUT
| STORAGE | STORAGE
| STRICT
| SYSID | SYSID
| TEMP | TEMP
| TEMPLATE | TEMPLATE
...@@ -6272,6 +6373,7 @@ unreserved_keyword: ...@@ -6272,6 +6373,7 @@ unreserved_keyword:
| VARYING | VARYING
| VERSION | VERSION
| VIEW | VIEW
| VOLATILE
| WITH | WITH
| WITHOUT | WITHOUT
| WORK | WORK
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.109 2002/05/03 00:32:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.110 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -57,6 +57,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -57,6 +57,7 @@ static const ScanKeyword ScanKeywords[] = {
{"both", BOTH}, {"both", BOTH},
{"by", BY}, {"by", BY},
{"cache", CACHE}, {"cache", CACHE},
{"called", CALLED},
{"cascade", CASCADE}, {"cascade", CASCADE},
{"case", CASE}, {"case", CASE},
{"cast", CAST}, {"cast", CAST},
...@@ -95,6 +96,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -95,6 +96,7 @@ static const ScanKeyword ScanKeywords[] = {
{"default", DEFAULT}, {"default", DEFAULT},
{"deferrable", DEFERRABLE}, {"deferrable", DEFERRABLE},
{"deferred", DEFERRED}, {"deferred", DEFERRED},
{"definer", DEFINER},
{"delete", DELETE}, {"delete", DELETE},
{"delimiters", DELIMITERS}, {"delimiters", DELIMITERS},
{"desc", DESC}, {"desc", DESC},
...@@ -114,6 +116,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -114,6 +116,7 @@ static const ScanKeyword ScanKeywords[] = {
{"execute", EXECUTE}, {"execute", EXECUTE},
{"exists", EXISTS}, {"exists", EXISTS},
{"explain", EXPLAIN}, {"explain", EXPLAIN},
{"external", EXTERNAL},
{"extract", EXTRACT}, {"extract", EXTRACT},
{"false", FALSE_P}, {"false", FALSE_P},
{"fetch", FETCH}, {"fetch", FETCH},
...@@ -134,6 +137,8 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -134,6 +137,8 @@ static const ScanKeyword ScanKeywords[] = {
{"hour", HOUR_P}, {"hour", HOUR_P},
{"ilike", ILIKE}, {"ilike", ILIKE},
{"immediate", IMMEDIATE}, {"immediate", IMMEDIATE},
{"immutable", IMMUTABLE},
{"implicit", IMPLICIT},
{"in", IN}, {"in", IN},
{"increment", INCREMENT}, {"increment", INCREMENT},
{"index", INDEX}, {"index", INDEX},
...@@ -141,6 +146,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -141,6 +146,7 @@ static const ScanKeyword ScanKeywords[] = {
{"initially", INITIALLY}, {"initially", INITIALLY},
{"inner", INNER_P}, {"inner", INNER_P},
{"inout", INOUT}, {"inout", INOUT},
{"input", INPUT},
{"insensitive", INSENSITIVE}, {"insensitive", INSENSITIVE},
{"insert", INSERT}, {"insert", INSERT},
{"instead", INSTEAD}, {"instead", INSTEAD},
...@@ -149,6 +155,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -149,6 +155,7 @@ static const ScanKeyword ScanKeywords[] = {
{"intersect", INTERSECT}, {"intersect", INTERSECT},
{"interval", INTERVAL}, {"interval", INTERVAL},
{"into", INTO}, {"into", INTO},
{"invoker", INVOKER},
{"is", IS}, {"is", IS},
{"isnull", ISNULL}, {"isnull", ISNULL},
{"isolation", ISOLATION}, {"isolation", ISOLATION},
...@@ -234,6 +241,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -234,6 +241,7 @@ static const ScanKeyword ScanKeywords[] = {
{"schema", SCHEMA}, {"schema", SCHEMA},
{"scroll", SCROLL}, {"scroll", SCROLL},
{"second", SECOND_P}, {"second", SECOND_P},
{"security", SECURITY},
{"select", SELECT}, {"select", SELECT},
{"sequence", SEQUENCE}, {"sequence", SEQUENCE},
{"serializable", SERIALIZABLE}, {"serializable", SERIALIZABLE},
...@@ -245,12 +253,14 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -245,12 +253,14 @@ static const ScanKeyword ScanKeywords[] = {
{"show", SHOW}, {"show", SHOW},
{"smallint", SMALLINT}, {"smallint", SMALLINT},
{"some", SOME}, {"some", SOME},
{"stable", STABLE},
{"start", START}, {"start", START},
{"statement", STATEMENT}, {"statement", STATEMENT},
{"statistics", STATISTICS}, {"statistics", STATISTICS},
{"stdin", STDIN}, {"stdin", STDIN},
{"stdout", STDOUT}, {"stdout", STDOUT},
{"storage", STORAGE}, {"storage", STORAGE},
{"strict", STRICT},
{"substring", SUBSTRING}, {"substring", SUBSTRING},
{"sysid", SYSID}, {"sysid", SYSID},
{"table", TABLE}, {"table", TABLE},
...@@ -288,6 +298,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -288,6 +298,7 @@ static const ScanKeyword ScanKeywords[] = {
{"verbose", VERBOSE}, {"verbose", VERBOSE},
{"version", VERSION}, {"version", VERSION},
{"view", VIEW}, {"view", VIEW},
{"volatile", VOLATILE},
{"when", WHEN}, {"when", WHEN},
{"where", WHERE}, {"where", WHERE},
{"with", WITH}, {"with", WITH},
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.265 2002/05/17 01:19:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.266 2002/05/17 18:32:52 petere Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -1688,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -1688,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.265 $ $Date: 2002/05/17 01:19:18 $\n"); puts("$Revision: 1.266 $ $Date: 2002/05/17 18:32:52 $\n");
} }
/* /*
...@@ -2229,7 +2229,7 @@ CreateCommandTag(Node *parsetree) ...@@ -2229,7 +2229,7 @@ CreateCommandTag(Node *parsetree)
tag = "CREATE"; tag = "CREATE";
break; break;
case T_ProcedureStmt: /* CREATE FUNCTION */ case T_CreateFunctionStmt: /* CREATE FUNCTION */
tag = "CREATE"; tag = "CREATE";
break; break;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.154 2002/05/17 01:19:18 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.155 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -574,8 +574,8 @@ ProcessUtility(Node *parsetree, ...@@ -574,8 +574,8 @@ ProcessUtility(Node *parsetree,
} }
break; break;
case T_ProcedureStmt: /* CREATE FUNCTION */ case T_CreateFunctionStmt: /* CREATE FUNCTION */
CreateFunction((ProcedureStmt *) parsetree); CreateFunction((CreateFunctionStmt *) parsetree);
break; break;
case T_IndexStmt: /* CREATE INDEX */ case T_IndexStmt: /* CREATE INDEX */
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.260 2002/05/13 17:45:30 tgl Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.261 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -3152,18 +3152,14 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs) ...@@ -3152,18 +3152,14 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
(*deps)[depIdx++] = strdup(lanplcallfoid); (*deps)[depIdx++] = strdup(lanplcallfoid);
appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE "); appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n", fmtId(lanname, force_quotes));
formatStringLiteral(delqry, lanname, CONV_ALL);
appendPQExpBuffer(delqry, ";\n");
appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE ", appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
(PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ? (PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ?
"TRUSTED " : ""); "TRUSTED " : "",
formatStringLiteral(defqry, lanname, CONV_ALL); fmtId(lanname, force_quotes));
appendPQExpBuffer(defqry, " HANDLER %s LANCOMPILER ", appendPQExpBuffer(defqry, " HANDLER %s;\n",
fmtId(finfo[fidx].proname, force_quotes)); fmtId(finfo[fidx].proname, force_quotes));
formatStringLiteral(defqry, lancompiler, CONV_ALL);
appendPQExpBuffer(defqry, ";\n");
(*deps)[depIdx++] = NULL; /* End of List */ (*deps)[depIdx++] = NULL; /* End of List */
...@@ -3221,9 +3217,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo) ...@@ -3221,9 +3217,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
char *proimplicit; char *proimplicit;
char *proisstrict; char *proisstrict;
char *lanname; char *lanname;
char *listSep;
char *listSepComma = ",";
char *listSepNone = "";
char *rettypename; char *rettypename;
if (finfo->dumped) if (finfo->dumped)
...@@ -3337,52 +3330,33 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo) ...@@ -3337,52 +3330,33 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque); rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque);
appendPQExpBuffer(q, "CREATE FUNCTION %s ", fn->data); appendPQExpBuffer(q, "CREATE FUNCTION %s ", fn->data);
appendPQExpBuffer(q, "RETURNS %s%s %s LANGUAGE ", appendPQExpBuffer(q, "RETURNS %s%s %s LANGUAGE %s",
(proretset[0] == 't') ? "SETOF " : "", (proretset[0] == 't') ? "SETOF " : "",
rettypename, rettypename,
asPart->data); asPart->data,
formatStringLiteral(q, lanname, CONV_ALL); fmtId(lanname, force_quotes));
free(rettypename); free(rettypename);
if (provolatile[0] != PROVOLATILE_VOLATILE || if (provolatile[0] != PROVOLATILE_VOLATILE)
proimplicit[0] == 't' ||
proisstrict[0] == 't') /* OR in new attrs here */
{ {
appendPQExpBuffer(q, " WITH (");
listSep = listSepNone;
if (provolatile[0] == PROVOLATILE_IMMUTABLE) if (provolatile[0] == PROVOLATILE_IMMUTABLE)
{ appendPQExpBuffer(q, " IMMUTABLE");
appendPQExpBuffer(q, "%s isImmutable", listSep);
listSep = listSepComma;
}
else if (provolatile[0] == PROVOLATILE_STABLE) else if (provolatile[0] == PROVOLATILE_STABLE)
{ appendPQExpBuffer(q, " STABLE");
appendPQExpBuffer(q, "%s isStable", listSep);
listSep = listSepComma;
}
else if (provolatile[0] != PROVOLATILE_VOLATILE) else if (provolatile[0] != PROVOLATILE_VOLATILE)
{ {
write_msg(NULL, "Unexpected provolatile value for function %s\n", write_msg(NULL, "Unexpected provolatile value for function %s\n",
finfo->proname); finfo->proname);
exit_nicely(); exit_nicely();
} }
}
if (proimplicit[0] == 't') if (proimplicit[0] == 't')
{ appendPQExpBuffer(q, " IMPLICIT CAST");
appendPQExpBuffer(q, "%s implicitCoercion", listSep);
listSep = listSepComma;
}
if (proisstrict[0] == 't') if (proisstrict[0] == 't')
{ appendPQExpBuffer(q, " STRICT");
appendPQExpBuffer(q, "%s isStrict", listSep);
listSep = listSepComma;
}
appendPQExpBuffer(q, " )");
}
appendPQExpBuffer(q, ";\n"); appendPQExpBuffer(q, ";\n");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: defrem.h,v 1.36 2002/04/16 23:08:12 tgl Exp $ * $Id: defrem.h,v 1.37 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -38,7 +38,7 @@ extern void ReindexDatabase(const char *databaseName, bool force, bool all); ...@@ -38,7 +38,7 @@ extern void ReindexDatabase(const char *databaseName, bool force, bool all);
* DefineFoo and RemoveFoo are now both in foocmds.c * DefineFoo and RemoveFoo are now both in foocmds.c
*/ */
extern void CreateFunction(ProcedureStmt *stmt); extern void CreateFunction(CreateFunctionStmt *stmt);
extern void RemoveFunction(List *functionName, List *argTypes); extern void RemoveFunction(List *functionName, List *argTypes);
extern void DefineOperator(List *names, List *parameters); extern void DefineOperator(List *names, List *parameters);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: nodes.h,v 1.107 2002/05/12 23:43:04 tgl Exp $ * $Id: nodes.h,v 1.108 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -160,7 +160,7 @@ typedef enum NodeTag ...@@ -160,7 +160,7 @@ typedef enum NodeTag
T_CommentStmt, T_CommentStmt,
T_FetchStmt, T_FetchStmt,
T_IndexStmt, T_IndexStmt,
T_ProcedureStmt, T_CreateFunctionStmt,
T_RemoveAggrStmt, T_RemoveAggrStmt,
T_RemoveFuncStmt, T_RemoveFuncStmt,
T_RemoveOperStmt, T_RemoveOperStmt,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.177 2002/05/17 01:19:19 tgl Exp $ * $Id: parsenodes.h,v 1.178 2002/05/17 18:32:52 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1200,17 +1200,16 @@ typedef struct IndexStmt ...@@ -1200,17 +1200,16 @@ typedef struct IndexStmt
* Create Function Statement * Create Function Statement
* ---------------------- * ----------------------
*/ */
typedef struct ProcedureStmt typedef struct CreateFunctionStmt
{ {
NodeTag type; NodeTag type;
bool replace; /* T => replace if already exists */ bool replace; /* T => replace if already exists */
List *funcname; /* qualified name of function to create */ List *funcname; /* qualified name of function to create */
List *argTypes; /* list of argument types (TypeName nodes) */ List *argTypes; /* list of argument types (TypeName nodes) */
TypeName *returnType; /* the return type */ TypeName *returnType; /* the return type */
List *options; /* a list of DefElem */
List *withClause; /* a list of DefElem */ List *withClause; /* a list of DefElem */
List *as; /* definition of function body */ } CreateFunctionStmt;
char *language; /* C, SQL, etc */
} ProcedureStmt;
/* ---------------------- /* ----------------------
* Drop Aggregate Statement * Drop Aggregate Statement
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment