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.
This commit is contained in:
parent
bc49968764
commit
eb3adab568
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -200,6 +200,16 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
|
||||
will call <command>CREATE LANGUAGE</command> internally.)
|
||||
</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>
|
||||
Use the <xref linkend="sql-createfunction" endterm="sql-createfunction-title"> command to create a new
|
||||
function.
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -170,9 +170,10 @@ CREATE TRIGGER
|
||||
<para>
|
||||
In <productname>PostgreSQL</productname> versions before 7.3, it was
|
||||
necessary to declare trigger functions as returning the placeholder
|
||||
type <type>opaque</>, rather than <type>trigger</>. This is still
|
||||
supported, but is deprecated because it is obscure and causes loss of
|
||||
type safety.
|
||||
type <type>opaque</>, rather than <type>trigger</>. To support loading
|
||||
of old dump files, <command>CREATE TRIGGER</> 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>trigger</>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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
|
||||
-->
|
||||
|
||||
@ -262,8 +262,10 @@ CREATE TYPE
|
||||
forward references to the type name with the placeholder pseudo-type
|
||||
<type>OPAQUE</>. The <type>cstring</> inputs and
|
||||
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
|
||||
deprecated because it causes loss of type safety.
|
||||
To support loading
|
||||
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>
|
||||
</note>
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@ -44,17 +44,17 @@
|
||||
/*
|
||||
* Translate the input language name to lower case.
|
||||
*
|
||||
* Output buffer should be NAMEDATALEN long.
|
||||
* Output buffer must be NAMEDATALEN long.
|
||||
*/
|
||||
void
|
||||
case_translate_language_name(const char *input, char *output)
|
||||
{
|
||||
int i;
|
||||
|
||||
MemSet(output, 0, NAMEDATALEN); /* ensure result Name is zero-filled */
|
||||
|
||||
for (i = 0; i < NAMEDATALEN - 1 && input[i]; ++i)
|
||||
output[i] = tolower((unsigned char) input[i]);
|
||||
|
||||
output[i] = '\0';
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* These routines take the parse tree and pick out the
|
||||
@ -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
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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)
|
||||
char languageName[NAMEDATALEN];
|
||||
Oid procOid,
|
||||
valProcOid;
|
||||
Oid funcrettype;
|
||||
Oid typev[FUNC_MAX_ARGS];
|
||||
char nulls[Natts_pg_language];
|
||||
Datum values[Natts_pg_language];
|
||||
@ -80,10 +81,24 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
||||
if (!OidIsValid(procOid))
|
||||
elog(ERROR, "function %s() doesn't exist",
|
||||
NameListToString(stmt->plhandler));
|
||||
if (get_func_rettype(procOid) != LANGUAGE_HANDLEROID)
|
||||
elog(ERROR, "function %s() does not return type %s",
|
||||
NameListToString(stmt->plhandler),
|
||||
format_type_be(LANGUAGE_HANDLEROID));
|
||||
funcrettype = get_func_rettype(procOid);
|
||||
if (funcrettype != 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 */
|
||||
if (stmt->plvalidator)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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 @@
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_trigger.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "executor/executor.h"
|
||||
#include "miscadmin.h"
|
||||
@ -75,6 +76,7 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
||||
HeapTuple tuple;
|
||||
Oid fargtypes[FUNC_MAX_ARGS];
|
||||
Oid funcoid;
|
||||
Oid funcrettype;
|
||||
Oid trigoid;
|
||||
int found = 0;
|
||||
int i;
|
||||
@ -217,22 +219,23 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
|
||||
if (!OidIsValid(funcoid))
|
||||
elog(ERROR, "CreateTrigger: function %s() does not exist",
|
||||
NameListToString(stmt->funcname));
|
||||
tuple = SearchSysCache(PROCOID,
|
||||
ObjectIdGetDatum(funcoid),
|
||||
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)
|
||||
funcrettype = get_func_rettype(funcoid);
|
||||
if (funcrettype != TRIGGEROID)
|
||||
{
|
||||
/* OPAQUE is deprecated, but allowed for backwards compatibility */
|
||||
if (((Form_pg_proc) GETSTRUCT(tuple))->prorettype == OPAQUEOID)
|
||||
elog(NOTICE, "CreateTrigger: OPAQUE is deprecated, use type TRIGGER instead to define trigger functions");
|
||||
/*
|
||||
* We allow OPAQUE just so we can load old dump files. When we
|
||||
* 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
|
||||
elog(ERROR, "CreateTrigger: function %s() must return TRIGGER",
|
||||
NameListToString(stmt->funcname));
|
||||
}
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
/*
|
||||
* Build the new pg_trigger tuple.
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@ -188,13 +188,19 @@ DefineType(List *names, List *parameters)
|
||||
|
||||
/*
|
||||
* Look to see if type already exists (presumably as a shell; if not,
|
||||
* TypeCreate will complain). If it does then the declarations of the
|
||||
* I/O functions might use it.
|
||||
* TypeCreate will complain). If it doesn't, create it as a shell,
|
||||
* so that the OID is known for use in the I/O function definitions.
|
||||
*/
|
||||
typoid = GetSysCacheOid(TYPENAMENSP,
|
||||
CStringGetDatum(typeName),
|
||||
ObjectIdGetDatum(typeNamespace),
|
||||
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
|
||||
@ -203,15 +209,18 @@ DefineType(List *names, List *parameters)
|
||||
outputOid = findTypeIOFunction(outputName, typoid, true);
|
||||
|
||||
/*
|
||||
* Verify that I/O procs return the expected thing. OPAQUE is an
|
||||
* allowed, but deprecated, alternative to the fully type-safe
|
||||
* choices.
|
||||
* Verify that I/O procs return the expected thing. If we see OPAQUE,
|
||||
* complain and change it to the correct type-safe choice.
|
||||
*/
|
||||
resulttype = get_func_rettype(inputOid);
|
||||
if (!(OidIsValid(typoid) && resulttype == typoid))
|
||||
if (resulttype != typoid)
|
||||
{
|
||||
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
|
||||
elog(ERROR, "Type input function %s must return %s",
|
||||
NameListToString(inputName), typeName);
|
||||
@ -220,7 +229,11 @@ DefineType(List *names, List *parameters)
|
||||
if (resulttype != CSTRINGOID)
|
||||
{
|
||||
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
|
||||
elog(ERROR, "Type output function %s must return cstring",
|
||||
NameListToString(outputName));
|
||||
@ -670,8 +683,8 @@ RemoveDomain(List *names, DropBehavior behavior)
|
||||
/*
|
||||
* Find a suitable I/O function for a type.
|
||||
*
|
||||
* typeOid is the type's OID, if it already exists as a shell type,
|
||||
* otherwise InvalidOid.
|
||||
* typeOid is the type's OID (which will already exist, if only as a shell
|
||||
* type).
|
||||
*/
|
||||
static Oid
|
||||
findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
|
||||
@ -683,35 +696,15 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
|
||||
{
|
||||
/*
|
||||
* Output functions can take a single argument of the type, or two
|
||||
* arguments (data value, element OID). The signature may use
|
||||
* OPAQUE in place of the actual type name; this is the only
|
||||
* possibility if the type doesn't yet exist as a shell.
|
||||
* arguments (data value, element OID).
|
||||
*
|
||||
* Note: although we could throw a NOTICE in this routine if OPAQUE
|
||||
* is used, we do not because of the probability that it'd be
|
||||
* duplicate with a notice issued in DefineType.
|
||||
* For backwards compatibility we allow OPAQUE in place of the actual
|
||||
* type name; if we see this, we issue a NOTICE and fix up the
|
||||
* pg_proc entry.
|
||||
*/
|
||||
if (OidIsValid(typeOid))
|
||||
{
|
||||
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||
|
||||
argList[0] = typeOid;
|
||||
|
||||
procOid = LookupFuncName(procname, 1, argList);
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
argList[1] = OIDOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 2, argList);
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
}
|
||||
|
||||
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||
|
||||
argList[0] = OPAQUEOID;
|
||||
argList[0] = typeOid;
|
||||
|
||||
procOid = LookupFuncName(procname, 1, argList);
|
||||
if (OidIsValid(procOid))
|
||||
@ -723,9 +716,37 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
/* Prefer type name over OPAQUE in the failure message. */
|
||||
if (OidIsValid(typeOid))
|
||||
argList[0] = typeOid;
|
||||
/* No luck, try it with OPAQUE */
|
||||
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||
|
||||
argList[0] = OPAQUEOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 1, argList);
|
||||
|
||||
if (!OidIsValid(procOid))
|
||||
{
|
||||
argList[1] = OIDOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 2, argList);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Use type name, not OPAQUE, in the failure message. */
|
||||
argList[0] = typeOid;
|
||||
|
||||
func_error("TypeCreate", procname, 1, argList, NULL);
|
||||
}
|
||||
@ -733,8 +754,10 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
|
||||
{
|
||||
/*
|
||||
* Input functions can take a single argument of type CSTRING, or
|
||||
* three arguments (string, element OID, typmod). The signature
|
||||
* may use OPAQUE in place of CSTRING.
|
||||
* three arguments (string, element OID, typmod).
|
||||
*
|
||||
* 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));
|
||||
|
||||
@ -751,20 +774,35 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
/* No luck, try it with OPAQUE */
|
||||
MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||
|
||||
argList[0] = OPAQUEOID;
|
||||
|
||||
procOid = LookupFuncName(procname, 1, argList);
|
||||
if (OidIsValid(procOid))
|
||||
return procOid;
|
||||
|
||||
argList[1] = OIDOID;
|
||||
argList[2] = INT4OID;
|
||||
if (!OidIsValid(procOid))
|
||||
{
|
||||
argList[1] = OIDOID;
|
||||
argList[2] = INT4OID;
|
||||
|
||||
procOid = LookupFuncName(procname, 3, argList);
|
||||
}
|
||||
|
||||
procOid = LookupFuncName(procname, 3, argList);
|
||||
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;
|
||||
}
|
||||
|
||||
/* Use CSTRING (preferred) in the error message */
|
||||
argList[0] = CSTRINGOID;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* 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 @@
|
||||
|
||||
#define DEFAULT_TYPDELIM ','
|
||||
|
||||
/*
|
||||
* prototypes in indexcmds.c
|
||||
*/
|
||||
/* commands/indexcmds.c */
|
||||
extern void DefineIndex(RangeVar *heapRelation,
|
||||
char *indexRelationName,
|
||||
char *accessMethodName,
|
||||
@ -35,24 +33,26 @@ extern void ReindexIndex(RangeVar *indexRelation, bool force);
|
||||
extern void ReindexTable(RangeVar *relation, bool force);
|
||||
extern void ReindexDatabase(const char *databaseName, bool force, bool all);
|
||||
|
||||
/*
|
||||
* DefineFoo and RemoveFoo are now both in foocmds.c
|
||||
*/
|
||||
|
||||
/* commands/functioncmds.c */
|
||||
extern void CreateFunction(CreateFunctionStmt *stmt);
|
||||
extern void RemoveFunction(RemoveFuncStmt *stmt);
|
||||
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 DropCast(DropCastStmt *stmt);
|
||||
extern void DropCastById(Oid castOid);
|
||||
|
||||
/* commands/operatorcmds.c */
|
||||
extern void DefineOperator(List *names, List *parameters);
|
||||
extern void RemoveOperator(RemoveOperStmt *stmt);
|
||||
extern void RemoveOperatorById(Oid operOid);
|
||||
|
||||
/* commands/aggregatecmds.c */
|
||||
extern void DefineAggregate(List *names, List *parameters);
|
||||
extern void RemoveAggregate(RemoveAggrStmt *stmt);
|
||||
|
||||
/* commands/typecmds.c */
|
||||
extern void DefineType(List *names, List *parameters);
|
||||
extern void RemoveType(List *names, DropBehavior behavior);
|
||||
extern void RemoveTypeById(Oid typeOid);
|
||||
@ -60,6 +60,7 @@ extern void DefineDomain(CreateDomainStmt *stmt);
|
||||
extern void RemoveDomain(List *names, DropBehavior behavior);
|
||||
extern Oid DefineCompositeType(const RangeVar *typevar, List *coldeflist);
|
||||
|
||||
/* commands/opclasscmds.c */
|
||||
extern void DefineOpClass(CreateOpClassStmt *stmt);
|
||||
extern void RemoveOpClass(RemoveOpClassStmt *stmt);
|
||||
extern void RemoveOpClassById(Oid opclassOid);
|
||||
|
@ -33,7 +33,7 @@
|
||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
if (procStruct->prorettype == VOIDOID)
|
||||
/* okay */ ;
|
||||
else if (procStruct->prorettype == TRIGGEROID ||
|
||||
procStruct->prorettype == OPAQUEOID)
|
||||
else if (procStruct->prorettype == TRIGGEROID)
|
||||
{
|
||||
free(prodesc->proname);
|
||||
free(prodesc);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* procedural language
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
@ -217,8 +217,7 @@ plpgsql_compile(Oid fn_oid, int functype)
|
||||
if (procStruct->prorettype == VOIDOID ||
|
||||
procStruct->prorettype == RECORDOID)
|
||||
/* okay */ ;
|
||||
else if (procStruct->prorettype == TRIGGEROID ||
|
||||
procStruct->prorettype == OPAQUEOID)
|
||||
else if (procStruct->prorettype == TRIGGEROID)
|
||||
elog(ERROR, "plpgsql functions cannot return type %s"
|
||||
"\n\texcept when used as triggers",
|
||||
format_type_be(procStruct->prorettype));
|
||||
|
@ -31,7 +31,7 @@
|
||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
if (procStruct->prorettype == VOIDOID)
|
||||
/* okay */ ;
|
||||
else if (procStruct->prorettype == TRIGGEROID ||
|
||||
procStruct->prorettype == OPAQUEOID)
|
||||
else if (procStruct->prorettype == TRIGGEROID)
|
||||
{
|
||||
free(prodesc->proname);
|
||||
free(prodesc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user