Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7f79192

Browse files
committed
In an attempt to simplify my life I'm submitting this patch that
restructures the deferred trigger queue. The fundamental change is to put all the static variables to hold the deferred triggers in a single structure. Alvaro Herrera
1 parent aa62f7f commit 7f79192

File tree

1 file changed

+70
-69
lines changed

1 file changed

+70
-69
lines changed

src/backend/commands/trigger.c

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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.148 2003/04/20 17:03:25 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.149 2003/06/24 23:25:44 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1601,25 +1601,22 @@ ltrmark:;
16011601
* ----------
16021602
*/
16031603

1604-
1605-
/*
1606-
* Internal data to the deferred trigger mechanism is held over
1607-
* statements/commands in a context which is created at transaction
1608-
* start and destroyed at transaction end.
1609-
*/
1610-
1611-
static MemoryContext deftrig_cxt = NULL;
1612-
1613-
/* ----------
1614-
* Global data that tells which triggers are actually in
1615-
* state IMMEDIATE or DEFERRED.
1616-
* ----------
1617-
*/
1618-
static bool deftrig_all_isset = false;
1619-
static bool deftrig_all_isdeferred = false;
1620-
static List *deftrig_trigstates;
1604+
typedef struct DeferredTriggersData {
1605+
/* Internal data is held in a per-transaction memory context */
1606+
MemoryContext deftrig_cxt;
1607+
/* ALL DEFERRED or ALL IMMEDIATE */
1608+
bool deftrig_all_isset;
1609+
bool deftrig_all_isdeferred;
1610+
/* Per trigger state */
1611+
List *deftrig_trigstates;
1612+
/* List of pending deferred triggers. Previous comment below */
1613+
DeferredTriggerEvent deftrig_events;
1614+
DeferredTriggerEvent deftrig_events_imm;
1615+
DeferredTriggerEvent deftrig_event_tail;
1616+
} DeferredTriggersData;
16211617

16221618
/* ----------
1619+
* deftrig_events, deftrig_event_tail:
16231620
* The list of pending deferred trigger events during the current transaction.
16241621
*
16251622
* deftrig_events is the head, deftrig_event_tail is the last entry.
@@ -1636,10 +1633,10 @@ static List *deftrig_trigstates;
16361633
* large...
16371634
* ----------
16381635
*/
1639-
static DeferredTriggerEvent deftrig_events;
1640-
static DeferredTriggerEvent deftrig_events_imm;
1641-
static DeferredTriggerEvent deftrig_event_tail;
16421636

1637+
typedef DeferredTriggersData *DeferredTriggers;
1638+
1639+
static DeferredTriggers deferredTriggers;
16431640

16441641
/* ----------
16451642
* deferredTriggerCheckState()
@@ -1665,7 +1662,7 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
16651662
/*
16661663
* Lookup if we know an individual state for this trigger
16671664
*/
1668-
foreach(sl, deftrig_trigstates)
1665+
foreach(sl, deferredTriggers->deftrig_trigstates)
16691666
{
16701667
trigstate = (DeferredTriggerStatus) lfirst(sl);
16711668
if (trigstate->dts_tgoid == tgoid)
@@ -1676,21 +1673,22 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
16761673
* No individual state known - so if the user issued a SET CONSTRAINT
16771674
* ALL ..., we return that instead of the triggers default state.
16781675
*/
1679-
if (deftrig_all_isset)
1680-
return deftrig_all_isdeferred;
1676+
if (deferredTriggers->deftrig_all_isset)
1677+
return deferredTriggers->deftrig_all_isdeferred;
16811678

16821679
/*
16831680
* No ALL state known either, remember the default state as the
16841681
* current and return that.
16851682
*/
1686-
oldcxt = MemoryContextSwitchTo(deftrig_cxt);
1683+
oldcxt = MemoryContextSwitchTo(deferredTriggers->deftrig_cxt);
16871684

16881685
trigstate = (DeferredTriggerStatus)
16891686
palloc(sizeof(DeferredTriggerStatusData));
16901687
trigstate->dts_tgoid = tgoid;
16911688
trigstate->dts_tgisdeferred =
16921689
((itemstate & TRIGGER_DEFERRED_INITDEFERRED) != 0);
1693-
deftrig_trigstates = lappend(deftrig_trigstates, trigstate);
1690+
deferredTriggers->deftrig_trigstates =
1691+
lappend(deferredTriggers->deftrig_trigstates, trigstate);
16941692

16951693
MemoryContextSwitchTo(oldcxt);
16961694

@@ -1713,16 +1711,16 @@ deferredTriggerAddEvent(DeferredTriggerEvent event)
17131711
* "lappend". This avoids O(N^2) behavior for large numbers of events.
17141712
*/
17151713
event->dte_next = NULL;
1716-
if (deftrig_event_tail == NULL)
1714+
if (deferredTriggers->deftrig_event_tail == NULL)
17171715
{
17181716
/* first list entry */
1719-
deftrig_events = event;
1720-
deftrig_event_tail = event;
1717+
deferredTriggers->deftrig_events = event;
1718+
deferredTriggers->deftrig_event_tail = event;
17211719
}
17221720
else
17231721
{
1724-
deftrig_event_tail->dte_next = event;
1725-
deftrig_event_tail = event;
1722+
deferredTriggers->deftrig_event_tail->dte_next = event;
1723+
deferredTriggers->deftrig_event_tail = event;
17261724
}
17271725
}
17281726

