diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 581c5b20ecf59944e437ada28931256f309eb967..e41d3245818cbbd7873360bcd673fb24e291ee00 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);