Provide an upgrade strategy for dump files containing functions declared
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 21 Sep 2002 18:39:26 +0000 (18:39 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 21 Sep 2002 18:39:26 +0000 (18:39 +0000)
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.

12 files changed:
doc/src/sgml/ref/create_language.sgml
doc/src/sgml/ref/create_trigger.sgml
doc/src/sgml/ref/create_type.sgml
src/backend/commands/define.c
src/backend/commands/functioncmds.c
src/backend/commands/proclang.c
src/backend/commands/trigger.c
src/backend/commands/typecmds.c
src/include/commands/defrem.h
src/pl/plperl/plperl.c
src/pl/plpgsql/src/pl_comp.c
src/pl/tcl/pltcl.c

index 5cdf5dc9345a91274ecc60394906e367df0bb9f5..1d6e61f07361f6c34d174792a072f243bb6e276d 100644 (file)
@@ -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.
index c736dd95df90114d3e1106a86ecec9687af38a8b..1134cd800e2497e9a25f2a93028a78a28bbd6ea3 100644 (file)
@@ -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>
index 26c134303fa2ff2f99ec1da60e9051e794803c9e..9243bda86fad443bcec1d3d2bc5546b47d3be236 100644 (file)
@@ -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>
 
index 09687818d831b6dc77741e1b967134227b2d9fc3..5b0624a03eae37f088d7fb57711c0237550d97dd 100644 (file)
@@ -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
 /*
  * 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';
 }
 
 
index f67538625ac6fa62ce547458fe1face42bb4f396..7857eb3bb3fea155ed272f8d078f7130be8f4d78 100644 (file)
@@ -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
index 0d282e8f85c98174fd3ecc7cd499d60e402028aa..03d022f1f4fb2da0ccb563f2fc7febbe7dde3a2b 100644 (file)
@@ -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)
index 1d0e969176c5f45e052d7bf984a99a5caa1c4aeb..eb78fe484a35ea82ba1bef0f8e8a1555621de22a 100644 (file)
@@ -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.
index d53f9abb94524310703f928d98a7b7768c49b7dd..3dea8bf633062aa689a2cbb9648329d6d1022233 100644 (file)
@@ -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,49 +696,57 @@ 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;
+               MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
 
-                       procOid = LookupFuncName(procname, 1, argList);
-                       if (OidIsValid(procOid))
-                               return procOid;
+               argList[0] = typeOid;
 
-                       argList[1] = OIDOID;
+               procOid = LookupFuncName(procname, 1, argList);
+               if (OidIsValid(procOid))
+                       return procOid;
 
-                       procOid = LookupFuncName(procname, 2, argList);
-                       if (OidIsValid(procOid))
-                               return procOid;
+               argList[1] = OIDOID;
 
-               }
+               procOid = LookupFuncName(procname, 2, argList);
+               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;
+               if (!OidIsValid(procOid))
+               {
+                       argList[1] = OIDOID;
+
+                       procOid = LookupFuncName(procname, 2, argList);
+               }
 
-               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;
+               }
 
-               /* Prefer type name over OPAQUE in the failure message. */
-               if (OidIsValid(typeOid))
-                       argList[0] = typeOid;
+               /* 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;
index e135d68af0cd9f13d5aec6fc85b6c43fbb4aa24e..401610af6aca074bf8b45cbda5d5689caaaef36c 100644 (file)
@@ -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);
index 2fe9f688ac7f136cf90a7ea0ab9f97bec0ddb3c0..299e389405fc4cdedda0fcf0100f656dfa0a320d 100644 (file)
@@ -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);
index 00f2997ae3e463bac38a1bdc4400879b98869793..56c5ca3e70b12cc14a0a4454c5f83c8130316a2b 100644 (file)
@@ -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));
index 44ee940e7855761ff43c6964361ad3846b03a770..d498a9b63744ab3ae429e02100200f9eaa1a4afd 100644 (file)
@@ -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);