diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index b0402effb9..d01ba4ec91 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 - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.85 2001/01/24 19:42:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.86 2001/01/27 05:16:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -911,7 +911,13 @@ ExecBRInsertTriggers(EState *estate, Relation rel, HeapTuple trigtuple) void ExecARInsertTriggers(EState *estate, Relation rel, HeapTuple trigtuple) { - DeferredTriggerSaveEvent(rel, TRIGGER_EVENT_INSERT, NULL, trigtuple); + /* Must save info if there are any deferred triggers on this rel */ + if (rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0 || + rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0 || + rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0) + { + DeferredTriggerSaveEvent(rel, TRIGGER_EVENT_INSERT, NULL, trigtuple); + } } bool @@ -956,10 +962,16 @@ void ExecARDeleteTriggers(EState *estate, ItemPointer tupleid) { Relation rel = estate->es_result_relation_info->ri_RelationDesc; - HeapTuple trigtuple = GetTupleForTrigger(estate, tupleid, NULL); - DeferredTriggerSaveEvent(rel, TRIGGER_EVENT_DELETE, trigtuple, NULL); - heap_freetuple(trigtuple); + /* Must save info if there are upd/del deferred triggers on this rel */ + if (rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0 || + rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0) + { + HeapTuple trigtuple = GetTupleForTrigger(estate, tupleid, NULL); + + DeferredTriggerSaveEvent(rel, TRIGGER_EVENT_DELETE, trigtuple, NULL); + heap_freetuple(trigtuple); + } } HeapTuple @@ -1011,10 +1023,16 @@ void ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple) { Relation rel = estate->es_result_relation_info->ri_RelationDesc; - HeapTuple trigtuple = GetTupleForTrigger(estate, tupleid, NULL); - DeferredTriggerSaveEvent(rel, TRIGGER_EVENT_UPDATE, trigtuple, newtuple); - heap_freetuple(trigtuple); + /* Must save info if there are upd/del deferred triggers on this rel */ + if (rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0 || + rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0) + { + HeapTuple trigtuple = GetTupleForTrigger(estate, tupleid, NULL); + + DeferredTriggerSaveEvent(rel, TRIGGER_EVENT_UPDATE, trigtuple, newtuple); + heap_freetuple(trigtuple); + } } @@ -1225,36 +1243,39 @@ deferredTriggerAddEvent(DeferredTriggerEvent event) /* ---------- * deferredTriggerGetPreviousEvent() * - * Backward scan the eventlist to find the event a given OLD tuple + * Scan the eventlist to find the event a given OLD tuple * resulted from in the same transaction. * ---------- */ static DeferredTriggerEvent deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid) { - DeferredTriggerEvent previous; - int n; + DeferredTriggerEvent previous = NULL; + List *dtev; - for (n = deftrig_n_events - 1; n >= 0; n--) + /* Search the list to find the last event affecting this tuple */ + foreach(dtev, deftrig_events) { - previous = (DeferredTriggerEvent) nth(n, deftrig_events); + DeferredTriggerEvent prev = (DeferredTriggerEvent) lfirst(dtev); - if (previous->dte_relid != relid) + if (prev->dte_relid != relid) continue; - if (previous->dte_event & TRIGGER_DEFERRED_CANCELED) + if (prev->dte_event & TRIGGER_DEFERRED_CANCELED) continue; if (ItemPointerGetBlockNumber(ctid) == - ItemPointerGetBlockNumber(&(previous->dte_newctid)) && + ItemPointerGetBlockNumber(&(prev->dte_newctid)) && ItemPointerGetOffsetNumber(ctid) == - ItemPointerGetOffsetNumber(&(previous->dte_newctid))) - return previous; + ItemPointerGetOffsetNumber(&(prev->dte_newctid))) + previous = prev; } - elog(ERROR, - "deferredTriggerGetPreviousEvent: event for tuple %s not found", - DatumGetCString(DirectFunctionCall1(tidout, PointerGetDatum(ctid)))); - return NULL; + if (previous == NULL) + elog(ERROR, + "deferredTriggerGetPreviousEvent: event for tuple %s not found", + DatumGetCString(DirectFunctionCall1(tidout, + PointerGetDatum(ctid)))); + return previous; } @@ -1874,6 +1895,11 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) * DeferredTriggerSaveEvent() * * Called by ExecAR...Triggers() to add the event to the queue. + * + * NOTE: should be called only if we've determined that an event must + * be added to the queue. We must save *all* events if there is either + * an UPDATE or a DELETE deferred trigger; see uses of + * deferredTriggerGetPreviousEvent. * ---------- */ static void @@ -1895,15 +1921,6 @@ DeferredTriggerSaveEvent(Relation rel, int event, elog(ERROR, "DeferredTriggerSaveEvent() called outside of transaction"); - /* ---------- - * Check if we're interested in this row at all - * ---------- - */ - ntriggers = rel->trigdesc->n_after_row[event]; - if (ntriggers <= 0) - return; - triggers = rel->trigdesc->tg_after_row[event]; - /* ---------- * Get the CTID's of OLD and NEW * ---------- @@ -1923,6 +1940,8 @@ DeferredTriggerSaveEvent(Relation rel, int event, */ oldcxt = MemoryContextSwitchTo(deftrig_cxt); + ntriggers = rel->trigdesc->n_after_row[event]; + triggers = rel->trigdesc->tg_after_row[event]; new_size = sizeof(DeferredTriggerEventData) + ntriggers * sizeof(DeferredTriggerEventItem); diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 2959234318..77af5e7ecc 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.136 2001/01/24 19:42:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.137 2001/01/27 05:16:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1264,8 +1264,7 @@ ExecAppend(TupleTableSlot *slot, ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false); /* AFTER ROW INSERT Triggers */ - if (resultRelationDesc->trigdesc && - resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0) + if (resultRelationDesc->trigdesc) ExecARInsertTriggers(estate, resultRelationDesc, tuple); } @@ -1351,8 +1350,7 @@ ldelete:; */ /* AFTER ROW DELETE Triggers */ - if (resultRelationDesc->trigdesc && - resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0) + if (resultRelationDesc->trigdesc) ExecARDeleteTriggers(estate, tupleid); } @@ -1491,8 +1489,7 @@ lreplace:; ExecInsertIndexTuples(slot, &(tuple->t_self), estate, true); /* AFTER ROW UPDATE Triggers */ - if (resultRelationDesc->trigdesc && - resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0) + if (resultRelationDesc->trigdesc) ExecARUpdateTriggers(estate, tupleid, tuple); }