7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
9
* 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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -1153,15 +1153,18 @@ static List *deftrig_trigstates;
1153
1153
1154
1154
/* ----------
1155
1155
* 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.
1157
1160
*
1158
1161
* XXX Need to be able to shove this data out to a file if it grows too
1159
1162
* large...
1160
1163
* ----------
1161
1164
*/
1162
1165
static 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 ;
1165
1168
1166
1169
1167
1170
/* ----------
@@ -1242,16 +1245,17 @@ deferredTriggerAddEvent(DeferredTriggerEvent event)
1242
1245
* list tail and append there, rather than just doing a stupid "lappend".
1243
1246
* This avoids O(N^2) behavior for large numbers of events.
1244
1247
*/
1245
- if (deftrig_event_tail == NIL )
1248
+ event -> dte_next = NULL ;
1249
+ if (deftrig_event_tail == NULL )
1246
1250
{
1247
1251
/* first list entry */
1248
- deftrig_events = makeList1 ( event ) ;
1249
- deftrig_event_tail = deftrig_events ;
1252
+ deftrig_events = event ;
1253
+ deftrig_event_tail = event ;
1250
1254
}
1251
1255
else
1252
1256
{
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 ;
1255
1259
}
1256
1260
deftrig_n_events ++ ;
1257
1261
}
@@ -1268,13 +1272,11 @@ static DeferredTriggerEvent
1268
1272
deferredTriggerGetPreviousEvent (Oid relid , ItemPointer ctid )
1269
1273
{
1270
1274
DeferredTriggerEvent previous = NULL ;
1271
- List * dtev ;
1275
+ DeferredTriggerEvent prev ;
1272
1276
1273
1277
/* 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 )
1275
1279
{
1276
- DeferredTriggerEvent prev = (DeferredTriggerEvent ) lfirst (dtev );
1277
-
1278
1280
if (prev -> dte_relid != relid )
1279
1281
continue ;
1280
1282
if (prev -> dte_event & TRIGGER_DEFERRED_CANCELED )
@@ -1411,7 +1413,6 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno,
1411
1413
static void
1412
1414
deferredTriggerInvokeEvents (bool immediate_only )
1413
1415
{
1414
- List * el ;
1415
1416
DeferredTriggerEvent event ;
1416
1417
int still_deferred_ones ;
1417
1418
int i ;
@@ -1435,19 +1436,18 @@ deferredTriggerInvokeEvents(bool immediate_only)
1435
1436
ALLOCSET_DEFAULT_INITSIZE ,
1436
1437
ALLOCSET_DEFAULT_MAXSIZE );
1437
1438
1438
- foreach ( el , deftrig_events )
1439
+ for ( event = deftrig_events ; event != NULL ; event = event -> dte_next )
1439
1440
{
1440
- MemoryContextReset (per_tuple_context );
1441
-
1442
1441
/* ----------
1443
- * Get the event and check if it is completely done.
1442
+ * Check if event is completely done.
1444
1443
* ----------
1445
1444
*/
1446
- event = (DeferredTriggerEvent ) lfirst (el );
1447
1445
if (event -> dte_event & (TRIGGER_DEFERRED_DONE |
1448
1446
TRIGGER_DEFERRED_CANCELED ))
1449
1447
continue ;
1450
1448
1449
+ MemoryContextReset (per_tuple_context );
1450
+
1451
1451
/* ----------
1452
1452
* Check each trigger item in the event.
1453
1453
* ----------
@@ -1561,8 +1561,8 @@ DeferredTriggerBeginXact(void)
1561
1561
MemoryContextSwitchTo (oldcxt );
1562
1562
1563
1563
deftrig_n_events = 0 ;
1564
- deftrig_events = NIL ;
1565
- deftrig_event_tail = NIL ;
1564
+ deftrig_events = NULL ;
1565
+ deftrig_event_tail = NULL ;
1566
1566
}
1567
1567
1568
1568
@@ -1957,16 +1957,16 @@ DeferredTriggerSaveEvent(Relation rel, int event,
1957
1957
1958
1958
ntriggers = rel -> trigdesc -> n_after_row [event ];
1959
1959
triggers = rel -> trigdesc -> tg_after_row [event ];
1960
- new_size = sizeof (DeferredTriggerEventData ) +
1960
+ new_size = offsetof (DeferredTriggerEventData , dte_item [ 0 ] ) +
1961
1961
ntriggers * sizeof (DeferredTriggerEventItem );
1962
1962
1963
1963
new_event = (DeferredTriggerEvent ) palloc (new_size );
1964
+ new_event -> dte_next = NULL ;
1964
1965
new_event -> dte_event = event & TRIGGER_EVENT_OPMASK ;
1965
1966
new_event -> dte_relid = rel -> rd_id ;
1966
1967
ItemPointerCopy (& oldctid , & (new_event -> dte_oldctid ));
1967
1968
ItemPointerCopy (& newctid , & (new_event -> dte_newctid ));
1968
1969
new_event -> dte_n_items = ntriggers ;
1969
- new_event -> dte_item [ntriggers ].dti_state = new_size ;
1970
1970
for (i = 0 ; i < ntriggers ; i ++ )
1971
1971
{
1972
1972
new_event -> dte_item [i ].dti_tgoid = triggers [i ]-> tgoid ;
@@ -1978,6 +1978,7 @@ DeferredTriggerSaveEvent(Relation rel, int event,
1978
1978
((rel -> trigdesc -> n_before_row [event ] > 0 ) ?
1979
1979
TRIGGER_DEFERRED_HAS_BEFORE : 0 );
1980
1980
}
1981
+
1981
1982
MemoryContextSwitchTo (oldcxt );
1982
1983
1983
1984
switch (event & TRIGGER_EVENT_OPMASK )
0 commit comments