? GNUmakefile ? config.log ? config.status ? postgres.core ? ruleutils.c ? contrib/tsearch/.deps ? contrib/tsearch/libtsearch.so.0 ? contrib/tsearch/parser.c ? contrib/tsearch/tsearch.sql ? src/Makefile.global ? src/backend/postgres ? src/backend/access/common/.deps ? src/backend/access/gist/.deps ? src/backend/access/hash/.deps ? src/backend/access/heap/.deps ? src/backend/access/index/.deps ? src/backend/access/nbtree/.deps ? src/backend/access/rtree/.deps ? src/backend/access/transam/.deps ? src/backend/bootstrap/.deps ? src/backend/catalog/.deps ? src/backend/catalog/postgres.bki ? src/backend/catalog/postgres.description ? src/backend/commands/.deps ? src/backend/executor/.deps ? src/backend/lib/.deps ? src/backend/libpq/.deps ? src/backend/main/.deps ? src/backend/nodes/.deps ? src/backend/optimizer/geqo/.deps ? src/backend/optimizer/path/.deps ? src/backend/optimizer/plan/.deps ? src/backend/optimizer/prep/.deps ? src/backend/optimizer/util/.deps ? src/backend/parser/.deps ? src/backend/port/.deps ? src/backend/postmaster/.deps ? src/backend/regex/.deps ? src/backend/rewrite/.deps ? src/backend/storage/buffer/.deps ? src/backend/storage/file/.deps ? src/backend/storage/freespace/.deps ? src/backend/storage/ipc/.deps ? src/backend/storage/large_object/.deps ? src/backend/storage/lmgr/.deps ? src/backend/storage/page/.deps ? src/backend/storage/smgr/.deps ? src/backend/tcop/.deps ? src/backend/utils/.deps ? src/backend/utils/adt/.deps ? src/backend/utils/cache/.deps ? src/backend/utils/error/.deps ? src/backend/utils/fmgr/.deps ? src/backend/utils/hash/.deps ? src/backend/utils/init/.deps ? src/backend/utils/mb/.deps ? src/backend/utils/mb/conversion_procs/conversion_create.sql ? src/backend/utils/mb/conversion_procs/ascii_and_mic/.deps ? src/backend/utils/mb/conversion_procs/ascii_and_mic/libascii_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/.deps ? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/libcyrillic_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/.deps ? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/libeuc_cn_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/.deps ? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/libeuc_jp_and_sjis.so.0 ? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/.deps ? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/libeuc_kr_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/.deps ? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/libeuc_tw_and_big5.so.0 ? src/backend/utils/mb/conversion_procs/latin2_and_win1250/.deps ? src/backend/utils/mb/conversion_procs/latin2_and_win1250/liblatin2_and_win1250.so.0 ? src/backend/utils/mb/conversion_procs/latin_and_mic/.deps ? src/backend/utils/mb/conversion_procs/latin_and_mic/liblatin_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_ascii/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_ascii/libutf8_and_ascii.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_big5/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_big5/libutf8_and_big5.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/libutf8_and_cyrillic.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/libutf8_and_euc_cn.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/libutf8_and_euc_jp.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/libutf8_and_euc_kr.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/libutf8_and_euc_tw.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/libutf8_and_gb18030.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_gbk/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_gbk/libutf8_and_gbk.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/libutf8_and_iso8859.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/libutf8_and_iso8859_1.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_johab/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_johab/libutf8_and_johab.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_sjis/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_sjis/libutf8_and_sjis.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_tcvn/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_tcvn/libutf8_and_tcvn.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_uhc/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_uhc/libutf8_and_uhc.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_win1250/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_win1250/libutf8_and_win1250.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_win1256/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_win1256/libutf8_and_win1256.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_win874/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_win874/libutf8_and_win874.so.0 ? src/backend/utils/misc/.deps ? src/backend/utils/mmgr/.deps ? src/backend/utils/sort/.deps ? src/backend/utils/time/.deps ? src/bin/initdb/initdb ? src/bin/initlocation/initlocation ? src/bin/ipcclean/ipcclean ? src/bin/pg_config/pg_config ? src/bin/pg_controldata/.deps ? src/bin/pg_controldata/pg_controldata ? src/bin/pg_ctl/pg_ctl ? src/bin/pg_dump/.deps ? src/bin/pg_dump/pg_dump ? src/bin/pg_dump/pg_dumpall ? src/bin/pg_dump/pg_restore ? src/bin/pg_encoding/.deps ? src/bin/pg_encoding/pg_encoding ? src/bin/pg_id/.deps ? src/bin/pg_id/pg_id ? src/bin/pg_resetxlog/.deps ? src/bin/pg_resetxlog/pg_resetxlog ? src/bin/psql/.deps ? src/bin/psql/psql ? src/bin/scripts/createlang ? src/include/pg_config.h ? src/include/stamp-h ? src/interfaces/ecpg/lib/.deps ? src/interfaces/ecpg/lib/libecpg.so.3 ? src/interfaces/ecpg/preproc/.deps ? src/interfaces/ecpg/preproc/ecpg ? src/interfaces/libpq/.deps ? src/interfaces/libpq/libpq.so.3 ? src/pl/plpgsql/src/.deps ? src/pl/plpgsql/src/libplpgsql.so.1 ? src/port/.deps Index: src/backend/utils/adt/ruleutils.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/ruleutils.c,v retrieving revision 1.136 diff -c -r1.136 ruleutils.c *** src/backend/utils/adt/ruleutils.c 2003/02/16 02:30:39 1.136 --- src/backend/utils/adt/ruleutils.c 2003/03/11 05:21:14 *************** *** 49,54 **** --- 49,55 ---- #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" *************** *** 369,374 **** --- 370,557 ---- return ruledef; } + /* ---------- + * get_triggerdef - Get the definition of a trigger + * ---------- + */ + Datum + 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; + char *tgname; + + /* + * Fetch the pg_trigger tuple by the Oid of the trigger + */ + tgrel = heap_openr(TriggerRelationName, AccessShareLock); + + /* + * Find the trigger + */ + ScanKeyEntryInitialize(&skey[0], 0x0, + ObjectIdAttributeNumber, F_OIDEQ, + ObjectIdGetDatum(trigid)); + + tgscan = systable_beginscan(tgrel, TriggerOidIndex, true, + SnapshotNow, 1, skey); + + ht_trig = systable_getnext(tgscan); + + 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 + * never be schema-qualified, but the trigger rel's name may be. + */ + initStringInfo(&buf); + + tgname = NameStr(trigrec->tgname); + appendStringInfo(&buf, "CREATE %sTRIGGER %s ", + trigrec->tgisconstraint ? "CONSTRAINT " : "", + quote_identifier(tgname)); + + if (TRIGGER_FOR_BEFORE(trigrec->tgtype)) + appendStringInfo(&buf, "BEFORE"); + else + appendStringInfo(&buf, "AFTER"); + if (TRIGGER_FOR_INSERT(trigrec->tgtype)) + { + appendStringInfo(&buf, " INSERT"); + findx++; + } + if (TRIGGER_FOR_DELETE(trigrec->tgtype)) + { + if (findx > 0) + appendStringInfo(&buf, " OR DELETE"); + else + appendStringInfo(&buf, " DELETE"); + findx++; + } + if (TRIGGER_FOR_UPDATE(trigrec->tgtype)) + { + if (findx > 0) + appendStringInfo(&buf, " OR UPDATE"); + else + appendStringInfo(&buf, " UPDATE"); + } + appendStringInfo(&buf, " ON %s ", + generate_relation_name(trigrec->tgrelid)); + + + if (trigrec->tgisconstraint) + { + if (trigrec->tgconstrrelid != 0) + { + appendStringInfo(&buf, "FROM %s ", + generate_relation_name(trigrec->tgconstrrelid)); + } + if (!trigrec->tgdeferrable) + appendStringInfo(&buf, "NOT "); + appendStringInfo(&buf, "DEFERRABLE INITIALLY "); + if (trigrec->tginitdeferred) + appendStringInfo(&buf, "DEFERRED "); + else + appendStringInfo(&buf, "IMMEDIATE "); + + } + + if (TRIGGER_FOR_ROW(trigrec->tgtype)) + appendStringInfo(&buf, "FOR EACH ROW "); + else + 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;;) + { + p = strchr(p, '\\'); + if (p == NULL) + { + elog(ERROR, "pg_get_triggerdef: bad argument string for trigger"); + } + 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, '\''); + appendStringInfo(&buf, (findx < trigrec->tgnargs - 1) ? ", " : ""); + tgargs = p + 4; + } + + /* Deliberately omit semi-colon */ + appendStringInfo(&buf, ")"); + + /* + * Create the result as a TEXT datum, and free working data + */ + len = buf.len + VARHDRSZ; + trigdef = (text *) palloc(len); + VARATT_SIZEP(trigdef) = len; + memcpy(VARDATA(trigdef), buf.data, buf.len); + + pfree(buf.data); + + ReleaseSysCache(ht_trig); + ReleaseSysCache(ht_proc); + heap_close(tgrel, AccessShareLock); + + PG_RETURN_TEXT_P(trigdef); + } /* ---------- * get_indexdef - Get the definition of an index Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v retrieving revision 1.286 diff -c -r1.286 pg_proc.h *** src/include/catalog/pg_proc.h 2003/03/10 22:28:20 1.286 --- src/include/catalog/pg_proc.h 2003/03/11 05:21:17 *************** *** 2194,2199 **** --- 2194,2201 ---- DESCR("user name by UID (with fallback)"); DATA(insert OID = 1643 ( pg_get_indexdef PGNSP PGUID 12 f f t f s 1 25 "26" pg_get_indexdef - _null_ )); DESCR("index description"); + DATA(insert OID = 1662 ( pg_get_triggerdef PGNSP PGUID 12 f f t f s 1 25 "26" pg_get_triggerdef - _null_ )); + DESCR("trigger description"); DATA(insert OID = 1387 ( pg_get_constraintdef PGNSP PGUID 12 f f t f s 1 25 "26" pg_get_constraintdef - _null_ )); DESCR("constraint description"); DATA(insert OID = 1716 ( pg_get_expr PGNSP PGUID 12 f f t f s 2 25 "25 26" pg_get_expr - _null_ )); Index: src/include/utils/builtins.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/utils/builtins.h,v retrieving revision 1.208 diff -c -r1.208 builtins.h *** src/include/utils/builtins.h 2003/02/13 05:24:04 1.208 --- src/include/utils/builtins.h 2003/03/11 05:21:17 *************** *** 399,404 **** --- 399,405 ---- extern Datum pg_get_viewdef(PG_FUNCTION_ARGS); extern Datum pg_get_viewdef_name(PG_FUNCTION_ARGS); extern Datum pg_get_indexdef(PG_FUNCTION_ARGS); + extern Datum pg_get_triggerdef(PG_FUNCTION_ARGS); extern Datum pg_get_constraintdef(PG_FUNCTION_ARGS); extern Datum pg_get_userbyid(PG_FUNCTION_ARGS); extern Datum pg_get_expr(PG_FUNCTION_ARGS);