Looks like I broke cases involving combinations of deferred update/delete

triggers ... oops ... but the regress tests should have covered this ...
This commit is contained in:
Tom Lane 2001-01-27 05:16:58 +00:00
parent 76beb79d27
commit a6f0adbe38
2 changed files with 54 additions and 38 deletions

View File

@ -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);

View File

@ -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);
}