]> granicus.if.org Git - postgresql/commitdiff
When compiling a plpgsql trigger function, include the OID of the table
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 18 Aug 2003 19:16:02 +0000 (19:16 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 18 Aug 2003 19:16:02 +0000 (19:16 +0000)
the trigger is attached to in the hashkey.  This ensures that we will
create separate compiled trees for each table the trigger is used with,
avoiding possible datatype-mismatch problems if the tables have different
rowtypes.  This is essentially the same bug recently identified in plpython
--- though plpgsql doesn't seem as prone to crash when the rowtype changes
underneath it.  But failing robustly is no substitute for just working.

src/pl/plpgsql/src/pl_comp.c
src/pl/plpgsql/src/plpgsql.h

index e4d7b3c062c87ed8d11e7399a78d18641ab5351a..84685c2103447f3d967606aa1ee2bcc9383b59e3 100644 (file)
@@ -3,7 +3,7 @@
  *                       procedural language
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.66 2003/08/08 19:19:32 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.67 2003/08/18 19:16:02 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -100,16 +100,16 @@ typedef struct plpgsql_hashent
  */
 static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
                   HeapTuple procTup,
-                  PLpgSQL_func_hashkey * hashkey);
+                  PLpgSQL_func_hashkey *hashkey);
 static void plpgsql_compile_error_callback(void *arg);
 static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod);
-static void compute_function_hashkey(FmgrInfo *flinfo,
+static void compute_function_hashkey(FunctionCallInfo fcinfo,
                                                 Form_pg_proc procStruct,
-                                                PLpgSQL_func_hashkey * hashkey);
-static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey * func_key);
-static void plpgsql_HashTableInsert(PLpgSQL_function * function,
-                                               PLpgSQL_func_hashkey * func_key);
-static void plpgsql_HashTableDelete(PLpgSQL_function * function);
+                                                PLpgSQL_func_hashkey *hashkey);
+static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
+static void plpgsql_HashTableInsert(PLpgSQL_function *function,
+                                               PLpgSQL_func_hashkey *func_key);
+static void plpgsql_HashTableDelete(PLpgSQL_function *function);
 
 /*
  * This routine is a crock, and so is everyplace that calls it.  The problem
@@ -169,7 +169,7 @@ plpgsql_compile(FunctionCallInfo fcinfo)
                        plpgsql_HashTableInit();
 
                /* Compute hashkey using function signature and actual arg types */
-               compute_function_hashkey(fcinfo->flinfo, procStruct, &hashkey);
+               compute_function_hashkey(fcinfo, procStruct, &hashkey);
                hashkey_valid = true;
 
                /* And do the lookup */
@@ -203,7 +203,7 @@ plpgsql_compile(FunctionCallInfo fcinfo)
                 * the completed function.
                 */
                if (!hashkey_valid)
-                       compute_function_hashkey(fcinfo->flinfo, procStruct, &hashkey);
+                       compute_function_hashkey(fcinfo, procStruct, &hashkey);
 
                /*
                 * Do the hard part.
@@ -230,7 +230,7 @@ plpgsql_compile(FunctionCallInfo fcinfo)
 static PLpgSQL_function *
 do_compile(FunctionCallInfo fcinfo,
                   HeapTuple procTup,
-                  PLpgSQL_func_hashkey * hashkey)
+                  PLpgSQL_func_hashkey *hashkey)
 {
        Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
        int                     functype = CALLED_AS_TRIGGER(fcinfo) ? T_TRIGGER : T_FUNCTION;
@@ -1711,16 +1711,25 @@ plpgsql_yyerror(const char *s)
  * The hashkey is returned into the caller-provided storage at *hashkey.
  */
 static void
-compute_function_hashkey(FmgrInfo *flinfo,
+compute_function_hashkey(FunctionCallInfo fcinfo,
                                                 Form_pg_proc procStruct,
-                                                PLpgSQL_func_hashkey * hashkey)
+                                                PLpgSQL_func_hashkey *hashkey)
 {
        int                     i;
 
        /* Make sure any unused bytes of the struct are zero */
        MemSet(hashkey, 0, sizeof(PLpgSQL_func_hashkey));
 
-       hashkey->funcOid = flinfo->fn_oid;
+       /* get function OID */
+       hashkey->funcOid = fcinfo->flinfo->fn_oid;
+
+       /* if trigger, get relation OID */
+       if (CALLED_AS_TRIGGER(fcinfo))
+       {
+               TriggerData *trigdata = (TriggerData *) fcinfo->context;
+
+               hashkey->trigrelOid = RelationGetRelid(trigdata->tg_relation);
+       }
 
        /* get the argument types */
        for (i = 0; i < procStruct->pronargs; i++)
@@ -1737,7 +1746,7 @@ compute_function_hashkey(FmgrInfo *flinfo,
                if (argtypeid == ANYARRAYOID || argtypeid == ANYELEMENTOID ||
                        argtypeid == ANYOID)
                {
-                       argtypeid = get_fn_expr_argtype(flinfo, i);
+                       argtypeid = get_fn_expr_argtype(fcinfo->flinfo, i);
                        if (!OidIsValid(argtypeid))
                                ereport(ERROR,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -1767,7 +1776,7 @@ plpgsql_HashTableInit(void)
 }
 
 static PLpgSQL_function *
-plpgsql_HashTableLookup(PLpgSQL_func_hashkey * func_key)
+plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key)
 {
        plpgsql_HashEnt *hentry;
 
@@ -1782,8 +1791,8 @@ plpgsql_HashTableLookup(PLpgSQL_func_hashkey * func_key)
 }
 
 static void
-plpgsql_HashTableInsert(PLpgSQL_function * function,
-                                               PLpgSQL_func_hashkey * func_key)
+plpgsql_HashTableInsert(PLpgSQL_function *function,
+                                               PLpgSQL_func_hashkey *func_key)
 {
        plpgsql_HashEnt *hentry;
        bool            found;
@@ -1805,7 +1814,7 @@ plpgsql_HashTableInsert(PLpgSQL_function * function,
 }
 
 static void
-plpgsql_HashTableDelete(PLpgSQL_function * function)
+plpgsql_HashTableDelete(PLpgSQL_function *function)
 {
        plpgsql_HashEnt *hentry;
 
index 1cb5ea2de902d616b1405539f2e92d99f8918675..3ec33091e358500d7dfbc893d63caab1eea7f8b1 100644 (file)
@@ -3,7 +3,7 @@
  *                       procedural language
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.39 2003/08/04 00:43:33 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.40 2003/08/18 19:16:02 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -491,6 +491,14 @@ typedef struct PLpgSQL_func_hashkey
 {                                                              /* Hash lookup key for functions */
        Oid                     funcOid;
 
+       /*
+        * For a trigger function, the OID of the relation triggered on is part
+        * of the hashkey --- we want to compile the trigger separately for each
+        * relation it is used with, in case the rowtype is different.  Zero if
+        * not called as a trigger.
+        */
+       Oid                     trigrelOid;
+
        /*
         * We include actual argument types in the hash key to support
         * polymorphic PLpgSQL functions.  Be careful that extra positions are