@@ -1884,15 +1882,15 @@ deferredTriggerInvokeEvents(bool immediate_only)
18841882
* are those since deftrig_events_imm. (But if deftrig_events_imm is
18851883
* NULL, we must scan the entire list.)
18861884
*/
1887-
if (immediate_only && deftrig_events_imm != NULL)
1885+
if (immediate_only && deferredTriggers->deftrig_events_imm != NULL)
18881886
{
1889-
prev_event = deftrig_events_imm;
1887+
prev_event = deferredTriggers->deftrig_events_imm;
18901888
event = prev_event->dte_next;
18911889
}
18921890
else
18931891
{
18941892
prev_event = NULL;
1895-
event = deftrig_events;
1893+
event = deferredTriggers->deftrig_events;
18961894
}
18971895

18981896
while (event != NULL)
@@ -1994,7 +1992,7 @@ deferredTriggerInvokeEvents(bool immediate_only)
19941992
if (prev_event)
19951993
prev_event->dte_next = next_event;
19961994
else
1997-
deftrig_events = next_event;
1995+
deferredTriggers->deftrig_events = next_event;
19981996
pfree(event);
19991997
}
20001998
else
@@ -2011,10 +2009,10 @@ deferredTriggerInvokeEvents(bool immediate_only)
20112009
}
20122010

20132011
/* Update list tail pointer in case we just deleted tail event */
2014-
deftrig_event_tail = prev_event;
2012+
deferredTriggers->deftrig_event_tail = prev_event;
20152013

20162014
/* Set the immediate event pointer for next time */
2017-
deftrig_events_imm = prev_event;
2015+
deferredTriggers->deftrig_events_imm = prev_event;
20182016

20192017
/* Release working resources */
20202018
if (rel)
@@ -2052,30 +2050,32 @@ DeferredTriggerInit(void)
20522050
void
20532051
DeferredTriggerBeginXact(void)
20542052
{
2055-
if (deftrig_cxt != NULL)
2056-
elog(ERROR,
2057-
"DeferredTriggerBeginXact() called while inside transaction");
2053+
/*
2054+
* This will be changed to a special context when
2055+
* the nested transactions project moves forward.
2056+
*/
2057+
MemoryContext cxt = TopTransactionContext;
2058+
deferredTriggers = (DeferredTriggers) MemoryContextAlloc(TopTransactionContext,
2059+
sizeof(DeferredTriggersData));
20582060

20592061
/*
20602062
* Create the per transaction memory context
20612063
*/
2062-
deftrig_cxt = AllocSetContextCreate(TopTransactionContext,
2064+
deferredTriggers->deftrig_cxt = AllocSetContextCreate(cxt,
20632065
"DeferredTriggerXact",
20642066
ALLOCSET_DEFAULT_MINSIZE,
20652067
ALLOCSET_DEFAULT_INITSIZE,
20662068
ALLOCSET_DEFAULT_MAXSIZE);
2067-
deftrig_all_isset = false;
2068-
20692069
/*
20702070
* If unspecified, constraints default to IMMEDIATE, per SQL
20712071
*/
2072-
deftrig_all_isdeferred = false;
2072+
deferredTriggers->deftrig_all_isdeferred = false;
2073+
deferredTriggers->deftrig_all_isset = false;
20732074

2074-
deftrig_trigstates = NIL;
2075-
2076-
deftrig_events = NULL;
2077-
deftrig_events_imm = NULL;
2078-
deftrig_event_tail = NULL;
2075+
deferredTriggers->deftrig_trigstates = NIL;
2076+
deferredTriggers->deftrig_events = NULL;
2077+
deferredTriggers->deftrig_events_imm = NULL;
2078+
deferredTriggers->deftrig_event_tail = NULL;
20792079
}
20802080

20812081

@@ -2092,7 +2092,7 @@ DeferredTriggerEndQuery(void)
20922092
/*
20932093
* Ignore call if we aren't in a transaction.
20942094
*/
2095-
if (deftrig_cxt == NULL)
2095+
if (deferredTriggers == NULL)
20962096
return;
20972097

20982098
deferredTriggerInvokeEvents(true);
@@ -2112,13 +2112,12 @@ DeferredTriggerEndXact(void)
21122112
/*
21132113
* Ignore call if we aren't in a transaction.
21142114
*/
2115-
if (deftrig_cxt == NULL)
2115+
if (deferredTriggers == NULL)
21162116
return;
21172117

21182118
deferredTriggerInvokeEvents(false);
21192119

2120-
MemoryContextDelete(deftrig_cxt);
2121-
deftrig_cxt = NULL;
2120+
deferredTriggers = NULL;
21222121
}
21232122

