Add CREATE OR REPLACE FUNCTION syntax to allow replacing a function
definition without changing the function's OID, thereby not breaking rules, views, triggers, etc that depend on it. From Gavin Sherry.
This commit is contained in:
parent
f24fe14162
commit
f2c657375d
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.26 2001/09/03 12:57:49 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.27 2001/10/02 21:39:35 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<refentry id="SQL-CREATEFUNCTION">
|
<refentry id="SQL-CREATEFUNCTION">
|
||||||
@ -15,12 +15,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.26 2001/09/03
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
|
CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
|
||||||
RETURNS <replaceable class="parameter">rettype</replaceable>
|
RETURNS <replaceable class="parameter">rettype</replaceable>
|
||||||
AS '<replaceable class="parameter">definition</replaceable>'
|
AS '<replaceable class="parameter">definition</replaceable>'
|
||||||
LANGUAGE <replaceable class="parameter">langname</replaceable>
|
LANGUAGE <replaceable class="parameter">langname</replaceable>
|
||||||
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
|
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
|
||||||
CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
|
CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
|
||||||
RETURNS <replaceable class="parameter">rettype</replaceable>
|
RETURNS <replaceable class="parameter">rettype</replaceable>
|
||||||
AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
|
AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
|
||||||
LANGUAGE <replaceable class="parameter">langname</replaceable>
|
LANGUAGE <replaceable class="parameter">langname</replaceable>
|
||||||
@ -33,6 +33,8 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>CREATE FUNCTION</command> defines a new function.
|
<command>CREATE FUNCTION</command> defines a new function.
|
||||||
|
<command>CREATE OR REPLACE FUNCTION</command> will either create
|
||||||
|
a new function, or replace an existing definition.
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<title>Parameters</title>
|
<title>Parameters</title>
|
||||||
@ -202,11 +204,6 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
|
|||||||
for further information on writing external functions.
|
for further information on writing external functions.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
Use <command>DROP FUNCTION</command>
|
|
||||||
to remove user-defined functions.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The full <acronym>SQL</acronym> type syntax is allowed for
|
The full <acronym>SQL</acronym> type syntax is allowed for
|
||||||
input arguments and return value. However, some details of the
|
input arguments and return value. However, some details of the
|
||||||
@ -250,6 +247,29 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
|
|||||||
linkend="sql-load"> command.
|
linkend="sql-load"> command.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Use <command>DROP FUNCTION</command>
|
||||||
|
to remove user-defined functions.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To update the definition of an existing function, use
|
||||||
|
<command>CREATE OR REPLACE FUNCTION</command>. Note that it is
|
||||||
|
not possible to change the name or argument types of a function
|
||||||
|
this way (if you tried, you'd just be creating a new, distinct
|
||||||
|
function). Also, <command>CREATE OR REPLACE FUNCTION</command>
|
||||||
|
will not let you change the return type of an existing function.
|
||||||
|
To do that, you must drop and re-create the function.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If you drop and then re-create a function, the new function is not
|
||||||
|
the same entity as the old; you will break existing rules, views,
|
||||||
|
triggers, etc that referred to the old function. Use
|
||||||
|
<command>CREATE OR REPLACE FUNCTION</command> to change a function
|
||||||
|
definition without breaking objects that refer to the function.
|
||||||
|
</para>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.59 2001/09/08 01:10:19 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.60 2001/10/02 21:39:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -41,6 +41,7 @@ static void checkretval(Oid rettype, List *queryTreeList);
|
|||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
ProcedureCreate(char *procedureName,
|
ProcedureCreate(char *procedureName,
|
||||||
|
bool replace,
|
||||||
bool returnsSet,
|
bool returnsSet,
|
||||||
char *returnTypeName,
|
char *returnTypeName,
|
||||||
char *languageName,
|
char *languageName,
|
||||||
@ -58,10 +59,12 @@ ProcedureCreate(char *procedureName,
|
|||||||
int i;
|
int i;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
|
HeapTuple oldtup;
|
||||||
bool defined;
|
bool defined;
|
||||||
uint16 parameterCount;
|
uint16 parameterCount;
|
||||||
char nulls[Natts_pg_proc];
|
char nulls[Natts_pg_proc];
|
||||||
Datum values[Natts_pg_proc];
|
Datum values[Natts_pg_proc];
|
||||||
|
char replaces[Natts_pg_proc];
|
||||||
Oid languageObjectId;
|
Oid languageObjectId;
|
||||||
Oid typeObjectId;
|
Oid typeObjectId;
|
||||||
List *x;
|
List *x;
|
||||||
@ -120,15 +123,6 @@ ProcedureCreate(char *procedureName,
|
|||||||
typev[parameterCount++] = toid;
|
typev[parameterCount++] = toid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for duplicate definition */
|
|
||||||
if (SearchSysCacheExists(PROCNAME,
|
|
||||||
PointerGetDatum(procedureName),
|
|
||||||
UInt16GetDatum(parameterCount),
|
|
||||||
PointerGetDatum(typev),
|
|
||||||
0))
|
|
||||||
elog(ERROR, "function %s already exists with same argument types",
|
|
||||||
procedureName);
|
|
||||||
|
|
||||||
if (languageObjectId == SQLlanguageId)
|
if (languageObjectId == SQLlanguageId)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -260,13 +254,14 @@ ProcedureCreate(char *procedureName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All seems OK; prepare the tuple to be inserted into pg_proc.
|
* All seems OK; prepare the data to be inserted into pg_proc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < Natts_pg_proc; ++i)
|
for (i = 0; i < Natts_pg_proc; ++i)
|
||||||
{
|
{
|
||||||
nulls[i] = ' ';
|
nulls[i] = ' ';
|
||||||
values[i] = (Datum) NULL;
|
values[i] = (Datum) NULL;
|
||||||
|
replaces[i] = 'r';
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -293,14 +288,49 @@ ProcedureCreate(char *procedureName,
|
|||||||
CStringGetDatum(probin));
|
CStringGetDatum(probin));
|
||||||
|
|
||||||
rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
tupDesc = rel->rd_att;
|
tupDesc = rel->rd_att;
|
||||||
tup = heap_formtuple(tupDesc,
|
|
||||||
values,
|
|
||||||
nulls);
|
|
||||||
|
|
||||||
|
/* Check for pre-existing definition */
|
||||||
|
oldtup = SearchSysCache(PROCNAME,
|
||||||
|
PointerGetDatum(procedureName),
|
||||||
|
UInt16GetDatum(parameterCount),
|
||||||
|
PointerGetDatum(typev),
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (HeapTupleIsValid(oldtup))
|
||||||
|
{
|
||||||
|
/* There is one; okay to replace it? */
|
||||||
|
Form_pg_proc oldproc = (Form_pg_proc) GETSTRUCT(oldtup);
|
||||||
|
|
||||||
|
if (!replace)
|
||||||
|
elog(ERROR, "function %s already exists with same argument types",
|
||||||
|
procedureName);
|
||||||
|
if (GetUserId() != oldproc->proowner && !superuser())
|
||||||
|
elog(ERROR, "ProcedureCreate: you do not have permission to replace function %s",
|
||||||
|
procedureName);
|
||||||
|
/*
|
||||||
|
* Not okay to change the return type of the existing proc, since
|
||||||
|
* existing rules, views, etc may depend on the return type.
|
||||||
|
*/
|
||||||
|
if (typeObjectId != oldproc->prorettype ||
|
||||||
|
returnsSet != oldproc->proretset)
|
||||||
|
elog(ERROR, "ProcedureCreate: cannot change return type of existing function."
|
||||||
|
"\n\tUse DROP FUNCTION first.");
|
||||||
|
|
||||||
|
/* Okay, do it... */
|
||||||
|
tup = heap_modifytuple(oldtup, rel, values, nulls, replaces);
|
||||||
|
simple_heap_update(rel, &tup->t_self, tup);
|
||||||
|
|
||||||
|
ReleaseSysCache(oldtup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Creating a new procedure */
|
||||||
|
tup = heap_formtuple(tupDesc, values, nulls);
|
||||||
heap_insert(rel, tup);
|
heap_insert(rel, tup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to update indices for either the insert or update case */
|
||||||
if (RelationGetForm(rel)->relhasindex)
|
if (RelationGetForm(rel)->relhasindex)
|
||||||
{
|
{
|
||||||
Relation idescs[Num_pg_proc_indices];
|
Relation idescs[Num_pg_proc_indices];
|
||||||
@ -309,9 +339,12 @@ ProcedureCreate(char *procedureName,
|
|||||||
CatalogIndexInsert(idescs, Num_pg_proc_indices, rel, tup);
|
CatalogIndexInsert(idescs, Num_pg_proc_indices, rel, tup);
|
||||||
CatalogCloseIndices(Num_pg_proc_indices, idescs);
|
CatalogCloseIndices(Num_pg_proc_indices, idescs);
|
||||||
}
|
}
|
||||||
heap_close(rel, RowExclusiveLock);
|
|
||||||
retval = tup->t_data->t_oid;
|
retval = tup->t_data->t_oid;
|
||||||
heap_freetuple(tup);
|
heap_freetuple(tup);
|
||||||
|
|
||||||
|
heap_close(rel, RowExclusiveLock);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.60 2001/09/08 01:10:20 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.61 2001/10/02 21:39:35 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
@ -324,6 +324,7 @@ CreateFunction(ProcedureStmt *stmt)
|
|||||||
* to do so, go ahead and create the function.
|
* to do so, go ahead and create the function.
|
||||||
*/
|
*/
|
||||||
ProcedureCreate(stmt->funcname,
|
ProcedureCreate(stmt->funcname,
|
||||||
|
stmt->replace,
|
||||||
returnsSet,
|
returnsSet,
|
||||||
prorettype,
|
prorettype,
|
||||||
languageName,
|
languageName,
|
||||||
|
@ -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.156 2001/09/18 01:59:06 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.157 2001/10/02 21:39:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2071,6 +2071,7 @@ _copyProcedureStmt(ProcedureStmt *from)
|
|||||||
{
|
{
|
||||||
ProcedureStmt *newnode = makeNode(ProcedureStmt);
|
ProcedureStmt *newnode = makeNode(ProcedureStmt);
|
||||||
|
|
||||||
|
newnode->replace = from->replace;
|
||||||
newnode->funcname = pstrdup(from->funcname);
|
newnode->funcname = pstrdup(from->funcname);
|
||||||
Node_Copy(from, newnode, argTypes);
|
Node_Copy(from, newnode, argTypes);
|
||||||
Node_Copy(from, newnode, returnType);
|
Node_Copy(from, newnode, returnType);
|
||||||
|
@ -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.104 2001/09/18 01:59:06 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.105 2001/10/02 21:39:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -941,6 +941,8 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
|
|||||||
static bool
|
static bool
|
||||||
_equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
|
_equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
|
||||||
{
|
{
|
||||||
|
if (a->replace != b->replace)
|
||||||
|
return false;
|
||||||
if (!equalstr(a->funcname, b->funcname))
|
if (!equalstr(a->funcname, b->funcname))
|
||||||
return false;
|
return false;
|
||||||
if (!equal(a->argTypes, b->argTypes))
|
if (!equal(a->argTypes, b->argTypes))
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.255 2001/10/01 04:19:18 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.256 2001/10/02 21:39:35 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -151,7 +151,7 @@ static void doNegateFloat(Value *v);
|
|||||||
%type <list> createdb_opt_list, createdb_opt_item
|
%type <list> createdb_opt_list, createdb_opt_item
|
||||||
|
|
||||||
%type <ival> opt_lock, lock_type
|
%type <ival> opt_lock, lock_type
|
||||||
%type <boolean> opt_force
|
%type <boolean> opt_force, opt_or_replace
|
||||||
|
|
||||||
%type <list> user_list
|
%type <list> user_list
|
||||||
|
|
||||||
@ -321,13 +321,13 @@ static void doNegateFloat(Value *v);
|
|||||||
VALUES, VARCHAR, VARYING, VIEW,
|
VALUES, VARCHAR, VARYING, VIEW,
|
||||||
WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
|
WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
|
||||||
|
|
||||||
/* Keywords (in SQL3 reserved words) */
|
/* Keywords (in SQL99 reserved words) */
|
||||||
%token CHAIN, CHARACTERISTICS,
|
%token CHAIN, CHARACTERISTICS,
|
||||||
DEFERRABLE, DEFERRED,
|
DEFERRABLE, DEFERRED,
|
||||||
IMMEDIATE, INITIALLY, INOUT,
|
IMMEDIATE, INITIALLY, INOUT,
|
||||||
OFF, OUT,
|
OFF, OUT,
|
||||||
PATH_P, PENDANT,
|
PATH_P, PENDANT,
|
||||||
RESTRICT,
|
REPLACE, RESTRICT,
|
||||||
TRIGGER,
|
TRIGGER,
|
||||||
WITHOUT
|
WITHOUT
|
||||||
|
|
||||||
@ -2497,33 +2497,32 @@ RecipeStmt: EXECUTE RECIPE recipe_name
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* QUERY:
|
* QUERY:
|
||||||
* define function <fname>
|
* create [or replace] function <fname>
|
||||||
* [(<type-1> { , <type-n>})]
|
* [(<type-1> { , <type-n>})]
|
||||||
* returns <type-r>
|
* returns <type-r>
|
||||||
* as <filename or code in language as appropriate>
|
* as <filename or code in language as appropriate>
|
||||||
* language <lang> [with
|
* language <lang> [with parameters]
|
||||||
* [ arch_pct = <percentage | pre-defined>]
|
|
||||||
* [, disk_pct = <percentage | pre-defined>]
|
|
||||||
* [, byte_pct = <percentage | pre-defined>]
|
|
||||||
* [, perbyte_cpu = <int | pre-defined>]
|
|
||||||
* [, percall_cpu = <int | pre-defined>]
|
|
||||||
* [, iscachable] ]
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
ProcedureStmt: CREATE FUNCTION func_name func_args
|
ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args
|
||||||
RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
|
RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
|
||||||
{
|
{
|
||||||
ProcedureStmt *n = makeNode(ProcedureStmt);
|
ProcedureStmt *n = makeNode(ProcedureStmt);
|
||||||
n->funcname = $3;
|
n->replace = $2;
|
||||||
n->argTypes = $4;
|
n->funcname = $4;
|
||||||
n->returnType = (Node *)$6;
|
n->argTypes = $5;
|
||||||
n->withClause = $11;
|
n->returnType = (Node *) $7;
|
||||||
n->as = $8;
|
n->withClause = $12;
|
||||||
n->language = $10;
|
n->as = $9;
|
||||||
|
n->language = $11;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
opt_or_replace: OR REPLACE { $$ = TRUE; }
|
||||||
|
| /*EMPTY*/ { $$ = FALSE; }
|
||||||
|
;
|
||||||
|
|
||||||
opt_with: WITH definition { $$ = $2; }
|
opt_with: WITH definition { $$ = $2; }
|
||||||
| /*EMPTY*/ { $$ = NIL; }
|
| /*EMPTY*/ { $$ = NIL; }
|
||||||
;
|
;
|
||||||
@ -5682,6 +5681,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; }
|
|||||||
| REINDEX { $$ = "reindex"; }
|
| REINDEX { $$ = "reindex"; }
|
||||||
| RELATIVE { $$ = "relative"; }
|
| RELATIVE { $$ = "relative"; }
|
||||||
| RENAME { $$ = "rename"; }
|
| RENAME { $$ = "rename"; }
|
||||||
|
| REPLACE { $$ = "replace"; }
|
||||||
| RESTRICT { $$ = "restrict"; }
|
| RESTRICT { $$ = "restrict"; }
|
||||||
| RETURNS { $$ = "returns"; }
|
| RETURNS { $$ = "returns"; }
|
||||||
| REVOKE { $$ = "revoke"; }
|
| REVOKE { $$ = "revoke"; }
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.97 2001/08/26 16:56:00 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.98 2001/10/02 21:39:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -216,6 +216,7 @@ static ScanKeyword ScanKeywords[] = {
|
|||||||
{"reindex", REINDEX},
|
{"reindex", REINDEX},
|
||||||
{"relative", RELATIVE},
|
{"relative", RELATIVE},
|
||||||
{"rename", RENAME},
|
{"rename", RENAME},
|
||||||
|
{"replace", REPLACE},
|
||||||
{"reset", RESET},
|
{"reset", RESET},
|
||||||
{"restrict", RESTRICT},
|
{"restrict", RESTRICT},
|
||||||
{"returns", RETURNS},
|
{"returns", RETURNS},
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.38 2001/09/08 01:10:20 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.39 2001/10/02 21:39:35 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -51,6 +51,7 @@ SetDefine(char *querystr, char *typename)
|
|||||||
char repl[Natts_pg_proc];
|
char repl[Natts_pg_proc];
|
||||||
|
|
||||||
setoid = ProcedureCreate(procname, /* changed below, after oid known */
|
setoid = ProcedureCreate(procname, /* changed below, after oid known */
|
||||||
|
false, /* don't replace */
|
||||||
true, /* returnsSet */
|
true, /* returnsSet */
|
||||||
typename, /* returnTypeName */
|
typename, /* returnTypeName */
|
||||||
"sql", /* languageName */
|
"sql", /* languageName */
|
||||||
|
@ -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: pg_proc.h,v 1.212 2001/09/28 08:09:13 thomas Exp $
|
* $Id: pg_proc.h,v 1.213 2001/10/02 21:39:36 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -2854,6 +2854,7 @@ DESCR("time zone");
|
|||||||
* prototypes for functions pg_proc.c
|
* prototypes for functions pg_proc.c
|
||||||
*/
|
*/
|
||||||
extern Oid ProcedureCreate(char *procedureName,
|
extern Oid ProcedureCreate(char *procedureName,
|
||||||
|
bool replace,
|
||||||
bool returnsSet,
|
bool returnsSet,
|
||||||
char *returnTypeName,
|
char *returnTypeName,
|
||||||
char *languageName,
|
char *languageName,
|
||||||
|
@ -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.144 2001/09/18 01:59:06 tgl Exp $
|
* $Id: parsenodes.h,v 1.145 2001/10/02 21:39:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -514,6 +514,7 @@ typedef struct IndexStmt
|
|||||||
typedef struct ProcedureStmt
|
typedef struct ProcedureStmt
|
||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
|
bool replace; /* T => replace if already exists */
|
||||||
char *funcname; /* name of function to create */
|
char *funcname; /* name of function to create */
|
||||||
List *argTypes; /* list of argument types (TypeName nodes) */
|
List *argTypes; /* list of argument types (TypeName nodes) */
|
||||||
Node *returnType; /* the return type (a TypeName node) */
|
Node *returnType; /* the return type (a TypeName node) */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.44 2001/09/19 14:09:32 meskes Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.45 2001/10/02 21:39:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -118,6 +118,7 @@ static ScanKeyword ScanKeywords[] = {
|
|||||||
{"force", FORCE},
|
{"force", FORCE},
|
||||||
{"foreign", FOREIGN},
|
{"foreign", FOREIGN},
|
||||||
{"forward", FORWARD},
|
{"forward", FORWARD},
|
||||||
|
{"freeze", FREEZE},
|
||||||
{"from", FROM},
|
{"from", FROM},
|
||||||
{"full", FULL},
|
{"full", FULL},
|
||||||
{"function", FUNCTION},
|
{"function", FUNCTION},
|
||||||
@ -215,6 +216,7 @@ static ScanKeyword ScanKeywords[] = {
|
|||||||
{"reindex", REINDEX},
|
{"reindex", REINDEX},
|
||||||
{"relative", RELATIVE},
|
{"relative", RELATIVE},
|
||||||
{"rename", RENAME},
|
{"rename", RENAME},
|
||||||
|
{"replace", REPLACE},
|
||||||
{"reset", RESET},
|
{"reset", RESET},
|
||||||
{"restrict", RESTRICT},
|
{"restrict", RESTRICT},
|
||||||
{"returns", RETURNS},
|
{"returns", RETURNS},
|
||||||
|
@ -202,7 +202,7 @@ make_name(void)
|
|||||||
%token DEFERRABLE, DEFERRED,
|
%token DEFERRABLE, DEFERRED,
|
||||||
IMMEDIATE, INITIALLY,
|
IMMEDIATE, INITIALLY,
|
||||||
PENDANT,
|
PENDANT,
|
||||||
RESTRICT,
|
REPLACE, RESTRICT,
|
||||||
TRIGGER
|
TRIGGER
|
||||||
|
|
||||||
/* Keywords (in SQL92 non-reserved words) */
|
/* Keywords (in SQL92 non-reserved words) */
|
||||||
@ -338,7 +338,7 @@ make_name(void)
|
|||||||
%type <str> constraints_set_mode comment_type comment_cl comment_ag
|
%type <str> constraints_set_mode comment_type comment_cl comment_ag
|
||||||
%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
|
%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
|
||||||
%type <str> opt_force key_update CreateSchemaStmt PosIntStringConst
|
%type <str> opt_force key_update CreateSchemaStmt PosIntStringConst
|
||||||
%type <str> IntConst PosIntConst grantee_list func_type
|
%type <str> IntConst PosIntConst grantee_list func_type opt_or_replace
|
||||||
%type <str> select_limit opt_for_update_clause CheckPointStmt
|
%type <str> select_limit opt_for_update_clause CheckPointStmt
|
||||||
|
|
||||||
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
|
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
|
||||||
@ -1881,26 +1881,24 @@ RecipeStmt: EXECUTE RECIPE recipe_name
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* QUERY:
|
* QUERY:
|
||||||
* define function <fname>
|
* create [or replace] function <fname>
|
||||||
* [(<type-1> { , <type-n>})]
|
* [(<type-1> { , <type-n>})]
|
||||||
* returns <type-r>
|
* returns <type-r>
|
||||||
* as <filename or code in language as appropriate>
|
* as <filename or code in language as appropriate>
|
||||||
* language <lang> [with
|
* language <lang> [with parameters]
|
||||||
* [ arch_pct = <percentage | pre-defined>]
|
|
||||||
* [, disk_pct = <percentage | pre-defined>]
|
|
||||||
* [, byte_pct = <percentage | pre-defined>]
|
|
||||||
* [, perbyte_cpu = <int | pre-defined>]
|
|
||||||
* [, percall_cpu = <int | pre-defined>]
|
|
||||||
* [, iscachable]
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
ProcedureStmt: CREATE FUNCTION func_name func_args
|
ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args
|
||||||
RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
|
RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
|
||||||
{
|
{
|
||||||
$$ = cat_str(10, make_str("create function"), $3, $4, make_str("returns"), $6, make_str("as"), $8, make_str("language"), $10, $11);
|
$$ = cat_str(12, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, make_str("as"), $9, make_str("language"), $11, $12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opt_or_replace: OR REPLACE { $$ = make_str("or replace"); }
|
||||||
|
| /*EMPTY*/ { $$ = EMPTY; }
|
||||||
|
;
|
||||||
|
|
||||||
opt_with: WITH definition { $$ = cat2_str(make_str("with"), $2); }
|
opt_with: WITH definition { $$ = cat2_str(make_str("with"), $2); }
|
||||||
| /*EMPTY*/ { $$ = EMPTY; }
|
| /*EMPTY*/ { $$ = EMPTY; }
|
||||||
;
|
;
|
||||||
@ -5043,6 +5041,7 @@ TokenId: ABSOLUTE { $$ = make_str("absolute"); }
|
|||||||
| REINDEX { $$ = make_str("reindex"); }
|
| REINDEX { $$ = make_str("reindex"); }
|
||||||
| RELATIVE { $$ = make_str("relative"); }
|
| RELATIVE { $$ = make_str("relative"); }
|
||||||
| RENAME { $$ = make_str("rename"); }
|
| RENAME { $$ = make_str("rename"); }
|
||||||
|
| REPLACE { $$ = make_str("replace"); }
|
||||||
| RESTRICT { $$ = make_str("restrict"); }
|
| RESTRICT { $$ = make_str("restrict"); }
|
||||||
| RETURNS { $$ = make_str("returns"); }
|
| RETURNS { $$ = make_str("returns"); }
|
||||||
| REVOKE { $$ = make_str("revoke"); }
|
| REVOKE { $$ = make_str("revoke"); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user