aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/tablecmds.c44
-rw-r--r--src/backend/commands/trigger.c75
2 files changed, 36 insertions, 83 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c54104200d7..4335792ee71 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.158 2005/05/30 06:52:38 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.159 2005/05/30 07:20:58 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@@ -156,12 +156,6 @@ typedef struct NewColumnValue
} NewColumnValue;
-/* Used by attribute and relation renaming routines: */
-#define RI_TRIGGER_PK 1 /* is a trigger on the PK relation */
-#define RI_TRIGGER_FK 2 /* is a trigger on the FK relation */
-#define RI_TRIGGER_NONE 0 /* is not an RI trigger function */
-
-
static List *MergeAttributes(List *schema, List *supers, bool istemp,
List **supOids, List **supconstr, int *supOidCount);
static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno);
@@ -246,7 +240,6 @@ static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
char *tablespacename);
static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace);
static void copy_relation_data(Relation rel, SMgrRelation dst);
-static int ri_trigger_type(Oid tgfoid);
static void update_ri_trigger_args(Oid relid,
const char *oldname,
const char *newname,
@@ -1571,39 +1564,6 @@ renamerel(Oid myrelid, const char *newrelname)
relation_close(targetrelation, NoLock);
}
-
-/*
- * Given a trigger function OID, determine whether it is an RI trigger,
- * and if so whether it is attached to PK or FK relation.
- *
- * XXX this probably doesn't belong here; should be exported by
- * ri_triggers.c
- */
-static int
-ri_trigger_type(Oid tgfoid)
-{
- switch (tgfoid)
- {
- case F_RI_FKEY_CASCADE_DEL:
- case F_RI_FKEY_CASCADE_UPD:
- case F_RI_FKEY_RESTRICT_DEL:
- case F_RI_FKEY_RESTRICT_UPD:
- case F_RI_FKEY_SETNULL_DEL:
- case F_RI_FKEY_SETNULL_UPD:
- case F_RI_FKEY_SETDEFAULT_DEL:
- case F_RI_FKEY_SETDEFAULT_UPD:
- case F_RI_FKEY_NOACTION_DEL:
- case F_RI_FKEY_NOACTION_UPD:
- return RI_TRIGGER_PK;
-
- case F_RI_FKEY_CHECK_INS:
- case F_RI_FKEY_CHECK_UPD:
- return RI_TRIGGER_FK;
- }
-
- return RI_TRIGGER_NONE;
-}
-
/*
* Scan pg_trigger for RI triggers that are on the specified relation
* (if fk_scan is false) or have it as the tgconstrrel (if fk_scan
@@ -1663,7 +1623,7 @@ update_ri_trigger_args(Oid relid,
const char *arga[RI_MAX_ARGUMENTS];
const char *argp;
- tg_type = ri_trigger_type(pg_trigger->tgfoid);
+ tg_type = RI_FKey_trigger_type(pg_trigger->tgfoid);
if (tg_type == RI_TRIGGER_NONE)
{
/* Not an RI trigger, forget it */
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index a78ad890b3c..e0cfd334855 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.188 2005/05/06 17:24:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.189 2005/05/30 07:20:58 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2994,54 +2994,47 @@ AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
continue;
/*
- * If it is an RI UPDATE trigger, and the referenced keys have
- * not changed, short-circuit queuing of the event; there's no
- * need to fire the trigger.
+ * If this is an UPDATE of a PK table or FK table that does
+ * not change the PK or FK respectively, we can skip queuing
+ * the event: there is no need to fire the trigger.
*/
if ((event & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE)
{
- bool is_ri_trigger;
-
- switch (trigger->tgfoid)
+ switch (RI_FKey_trigger_type(trigger->tgfoid))
{
- case F_RI_FKEY_NOACTION_UPD:
- case F_RI_FKEY_CASCADE_UPD:
- case F_RI_FKEY_RESTRICT_UPD:
- case F_RI_FKEY_SETNULL_UPD:
- case F_RI_FKEY_SETDEFAULT_UPD:
- is_ri_trigger = true;
+ case RI_TRIGGER_PK:
+ /* Update on PK table */
+ if (RI_FKey_keyequal_upd_pk(trigger, rel, oldtup, newtup))
+ {
+ /* key unchanged, so skip queuing this event */
+ continue;
+ }
break;
- default:
- is_ri_trigger = false;
+ case RI_TRIGGER_FK:
+ /*
+ * Update on FK table
+ *
+ * There is one exception when updating FK tables:
+ * if the updated row was inserted by our own
+ * transaction and the FK is deferred, we still
+ * need to fire the trigger. This is because our
+ * UPDATE will invalidate the INSERT so the
+ * end-of-transaction INSERT RI trigger will not
+ * do anything, so we have to do the check for the
+ * UPDATE anyway.
+ */
+ if (HeapTupleHeaderGetXmin(oldtup->t_data) !=
+ GetCurrentTransactionId() &&
+ RI_FKey_keyequal_upd_fk(trigger, rel, oldtup, newtup))
+ {
+ continue;
+ }
break;
- }
- if (is_ri_trigger)
- {
- TriggerData LocTriggerData;
-
- LocTriggerData.type = T_TriggerData;
- LocTriggerData.tg_event =
- TRIGGER_EVENT_UPDATE | TRIGGER_EVENT_ROW;
- LocTriggerData.tg_relation = rel;
- LocTriggerData.tg_trigtuple = oldtup;
- LocTriggerData.tg_newtuple = newtup;
- LocTriggerData.tg_trigger = trigger;
- /*
- * We do not currently know which buffers the passed tuples
- * are in, but it does not matter because RI_FKey_keyequal_upd
- * does not care. We could expand the API of this function
- * if it becomes necessary to set these fields accurately.
- */
- LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
- LocTriggerData.tg_newtuplebuf = InvalidBuffer;
-
- if (RI_FKey_keyequal_upd(&LocTriggerData))
- {
- /* key unchanged, so skip queuing this event */
- continue;
- }
+ case RI_TRIGGER_NONE:
+ /* Not an FK trigger */
+ break;
}
}