Commit eb3adab5 authored by Tom Lane's avatar Tom Lane

Provide an upgrade strategy for dump files containing functions declared

with OPAQUE.  CREATE LANGUAGE, CREATE TRIGGER, and CREATE TYPE will all
accept references to functions declared with OPAQUE --- but they will
issue a NOTICE, and will modify the function entries in pg_proc to have
the preferred type-safe argument or result types instead of OPAQUE.
Per recent pghackers discussions.
parent bc499687
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.27 2002/08/22 00:01:40 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.28 2002/09/21 18:39:25 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -200,6 +200,16 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable ...@@ -200,6 +200,16 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
will call <command>CREATE LANGUAGE</command> internally.) will call <command>CREATE LANGUAGE</command> internally.)
</para> </para>
<para>
In <productname>PostgreSQL</productname> versions before 7.3, it was
necessary to declare handler functions as returning the placeholder
type <type>opaque</>, rather than <type>language_handler</>.
To support loading
of old dump files, <command>CREATE LANGUAGE</> will accept a function
declared as returning <type>opaque</>, but it will issue a NOTICE and
change the function's declared return type to <type>language_handler</>.
</para>
<para> <para>
Use the <xref linkend="sql-createfunction" endterm="sql-createfunction-title"> command to create a new Use the <xref linkend="sql-createfunction" endterm="sql-createfunction-title"> command to create a new
function. function.
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.27 2002/08/22 00:01:40 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.28 2002/09/21 18:39:25 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -170,9 +170,10 @@ CREATE TRIGGER ...@@ -170,9 +170,10 @@ CREATE TRIGGER
<para> <para>
In <productname>PostgreSQL</productname> versions before 7.3, it was In <productname>PostgreSQL</productname> versions before 7.3, it was
necessary to declare trigger functions as returning the placeholder necessary to declare trigger functions as returning the placeholder
type <type>opaque</>, rather than <type>trigger</>. This is still type <type>opaque</>, rather than <type>trigger</>. To support loading
supported, but is deprecated because it is obscure and causes loss of of old dump files, <command>CREATE TRIGGER</> will accept a function
type safety. declared as returning <type>opaque</>, but it will issue a NOTICE and
change the function's declared return type to <type>trigger</>.
</para> </para>
<para> <para>
......
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_type.sgml,v 1.35 2002/09/21 18:32:54 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_type.sgml,v 1.36 2002/09/21 18:39:25 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -262,8 +262,10 @@ CREATE TYPE ...@@ -262,8 +262,10 @@ CREATE TYPE
forward references to the type name with the placeholder pseudo-type forward references to the type name with the placeholder pseudo-type
<type>OPAQUE</>. The <type>cstring</> inputs and <type>OPAQUE</>. The <type>cstring</> inputs and
results also had to be declared as <type>OPAQUE</> before 7.3. results also had to be declared as <type>OPAQUE</> before 7.3.
Use of <type>OPAQUE</> for this purpose is still supported, but it is To support loading
deprecated because it causes loss of type safety. of old dump files, <command>CREATE TYPE</> will accept functions
declared using <type>opaque</>, but it will issue a NOTICE and
change the function's declaration to use the correct types.
</para> </para>
</note> </note>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.80 2002/09/04 20:31:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.81 2002/09/21 18:39:25 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
...@@ -44,17 +44,17 @@ ...@@ -44,17 +44,17 @@
/* /*
* Translate the input language name to lower case. * Translate the input language name to lower case.
* *
* Output buffer should be NAMEDATALEN long. * Output buffer must be NAMEDATALEN long.
*/ */
void void
case_translate_language_name(const char *input, char *output) case_translate_language_name(const char *input, char *output)
{ {
int i; int i;
MemSet(output, 0, NAMEDATALEN); /* ensure result Name is zero-filled */
for (i = 0; i < NAMEDATALEN - 1 && input[i]; ++i) for (i = 0; i < NAMEDATALEN - 1 && input[i]; ++i)
output[i] = tolower((unsigned char) input[i]); output[i] = tolower((unsigned char) input[i]);
output[i] = '\0';
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.21 2002/09/18 21:35:20 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.22 2002/09/21 18:39:25 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* These routines take the parse tree and pick out the * These routines take the parse tree and pick out the
...@@ -591,6 +591,85 @@ RemoveFunctionById(Oid funcOid) ...@@ -591,6 +591,85 @@ RemoveFunctionById(Oid funcOid)
} }
/*
* SetFunctionReturnType - change declared return type of a function
*
* This is presently only used for adjusting legacy functions that return
* OPAQUE to return whatever we find their correct definition should be.
* The caller should emit a suitable NOTICE explaining what we did.
*/
void
SetFunctionReturnType(Oid funcOid, Oid newRetType)
{
Relation pg_proc_rel;
HeapTuple tup;
Form_pg_proc procForm;
pg_proc_rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
tup = SearchSysCacheCopy(PROCOID,
ObjectIdGetDatum(funcOid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "SetFunctionReturnType: couldn't find tuple for function %u",
funcOid);
procForm = (Form_pg_proc) GETSTRUCT(tup);
if (procForm->prorettype != OPAQUEOID)
elog(ERROR, "SetFunctionReturnType: function %u doesn't return OPAQUE",
funcOid);
/* okay to overwrite copied tuple */
procForm->prorettype = newRetType;
/* update the catalog and its indexes */
simple_heap_update(pg_proc_rel, &tup->t_self, tup);
CatalogUpdateIndexes(pg_proc_rel, tup);
heap_close(pg_proc_rel, RowExclusiveLock);
}
/*
* SetFunctionArgType - change declared argument type of a function
*
* As above, but change an argument's type.
*/
void
SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType)
{
Relation pg_proc_rel;
HeapTuple tup;
Form_pg_proc procForm;
pg_proc_rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
tup = SearchSysCacheCopy(PROCOID,
ObjectIdGetDatum(funcOid),
0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "SetFunctionArgType: couldn't find tuple for function %u",
funcOid);
procForm = (Form_pg_proc) GETSTRUCT(tup);
if (argIndex < 0 || argIndex >= procForm->pronargs ||
procForm->proargtypes[argIndex] != OPAQUEOID)
elog(ERROR, "SetFunctionArgType: function %u doesn't take OPAQUE",
funcOid);
/* okay to overwrite copied tuple */
procForm->proargtypes[argIndex] = newArgType;
/* update the catalog and its indexes */
simple_heap_update(pg_proc_rel, &tup->t_self, tup);
CatalogUpdateIndexes(pg_proc_rel, tup);
heap_close(pg_proc_rel, RowExclusiveLock);
}
/* /*
* CREATE CAST * CREATE CAST
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,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/commands/proclang.c,v 1.42 2002/09/04 20:31:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.43 2002/09/21 18:39:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -43,6 +43,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) ...@@ -43,6 +43,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
char languageName[NAMEDATALEN]; char languageName[NAMEDATALEN];
Oid procOid, Oid procOid,
valProcOid; valProcOid;
Oid funcrettype;
Oid typev[FUNC_MAX_ARGS]; Oid typev[FUNC_MAX_ARGS];
char nulls[Natts_pg_language]; char nulls[Natts_pg_language];
Datum values[Natts_pg_language]; Datum values[Natts_pg_language];
...@@ -80,10 +81,24 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) ...@@ -80,10 +81,24 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
if (!OidIsValid(procOid)) if (!OidIsValid(procOid))
elog(ERROR, "function %s() doesn't exist", elog(ERROR, "function %s() doesn't exist",
NameListToString(stmt->plhandler)); NameListToString(stmt->plhandler));
if (get_func_rettype(procOid) != LANGUAGE_HANDLEROID) funcrettype = get_func_rettype(procOid);
elog(ERROR, "function %s() does not return type %s", if (funcrettype != LANGUAGE_HANDLEROID)
NameListToString(stmt->plhandler), {
format_type_be(LANGUAGE_HANDLEROID)); /*
* We allow OPAQUE just so we can load old dump files. When we
* see a handler function declared OPAQUE, change it to
* LANGUAGE_HANDLER.
*/
if (funcrettype == OPAQUEOID)
{
elog(NOTICE, "CreateProceduralLanguage: changing return type of function %s() from OPAQUE to LANGUAGE_HANDLER",
NameListToString(stmt->plhandler));
SetFunctionReturnType(procOid, LANGUAGE_HANDLEROID);
}
else
elog(ERROR, "CreateProceduralLanguage: function %s() must return LANGUAGE_HANDLER",
NameListToString(stmt->plhandler));
}
/* validate the validator function */ /* validate the validator function */
if (stmt->plvalidator) if (stmt->plvalidator)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,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/commands/trigger.c,v 1.131 2002/09/04 20:31:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.132 2002/09/21 18:39:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_trigger.h" #include "catalog/pg_trigger.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -75,6 +76,7 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) ...@@ -75,6 +76,7 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
HeapTuple tuple; HeapTuple tuple;
Oid fargtypes[FUNC_MAX_ARGS]; Oid fargtypes[FUNC_MAX_ARGS];
Oid funcoid; Oid funcoid;
Oid funcrettype;
Oid trigoid; Oid trigoid;
int found = 0; int found = 0;
int i; int i;
...@@ -217,22 +219,23 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) ...@@ -217,22 +219,23 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
if (!OidIsValid(funcoid)) if (!OidIsValid(funcoid))
elog(ERROR, "CreateTrigger: function %s() does not exist", elog(ERROR, "CreateTrigger: function %s() does not exist",
NameListToString(stmt->funcname)); NameListToString(stmt->funcname));
tuple = SearchSysCache(PROCOID, funcrettype = get_func_rettype(funcoid);
ObjectIdGetDatum(funcoid), if (funcrettype != TRIGGEROID)
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "CreateTrigger: function %s() does not exist",
NameListToString(stmt->funcname));
if (((Form_pg_proc) GETSTRUCT(tuple))->prorettype != TRIGGEROID)
{ {
/* OPAQUE is deprecated, but allowed for backwards compatibility */ /*
if (((Form_pg_proc) GETSTRUCT(tuple))->prorettype == OPAQUEOID) * We allow OPAQUE just so we can load old dump files. When we
elog(NOTICE, "CreateTrigger: OPAQUE is deprecated, use type TRIGGER instead to define trigger functions"); * see a trigger function declared OPAQUE, change it to TRIGGER.
*/
if (funcrettype == OPAQUEOID)
{
elog(NOTICE, "CreateTrigger: changing return type of function %s() from OPAQUE to TRIGGER",
NameListToString(stmt->funcname));
SetFunctionReturnType(funcoid, TRIGGEROID);
}
else else
elog(ERROR, "CreateTrigger: function %s() must return TRIGGER", elog(ERROR, "CreateTrigger: function %s() must return TRIGGER",
NameListToString(stmt->funcname)); NameListToString(stmt->funcname));
} }
ReleaseSysCache(tuple);
/* /*
* Build the new pg_trigger tuple. * Build the new pg_trigger tuple.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.14 2002/09/19 22:48:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.15 2002/09/21 18:39:25 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
...@@ -188,13 +188,19 @@ DefineType(List *names, List *parameters) ...@@ -188,13 +188,19 @@ DefineType(List *names, List *parameters)
/* /*
* Look to see if type already exists (presumably as a shell; if not, * Look to see if type already exists (presumably as a shell; if not,
* TypeCreate will complain). If it does then the declarations of the * TypeCreate will complain). If it doesn't, create it as a shell,
* I/O functions might use it. * so that the OID is known for use in the I/O function definitions.
*/ */
typoid = GetSysCacheOid(TYPENAMENSP, typoid = GetSysCacheOid(TYPENAMENSP,
CStringGetDatum(typeName), CStringGetDatum(typeName),
ObjectIdGetDatum(typeNamespace), ObjectIdGetDatum(typeNamespace),
0, 0); 0, 0);
if (!OidIsValid(typoid))
{
typoid = TypeShellMake(typeName, typeNamespace);
/* Make new shell type visible for modification below */
CommandCounterIncrement();
}
/* /*
* Convert I/O proc names to OIDs * Convert I/O proc names to OIDs
...@@ -203,15 +209,18 @@ DefineType(List *names, List *parameters) ...@@ -203,15 +209,18 @@ DefineType(List *names, List *parameters)
outputOid = findTypeIOFunction(outputName, typoid, true); outputOid = findTypeIOFunction(outputName, typoid, true);
/* /*
* Verify that I/O procs return the expected thing. OPAQUE is an * Verify that I/O procs return the expected thing. If we see OPAQUE,
* allowed, but deprecated, alternative to the fully type-safe * complain and change it to the correct type-safe choice.
* choices.
*/ */
resulttype = get_func_rettype(inputOid); resulttype = get_func_rettype(inputOid);
if (!(OidIsValid(typoid) && resulttype == typoid)) if (resulttype != typoid)
{ {
if (resulttype == OPAQUEOID) if (resulttype == OPAQUEOID)
elog(NOTICE, "DefineType: OPAQUE is deprecated, instead declare I/O functions using their true datatypes"); {
elog(NOTICE, "TypeCreate: changing return type of function %s from OPAQUE to %s",
NameListToString(inputName), typeName);
SetFunctionReturnType(inputOid, typoid);
}
else else
elog(ERROR, "Type input function %s must return %s", elog(ERROR, "Type input function %s must return %s",
NameListToString(inputName), typeName); NameListToString(inputName), typeName);
...@@ -220,7 +229,11 @@ DefineType(List *names, List *parameters) ...@@ -220,7 +229,11 @@ DefineType(List *names, List *parameters)
if (resulttype != CSTRINGOID) if (resulttype != CSTRINGOID)
{ {
if (resulttype == OPAQUEOID) if (resulttype == OPAQUEOID)
elog(NOTICE, "DefineType: OPAQUE is deprecated, instead declare I/O functions using their true datatypes"); {
elog(NOTICE, "TypeCreate: changing return type of function %s from OPAQUE to CSTRING",
NameListToString(outputName));
SetFunctionReturnType(outputOid, CSTRINGOID);
}
else else
elog(ERROR, "Type output function %s must return cstring", elog(ERROR, "Type output function %s must return cstring",
NameListToString(outputName)); NameListToString(outputName));
...@@ -670,8 +683,8 @@ RemoveDomain(List *names, DropBehavior behavior) ...@@ -670,8 +683,8 @@ RemoveDomain(List *names, DropBehavior behavior)
/* /*
* Find a suitable I/O function for a type. * Find a suitable I/O function for a type.
* *
* typeOid is the type's OID, if it already exists as a shell type, * typeOid is the type's OID (which will already exist, if only as a shell
* otherwise InvalidOid. * type).
*/ */
static Oid static Oid
findTypeIOFunction(List *procname, Oid typeOid, bool isOutput) findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
...@@ -683,16 +696,12 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput) ...@@ -683,16 +696,12 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
{ {
/* /*
* Output functions can take a single argument of the type, or two * Output functions can take a single argument of the type, or two
* arguments (data value, element OID). The signature may use * arguments (data value, element OID).
* OPAQUE in place of the actual type name; this is the only
* possibility if the type doesn't yet exist as a shell.
* *
* Note: although we could throw a NOTICE in this routine if OPAQUE * For backwards compatibility we allow OPAQUE in place of the actual
* is used, we do not because of the probability that it'd be * type name; if we see this, we issue a NOTICE and fix up the
* duplicate with a notice issued in DefineType. * pg_proc entry.
*/ */
if (OidIsValid(typeOid))
{
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
argList[0] = typeOid; argList[0] = typeOid;
...@@ -707,24 +716,36 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput) ...@@ -707,24 +716,36 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
if (OidIsValid(procOid)) if (OidIsValid(procOid))
return procOid; return procOid;
} /* No luck, try it with OPAQUE */
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
argList[0] = OPAQUEOID; argList[0] = OPAQUEOID;
procOid = LookupFuncName(procname, 1, argList); procOid = LookupFuncName(procname, 1, argList);
if (OidIsValid(procOid))
return procOid;
if (!OidIsValid(procOid))
{
argList[1] = OIDOID; argList[1] = OIDOID;
procOid = LookupFuncName(procname, 2, argList); procOid = LookupFuncName(procname, 2, argList);
}
if (OidIsValid(procOid)) if (OidIsValid(procOid))
{
/* Found, but must complain and fix the pg_proc entry */
elog(NOTICE, "TypeCreate: changing argument type of function %s from OPAQUE to %s",
NameListToString(procname), format_type_be(typeOid));
SetFunctionArgType(procOid, 0, typeOid);
/*
* Need CommandCounterIncrement since DefineType will likely
* try to alter the pg_proc tuple again.
*/
CommandCounterIncrement();
return procOid; return procOid;
}
/* Prefer type name over OPAQUE in the failure message. */ /* Use type name, not OPAQUE, in the failure message. */
if (OidIsValid(typeOid))
argList[0] = typeOid; argList[0] = typeOid;
func_error("TypeCreate", procname, 1, argList, NULL); func_error("TypeCreate", procname, 1, argList, NULL);
...@@ -733,8 +754,10 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput) ...@@ -733,8 +754,10 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
{ {
/* /*
* Input functions can take a single argument of type CSTRING, or * Input functions can take a single argument of type CSTRING, or
* three arguments (string, element OID, typmod). The signature * three arguments (string, element OID, typmod).
* may use OPAQUE in place of CSTRING. *
* For backwards compatibility we allow OPAQUE in place of CSTRING;
* if we see this, we issue a NOTICE and fix up the pg_proc entry.
*/ */
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
...@@ -751,20 +774,35 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput) ...@@ -751,20 +774,35 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
if (OidIsValid(procOid)) if (OidIsValid(procOid))
return procOid; return procOid;
/* No luck, try it with OPAQUE */
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
argList[0] = OPAQUEOID; argList[0] = OPAQUEOID;
procOid = LookupFuncName(procname, 1, argList); procOid = LookupFuncName(procname, 1, argList);
if (OidIsValid(procOid))
return procOid;
if (!OidIsValid(procOid))
{
argList[1] = OIDOID; argList[1] = OIDOID;
argList[2] = INT4OID; argList[2] = INT4OID;
procOid = LookupFuncName(procname, 3, argList); procOid = LookupFuncName(procname, 3, argList);
}
if (OidIsValid(procOid)) if (OidIsValid(procOid))
{
/* Found, but must complain and fix the pg_proc entry */
elog(NOTICE, "TypeCreate: changing argument type of function %s from OPAQUE to CSTRING",
NameListToString(procname));
SetFunctionArgType(procOid, 0, CSTRINGOID);
/*
* Need CommandCounterIncrement since DefineType will likely
* try to alter the pg_proc tuple again.
*/
CommandCounterIncrement();
return procOid; return procOid;
}
/* Use CSTRING (preferred) in the error message */ /* Use CSTRING (preferred) in the error message */
argList[0] = CSTRINGOID; argList[0] = CSTRINGOID;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, 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.45 2002/09/04 20:31:42 momjian Exp $ * $Id: defrem.h,v 1.46 2002/09/21 18:39:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,9 +18,7 @@ ...@@ -18,9 +18,7 @@
#define DEFAULT_TYPDELIM ',' #define DEFAULT_TYPDELIM ','
/* /* commands/indexcmds.c */
* prototypes in indexcmds.c
*/
extern void DefineIndex(RangeVar *heapRelation, extern void DefineIndex(RangeVar *heapRelation,
char *indexRelationName, char *indexRelationName,
char *accessMethodName, char *accessMethodName,
...@@ -35,24 +33,26 @@ extern void ReindexIndex(RangeVar *indexRelation, bool force); ...@@ -35,24 +33,26 @@ extern void ReindexIndex(RangeVar *indexRelation, bool force);
extern void ReindexTable(RangeVar *relation, bool force); extern void ReindexTable(RangeVar *relation, bool force);
extern void ReindexDatabase(const char *databaseName, bool force, bool all); extern void ReindexDatabase(const char *databaseName, bool force, bool all);
/* /* commands/functioncmds.c */
* DefineFoo and RemoveFoo are now both in foocmds.c
*/
extern void CreateFunction(CreateFunctionStmt *stmt); extern void CreateFunction(CreateFunctionStmt *stmt);
extern void RemoveFunction(RemoveFuncStmt *stmt); extern void RemoveFunction(RemoveFuncStmt *stmt);
extern void RemoveFunctionById(Oid funcOid); extern void RemoveFunctionById(Oid funcOid);
extern void SetFunctionReturnType(Oid funcOid, Oid newRetType);
extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType);
extern void CreateCast(CreateCastStmt *stmt); extern void CreateCast(CreateCastStmt *stmt);
extern void DropCast(DropCastStmt *stmt); extern void DropCast(DropCastStmt *stmt);
extern void DropCastById(Oid castOid); extern void DropCastById(Oid castOid);
/* commands/operatorcmds.c */
extern void DefineOperator(List *names, List *parameters); extern void DefineOperator(List *names, List *parameters);
extern void RemoveOperator(RemoveOperStmt *stmt); extern void RemoveOperator(RemoveOperStmt *stmt);
extern void RemoveOperatorById(Oid operOid); extern void RemoveOperatorById(Oid operOid);
/* commands/aggregatecmds.c */
extern void DefineAggregate(List *names, List *parameters); extern void DefineAggregate(List *names, List *parameters);
extern void RemoveAggregate(RemoveAggrStmt *stmt); extern void RemoveAggregate(RemoveAggrStmt *stmt);
/* commands/typecmds.c */
extern void DefineType(List *names, List *parameters); extern void DefineType(List *names, List *parameters);
extern void RemoveType(List *names, DropBehavior behavior); extern void RemoveType(List *names, DropBehavior behavior);
extern void RemoveTypeById(Oid typeOid); extern void RemoveTypeById(Oid typeOid);
...@@ -60,6 +60,7 @@ extern void DefineDomain(CreateDomainStmt *stmt); ...@@ -60,6 +60,7 @@ extern void DefineDomain(CreateDomainStmt *stmt);
extern void RemoveDomain(List *names, DropBehavior behavior); extern void RemoveDomain(List *names, DropBehavior behavior);
extern Oid DefineCompositeType(const RangeVar *typevar, List *coldeflist); extern Oid DefineCompositeType(const RangeVar *typevar, List *coldeflist);
/* commands/opclasscmds.c */
extern void DefineOpClass(CreateOpClassStmt *stmt); extern void DefineOpClass(CreateOpClassStmt *stmt);
extern void RemoveOpClass(RemoveOpClassStmt *stmt); extern void RemoveOpClass(RemoveOpClassStmt *stmt);
extern void RemoveOpClassById(Oid opclassOid); extern void RemoveOpClassById(Oid opclassOid);
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.34 2002/09/04 22:49:37 tgl Exp $ * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.35 2002/09/21 18:39:26 tgl Exp $
* *
**********************************************************************/ **********************************************************************/
...@@ -624,8 +624,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger) ...@@ -624,8 +624,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger)
{ {
if (procStruct->prorettype == VOIDOID) if (procStruct->prorettype == VOIDOID)
/* okay */ ; /* okay */ ;
else if (procStruct->prorettype == TRIGGEROID || else if (procStruct->prorettype == TRIGGEROID)
procStruct->prorettype == OPAQUEOID)
{ {
free(prodesc->proname); free(prodesc->proname);
free(prodesc); free(prodesc);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.52 2002/09/12 00:24:09 momjian Exp $ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.53 2002/09/21 18:39:26 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -217,8 +217,7 @@ plpgsql_compile(Oid fn_oid, int functype) ...@@ -217,8 +217,7 @@ plpgsql_compile(Oid fn_oid, int functype)
if (procStruct->prorettype == VOIDOID || if (procStruct->prorettype == VOIDOID ||
procStruct->prorettype == RECORDOID) procStruct->prorettype == RECORDOID)
/* okay */ ; /* okay */ ;
else if (procStruct->prorettype == TRIGGEROID || else if (procStruct->prorettype == TRIGGEROID)
procStruct->prorettype == OPAQUEOID)
elog(ERROR, "plpgsql functions cannot return type %s" elog(ERROR, "plpgsql functions cannot return type %s"
"\n\texcept when used as triggers", "\n\texcept when used as triggers",
format_type_be(procStruct->prorettype)); format_type_be(procStruct->prorettype));
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.61 2002/09/04 20:31:48 momjian Exp $ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.62 2002/09/21 18:39:26 tgl Exp $
* *
**********************************************************************/ **********************************************************************/
...@@ -1061,8 +1061,7 @@ compile_pltcl_function(Oid fn_oid, bool is_trigger) ...@@ -1061,8 +1061,7 @@ compile_pltcl_function(Oid fn_oid, bool is_trigger)
{ {
if (procStruct->prorettype == VOIDOID) if (procStruct->prorettype == VOIDOID)
/* okay */ ; /* okay */ ;
else if (procStruct->prorettype == TRIGGEROID || else if (procStruct->prorettype == TRIGGEROID)
procStruct->prorettype == OPAQUEOID)
{ {
free(prodesc->proname); free(prodesc->proname);
free(prodesc); free(prodesc);
......
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