aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-05-20 20:35:10 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-05-20 20:35:10 +0000
commit0b5b3e9e65e65890ba73a3e9c282e136ee42a9d6 (patch)
tree81f018c5dd38270842abf0435f409f72e928c276 /src
parentdc554458ad0aa810e6b0fd21fe672842cd11599b (diff)
downloadpostgresql-0b5b3e9e65e65890ba73a3e9c282e136ee42a9d6.tar.gz
postgresql-0b5b3e9e65e65890ba73a3e9c282e136ee42a9d6.zip
Fix coredump in pg_get_triggerdef, ensure function name is schema-
qualified when necessary, simplify argument-printing code.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/ruleutils.c127
1 files changed, 47 insertions, 80 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 581c5b20ecf..e41d3245818 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -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.
*
@@ -49,10 +49,10 @@
#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);