OSDN Git Service

Fix coredump in pg_get_triggerdef, ensure function name is schema-
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 20 May 2003 20:35:10 +0000 (20:35 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 20 May 2003 20:35:10 +0000 (20:35 +0000)
qualified when necessary, simplify argument-printing code.

src/backend/utils/adt/ruleutils.c

index 581c5b2..e41d324 100644 (file)
@@ -3,7 +3,7 @@
  *                             back to source text
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.139 2003/04/24 21:16:43 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.140 2003/05/20 20:35:10 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
 #include "catalog/pg_cast.h"
 #include "catalog/pg_constraint.h"
 #include "catalog/pg_index.h"
-#include "catalog/pg_trigger.h"
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_shadow.h"
+#include "catalog/pg_trigger.h"
 #include "executor/spi.h"
 #include "lib/stringinfo.h"
 #include "nodes/makefuncs.h"
@@ -380,53 +380,34 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
        Oid                     trigid = PG_GETARG_OID(0);
        text       *trigdef;
        HeapTuple       ht_trig;
-       HeapTuple       ht_proc;
        Form_pg_trigger trigrec;
        int                     len;
        StringInfoData buf;
-        Relation        tgrel;
-        ScanKeyData skey[1];
-        SysScanDesc tgscan;
-       int             findx = 0;
-       const char *tgargs;
-       const char *p;
-       char            *tgfname;
+       Relation        tgrel;
+       ScanKeyData skey[1];
+       SysScanDesc tgscan;
+       int                     findx = 0;
        char            *tgname;
 
        /*
         * Fetch the pg_trigger tuple by the Oid of the trigger
         */
-        tgrel = heap_openr(TriggerRelationName, AccessShareLock);
+       tgrel = heap_openr(TriggerRelationName, AccessShareLock);
 
-        /*
-         * Find the trigger
-         */
-        ScanKeyEntryInitialize(&skey[0], 0x0,
-                                                   ObjectIdAttributeNumber, F_OIDEQ,
-                                                   ObjectIdGetDatum(trigid));
+       ScanKeyEntryInitialize(&skey[0], 0x0,
+                                                  ObjectIdAttributeNumber, F_OIDEQ,
+                                                  ObjectIdGetDatum(trigid));
 
-        tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
-                                                                SnapshotNow, 1, skey);
+       tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
+                                                               SnapshotNow, 1, skey);
 
-        ht_trig = systable_getnext(tgscan);
+       ht_trig = systable_getnext(tgscan);
 
-        if (!HeapTupleIsValid(ht_trig))
-                elog(ERROR, "pg_get_triggerdef: there is no trigger with oid %u",
-                         trigid);
+       if (!HeapTupleIsValid(ht_trig))
+               elog(ERROR, "pg_get_triggerdef: there is no trigger with oid %u",
+                        trigid);
 
        trigrec = (Form_pg_trigger) GETSTRUCT(ht_trig);
-       systable_endscan(tgscan);
-
-       /*
-        * Fetch the pg_proc tuple of the trigger's function
-        */
-       ht_proc = SearchSysCache(PROCOID,
-                                                  ObjectIdGetDatum(trigrec->tgfoid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(ht_proc))
-               elog(ERROR, "syscache lookup for function %u failed", trigrec->tgfoid);
-
-       tgfname = NameStr(((Form_pg_proc) GETSTRUCT(ht_proc))->proname);
 
        /*
         * Start the trigger definition. Note that the trigger's name should
@@ -464,16 +445,13 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
                        appendStringInfo(&buf, " UPDATE");
        }
        appendStringInfo(&buf, " ON %s ",
-                                       generate_relation_name(trigrec->tgrelid));
-
+                                        generate_relation_name(trigrec->tgrelid));
 
        if (trigrec->tgisconstraint)
        {
-               if (trigrec->tgconstrrelid != 0)
-               {
+               if (trigrec->tgconstrrelid != InvalidOid)
                        appendStringInfo(&buf, "FROM %s ",
-                                       generate_relation_name(trigrec->tgconstrrelid));
-               }
+                                                        generate_relation_name(trigrec->tgconstrrelid));
                if (!trigrec->tgdeferrable)
                        appendStringInfo(&buf, "NOT ");
                appendStringInfo(&buf, "DEFERRABLE INITIALLY ");
@@ -490,50 +468,39 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
                appendStringInfo(&buf, "FOR EACH STATEMENT ");
 
        appendStringInfo(&buf, "EXECUTE PROCEDURE %s(",
-                                       quote_identifier(tgfname));
-
-       /* Get args string */
-       tgargs = DatumGetCString(DirectFunctionCall1(byteaout,
-                                                               PointerGetDatum(&trigrec->tgargs)));
-       /* If it's NULL, fail */
-       if (tgargs == NULL)
-               elog(ERROR, "pg_get_triggerdef: tgargs is NULL");
-
-       for (findx = 0; findx < trigrec->tgnargs; findx++)
-       {
-               const char *s;
-
-               for (p = tgargs;;)
+                                        generate_function_name(trigrec->tgfoid, 0, NULL));
+
+       if (trigrec->tgnargs > 0)
+       {
+               bytea      *val;
+               bool            isnull;
+               char       *p;
+               int                     i;
+
+               val = (bytea *) fastgetattr(ht_trig,
+                                                                       Anum_pg_trigger_tgargs,
+                                                                       tgrel->rd_att, &isnull);
+               if (isnull)
+                       elog(ERROR, "tgargs is null for trigger %u", trigid);
+               p = (char *) VARDATA(val);
+               for (i = 0; i < trigrec->tgnargs; i++)
                {
-                       p = strchr(p, '\\');
-                       if (p == NULL)
+                       if (i > 0)
+                               appendStringInfo(&buf, ", ");
+                       appendStringInfoChar(&buf, '\'');
+                       while (*p)
                        {
-                               elog(ERROR, "pg_get_triggerdef: bad argument string for trigger");
+                               /* escape quotes and backslashes */
+                               if (*p == '\'' || *p == '\\')
+                                       appendStringInfoChar(&buf, '\\');
+                               appendStringInfoChar(&buf, *p++);
                        }
                        p++;
-                       if (*p == '\\')
-                       {
-                               p++;
-                               continue;
-                       }
-                       if (p[0] == '0' && p[1] == '0' && p[2] == '0')
-                               break;
-               }
-               p--;
-               appendStringInfoChar(&buf, '\'');
-               for (s = tgargs; s < p;)
-               {
-                       /* If character is an apostrophe, escape it */
-                       if (*s == '\'')
-                               appendStringInfoChar(&buf, '\\');
-                       appendStringInfoChar(&buf, *s++);
+                       appendStringInfoChar(&buf, '\'');
                }
-               appendStringInfoChar(&buf, '\'');
-               appendStringInfo(&buf, (findx < trigrec->tgnargs - 1) ? ", " : "");
-               tgargs = p + 4;
        }
 
-       /* Deliberately omit semi-colon */
+       /* We deliberately do not put semi-colon at end */
        appendStringInfo(&buf, ")");
 
        /*
@@ -546,8 +513,8 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
 
        pfree(buf.data);
 
-       ReleaseSysCache(ht_trig);
-       ReleaseSysCache(ht_proc);
+       systable_endscan(tgscan);
+
        heap_close(tgrel, AccessShareLock);
 
        PG_RETURN_TEXT_P(trigdef);