From eb3adab5685ce5a60bcf96628244f1e2a8e0ab3b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 21 Sep 2002 18:39:26 +0000 Subject: [PATCH] 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. --- doc/src/sgml/ref/create_language.sgml | 12 ++- doc/src/sgml/ref/create_trigger.sgml | 9 +- doc/src/sgml/ref/create_type.sgml | 8 +- src/backend/commands/define.c | 8 +- src/backend/commands/functioncmds.c | 81 +++++++++++++++- src/backend/commands/proclang.c | 25 ++++- src/backend/commands/trigger.c | 27 +++--- src/backend/commands/typecmds.c | 130 +++++++++++++++++--------- src/include/commands/defrem.h | 17 ++-- src/pl/plperl/plperl.c | 5 +- src/pl/plpgsql/src/pl_comp.c | 5 +- src/pl/tcl/pltcl.c | 5 +- 12 files changed, 239 insertions(+), 93 deletions(-) diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml index 5cdf5dc934..1d6e61f073 100644 --- a/doc/src/sgml/ref/create_language.sgml +++ b/doc/src/sgml/ref/create_language.sgml @@ -1,5 +1,5 @@ @@ -200,6 +200,16 @@ ERROR: PL handler function funcnameCREATE LANGUAGE internally.) + + In PostgreSQL versions before 7.3, it was + necessary to declare handler functions as returning the placeholder + type opaque, rather than language_handler. + To support loading + of old dump files, CREATE LANGUAGE will accept a function + declared as returning opaque, but it will issue a NOTICE and + change the function's declared return type to language_handler. + + Use the command to create a new function. diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml index c736dd95df..1134cd800e 100644 --- a/doc/src/sgml/ref/create_trigger.sgml +++ b/doc/src/sgml/ref/create_trigger.sgml @@ -1,5 +1,5 @@ @@ -170,9 +170,10 @@ CREATE TRIGGER In PostgreSQL versions before 7.3, it was necessary to declare trigger functions as returning the placeholder - type opaque, rather than trigger. This is still - supported, but is deprecated because it is obscure and causes loss of - type safety. + type opaque, rather than trigger. To support loading + of old dump files, CREATE TRIGGER will accept a function + declared as returning opaque, but it will issue a NOTICE and + change the function's declared return type to trigger. diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 26c134303f..9243bda86f 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -1,5 +1,5 @@ @@ -262,8 +262,10 @@ CREATE TYPE forward references to the type name with the placeholder pseudo-type OPAQUE. The cstring inputs and results also had to be declared as OPAQUE before 7.3. - Use of 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, CREATE TYPE will accept functions + declared using opaque, but it will issue a NOTICE and + change the function's declaration to use the correct types. diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 09687818d8..5b0624a03e 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -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'; } diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index f67538625a..7857eb3bb3 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -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 diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 0d282e8f85..03d022f1f4 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -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) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 1d0e969176..eb78fe484a 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -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. diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index d53f9abb94..3dea8bf633 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -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; diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index e135d68af0..401610af6a 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -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); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 2fe9f688ac..299e389405 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -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); diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 00f2997ae3..56c5ca3e70 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -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)); diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 44ee940e78..d498a9b637 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -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);