mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Extend syntax of CREATE FUNCTION to resemble SQL99.
This commit is contained in:
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* These routines take the parse tree and pick out the
|
||||
@ -159,6 +159,104 @@ compute_parameter_types(List *argTypes, Oid languageOid,
|
||||
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
|
||||
* *byte_pct_p, etc.
|
||||
@ -183,23 +281,14 @@ compute_parameter_types(List *argTypes, Oid languageOid,
|
||||
*------------
|
||||
*/
|
||||
static void
|
||||
compute_full_attributes(List *parameters,
|
||||
int32 *byte_pct_p, int32 *perbyte_cpu_p,
|
||||
int32 *percall_cpu_p, int32 *outin_ratio_p,
|
||||
bool *isImplicit_p, bool *isStrict_p,
|
||||
char *volatility_p)
|
||||
compute_attributes_with_style(List *parameters,
|
||||
int32 *byte_pct_p, int32 *perbyte_cpu_p,
|
||||
int32 *percall_cpu_p, int32 *outin_ratio_p,
|
||||
bool *isImplicit_p, bool *isStrict_p,
|
||||
char *volatility_p)
|
||||
{
|
||||
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)
|
||||
{
|
||||
DefElem *param = (DefElem *) lfirst(pl);
|
||||
@ -290,12 +379,13 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
|
||||
* Execute a CREATE FUNCTION utility statement.
|
||||
*/
|
||||
void
|
||||
CreateFunction(ProcedureStmt *stmt)
|
||||
CreateFunction(CreateFunctionStmt *stmt)
|
||||
{
|
||||
char *probin_str;
|
||||
char *prosrc_str;
|
||||
Oid prorettype;
|
||||
bool returnsSet;
|
||||
char *language;
|
||||
char languageName[NAMEDATALEN];
|
||||
Oid languageOid;
|
||||
char *funcname;
|
||||
@ -308,10 +398,12 @@ CreateFunction(ProcedureStmt *stmt)
|
||||
percall_cpu,
|
||||
outin_ratio;
|
||||
bool isImplicit,
|
||||
isStrict;
|
||||
isStrict,
|
||||
security;
|
||||
char volatility;
|
||||
HeapTuple languageTuple;
|
||||
Form_pg_language languageStruct;
|
||||
List *as_clause;
|
||||
|
||||
/* Convert list of names to a name and namespace */
|
||||
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
|
||||
@ -322,8 +414,21 @@ CreateFunction(ProcedureStmt *stmt)
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
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 */
|
||||
case_translate_language_name(stmt->language, languageName);
|
||||
case_translate_language_name(language, languageName);
|
||||
|
||||
/* Look up the language and validate permissions */
|
||||
languageTuple = SearchSysCache(LANGNAME,
|
||||
@ -363,12 +468,12 @@ CreateFunction(ProcedureStmt *stmt)
|
||||
parameterCount = compute_parameter_types(stmt->argTypes, languageOid,
|
||||
parameterTypes);
|
||||
|
||||
compute_full_attributes(stmt->withClause,
|
||||
&byte_pct, &perbyte_cpu, &percall_cpu,
|
||||
&outin_ratio, &isImplicit, &isStrict,
|
||||
&volatility);
|
||||
compute_attributes_with_style(stmt->withClause,
|
||||
&byte_pct, &perbyte_cpu, &percall_cpu,
|
||||
&outin_ratio, &isImplicit, &isStrict,
|
||||
&volatility);
|
||||
|
||||
interpret_AS_clause(languageOid, languageName, stmt->as,
|
||||
interpret_AS_clause(languageOid, languageName, as_clause,
|
||||
&prosrc_str, &probin_str);
|
||||
|
||||
/*
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static ProcedureStmt *
|
||||
_copyProcedureStmt(ProcedureStmt *from)
|
||||
static CreateFunctionStmt *
|
||||
_copyCreateFunctionStmt(CreateFunctionStmt *from)
|
||||
{
|
||||
ProcedureStmt *newnode = makeNode(ProcedureStmt);
|
||||
CreateFunctionStmt *newnode = makeNode(CreateFunctionStmt);
|
||||
|
||||
newnode->replace = from->replace;
|
||||
Node_Copy(from, newnode, funcname);
|
||||
Node_Copy(from, newnode, argTypes);
|
||||
Node_Copy(from, newnode, returnType);
|
||||
Node_Copy(from, newnode, options);
|
||||
Node_Copy(from, newnode, withClause);
|
||||
Node_Copy(from, newnode, as);
|
||||
newnode->language = pstrdup(from->language);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@ -2865,8 +2864,8 @@ copyObject(void *from)
|
||||
case T_IndexStmt:
|
||||
retval = _copyIndexStmt(from);
|
||||
break;
|
||||
case T_ProcedureStmt:
|
||||
retval = _copyProcedureStmt(from);
|
||||
case T_CreateFunctionStmt:
|
||||
retval = _copyCreateFunctionStmt(from);
|
||||
break;
|
||||
case T_RemoveAggrStmt:
|
||||
retval = _copyRemoveAggrStmt(from);
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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)
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
|
||||
_equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
|
||||
{
|
||||
if (a->replace != b->replace)
|
||||
return false;
|
||||
@ -933,12 +933,10 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
|
||||
return false;
|
||||
if (!equal(a->returnType, b->returnType))
|
||||
return false;
|
||||
if (!equal(a->options, b->options))
|
||||
return false;
|
||||
if (!equal(a->withClause, b->withClause))
|
||||
return false;
|
||||
if (!equal(a->as, b->as))
|
||||
return false;
|
||||
if (!equalstr(a->language, b->language))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2020,8 +2018,8 @@ equal(void *a, void *b)
|
||||
case T_IndexStmt:
|
||||
retval = _equalIndexStmt(a, b);
|
||||
break;
|
||||
case T_ProcedureStmt:
|
||||
retval = _equalProcedureStmt(a, b);
|
||||
case T_CreateFunctionStmt:
|
||||
retval = _equalCreateFunctionStmt(a, b);
|
||||
break;
|
||||
case T_RemoveAggrStmt:
|
||||
retval = _equalRemoveAggrStmt(a, b);
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -141,7 +141,7 @@ static void doNegateFloat(Value *v);
|
||||
DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropAssertStmt, DropTrigStmt,
|
||||
DropRuleStmt, DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
|
||||
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
|
||||
NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt,
|
||||
NotifyStmt, OptimizableStmt, CreateFunctionStmt, ReindexStmt,
|
||||
RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,
|
||||
RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty,
|
||||
RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
|
||||
@ -201,7 +201,7 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
%type <list> stmtblock, stmtmulti,
|
||||
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,
|
||||
opt_column_list, columnList, opt_name_list,
|
||||
sort_clause, sortby_list, index_params, index_list, name_list,
|
||||
@ -214,6 +214,7 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
%type <range> into_clause, OptTempTableName
|
||||
|
||||
%type <defelt> createfunc_opt_item
|
||||
%type <typnam> func_arg, func_return, func_type, aggr_argtype
|
||||
|
||||
%type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids
|
||||
@ -388,6 +389,9 @@ static void doNegateFloat(Value *v);
|
||||
TEMP, TEMPLATE, TOAST, TRUNCATE, TRUSTED,
|
||||
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
|
||||
* list and so can never be entered directly. The filter in parser.c
|
||||
* creates these tokens when required.
|
||||
@ -467,6 +471,7 @@ stmt : AlterDatabaseSetStmt
|
||||
| CreateStmt
|
||||
| CreateAsStmt
|
||||
| CreateDomainStmt
|
||||
| CreateFunctionStmt
|
||||
| CreateSchemaStmt
|
||||
| CreateGroupStmt
|
||||
| CreateSeqStmt
|
||||
@ -494,7 +499,6 @@ stmt : AlterDatabaseSetStmt
|
||||
| UnlistenStmt
|
||||
| LockStmt
|
||||
| NotifyStmt
|
||||
| ProcedureStmt
|
||||
| ReindexStmt
|
||||
| RemoveAggrStmt
|
||||
| RemoveOperStmt
|
||||
@ -2769,17 +2773,16 @@ RecipeStmt: EXECUTE RECIPE recipe_name
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args
|
||||
RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
|
||||
CreateFunctionStmt: CREATE opt_or_replace FUNCTION func_name func_args
|
||||
RETURNS func_return createfunc_opt_list opt_with
|
||||
{
|
||||
ProcedureStmt *n = makeNode(ProcedureStmt);
|
||||
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
|
||||
n->replace = $2;
|
||||
n->funcname = $4;
|
||||
n->argTypes = $5;
|
||||
n->returnType = $7;
|
||||
n->withClause = $12;
|
||||
n->as = $9;
|
||||
n->language = $11;
|
||||
n->options = $8;
|
||||
n->withClause = $9;
|
||||
$$ = (Node *)n;
|
||||
};
|
||||
|
||||
@ -2787,10 +2790,6 @@ opt_or_replace: OR REPLACE { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
opt_with: WITH definition { $$ = $2; }
|
||||
| /*EMPTY*/ { $$ = NIL; }
|
||||
;
|
||||
|
||||
func_args: '(' func_args_list ')' { $$ = $2; }
|
||||
| '(' ')' { $$ = NIL; }
|
||||
;
|
||||
@ -2831,12 +2830,6 @@ opt_arg: IN
|
||||
}
|
||||
;
|
||||
|
||||
func_as: Sconst
|
||||
{ $$ = makeList1(makeString($1)); }
|
||||
| Sconst ',' Sconst
|
||||
{ $$ = makeList2(makeString($1), makeString($3)); }
|
||||
;
|
||||
|
||||
func_return: func_type
|
||||
{
|
||||
/* We can catch over-specified arguments here if we want to,
|
||||
@ -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:
|
||||
@ -6137,6 +6228,7 @@ unreserved_keyword:
|
||||
| BEGIN_TRANS
|
||||
| BY
|
||||
| CACHE
|
||||
| CALLED
|
||||
| CASCADE
|
||||
| CHAIN
|
||||
| CHARACTERISTICS
|
||||
@ -6156,6 +6248,7 @@ unreserved_keyword:
|
||||
| DAY_P
|
||||
| DECLARE
|
||||
| DEFERRED
|
||||
| DEFINER
|
||||
| DELETE
|
||||
| DELIMITERS
|
||||
| DOMAIN_P
|
||||
@ -6168,6 +6261,7 @@ unreserved_keyword:
|
||||
| EXCLUSIVE
|
||||
| EXECUTE
|
||||
| EXPLAIN
|
||||
| EXTERNAL
|
||||
| FETCH
|
||||
| FORCE
|
||||
| FORWARD
|
||||
@ -6176,13 +6270,17 @@ unreserved_keyword:
|
||||
| HANDLER
|
||||
| HOUR_P
|
||||
| IMMEDIATE
|
||||
| IMMUTABLE
|
||||
| IMPLICIT
|
||||
| INCREMENT
|
||||
| INDEX
|
||||
| INHERITS
|
||||
| INOUT
|
||||
| INPUT
|
||||
| INSENSITIVE
|
||||
| INSERT
|
||||
| INSTEAD
|
||||
| INVOKER
|
||||
| ISOLATION
|
||||
| KEY
|
||||
| LANGUAGE
|
||||
@ -6238,18 +6336,21 @@ unreserved_keyword:
|
||||
| SCHEMA
|
||||
| SCROLL
|
||||
| SECOND_P
|
||||
| SECURITY
|
||||
| SESSION
|
||||
| SEQUENCE
|
||||
| SERIALIZABLE
|
||||
| SET
|
||||
| SHARE
|
||||
| SHOW
|
||||
| STABLE
|
||||
| START
|
||||
| STATEMENT
|
||||
| STATISTICS
|
||||
| STDIN
|
||||
| STDOUT
|
||||
| STORAGE
|
||||
| STRICT
|
||||
| SYSID
|
||||
| TEMP
|
||||
| TEMPLATE
|
||||
@ -6272,6 +6373,7 @@ unreserved_keyword:
|
||||
| VARYING
|
||||
| VERSION
|
||||
| VIEW
|
||||
| VOLATILE
|
||||
| WITH
|
||||
| WITHOUT
|
||||
| WORK
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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[] = {
|
||||
{"both", BOTH},
|
||||
{"by", BY},
|
||||
{"cache", CACHE},
|
||||
{"called", CALLED},
|
||||
{"cascade", CASCADE},
|
||||
{"case", CASE},
|
||||
{"cast", CAST},
|
||||
@ -95,6 +96,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"default", DEFAULT},
|
||||
{"deferrable", DEFERRABLE},
|
||||
{"deferred", DEFERRED},
|
||||
{"definer", DEFINER},
|
||||
{"delete", DELETE},
|
||||
{"delimiters", DELIMITERS},
|
||||
{"desc", DESC},
|
||||
@ -114,6 +116,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"execute", EXECUTE},
|
||||
{"exists", EXISTS},
|
||||
{"explain", EXPLAIN},
|
||||
{"external", EXTERNAL},
|
||||
{"extract", EXTRACT},
|
||||
{"false", FALSE_P},
|
||||
{"fetch", FETCH},
|
||||
@ -134,6 +137,8 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"hour", HOUR_P},
|
||||
{"ilike", ILIKE},
|
||||
{"immediate", IMMEDIATE},
|
||||
{"immutable", IMMUTABLE},
|
||||
{"implicit", IMPLICIT},
|
||||
{"in", IN},
|
||||
{"increment", INCREMENT},
|
||||
{"index", INDEX},
|
||||
@ -141,6 +146,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"initially", INITIALLY},
|
||||
{"inner", INNER_P},
|
||||
{"inout", INOUT},
|
||||
{"input", INPUT},
|
||||
{"insensitive", INSENSITIVE},
|
||||
{"insert", INSERT},
|
||||
{"instead", INSTEAD},
|
||||
@ -149,6 +155,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"intersect", INTERSECT},
|
||||
{"interval", INTERVAL},
|
||||
{"into", INTO},
|
||||
{"invoker", INVOKER},
|
||||
{"is", IS},
|
||||
{"isnull", ISNULL},
|
||||
{"isolation", ISOLATION},
|
||||
@ -234,6 +241,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"schema", SCHEMA},
|
||||
{"scroll", SCROLL},
|
||||
{"second", SECOND_P},
|
||||
{"security", SECURITY},
|
||||
{"select", SELECT},
|
||||
{"sequence", SEQUENCE},
|
||||
{"serializable", SERIALIZABLE},
|
||||
@ -245,12 +253,14 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"show", SHOW},
|
||||
{"smallint", SMALLINT},
|
||||
{"some", SOME},
|
||||
{"stable", STABLE},
|
||||
{"start", START},
|
||||
{"statement", STATEMENT},
|
||||
{"statistics", STATISTICS},
|
||||
{"stdin", STDIN},
|
||||
{"stdout", STDOUT},
|
||||
{"storage", STORAGE},
|
||||
{"strict", STRICT},
|
||||
{"substring", SUBSTRING},
|
||||
{"sysid", SYSID},
|
||||
{"table", TABLE},
|
||||
@ -288,6 +298,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"verbose", VERBOSE},
|
||||
{"version", VERSION},
|
||||
{"view", VIEW},
|
||||
{"volatile", VOLATILE},
|
||||
{"when", WHEN},
|
||||
{"where", WHERE},
|
||||
{"with", WITH},
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* this is the "main" module of the postgres backend and
|
||||
@ -1688,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
||||
if (!IsUnderPostmaster)
|
||||
{
|
||||
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)
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
case T_ProcedureStmt: /* CREATE FUNCTION */
|
||||
case T_CreateFunctionStmt: /* CREATE FUNCTION */
|
||||
tag = "CREATE";
|
||||
break;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* 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,
|
||||
}
|
||||
break;
|
||||
|
||||
case T_ProcedureStmt: /* CREATE FUNCTION */
|
||||
CreateFunction((ProcedureStmt *) parsetree);
|
||||
case T_CreateFunctionStmt: /* CREATE FUNCTION */
|
||||
CreateFunction((CreateFunctionStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_IndexStmt: /* CREATE INDEX */
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*
|
||||
* 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)
|
||||
|
||||
(*deps)[depIdx++] = strdup(lanplcallfoid);
|
||||
|
||||
appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE ");
|
||||
formatStringLiteral(delqry, lanname, CONV_ALL);
|
||||
appendPQExpBuffer(delqry, ";\n");
|
||||
appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n", fmtId(lanname, force_quotes));
|
||||
|
||||
appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE ",
|
||||
appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
|
||||
(PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ?
|
||||
"TRUSTED " : "");
|
||||
formatStringLiteral(defqry, lanname, CONV_ALL);
|
||||
appendPQExpBuffer(defqry, " HANDLER %s LANCOMPILER ",
|
||||
"TRUSTED " : "",
|
||||
fmtId(lanname, force_quotes));
|
||||
appendPQExpBuffer(defqry, " HANDLER %s;\n",
|
||||
fmtId(finfo[fidx].proname, force_quotes));
|
||||
formatStringLiteral(defqry, lancompiler, CONV_ALL);
|
||||
appendPQExpBuffer(defqry, ";\n");
|
||||
|
||||
(*deps)[depIdx++] = NULL; /* End of List */
|
||||
|
||||
@ -3221,9 +3217,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
char *proimplicit;
|
||||
char *proisstrict;
|
||||
char *lanname;
|
||||
char *listSep;
|
||||
char *listSepComma = ",";
|
||||
char *listSepNone = "";
|
||||
char *rettypename;
|
||||
|
||||
if (finfo->dumped)
|
||||
@ -3337,52 +3330,33 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque);
|
||||
|
||||
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 " : "",
|
||||
rettypename,
|
||||
asPart->data);
|
||||
formatStringLiteral(q, lanname, CONV_ALL);
|
||||
asPart->data,
|
||||
fmtId(lanname, force_quotes));
|
||||
|
||||
free(rettypename);
|
||||
|
||||
if (provolatile[0] != PROVOLATILE_VOLATILE ||
|
||||
proimplicit[0] == 't' ||
|
||||
proisstrict[0] == 't') /* OR in new attrs here */
|
||||
if (provolatile[0] != PROVOLATILE_VOLATILE)
|
||||
{
|
||||
appendPQExpBuffer(q, " WITH (");
|
||||
listSep = listSepNone;
|
||||
|
||||
if (provolatile[0] == PROVOLATILE_IMMUTABLE)
|
||||
{
|
||||
appendPQExpBuffer(q, "%s isImmutable", listSep);
|
||||
listSep = listSepComma;
|
||||
}
|
||||
appendPQExpBuffer(q, " IMMUTABLE");
|
||||
else if (provolatile[0] == PROVOLATILE_STABLE)
|
||||
{
|
||||
appendPQExpBuffer(q, "%s isStable", listSep);
|
||||
listSep = listSepComma;
|
||||
}
|
||||
appendPQExpBuffer(q, " STABLE");
|
||||
else if (provolatile[0] != PROVOLATILE_VOLATILE)
|
||||
{
|
||||
write_msg(NULL, "Unexpected provolatile value for function %s\n",
|
||||
finfo->proname);
|
||||
exit_nicely();
|
||||
}
|
||||
}
|
||||
|
||||
if (proimplicit[0] == 't')
|
||||
{
|
||||
appendPQExpBuffer(q, "%s implicitCoercion", listSep);
|
||||
listSep = listSepComma;
|
||||
}
|
||||
if (proimplicit[0] == 't')
|
||||
appendPQExpBuffer(q, " IMPLICIT CAST");
|
||||
|
||||
if (proisstrict[0] == 't')
|
||||
{
|
||||
appendPQExpBuffer(q, "%s isStrict", listSep);
|
||||
listSep = listSepComma;
|
||||
}
|
||||
|
||||
appendPQExpBuffer(q, " )");
|
||||
}
|
||||
if (proisstrict[0] == 't')
|
||||
appendPQExpBuffer(q, " STRICT");
|
||||
|
||||
appendPQExpBuffer(q, ";\n");
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* 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);
|
||||
* 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 DefineOperator(List *names, List *parameters);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* 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
|
||||
T_CommentStmt,
|
||||
T_FetchStmt,
|
||||
T_IndexStmt,
|
||||
T_ProcedureStmt,
|
||||
T_CreateFunctionStmt,
|
||||
T_RemoveAggrStmt,
|
||||
T_RemoveFuncStmt,
|
||||
T_RemoveOperStmt,
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* 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
|
||||
* Create Function Statement
|
||||
* ----------------------
|
||||
*/
|
||||
typedef struct ProcedureStmt
|
||||
typedef struct CreateFunctionStmt
|
||||
{
|
||||
NodeTag type;
|
||||
bool replace; /* T => replace if already exists */
|
||||
List *funcname; /* qualified name of function to create */
|
||||
List *argTypes; /* list of argument types (TypeName nodes) */
|
||||
TypeName *returnType; /* the return type */
|
||||
List *options; /* a list of DefElem */
|
||||
List *withClause; /* a list of DefElem */
|
||||
List *as; /* definition of function body */
|
||||
char *language; /* C, SQL, etc */
|
||||
} ProcedureStmt;
|
||||
} CreateFunctionStmt;
|
||||
|
||||
/* ----------------------
|
||||
* Drop Aggregate Statement
|
||||
|
Reference in New Issue
Block a user