| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * pg_trigger.h |
| 4 | * definition of the "trigger" system catalog (pg_trigger) |
| 5 | * |
| 6 | * |
| 7 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 8 | * Portions Copyright (c) 1994, Regents of the University of California |
| 9 | * |
| 10 | * src/include/catalog/pg_trigger.h |
| 11 | * |
| 12 | * NOTES |
| 13 | * The Catalog.pm module reads this file and derives schema |
| 14 | * information. |
| 15 | * |
| 16 | *------------------------------------------------------------------------- |
| 17 | */ |
| 18 | #ifndef PG_TRIGGER_H |
| 19 | #define PG_TRIGGER_H |
| 20 | |
| 21 | #include "catalog/genbki.h" |
| 22 | #include "catalog/pg_trigger_d.h" |
| 23 | |
| 24 | /* ---------------- |
| 25 | * pg_trigger definition. cpp turns this into |
| 26 | * typedef struct FormData_pg_trigger |
| 27 | * |
| 28 | * Note: when tgconstraint is nonzero, tgconstrrelid, tgconstrindid, |
| 29 | * tgdeferrable, and tginitdeferred are largely redundant with the referenced |
| 30 | * pg_constraint entry. However, it is possible for a non-deferrable trigger |
| 31 | * to be associated with a deferrable constraint. |
| 32 | * ---------------- |
| 33 | */ |
| 34 | CATALOG(pg_trigger,2620,TriggerRelationId) |
| 35 | { |
| 36 | Oid oid; /* oid */ |
| 37 | Oid tgrelid; /* relation trigger is attached to */ |
| 38 | NameData tgname; /* trigger's name */ |
| 39 | Oid tgfoid; /* OID of function to be called */ |
| 40 | int16 tgtype; /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT, |
| 41 | * ROW/STATEMENT; see below */ |
| 42 | char tgenabled; /* trigger's firing configuration WRT |
| 43 | * session_replication_role */ |
| 44 | bool tgisinternal; /* trigger is system-generated */ |
| 45 | Oid tgconstrrelid; /* constraint's FROM table, if any */ |
| 46 | Oid tgconstrindid; /* constraint's supporting index, if any */ |
| 47 | Oid tgconstraint; /* associated pg_constraint entry, if any */ |
| 48 | bool tgdeferrable; /* constraint trigger is deferrable */ |
| 49 | bool tginitdeferred; /* constraint trigger is deferred initially */ |
| 50 | int16 tgnargs; /* # of extra arguments in tgargs */ |
| 51 | |
| 52 | /* |
| 53 | * Variable-length fields start here, but we allow direct access to |
| 54 | * tgattr. Note: tgattr and tgargs must not be null. |
| 55 | */ |
| 56 | int2vector tgattr; /* column numbers, if trigger is on columns */ |
| 57 | |
| 58 | #ifdef CATALOG_VARLEN |
| 59 | bytea tgargs BKI_FORCE_NOT_NULL; /* first\000second\000tgnargs\000 */ |
| 60 | pg_node_tree tgqual; /* WHEN expression, or NULL if none */ |
| 61 | NameData tgoldtable; /* old transition table, or NULL if none */ |
| 62 | NameData tgnewtable; /* new transition table, or NULL if none */ |
| 63 | #endif |
| 64 | } FormData_pg_trigger; |
| 65 | |
| 66 | /* ---------------- |
| 67 | * Form_pg_trigger corresponds to a pointer to a tuple with |
| 68 | * the format of pg_trigger relation. |
| 69 | * ---------------- |
| 70 | */ |
| 71 | typedef FormData_pg_trigger *Form_pg_trigger; |
| 72 | |
| 73 | #ifdef EXPOSE_TO_CLIENT_CODE |
| 74 | |
| 75 | /* Bits within tgtype */ |
| 76 | #define TRIGGER_TYPE_ROW (1 << 0) |
| 77 | #define TRIGGER_TYPE_BEFORE (1 << 1) |
| 78 | #define TRIGGER_TYPE_INSERT (1 << 2) |
| 79 | #define TRIGGER_TYPE_DELETE (1 << 3) |
| 80 | #define TRIGGER_TYPE_UPDATE (1 << 4) |
| 81 | #define TRIGGER_TYPE_TRUNCATE (1 << 5) |
| 82 | #define TRIGGER_TYPE_INSTEAD (1 << 6) |
| 83 | |
| 84 | #define TRIGGER_TYPE_LEVEL_MASK (TRIGGER_TYPE_ROW) |
| 85 | #define TRIGGER_TYPE_STATEMENT 0 |
| 86 | |
| 87 | /* Note bits within TRIGGER_TYPE_TIMING_MASK aren't adjacent */ |
| 88 | #define TRIGGER_TYPE_TIMING_MASK \ |
| 89 | (TRIGGER_TYPE_BEFORE | TRIGGER_TYPE_INSTEAD) |
| 90 | #define TRIGGER_TYPE_AFTER 0 |
| 91 | |
| 92 | #define TRIGGER_TYPE_EVENT_MASK \ |
| 93 | (TRIGGER_TYPE_INSERT | TRIGGER_TYPE_DELETE | TRIGGER_TYPE_UPDATE | TRIGGER_TYPE_TRUNCATE) |
| 94 | |
| 95 | /* Macros for manipulating tgtype */ |
| 96 | #define TRIGGER_CLEAR_TYPE(type) ((type) = 0) |
| 97 | |
| 98 | #define TRIGGER_SETT_ROW(type) ((type) |= TRIGGER_TYPE_ROW) |
| 99 | #define TRIGGER_SETT_STATEMENT(type) ((type) |= TRIGGER_TYPE_STATEMENT) |
| 100 | #define TRIGGER_SETT_BEFORE(type) ((type) |= TRIGGER_TYPE_BEFORE) |
| 101 | #define TRIGGER_SETT_AFTER(type) ((type) |= TRIGGER_TYPE_AFTER) |
| 102 | #define TRIGGER_SETT_INSTEAD(type) ((type) |= TRIGGER_TYPE_INSTEAD) |
| 103 | #define TRIGGER_SETT_INSERT(type) ((type) |= TRIGGER_TYPE_INSERT) |
| 104 | #define TRIGGER_SETT_DELETE(type) ((type) |= TRIGGER_TYPE_DELETE) |
| 105 | #define TRIGGER_SETT_UPDATE(type) ((type) |= TRIGGER_TYPE_UPDATE) |
| 106 | #define TRIGGER_SETT_TRUNCATE(type) ((type) |= TRIGGER_TYPE_TRUNCATE) |
| 107 | |
| 108 | #define TRIGGER_FOR_ROW(type) ((type) & TRIGGER_TYPE_ROW) |
| 109 | #define TRIGGER_FOR_BEFORE(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_BEFORE) |
| 110 | #define TRIGGER_FOR_AFTER(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_AFTER) |
| 111 | #define TRIGGER_FOR_INSTEAD(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_INSTEAD) |
| 112 | #define TRIGGER_FOR_INSERT(type) ((type) & TRIGGER_TYPE_INSERT) |
| 113 | #define TRIGGER_FOR_DELETE(type) ((type) & TRIGGER_TYPE_DELETE) |
| 114 | #define TRIGGER_FOR_UPDATE(type) ((type) & TRIGGER_TYPE_UPDATE) |
| 115 | #define TRIGGER_FOR_TRUNCATE(type) ((type) & TRIGGER_TYPE_TRUNCATE) |
| 116 | |
| 117 | /* |
| 118 | * Efficient macro for checking if tgtype matches a particular level |
| 119 | * (TRIGGER_TYPE_ROW or TRIGGER_TYPE_STATEMENT), timing (TRIGGER_TYPE_BEFORE, |
| 120 | * TRIGGER_TYPE_AFTER or TRIGGER_TYPE_INSTEAD), and event (TRIGGER_TYPE_INSERT, |
| 121 | * TRIGGER_TYPE_DELETE, TRIGGER_TYPE_UPDATE, or TRIGGER_TYPE_TRUNCATE). Note |
| 122 | * that a tgtype can match more than one event, but only one level or timing. |
| 123 | */ |
| 124 | #define TRIGGER_TYPE_MATCHES(type, level, timing, event) \ |
| 125 | (((type) & (TRIGGER_TYPE_LEVEL_MASK | TRIGGER_TYPE_TIMING_MASK | (event))) == ((level) | (timing) | (event))) |
| 126 | |
| 127 | /* |
| 128 | * Macro to determine whether tgnewtable or tgoldtable has been specified for |
| 129 | * a trigger. |
| 130 | */ |
| 131 | #define TRIGGER_USES_TRANSITION_TABLE(namepointer) \ |
| 132 | ((namepointer) != (char *) NULL) |
| 133 | |
| 134 | #endif /* EXPOSE_TO_CLIENT_CODE */ |
| 135 | |
| 136 | #endif /* PG_TRIGGER_H */ |
| 137 | |