diff options
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
| -rw-r--r-- | src/include/catalog/pg_trigger.h | 31 | ||||
| -rw-r--r-- | src/include/commands/trigger.h | 58 | ||||
| -rw-r--r-- | src/include/nodes/parsenodes.h | 5 | ||||
| -rw-r--r-- | src/include/utils/rel.h | 41 |
5 files changed, 92 insertions, 45 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index c9212ab584b..910474cdcfc 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201009281 +#define CATALOG_VERSION_NO 201010101 #endif diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h index 46285ac3038..4eb72f20916 100644 --- a/src/include/catalog/pg_trigger.h +++ b/src/include/catalog/pg_trigger.h @@ -38,7 +38,7 @@ CATALOG(pg_trigger,2620) Oid tgrelid; /* relation trigger is attached to */ NameData tgname; /* trigger's name */ Oid tgfoid; /* OID of function to be called */ - int2 tgtype; /* BEFORE/AFTER UPDATE/DELETE/INSERT + int2 tgtype; /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT, * ROW/STATEMENT; see below */ char tgenabled; /* trigger's firing configuration WRT * session_replication_role */ @@ -91,22 +91,49 @@ typedef FormData_pg_trigger *Form_pg_trigger; #define TRIGGER_TYPE_DELETE (1 << 3) #define TRIGGER_TYPE_UPDATE (1 << 4) #define TRIGGER_TYPE_TRUNCATE (1 << 5) +#define TRIGGER_TYPE_INSTEAD (1 << 6) + +#define TRIGGER_TYPE_LEVEL_MASK (TRIGGER_TYPE_ROW) +#define TRIGGER_TYPE_STATEMENT 0 + +/* Note bits within TRIGGER_TYPE_TIMING_MASK aren't adjacent */ +#define TRIGGER_TYPE_TIMING_MASK \ + (TRIGGER_TYPE_BEFORE | TRIGGER_TYPE_INSTEAD) +#define TRIGGER_TYPE_AFTER 0 + +#define TRIGGER_TYPE_EVENT_MASK \ + (TRIGGER_TYPE_INSERT | TRIGGER_TYPE_DELETE | TRIGGER_TYPE_UPDATE | TRIGGER_TYPE_TRUNCATE) /* Macros for manipulating tgtype */ #define TRIGGER_CLEAR_TYPE(type) ((type) = 0) #define TRIGGER_SETT_ROW(type) ((type) |= TRIGGER_TYPE_ROW) +#define TRIGGER_SETT_STATEMENT(type) ((type) |= TRIGGER_TYPE_STATEMENT) #define TRIGGER_SETT_BEFORE(type) ((type) |= TRIGGER_TYPE_BEFORE) +#define TRIGGER_SETT_AFTER(type) ((type) |= TRIGGER_TYPE_AFTER) +#define TRIGGER_SETT_INSTEAD(type) ((type) |= TRIGGER_TYPE_INSTEAD) #define TRIGGER_SETT_INSERT(type) ((type) |= TRIGGER_TYPE_INSERT) #define TRIGGER_SETT_DELETE(type) ((type) |= TRIGGER_TYPE_DELETE) #define TRIGGER_SETT_UPDATE(type) ((type) |= TRIGGER_TYPE_UPDATE) #define TRIGGER_SETT_TRUNCATE(type) ((type) |= TRIGGER_TYPE_TRUNCATE) #define TRIGGER_FOR_ROW(type) ((type) & TRIGGER_TYPE_ROW) -#define TRIGGER_FOR_BEFORE(type) ((type) & TRIGGER_TYPE_BEFORE) +#define TRIGGER_FOR_BEFORE(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_BEFORE) +#define TRIGGER_FOR_AFTER(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_AFTER) +#define TRIGGER_FOR_INSTEAD(type) (((type) & TRIGGER_TYPE_TIMING_MASK) == TRIGGER_TYPE_INSTEAD) #define TRIGGER_FOR_INSERT(type) ((type) & TRIGGER_TYPE_INSERT) #define TRIGGER_FOR_DELETE(type) ((type) & TRIGGER_TYPE_DELETE) #define TRIGGER_FOR_UPDATE(type) ((type) & TRIGGER_TYPE_UPDATE) #define TRIGGER_FOR_TRUNCATE(type) ((type) & TRIGGER_TYPE_TRUNCATE) +/* + * Efficient macro for checking if tgtype matches a particular level + * (TRIGGER_TYPE_ROW or TRIGGER_TYPE_STATEMENT), timing (TRIGGER_TYPE_BEFORE, + * TRIGGER_TYPE_AFTER or TRIGGER_TYPE_INSTEAD), and event (TRIGGER_TYPE_INSERT, + * TRIGGER_TYPE_DELETE, TRIGGER_TYPE_UPDATE, or TRIGGER_TYPE_TRUNCATE). Note + * that a tgtype can match more than one event, but only one level or timing. + */ +#define TRIGGER_TYPE_MATCHES(type, level, timing, event) \ + (((type) & (TRIGGER_TYPE_LEVEL_MASK | TRIGGER_TYPE_TIMING_MASK | (event))) == ((level) | (timing) | (event))) + #endif /* PG_TRIGGER_H */ diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 08bb22a3681..30dc314c00d 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -51,44 +51,48 @@ typedef struct TriggerData #define TRIGGER_EVENT_UPDATE 0x00000002 #define TRIGGER_EVENT_TRUNCATE 0x00000003 #define TRIGGER_EVENT_OPMASK 0x00000003 + #define TRIGGER_EVENT_ROW 0x00000004 + #define TRIGGER_EVENT_BEFORE 0x00000008 +#define TRIGGER_EVENT_AFTER 0x00000000 +#define TRIGGER_EVENT_INSTEAD 0x00000010 +#define TRIGGER_EVENT_TIMINGMASK 0x00000018 /* More TriggerEvent flags, used only within trigger.c */ -#define AFTER_TRIGGER_DEFERRABLE 0x00000010 -#define AFTER_TRIGGER_INITDEFERRED 0x00000020 +#define AFTER_TRIGGER_DEFERRABLE 0x00000020 +#define AFTER_TRIGGER_INITDEFERRED 0x00000040 -#define TRIGGER_FIRED_BY_INSERT(event) \ - (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \ - TRIGGER_EVENT_INSERT) +#define TRIGGER_FIRED_BY_INSERT(event) \ + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_INSERT) -#define TRIGGER_FIRED_BY_DELETE(event) \ - (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \ - TRIGGER_EVENT_DELETE) +#define TRIGGER_FIRED_BY_DELETE(event) \ + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_DELETE) -#define TRIGGER_FIRED_BY_UPDATE(event) \ - (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \ - TRIGGER_EVENT_UPDATE) +#define TRIGGER_FIRED_BY_UPDATE(event) \ + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE) #define TRIGGER_FIRED_BY_TRUNCATE(event) \ - (((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \ - TRIGGER_EVENT_TRUNCATE) + (((event) & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_TRUNCATE) + +#define TRIGGER_FIRED_FOR_ROW(event) \ + ((event) & TRIGGER_EVENT_ROW) -#define TRIGGER_FIRED_FOR_ROW(event) \ - ((TriggerEvent) (event) & TRIGGER_EVENT_ROW) +#define TRIGGER_FIRED_FOR_STATEMENT(event) \ + (!TRIGGER_FIRED_FOR_ROW(event)) -#define TRIGGER_FIRED_FOR_STATEMENT(event) \ - (!TRIGGER_FIRED_FOR_ROW (event)) +#define TRIGGER_FIRED_BEFORE(event) \ + (((event) & TRIGGER_EVENT_TIMINGMASK) == TRIGGER_EVENT_BEFORE) -#define TRIGGER_FIRED_BEFORE(event) \ - ((TriggerEvent) (event) & TRIGGER_EVENT_BEFORE) +#define TRIGGER_FIRED_AFTER(event) \ + (((event) & TRIGGER_EVENT_TIMINGMASK) == TRIGGER_EVENT_AFTER) -#define TRIGGER_FIRED_AFTER(event) \ - (!TRIGGER_FIRED_BEFORE (event)) +#define TRIGGER_FIRED_INSTEAD(event) \ + (((event) & TRIGGER_EVENT_TIMINGMASK) == TRIGGER_EVENT_INSTEAD) /* - * Definitions for the replication role based firing. + * Definitions for replication role based firing. */ #define SESSION_REPLICATION_ROLE_ORIGIN 0 #define SESSION_REPLICATION_ROLE_REPLICA 1 @@ -135,6 +139,9 @@ extern void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, HeapTuple trigtuple, List *recheckIndexes); +extern HeapTuple ExecIRInsertTriggers(EState *estate, + ResultRelInfo *relinfo, + HeapTuple trigtuple); extern void ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo); extern void ExecASDeleteTriggers(EState *estate, @@ -146,6 +153,9 @@ extern bool ExecBRDeleteTriggers(EState *estate, extern void ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, ItemPointer tupleid); +extern bool ExecIRDeleteTriggers(EState *estate, + ResultRelInfo *relinfo, + HeapTuple trigtuple); extern void ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo); extern void ExecASUpdateTriggers(EState *estate, @@ -160,6 +170,10 @@ extern void ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple, List *recheckIndexes); +extern HeapTuple ExecIRUpdateTriggers(EState *estate, + ResultRelInfo *relinfo, + HeapTuple oldtuple, + HeapTuple newtuple); extern void ExecBSTruncateTriggers(EState *estate, ResultRelInfo *relinfo); extern void ExecASTruncateTriggers(EState *estate, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index b2f0fef5139..ca225d06ec1 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1608,10 +1608,11 @@ typedef struct CreateTrigStmt RangeVar *relation; /* relation trigger is on */ List *funcname; /* qual. name of function to call */ List *args; /* list of (T_String) Values or NIL */ - bool before; /* BEFORE/AFTER */ bool row; /* ROW/STATEMENT */ + /* timing uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ + int16 timing; /* BEFORE, AFTER, or INSTEAD */ /* events uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ - int16 events; /* INSERT/UPDATE/DELETE/TRUNCATE */ + int16 events; /* "OR" of INSERT/UPDATE/DELETE/TRUNCATE */ List *columns; /* column names, or NIL for all columns */ Node *whenClause; /* qual expression, or NULL if none */ bool isconstraint; /* This is a constraint trigger */ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 17ad88820d8..9ad92c299e8 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -71,26 +71,31 @@ typedef struct Trigger typedef struct TriggerDesc { + Trigger *triggers; /* array of Trigger structs */ + int numtriggers; /* number of array entries */ + /* - * Index data to identify which triggers are which. Since each trigger - * can appear in more than one class, for each class we provide a list of - * integer indexes into the triggers array. The class codes are defined - * by TRIGGER_EVENT_xxx macros in commands/trigger.h. + * These flags indicate whether the array contains at least one of each + * type of trigger. We use these to skip searching the array if not. */ -#define TRIGGER_NUM_EVENT_CLASSES 4 - - uint16 n_before_statement[TRIGGER_NUM_EVENT_CLASSES]; - uint16 n_before_row[TRIGGER_NUM_EVENT_CLASSES]; - uint16 n_after_row[TRIGGER_NUM_EVENT_CLASSES]; - uint16 n_after_statement[TRIGGER_NUM_EVENT_CLASSES]; - int *tg_before_statement[TRIGGER_NUM_EVENT_CLASSES]; - int *tg_before_row[TRIGGER_NUM_EVENT_CLASSES]; - int *tg_after_row[TRIGGER_NUM_EVENT_CLASSES]; - int *tg_after_statement[TRIGGER_NUM_EVENT_CLASSES]; - - /* The actual array of triggers is here */ - Trigger *triggers; - int numtriggers; + bool trig_insert_before_row; + bool trig_insert_after_row; + bool trig_insert_instead_row; + bool trig_insert_before_statement; + bool trig_insert_after_statement; + bool trig_update_before_row; + bool trig_update_after_row; + bool trig_update_instead_row; + bool trig_update_before_statement; + bool trig_update_after_statement; + bool trig_delete_before_row; + bool trig_delete_after_row; + bool trig_delete_instead_row; + bool trig_delete_before_statement; + bool trig_delete_after_statement; + /* there are no row-level truncate triggers */ + bool trig_truncate_before_statement; + bool trig_truncate_after_statement; } TriggerDesc; |
