Commit 0b5b3e9e authored by Tom Lane's avatar Tom Lane

Fix coredump in pg_get_triggerdef, ensure function name is schema-

qualified when necessary, simplify argument-printing code.
parent dc554458
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* back to source text * back to source text
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -49,10 +49,10 @@ ...@@ -49,10 +49,10 @@
#include "catalog/pg_cast.h" #include "catalog/pg_cast.h"
#include "catalog/pg_constraint.h" #include "catalog/pg_constraint.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/pg_trigger.h"
#include "executor/spi.h" #include "executor/spi.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
...@@ -380,7 +380,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) ...@@ -380,7 +380,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
Oid trigid = PG_GETARG_OID(0); Oid trigid = PG_GETARG_OID(0);
text *trigdef; text *trigdef;
HeapTuple ht_trig; HeapTuple ht_trig;
HeapTuple ht_proc;
Form_pg_trigger trigrec; Form_pg_trigger trigrec;
int len; int len;
StringInfoData buf; StringInfoData buf;
...@@ -388,9 +387,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) ...@@ -388,9 +387,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
ScanKeyData skey[1]; ScanKeyData skey[1];
SysScanDesc tgscan; SysScanDesc tgscan;
int findx = 0; int findx = 0;
const char *tgargs;
const char *p;
char *tgfname;
char *tgname; char *tgname;
/* /*
...@@ -398,9 +394,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) ...@@ -398,9 +394,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
*/ */
tgrel = heap_openr(TriggerRelationName, AccessShareLock); tgrel = heap_openr(TriggerRelationName, AccessShareLock);
/*
* Find the trigger
*/
ScanKeyEntryInitialize(&skey[0], 0x0, ScanKeyEntryInitialize(&skey[0], 0x0,
ObjectIdAttributeNumber, F_OIDEQ, ObjectIdAttributeNumber, F_OIDEQ,
ObjectIdGetDatum(trigid)); ObjectIdGetDatum(trigid));
...@@ -415,18 +408,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) ...@@ -415,18 +408,6 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
trigid); trigid);
trigrec = (Form_pg_trigger) GETSTRUCT(ht_trig); 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 * Start the trigger definition. Note that the trigger's name should
...@@ -466,14 +447,11 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) ...@@ -466,14 +447,11 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, " ON %s ", appendStringInfo(&buf, " ON %s ",
generate_relation_name(trigrec->tgrelid)); generate_relation_name(trigrec->tgrelid));
if (trigrec->tgisconstraint) if (trigrec->tgisconstraint)
{ {
if (trigrec->tgconstrrelid != 0) if (trigrec->tgconstrrelid != InvalidOid)
{
appendStringInfo(&buf, "FROM %s ", appendStringInfo(&buf, "FROM %s ",
generate_relation_name(trigrec->tgconstrrelid)); generate_relation_name(trigrec->tgconstrrelid));
}
if (!trigrec->tgdeferrable) if (!trigrec->tgdeferrable)
appendStringInfo(&buf, "NOT "); appendStringInfo(&buf, "NOT ");
appendStringInfo(&buf, "DEFERRABLE INITIALLY "); appendStringInfo(&buf, "DEFERRABLE INITIALLY ");
...@@ -490,50 +468,39 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) ...@@ -490,50 +468,39 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, "FOR EACH STATEMENT "); appendStringInfo(&buf, "FOR EACH STATEMENT ");
appendStringInfo(&buf, "EXECUTE PROCEDURE %s(", appendStringInfo(&buf, "EXECUTE PROCEDURE %s(",
quote_identifier(tgfname)); generate_function_name(trigrec->tgfoid, 0, NULL));
/* 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++) if (trigrec->tgnargs > 0)
{ {
const char *s; bytea *val;
bool isnull;
char *p;
int i;
for (p = tgargs;;) val = (bytea *) fastgetattr(ht_trig,
{ Anum_pg_trigger_tgargs,
p = strchr(p, '\\'); tgrel->rd_att, &isnull);
if (p == NULL) if (isnull)
{ elog(ERROR, "tgargs is null for trigger %u", trigid);
elog(ERROR, "pg_get_triggerdef: bad argument string for trigger"); p = (char *) VARDATA(val);
} for (i = 0; i < trigrec->tgnargs; i++)
p++;
if (*p == '\\')
{ {
p++; if (i > 0)
continue; appendStringInfo(&buf, ", ");
}
if (p[0] == '0' && p[1] == '0' && p[2] == '0')
break;
}
p--;
appendStringInfoChar(&buf, '\''); appendStringInfoChar(&buf, '\'');
for (s = tgargs; s < p;) while (*p)
{ {
/* If character is an apostrophe, escape it */ /* escape quotes and backslashes */
if (*s == '\'') if (*p == '\'' || *p == '\\')
appendStringInfoChar(&buf, '\\'); appendStringInfoChar(&buf, '\\');
appendStringInfoChar(&buf, *s++); appendStringInfoChar(&buf, *p++);
} }
p++;
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, ")"); appendStringInfo(&buf, ")");
/* /*
...@@ -546,8 +513,8 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) ...@@ -546,8 +513,8 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
pfree(buf.data); pfree(buf.data);
ReleaseSysCache(ht_trig); systable_endscan(tgscan);
ReleaseSysCache(ht_proc);
heap_close(tgrel, AccessShareLock); heap_close(tgrel, AccessShareLock);
PG_RETURN_TEXT_P(trigdef); PG_RETURN_TEXT_P(trigdef);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment