77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.87 2001/03/12 23:02:00 tgl Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.88 2001/03/14 21:50:32 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -1153,15 +1153,18 @@ static List *deftrig_trigstates;
11531153
11541154/* ----------
11551155 * The list of events during the entire transaction. deftrig_events
1156- * is the head, deftrig_event_tail is the last entry.
1156+ * is the head, deftrig_event_tail is the last entry. Because this can
1157+ * grow pretty large, we don't use separate List nodes, but instead thread
1158+ * the list through the dte_next fields of the member nodes. Saves just a
1159+ * few bytes per entry, but that adds up.
11571160 *
11581161 * XXX Need to be able to shove this data out to a file if it grows too
11591162 * large...
11601163 * ----------
11611164 */
11621165static int deftrig_n_events ;
1163- static List * deftrig_events ;
1164- static List * deftrig_event_tail ;
1166+ static DeferredTriggerEvent deftrig_events ;
1167+ static DeferredTriggerEvent deftrig_event_tail ;
11651168
11661169
11671170/* ----------
@@ -1242,16 +1245,17 @@ deferredTriggerAddEvent(DeferredTriggerEvent event)
12421245 * list tail and append there, rather than just doing a stupid "lappend".
12431246 * This avoids O(N^2) behavior for large numbers of events.
12441247 */
1245- if (deftrig_event_tail == NIL )
1248+ event -> dte_next = NULL ;
1249+ if (deftrig_event_tail == NULL )
12461250 {
12471251 /* first list entry */
1248- deftrig_events = makeList1 ( event ) ;
1249- deftrig_event_tail = deftrig_events ;
1252+ deftrig_events = event ;
1253+ deftrig_event_tail = event ;
12501254 }
12511255 else
12521256 {
1253- lnext ( deftrig_event_tail ) = makeList1 ( event ) ;
1254- deftrig_event_tail = lnext ( deftrig_event_tail ) ;
1257+ deftrig_event_tail -> dte_next = event ;
1258+ deftrig_event_tail = event ;
12551259 }
12561260 deftrig_n_events ++ ;
12571261}
@@ -1268,13 +1272,11 @@ static DeferredTriggerEvent
12681272deferredTriggerGetPreviousEvent (Oid relid , ItemPointer ctid )
12691273{
12701274 DeferredTriggerEvent previous = NULL ;
1271- List * dtev ;
1275+ DeferredTriggerEvent prev ;
12721276
12731277 /* Search the list to find the last event affecting this tuple */
1274- foreach ( dtev , deftrig_events )
1278+ for ( prev = deftrig_events ; prev != NULL ; prev = prev -> dte_next )
12751279 {
1276- DeferredTriggerEvent prev = (DeferredTriggerEvent ) lfirst (dtev );
1277-
12781280 if (prev -> dte_relid != relid )
12791281 continue ;
12801282 if (prev -> dte_event & TRIGGER_DEFERRED_CANCELED )
@@ -1411,7 +1413,6 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno,
14111413static void
14121414deferredTriggerInvokeEvents (bool immediate_only )
14131415{
1414- List * el ;
14151416 DeferredTriggerEvent event ;
14161417 int still_deferred_ones ;
14171418 int i ;
@@ -1435,19 +1436,18 @@ deferredTriggerInvokeEvents(bool immediate_only)
14351436 ALLOCSET_DEFAULT_INITSIZE ,
14361437 ALLOCSET_DEFAULT_MAXSIZE );
14371438
1438- foreach ( el , deftrig_events )
1439+ for ( event = deftrig_events ; event != NULL ; event = event -> dte_next )
14391440 {
1440- MemoryContextReset (per_tuple_context );
1441-
14421441 /* ----------
1443- * Get the event and check if it is completely done.
1442+ * Check if event is completely done.
14441443 * ----------
14451444 */
1446- event = (DeferredTriggerEvent ) lfirst (el );
14471445 if (event -> dte_event & (TRIGGER_DEFERRED_DONE |
14481446 TRIGGER_DEFERRED_CANCELED ))
14491447 continue ;
14501448
1449+ MemoryContextReset (per_tuple_context );
1450+
14511451 /* ----------
14521452 * Check each trigger item in the event.
14531453 * ----------
@@ -1561,8 +1561,8 @@ DeferredTriggerBeginXact(void)
15611561 MemoryContextSwitchTo (oldcxt );
15621562
15631563 deftrig_n_events = 0 ;
1564- deftrig_events = NIL ;
1565- deftrig_event_tail = NIL ;
1564+ deftrig_events = NULL ;
1565+ deftrig_event_tail = NULL ;
15661566}
15671567
15681568
@@ -1957,16 +1957,16 @@ DeferredTriggerSaveEvent(Relation rel, int event,
19571957
19581958 ntriggers = rel -> trigdesc -> n_after_row [event ];
19591959 triggers = rel -> trigdesc -> tg_after_row [event ];
1960- new_size = sizeof (DeferredTriggerEventData ) +
1960+ new_size = offsetof (DeferredTriggerEventData , dte_item [ 0 ] ) +
19611961 ntriggers * sizeof (DeferredTriggerEventItem );
19621962
19631963 new_event = (DeferredTriggerEvent ) palloc (new_size );
1964+ new_event -> dte_next = NULL ;
19641965 new_event -> dte_event = event & TRIGGER_EVENT_OPMASK ;
19651966 new_event -> dte_relid = rel -> rd_id ;
19661967 ItemPointerCopy (& oldctid , & (new_event -> dte_oldctid ));
19671968 ItemPointerCopy (& newctid , & (new_event -> dte_newctid ));
19681969 new_event -> dte_n_items = ntriggers ;
1969- new_event -> dte_item [ntriggers ].dti_state = new_size ;
19701970 for (i = 0 ; i < ntriggers ; i ++ )
19711971 {
19721972 new_event -> dte_item [i ].dti_tgoid = triggers [i ]-> tgoid ;
@@ -1978,6 +1978,7 @@ DeferredTriggerSaveEvent(Relation rel, int event,
19781978 ((rel -> trigdesc -> n_before_row [event ] > 0 ) ?
19791979 TRIGGER_DEFERRED_HAS_BEFORE : 0 );
19801980 }
1981+
19811982 MemoryContextSwitchTo (oldcxt );
19821983
19831984 switch (event & TRIGGER_EVENT_OPMASK )
0 commit comments