21242123

@@ -2136,11 +2135,13 @@ DeferredTriggerAbortXact(void)
21362135
/*
21372136
* Ignore call if we aren't in a transaction.
21382137
*/
2139-
if (deftrig_cxt == NULL)
2140-
return;
2138+
if (deferredTriggers == NULL)
2139+
return;
21412140

2142-
MemoryContextDelete(deftrig_cxt);
2143-
deftrig_cxt = NULL;
2141+
/*
2142+
* Forget everything we know about deferred triggers.
2143+
*/
2144+
deferredTriggers = NULL;
21442145
}
21452146

21462147

@@ -2158,7 +2159,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
21582159
/*
21592160
* Ignore call if we aren't in a transaction.
21602161
*/
2161-
if (deftrig_cxt == NULL)
2162+
if (deferredTriggers == NULL)
21622163
return;
21632164

21642165
/*
@@ -2170,7 +2171,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
21702171
* Drop all per-transaction information about individual trigger
21712172
* states.
21722173
*/
2173-
l = deftrig_trigstates;
2174+
l = deferredTriggers->deftrig_trigstates;
21742175
while (l != NIL)
21752176
{
21762177
List *next = lnext(l);
@@ -2179,13 +2180,13 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
21792180
pfree(l);
21802181
l = next;
21812182
}
2182-
deftrig_trigstates = NIL;
2183+
deferredTriggers->deftrig_trigstates = NIL;
21832184

21842185
/*
21852186
* Set the per-transaction ALL state to known.
21862187
*/
2187-
deftrig_all_isset = true;
2188-
deftrig_all_isdeferred = stmt->deferred;
2188+
deferredTriggers->deftrig_all_isset = true;
2189+
deferredTriggers->deftrig_all_isdeferred = stmt->deferred;
21892190
}
21902191
else
21912192
{
@@ -2267,12 +2268,12 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
22672268
* Inside of a transaction block set the trigger states of
22682269
* individual triggers on transaction level.
22692270
*/
2270-
oldcxt = MemoryContextSwitchTo(deftrig_cxt);
2271+
oldcxt = MemoryContextSwitchTo(deferredTriggers->deftrig_cxt);
22712272

22722273
foreach(l, loid)
22732274
{
22742275
found = false;
2275-
foreach(ls, deftrig_trigstates)
2276+
foreach(ls, deferredTriggers->deftrig_trigstates)
22762277
{
22772278
state = (DeferredTriggerStatus) lfirst(ls);
22782279
if (state->dts_tgoid == lfirsto(l))
@@ -2289,8 +2290,8 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
22892290
state->dts_tgoid = lfirsto(l);
22902291
state->dts_tgisdeferred = stmt->deferred;
22912292

2292-
deftrig_trigstates =
2293-
lappend(deftrig_trigstates, state);
2293+
deferredTriggers->deftrig_trigstates =
2294+
lappend(deferredTriggers->deftrig_trigstates, state);
22942295
}
22952296
}
22962297

@@ -2308,7 +2309,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
23082309
* tail pointer to make it rescan the entire list, in case some deferred
23092310
* events are now immediately invokable.
23102311
*/
2311-
deftrig_events_imm = NULL;
2312+
deferredTriggers->deftrig_events_imm = NULL;
23122313
}
23132314

23142315

@@ -2337,7 +2338,7 @@ DeferredTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
23372338
ItemPointerData oldctid;
23382339
ItemPointerData newctid;
23392340

2340-
if (deftrig_cxt == NULL)
2341+
if (deferredTriggers == NULL)
23412342
elog(ERROR,
23422343
"DeferredTriggerSaveEvent() called outside of transaction");
23432344

@@ -2387,7 +2388,7 @@ DeferredTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
23872388
/*
23882389
* Create a new event
23892390
*/
2390-
oldcxt = MemoryContextSwitchTo(deftrig_cxt);
2391+
oldcxt = MemoryContextSwitchTo(deferredTriggers->deftrig_cxt);
23912392

23922393
new_size = offsetof(DeferredTriggerEventData, dte_item[0]) +
23932394
n_enabled_triggers * sizeof(DeferredTriggerEventItem);

0 commit comments

Comments
 (0)