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.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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -1601,25 +1601,22 @@ ltrmark:;
1601
1601
* ----------
1602
1602
*/
1603
1603
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 ;
1621
1617
1622
1618
/* ----------
1619
+ * deftrig_events, deftrig_event_tail:
1623
1620
* The list of pending deferred trigger events during the current transaction.
1624
1621
*
1625
1622
* deftrig_events is the head, deftrig_event_tail is the last entry.
@@ -1636,10 +1633,10 @@ static List *deftrig_trigstates;
1636
1633
* large...
1637
1634
* ----------
1638
1635
*/
1639
- static DeferredTriggerEvent deftrig_events ;
1640
- static DeferredTriggerEvent deftrig_events_imm ;
1641
- static DeferredTriggerEvent deftrig_event_tail ;
1642
1636
1637
+ typedef DeferredTriggersData * DeferredTriggers ;
1638
+
1639
+ static DeferredTriggers deferredTriggers ;
1643
1640
1644
1641
/* ----------
1645
1642
* deferredTriggerCheckState()
@@ -1665,7 +1662,7 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
1665
1662
/*
1666
1663
* Lookup if we know an individual state for this trigger
1667
1664
*/
1668
- foreach (sl , deftrig_trigstates )
1665
+ foreach (sl , deferredTriggers -> deftrig_trigstates )
1669
1666
{
1670
1667
trigstate = (DeferredTriggerStatus ) lfirst (sl );
1671
1668
if (trigstate -> dts_tgoid == tgoid )
@@ -1676,21 +1673,22 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
1676
1673
* No individual state known - so if the user issued a SET CONSTRAINT
1677
1674
* ALL ..., we return that instead of the triggers default state.
1678
1675
*/
1679
- if (deftrig_all_isset )
1680
- return deftrig_all_isdeferred ;
1676
+ if (deferredTriggers -> deftrig_all_isset )
1677
+ return deferredTriggers -> deftrig_all_isdeferred ;
1681
1678
1682
1679
/*
1683
1680
* No ALL state known either, remember the default state as the
1684
1681
* current and return that.
1685
1682
*/
1686
- oldcxt = MemoryContextSwitchTo (deftrig_cxt );
1683
+ oldcxt = MemoryContextSwitchTo (deferredTriggers -> deftrig_cxt );
1687
1684
1688
1685
trigstate = (DeferredTriggerStatus )
1689
1686
palloc (sizeof (DeferredTriggerStatusData ));
1690
1687
trigstate -> dts_tgoid = tgoid ;
1691
1688
trigstate -> dts_tgisdeferred =
1692
1689
((itemstate & TRIGGER_DEFERRED_INITDEFERRED ) != 0 );
1693
- deftrig_trigstates = lappend (deftrig_trigstates , trigstate );
1690
+ deferredTriggers -> deftrig_trigstates =
1691
+ lappend (deferredTriggers -> deftrig_trigstates , trigstate );
1694
1692
1695
1693
MemoryContextSwitchTo (oldcxt );
1696
1694
@@ -1713,16 +1711,16 @@ deferredTriggerAddEvent(DeferredTriggerEvent event)
1713
1711
* "lappend". This avoids O(N^2) behavior for large numbers of events.
1714
1712
*/
1715
1713
event -> dte_next = NULL ;
1716
- if (deftrig_event_tail == NULL )
1714
+ if (deferredTriggers -> deftrig_event_tail == NULL )
1717
1715
{
1718
1716
/* first list entry */
1719
- deftrig_events = event ;
1720
- deftrig_event_tail = event ;
1717
+ deferredTriggers -> deftrig_events = event ;
1718
+ deferredTriggers -> deftrig_event_tail = event ;
1721
1719
}
1722
1720
else
1723
1721
{
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 ;
1726
1724
}
1727
1725
}
1728
1726
@@ -1884,15 +1882,15 @@ deferredTriggerInvokeEvents(bool immediate_only)
1884
1882
* are those since deftrig_events_imm. (But if deftrig_events_imm is
1885
1883
* NULL, we must scan the entire list.)
1886
1884
*/
1887
- if (immediate_only && deftrig_events_imm != NULL )
1885
+ if (immediate_only && deferredTriggers -> deftrig_events_imm != NULL )
1888
1886
{
1889
- prev_event = deftrig_events_imm ;
1887
+ prev_event = deferredTriggers -> deftrig_events_imm ;
1890
1888
event = prev_event -> dte_next ;
1891
1889
}
1892
1890
else
1893
1891
{
1894
1892
prev_event = NULL ;
1895
- event = deftrig_events ;
1893
+ event = deferredTriggers -> deftrig_events ;
1896
1894
}
1897
1895
1898
1896
while (event != NULL )
@@ -1994,7 +1992,7 @@ deferredTriggerInvokeEvents(bool immediate_only)
1994
1992
if (prev_event )
1995
1993
prev_event -> dte_next = next_event ;
1996
1994
else
1997
- deftrig_events = next_event ;
1995
+ deferredTriggers -> deftrig_events = next_event ;
1998
1996
pfree (event );
1999
1997
}
2000
1998
else
@@ -2011,10 +2009,10 @@ deferredTriggerInvokeEvents(bool immediate_only)
2011
2009
}
2012
2010
2013
2011
/* Update list tail pointer in case we just deleted tail event */
2014
- deftrig_event_tail = prev_event ;
2012
+ deferredTriggers -> deftrig_event_tail = prev_event ;
2015
2013
2016
2014
/* Set the immediate event pointer for next time */
2017
- deftrig_events_imm = prev_event ;
2015
+ deferredTriggers -> deftrig_events_imm = prev_event ;
2018
2016
2019
2017
/* Release working resources */
2020
2018
if (rel )
@@ -2052,30 +2050,32 @@ DeferredTriggerInit(void)
2052
2050
void
2053
2051
DeferredTriggerBeginXact (void )
2054
2052
{
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 ));
2058
2060
2059
2061
/*
2060
2062
* Create the per transaction memory context
2061
2063
*/
2062
- deftrig_cxt = AllocSetContextCreate (TopTransactionContext ,
2064
+ deferredTriggers -> deftrig_cxt = AllocSetContextCreate (cxt ,
2063
2065
"DeferredTriggerXact" ,
2064
2066
ALLOCSET_DEFAULT_MINSIZE ,
2065
2067
ALLOCSET_DEFAULT_INITSIZE ,
2066
2068
ALLOCSET_DEFAULT_MAXSIZE );
2067
- deftrig_all_isset = false;
2068
-
2069
2069
/*
2070
2070
* If unspecified, constraints default to IMMEDIATE, per SQL
2071
2071
*/
2072
- deftrig_all_isdeferred = false;
2072
+ deferredTriggers -> deftrig_all_isdeferred = false;
2073
+ deferredTriggers -> deftrig_all_isset = false;
2073
2074
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 ;
2079
2079
}
2080
2080
2081
2081
@@ -2092,7 +2092,7 @@ DeferredTriggerEndQuery(void)
2092
2092
/*
2093
2093
* Ignore call if we aren't in a transaction.
2094
2094
*/
2095
- if (deftrig_cxt == NULL )
2095
+ if (deferredTriggers == NULL )
2096
2096
return ;
2097
2097
2098
2098
deferredTriggerInvokeEvents (true);
@@ -2112,13 +2112,12 @@ DeferredTriggerEndXact(void)
2112
2112
/*
2113
2113
* Ignore call if we aren't in a transaction.
2114
2114
*/
2115
- if (deftrig_cxt == NULL )
2115
+ if (deferredTriggers == NULL )
2116
2116
return ;
2117
2117
2118
2118
deferredTriggerInvokeEvents (false);
2119
2119
2120
- MemoryContextDelete (deftrig_cxt );
2121
- deftrig_cxt = NULL ;
2120
+ deferredTriggers = NULL ;
2122
2121
}
2123
2122
2124
2123
@@ -2136,11 +2135,13 @@ DeferredTriggerAbortXact(void)
2136
2135
/*
2137
2136
* Ignore call if we aren't in a transaction.
2138
2137
*/
2139
- if (deftrig_cxt == NULL )
2140
- return ;
2138
+ if (deferredTriggers == NULL )
2139
+ return ;
2141
2140
2142
- MemoryContextDelete (deftrig_cxt );
2143
- deftrig_cxt = NULL ;
2141
+ /*
2142
+ * Forget everything we know about deferred triggers.
2143
+ */
2144
+ deferredTriggers = NULL ;
2144
2145
}
2145
2146
2146
2147
@@ -2158,7 +2159,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
2158
2159
/*
2159
2160
* Ignore call if we aren't in a transaction.
2160
2161
*/
2161
- if (deftrig_cxt == NULL )
2162
+ if (deferredTriggers == NULL )
2162
2163
return ;
2163
2164
2164
2165
/*
@@ -2170,7 +2171,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
2170
2171
* Drop all per-transaction information about individual trigger
2171
2172
* states.
2172
2173
*/
2173
- l = deftrig_trigstates ;
2174
+ l = deferredTriggers -> deftrig_trigstates ;
2174
2175
while (l != NIL )
2175
2176
{
2176
2177
List * next = lnext (l );
@@ -2179,13 +2180,13 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
2179
2180
pfree (l );
2180
2181
l = next ;
2181
2182
}
2182
- deftrig_trigstates = NIL ;
2183
+ deferredTriggers -> deftrig_trigstates = NIL ;
2183
2184
2184
2185
/*
2185
2186
* Set the per-transaction ALL state to known.
2186
2187
*/
2187
- deftrig_all_isset = true;
2188
- deftrig_all_isdeferred = stmt -> deferred ;
2188
+ deferredTriggers -> deftrig_all_isset = true;
2189
+ deferredTriggers -> deftrig_all_isdeferred = stmt -> deferred ;
2189
2190
}
2190
2191
else
2191
2192
{
@@ -2267,12 +2268,12 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
2267
2268
* Inside of a transaction block set the trigger states of
2268
2269
* individual triggers on transaction level.
2269
2270
*/
2270
- oldcxt = MemoryContextSwitchTo (deftrig_cxt );
2271
+ oldcxt = MemoryContextSwitchTo (deferredTriggers -> deftrig_cxt );
2271
2272
2272
2273
foreach (l , loid )
2273
2274
{
2274
2275
found = false;
2275
- foreach (ls , deftrig_trigstates )
2276
+ foreach (ls , deferredTriggers -> deftrig_trigstates )
2276
2277
{
2277
2278
state = (DeferredTriggerStatus ) lfirst (ls );
2278
2279
if (state -> dts_tgoid == lfirsto (l ))
@@ -2289,8 +2290,8 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
2289
2290
state -> dts_tgoid = lfirsto (l );
2290
2291
state -> dts_tgisdeferred = stmt -> deferred ;
2291
2292
2292
- deftrig_trigstates =
2293
- lappend (deftrig_trigstates , state );
2293
+ deferredTriggers -> deftrig_trigstates =
2294
+ lappend (deferredTriggers -> deftrig_trigstates , state );
2294
2295
}
2295
2296
}
2296
2297
@@ -2308,7 +2309,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
2308
2309
* tail pointer to make it rescan the entire list, in case some deferred
2309
2310
* events are now immediately invokable.
2310
2311
*/
2311
- deftrig_events_imm = NULL ;
2312
+ deferredTriggers -> deftrig_events_imm = NULL ;
2312
2313
}
2313
2314
2314
2315
@@ -2337,7 +2338,7 @@ DeferredTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
2337
2338
ItemPointerData oldctid ;
2338
2339
ItemPointerData newctid ;
2339
2340
2340
- if (deftrig_cxt == NULL )
2341
+ if (deferredTriggers == NULL )
2341
2342
elog (ERROR ,
2342
2343
"DeferredTriggerSaveEvent() called outside of transaction" );
2343
2344
@@ -2387,7 +2388,7 @@ DeferredTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
2387
2388
/*
2388
2389
* Create a new event
2389
2390
*/
2390
- oldcxt = MemoryContextSwitchTo (deftrig_cxt );
2391
+ oldcxt = MemoryContextSwitchTo (deferredTriggers -> deftrig_cxt );
2391
2392
2392
2393
new_size = offsetof(DeferredTriggerEventData , dte_item [0 ]) +
2393
2394
n_enabled_triggers * sizeof (DeferredTriggerEventItem );
0 commit comments