]> granicus.if.org Git - postgresql/blob - src/backend/access/transam/xact.c
79158d8d71e2650ebad2ae45d9558d0223458325
[postgresql] / src / backend / access / transam / xact.c
1 /*-------------------------------------------------------------------------
2  *
3  * xact.c
4  *        top level transaction system support routines
5  *
6  * See src/backend/access/transam/README for more information.
7  *
8  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  *
12  * IDENTIFICATION
13  *        $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.259 2008/03/17 02:18:55 tgl Exp $
14  *
15  *-------------------------------------------------------------------------
16  */
17
18 #include "postgres.h"
19
20 #include <time.h>
21 #include <unistd.h>
22
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/namespace.h"
30 #include "commands/async.h"
31 #include "commands/tablecmds.h"
32 #include "commands/trigger.h"
33 #include "executor/spi.h"
34 #include "libpq/be-fsstubs.h"
35 #include "miscadmin.h"
36 #include "pgstat.h"
37 #include "storage/fd.h"
38 #include "storage/lmgr.h"
39 #include "storage/procarray.h"
40 #include "storage/sinvaladt.h"
41 #include "storage/smgr.h"
42 #include "utils/combocid.h"
43 #include "utils/flatfiles.h"
44 #include "utils/guc.h"
45 #include "utils/inval.h"
46 #include "utils/memutils.h"
47 #include "utils/relcache.h"
48 #include "utils/xml.h"
49
50
51 /*
52  *      User-tweakable parameters
53  */
54 int                     DefaultXactIsoLevel = XACT_READ_COMMITTED;
55 int                     XactIsoLevel;
56
57 bool            DefaultXactReadOnly = false;
58 bool            XactReadOnly;
59
60 bool            XactSyncCommit = true;
61
62 int                     CommitDelay = 0;        /* precommit delay in microseconds */
63 int                     CommitSiblings = 5; /* # concurrent xacts needed to sleep */
64
65 /*
66  * MyXactAccessedTempRel is set when a temporary relation is accessed.
67  * We don't allow PREPARE TRANSACTION in that case.  (This is global
68  * so that it can be set from heapam.c.)
69  */
70 bool            MyXactAccessedTempRel = false;
71
72
73 /*
74  *      transaction states - transaction state from server perspective
75  */
76 typedef enum TransState
77 {
78         TRANS_DEFAULT,                          /* idle */
79         TRANS_START,                            /* transaction starting */
80         TRANS_INPROGRESS,                       /* inside a valid transaction */
81         TRANS_COMMIT,                           /* commit in progress */
82         TRANS_ABORT,                            /* abort in progress */
83         TRANS_PREPARE                           /* prepare in progress */
84 } TransState;
85
86 /*
87  *      transaction block states - transaction state of client queries
88  *
89  * Note: the subtransaction states are used only for non-topmost
90  * transactions; the others appear only in the topmost transaction.
91  */
92 typedef enum TBlockState
93 {
94         /* not-in-transaction-block states */
95         TBLOCK_DEFAULT,                         /* idle */
96         TBLOCK_STARTED,                         /* running single-query transaction */
97
98         /* transaction block states */
99         TBLOCK_BEGIN,                           /* starting transaction block */
100         TBLOCK_INPROGRESS,                      /* live transaction */
101         TBLOCK_END,                                     /* COMMIT received */
102         TBLOCK_ABORT,                           /* failed xact, awaiting ROLLBACK */
103         TBLOCK_ABORT_END,                       /* failed xact, ROLLBACK received */
104         TBLOCK_ABORT_PENDING,           /* live xact, ROLLBACK received */
105         TBLOCK_PREPARE,                         /* live xact, PREPARE received */
106
107         /* subtransaction states */
108         TBLOCK_SUBBEGIN,                        /* starting a subtransaction */
109         TBLOCK_SUBINPROGRESS,           /* live subtransaction */
110         TBLOCK_SUBEND,                          /* RELEASE received */
111         TBLOCK_SUBABORT,                        /* failed subxact, awaiting ROLLBACK */
112         TBLOCK_SUBABORT_END,            /* failed subxact, ROLLBACK received */
113         TBLOCK_SUBABORT_PENDING,        /* live subxact, ROLLBACK received */
114         TBLOCK_SUBRESTART,                      /* live subxact, ROLLBACK TO received */
115         TBLOCK_SUBABORT_RESTART         /* failed subxact, ROLLBACK TO received */
116 } TBlockState;
117
118 /*
119  *      transaction state structure
120  */
121 typedef struct TransactionStateData
122 {
123         TransactionId transactionId;    /* my XID, or Invalid if none */
124         SubTransactionId subTransactionId;      /* my subxact ID */
125         char       *name;                       /* savepoint name, if any */
126         int                     savepointLevel; /* savepoint level */
127         TransState      state;                  /* low-level state */
128         TBlockState blockState;         /* high-level state */
129         int                     nestingLevel;   /* transaction nesting depth */
130         int                     gucNestLevel;   /* GUC context nesting depth */
131         MemoryContext curTransactionContext;            /* my xact-lifetime context */
132         ResourceOwner curTransactionOwner;      /* my query resources */
133         TransactionId *childXids;       /* subcommitted child XIDs, in XID order */
134         int                     nChildXids;             /* # of subcommitted child XIDs */
135         int                     maxChildXids;   /* allocated size of childXids[] */
136         Oid                     prevUser;               /* previous CurrentUserId setting */
137         bool            prevSecDefCxt;  /* previous SecurityDefinerContext setting */
138         bool            prevXactReadOnly;               /* entry-time xact r/o state */
139         struct TransactionStateData *parent;            /* back link to parent */
140 } TransactionStateData;
141
142 typedef TransactionStateData *TransactionState;
143
144 /*
145  * CurrentTransactionState always points to the current transaction state
146  * block.  It will point to TopTransactionStateData when not in a
147  * transaction at all, or when in a top-level transaction.
148  */
149 static TransactionStateData TopTransactionStateData = {
150         0,                                                      /* transaction id */
151         0,                                                      /* subtransaction id */
152         NULL,                                           /* savepoint name */
153         0,                                                      /* savepoint level */
154         TRANS_DEFAULT,                          /* transaction state */
155         TBLOCK_DEFAULT,                         /* transaction block state from the client
156                                                                  * perspective */
157         0,                                                      /* transaction nesting depth */
158         0,                                                      /* GUC context nesting depth */
159         NULL,                                           /* cur transaction context */
160         NULL,                                           /* cur transaction resource owner */
161         NULL,                                           /* subcommitted child Xids */
162         0,                                                      /* # of subcommitted child Xids */
163         0,                                                      /* allocated size of childXids[] */
164         InvalidOid,                                     /* previous CurrentUserId setting */
165         false,                                          /* previous SecurityDefinerContext setting */
166         false,                                          /* entry-time xact r/o state */
167         NULL                                            /* link to parent state block */
168 };
169
170 static TransactionState CurrentTransactionState = &TopTransactionStateData;
171
172 /*
173  * The subtransaction ID and command ID assignment counters are global
174  * to a whole transaction, so we do not keep them in the state stack.
175  */
176 static SubTransactionId currentSubTransactionId;
177 static CommandId currentCommandId;
178 static bool currentCommandIdUsed;
179
180 /*
181  * xactStartTimestamp is the value of transaction_timestamp().
182  * stmtStartTimestamp is the value of statement_timestamp().
183  * xactStopTimestamp is the time at which we log a commit or abort WAL record.
184  * These do not change as we enter and exit subtransactions, so we don't
185  * keep them inside the TransactionState stack.
186  */
187 static TimestampTz xactStartTimestamp;
188 static TimestampTz stmtStartTimestamp;
189 static TimestampTz xactStopTimestamp;
190
191 /*
192  * GID to be used for preparing the current transaction.  This is also
193  * global to a whole transaction, so we don't keep it in the state stack.
194  */
195 static char *prepareGID;
196
197 /*
198  * Some commands want to force synchronous commit.
199  */
200 static bool forceSyncCommit = false;
201
202 /*
203  * Private context for transaction-abort work --- we reserve space for this
204  * at startup to ensure that AbortTransaction and AbortSubTransaction can work
205  * when we've run out of memory.
206  */
207 static MemoryContext TransactionAbortContext = NULL;
208
209 /*
210  * List of add-on start- and end-of-xact callbacks
211  */
212 typedef struct XactCallbackItem
213 {
214         struct XactCallbackItem *next;
215         XactCallback callback;
216         void       *arg;
217 } XactCallbackItem;
218
219 static XactCallbackItem *Xact_callbacks = NULL;
220
221 /*
222  * List of add-on start- and end-of-subxact callbacks
223  */
224 typedef struct SubXactCallbackItem
225 {
226         struct SubXactCallbackItem *next;
227         SubXactCallback callback;
228         void       *arg;
229 } SubXactCallbackItem;
230
231 static SubXactCallbackItem *SubXact_callbacks = NULL;
232
233
234 /* local function prototypes */
235 static void AssignTransactionId(TransactionState s);
236 static void AbortTransaction(void);
237 static void AtAbort_Memory(void);
238 static void AtCleanup_Memory(void);
239 static void AtAbort_ResourceOwner(void);
240 static void AtCommit_LocalCache(void);
241 static void AtCommit_Memory(void);
242 static void AtStart_Cache(void);
243 static void AtStart_Memory(void);
244 static void AtStart_ResourceOwner(void);
245 static void CallXactCallbacks(XactEvent event);
246 static void CallSubXactCallbacks(SubXactEvent event,
247                                          SubTransactionId mySubid,
248                                          SubTransactionId parentSubid);
249 static void CleanupTransaction(void);
250 static void CommitTransaction(void);
251 static TransactionId RecordTransactionAbort(bool isSubXact);
252 static void StartTransaction(void);
253
254 static void RecordSubTransactionCommit(void);
255 static void StartSubTransaction(void);
256 static void CommitSubTransaction(void);
257 static void AbortSubTransaction(void);
258 static void CleanupSubTransaction(void);
259 static void PushTransaction(void);
260 static void PopTransaction(void);
261
262 static void AtSubAbort_Memory(void);
263 static void AtSubCleanup_Memory(void);
264 static void AtSubAbort_ResourceOwner(void);
265 static void AtSubCommit_Memory(void);
266 static void AtSubStart_Memory(void);
267 static void AtSubStart_ResourceOwner(void);
268
269 static void ShowTransactionState(const char *str);
270 static void ShowTransactionStateRec(TransactionState state);
271 static const char *BlockStateAsString(TBlockState blockState);
272 static const char *TransStateAsString(TransState state);
273
274
275 /* ----------------------------------------------------------------
276  *      transaction state accessors
277  * ----------------------------------------------------------------
278  */
279
280 /*
281  *      IsTransactionState
282  *
283  *      This returns true if we are inside a valid transaction; that is,
284  *      it is safe to initiate database access, take heavyweight locks, etc.
285  */
286 bool
287 IsTransactionState(void)
288 {
289         TransactionState s = CurrentTransactionState;
290
291         /*
292          * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states.  However, we
293          * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
294          * TRANS_PREPARE since it might be too soon or too late within those
295          * transition states to do anything interesting.  Hence, the only "valid"
296          * state is TRANS_INPROGRESS.
297          */
298         return (s->state == TRANS_INPROGRESS);
299 }
300
301 /*
302  *      IsAbortedTransactionBlockState
303  *
304  *      This returns true if we are currently running a query
305  *      within an aborted transaction block.
306  */
307 bool
308 IsAbortedTransactionBlockState(void)
309 {
310         TransactionState s = CurrentTransactionState;
311
312         if (s->blockState == TBLOCK_ABORT ||
313                 s->blockState == TBLOCK_SUBABORT)
314                 return true;
315
316         return false;
317 }
318
319
320 /*
321  *      GetTopTransactionId
322  *
323  * This will return the XID of the main transaction, assigning one if
324  * it's not yet set.  Be careful to call this only inside a valid xact.
325  */
326 TransactionId
327 GetTopTransactionId(void)
328 {
329         if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
330                 AssignTransactionId(&TopTransactionStateData);
331         return TopTransactionStateData.transactionId;
332 }
333
334 /*
335  *      GetTopTransactionIdIfAny
336  *
337  * This will return the XID of the main transaction, if one is assigned.
338  * It will return InvalidTransactionId if we are not currently inside a
339  * transaction, or inside a transaction that hasn't yet been assigned an XID.
340  */
341 TransactionId
342 GetTopTransactionIdIfAny(void)
343 {
344         return TopTransactionStateData.transactionId;
345 }
346
347 /*
348  *      GetCurrentTransactionId
349  *
350  * This will return the XID of the current transaction (main or sub
351  * transaction), assigning one if it's not yet set.  Be careful to call this
352  * only inside a valid xact.
353  */
354 TransactionId
355 GetCurrentTransactionId(void)
356 {
357         TransactionState s = CurrentTransactionState;
358
359         if (!TransactionIdIsValid(s->transactionId))
360                 AssignTransactionId(s);
361         return s->transactionId;
362 }
363
364 /*
365  *      GetCurrentTransactionIdIfAny
366  *
367  * This will return the XID of the current sub xact, if one is assigned.
368  * It will return InvalidTransactionId if we are not currently inside a
369  * transaction, or inside a transaction that hasn't been assigned an XID yet.
370  */
371 TransactionId
372 GetCurrentTransactionIdIfAny(void)
373 {
374         return CurrentTransactionState->transactionId;
375 }
376
377
378 /*
379  * AssignTransactionId
380  *
381  * Assigns a new permanent XID to the given TransactionState.
382  * We do not assign XIDs to transactions until/unless this is called.
383  * Also, any parent TransactionStates that don't yet have XIDs are assigned
384  * one; this maintains the invariant that a child transaction has an XID
385  * following its parent's.
386  */
387 static void
388 AssignTransactionId(TransactionState s)
389 {
390         bool            isSubXact = (s->parent != NULL);
391         ResourceOwner currentOwner;
392
393         /* Assert that caller didn't screw up */
394         Assert(!TransactionIdIsValid(s->transactionId));
395         Assert(s->state == TRANS_INPROGRESS);
396
397         /*
398          * Ensure parent(s) have XIDs, so that a child always has an XID later
399          * than its parent.
400          */
401         if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
402                 AssignTransactionId(s->parent);
403
404         /*
405          * Generate a new Xid and record it in PG_PROC and pg_subtrans.
406          *
407          * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
408          * shared storage other than PG_PROC; because if there's no room for it in
409          * PG_PROC, the subtrans entry is needed to ensure that other backends see
410          * the Xid as "running".  See GetNewTransactionId.
411          */
412         s->transactionId = GetNewTransactionId(isSubXact);
413
414         if (isSubXact)
415                 SubTransSetParent(s->transactionId, s->parent->transactionId);
416
417         /*
418          * Acquire lock on the transaction XID.  (We assume this cannot block.) We
419          * have to ensure that the lock is assigned to the transaction's own
420          * ResourceOwner.
421          */
422         currentOwner = CurrentResourceOwner;
423         PG_TRY();
424         {
425                 CurrentResourceOwner = s->curTransactionOwner;
426                 XactLockTableInsert(s->transactionId);
427         }
428         PG_CATCH();
429         {
430                 /* Ensure CurrentResourceOwner is restored on error */
431                 CurrentResourceOwner = currentOwner;
432                 PG_RE_THROW();
433         }
434         PG_END_TRY();
435         CurrentResourceOwner = currentOwner;
436 }
437
438
439 /*
440  *      GetCurrentSubTransactionId
441  */
442 SubTransactionId
443 GetCurrentSubTransactionId(void)
444 {
445         TransactionState s = CurrentTransactionState;
446
447         return s->subTransactionId;
448 }
449
450
451 /*
452  *      GetCurrentCommandId
453  *
454  * "used" must be TRUE if the caller intends to use the command ID to mark
455  * inserted/updated/deleted tuples.  FALSE means the ID is being fetched
456  * for read-only purposes (ie, as a snapshot validity cutoff).  See
457  * CommandCounterIncrement() for discussion.
458  */
459 CommandId
460 GetCurrentCommandId(bool used)
461 {
462         /* this is global to a transaction, not subtransaction-local */
463         if (used)
464                 currentCommandIdUsed = true;
465         return currentCommandId;
466 }
467
468 /*
469  *      GetCurrentTransactionStartTimestamp
470  */
471 TimestampTz
472 GetCurrentTransactionStartTimestamp(void)
473 {
474         return xactStartTimestamp;
475 }
476
477 /*
478  *      GetCurrentStatementStartTimestamp
479  */
480 TimestampTz
481 GetCurrentStatementStartTimestamp(void)
482 {
483         return stmtStartTimestamp;
484 }
485
486 /*
487  *      GetCurrentTransactionStopTimestamp
488  *
489  * We return current time if the transaction stop time hasn't been set
490  * (which can happen if we decide we don't need to log an XLOG record).
491  */
492 TimestampTz
493 GetCurrentTransactionStopTimestamp(void)
494 {
495         if (xactStopTimestamp != 0)
496                 return xactStopTimestamp;
497         return GetCurrentTimestamp();
498 }
499
500 /*
501  *      SetCurrentStatementStartTimestamp
502  */
503 void
504 SetCurrentStatementStartTimestamp(void)
505 {
506         stmtStartTimestamp = GetCurrentTimestamp();
507 }
508
509 /*
510  *      SetCurrentTransactionStopTimestamp
511  */
512 static inline void
513 SetCurrentTransactionStopTimestamp(void)
514 {
515         xactStopTimestamp = GetCurrentTimestamp();
516 }
517
518 /*
519  *      GetCurrentTransactionNestLevel
520  *
521  * Note: this will return zero when not inside any transaction, one when
522  * inside a top-level transaction, etc.
523  */
524 int
525 GetCurrentTransactionNestLevel(void)
526 {
527         TransactionState s = CurrentTransactionState;
528
529         return s->nestingLevel;
530 }
531
532
533 /*
534  *      TransactionIdIsCurrentTransactionId
535  */
536 bool
537 TransactionIdIsCurrentTransactionId(TransactionId xid)
538 {
539         TransactionState s;
540
541         /*
542          * We always say that BootstrapTransactionId is "not my transaction ID"
543          * even when it is (ie, during bootstrap).      Along with the fact that
544          * transam.c always treats BootstrapTransactionId as already committed,
545          * this causes the tqual.c routines to see all tuples as committed, which
546          * is what we need during bootstrap.  (Bootstrap mode only inserts tuples,
547          * it never updates or deletes them, so all tuples can be presumed good
548          * immediately.)
549          *
550          * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
551          * not my transaction ID, so we can just return "false" immediately for
552          * any non-normal XID.
553          */
554         if (!TransactionIdIsNormal(xid))
555                 return false;
556
557         /*
558          * We will return true for the Xid of the current subtransaction, any of
559          * its subcommitted children, any of its parents, or any of their
560          * previously subcommitted children.  However, a transaction being aborted
561          * is no longer "current", even though it may still have an entry on the
562          * state stack.
563          */
564         for (s = CurrentTransactionState; s != NULL; s = s->parent)
565         {
566                 int low, high;
567
568                 if (s->state == TRANS_ABORT)
569                         continue;
570                 if (!TransactionIdIsValid(s->transactionId))
571                         continue;                       /* it can't have any child XIDs either */
572                 if (TransactionIdEquals(xid, s->transactionId))
573                         return true;
574                 /* As the childXids array is ordered, we can use binary search */
575                 low = 0;
576                 high = s->nChildXids - 1;
577                 while (low <= high)
578                 {
579                         int                             middle;
580                         TransactionId   probe;
581
582                         middle = low + (high - low) / 2;
583                         probe = s->childXids[middle];
584                         if (TransactionIdEquals(probe, xid))
585                                 return true;
586                         else if (TransactionIdPrecedes(probe, xid))
587                                 low = middle + 1;
588                         else
589                                 high = middle - 1;
590                 }
591         }
592
593         return false;
594 }
595
596
597 /*
598  *      CommandCounterIncrement
599  */
600 void
601 CommandCounterIncrement(void)
602 {
603         /*
604          * If the current value of the command counter hasn't been "used" to
605          * mark tuples, we need not increment it, since there's no need to
606          * distinguish a read-only command from others.  This helps postpone
607          * command counter overflow, and keeps no-op CommandCounterIncrement
608          * operations cheap.
609          */
610         if (currentCommandIdUsed)
611         {
612                 currentCommandId += 1;
613                 if (currentCommandId == FirstCommandId) /* check for overflow */
614                 {
615                         currentCommandId -= 1;
616                         ereport(ERROR,
617                                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
618                   errmsg("cannot have more than 2^32-1 commands in a transaction")));
619                 }
620                 currentCommandIdUsed = false;
621
622                 /* Propagate new command ID into static snapshots, if set */
623                 if (SerializableSnapshot)
624                         SerializableSnapshot->curcid = currentCommandId;
625                 if (LatestSnapshot)
626                         LatestSnapshot->curcid = currentCommandId;
627
628                 /*
629                  * Make any catalog changes done by the just-completed command
630                  * visible in the local syscache.  We obviously don't need to do
631                  * this after a read-only command.  (But see hacks in inval.c
632                  * to make real sure we don't think a command that queued inval
633                  * messages was read-only.)
634                  */
635                 AtCommit_LocalCache();
636         }
637
638         /*
639          * Make any other backends' catalog changes visible to me.
640          *
641          * XXX this is probably in the wrong place: CommandCounterIncrement
642          * should be purely a local operation, most likely.  However fooling
643          * with this will affect asynchronous cross-backend interactions,
644          * which doesn't seem like a wise thing to do in late beta, so save
645          * improving this for another day - tgl 2007-11-30
646          */
647         AtStart_Cache();
648 }
649
650 /*
651  * ForceSyncCommit
652  *
653  * Interface routine to allow commands to force a synchronous commit of the
654  * current top-level transaction
655  */
656 void
657 ForceSyncCommit(void)
658 {
659         forceSyncCommit = true;
660 }
661
662
663 /* ----------------------------------------------------------------
664  *                                              StartTransaction stuff
665  * ----------------------------------------------------------------
666  */
667
668 /*
669  *      AtStart_Cache
670  */
671 static void
672 AtStart_Cache(void)
673 {
674         AcceptInvalidationMessages();
675 }
676
677 /*
678  *      AtStart_Memory
679  */
680 static void
681 AtStart_Memory(void)
682 {
683         TransactionState s = CurrentTransactionState;
684
685         /*
686          * If this is the first time through, create a private context for
687          * AbortTransaction to work in.  By reserving some space now, we can
688          * insulate AbortTransaction from out-of-memory scenarios.      Like
689          * ErrorContext, we set it up with slow growth rate and a nonzero minimum
690          * size, so that space will be reserved immediately.
691          */
692         if (TransactionAbortContext == NULL)
693                 TransactionAbortContext =
694                         AllocSetContextCreate(TopMemoryContext,
695                                                                   "TransactionAbortContext",
696                                                                   32 * 1024,
697                                                                   32 * 1024,
698                                                                   32 * 1024);
699
700         /*
701          * We shouldn't have a transaction context already.
702          */
703         Assert(TopTransactionContext == NULL);
704
705         /*
706          * Create a toplevel context for the transaction.
707          */
708         TopTransactionContext =
709                 AllocSetContextCreate(TopMemoryContext,
710                                                           "TopTransactionContext",
711                                                           ALLOCSET_DEFAULT_MINSIZE,
712                                                           ALLOCSET_DEFAULT_INITSIZE,
713                                                           ALLOCSET_DEFAULT_MAXSIZE);
714
715         /*
716          * In a top-level transaction, CurTransactionContext is the same as
717          * TopTransactionContext.
718          */
719         CurTransactionContext = TopTransactionContext;
720         s->curTransactionContext = CurTransactionContext;
721
722         /* Make the CurTransactionContext active. */
723         MemoryContextSwitchTo(CurTransactionContext);
724 }
725
726 /*
727  *      AtStart_ResourceOwner
728  */
729 static void
730 AtStart_ResourceOwner(void)
731 {
732         TransactionState s = CurrentTransactionState;
733
734         /*
735          * We shouldn't have a transaction resource owner already.
736          */
737         Assert(TopTransactionResourceOwner == NULL);
738
739         /*
740          * Create a toplevel resource owner for the transaction.
741          */
742         s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
743
744         TopTransactionResourceOwner = s->curTransactionOwner;
745         CurTransactionResourceOwner = s->curTransactionOwner;
746         CurrentResourceOwner = s->curTransactionOwner;
747 }
748
749 /* ----------------------------------------------------------------
750  *                                              StartSubTransaction stuff
751  * ----------------------------------------------------------------
752  */
753
754 /*
755  * AtSubStart_Memory
756  */
757 static void
758 AtSubStart_Memory(void)
759 {
760         TransactionState s = CurrentTransactionState;
761
762         Assert(CurTransactionContext != NULL);
763
764         /*
765          * Create a CurTransactionContext, which will be used to hold data that
766          * survives subtransaction commit but disappears on subtransaction abort.
767          * We make it a child of the immediate parent's CurTransactionContext.
768          */
769         CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
770                                                                                                   "CurTransactionContext",
771                                                                                                   ALLOCSET_DEFAULT_MINSIZE,
772                                                                                                   ALLOCSET_DEFAULT_INITSIZE,
773                                                                                                   ALLOCSET_DEFAULT_MAXSIZE);
774         s->curTransactionContext = CurTransactionContext;
775
776         /* Make the CurTransactionContext active. */
777         MemoryContextSwitchTo(CurTransactionContext);
778 }
779
780 /*
781  * AtSubStart_ResourceOwner
782  */
783 static void
784 AtSubStart_ResourceOwner(void)
785 {
786         TransactionState s = CurrentTransactionState;
787
788         Assert(s->parent != NULL);
789
790         /*
791          * Create a resource owner for the subtransaction.      We make it a child of
792          * the immediate parent's resource owner.
793          */
794         s->curTransactionOwner =
795                 ResourceOwnerCreate(s->parent->curTransactionOwner,
796                                                         "SubTransaction");
797
798         CurTransactionResourceOwner = s->curTransactionOwner;
799         CurrentResourceOwner = s->curTransactionOwner;
800 }
801
802 /* ----------------------------------------------------------------
803  *                                              CommitTransaction stuff
804  * ----------------------------------------------------------------
805  */
806
807 /*
808  *      RecordTransactionCommit
809  *
810  * Returns latest XID among xact and its children, or InvalidTransactionId
811  * if the xact has no XID.      (We compute that here just because it's easier.)
812  *
813  * This is exported only to support an ugly hack in VACUUM FULL.
814  */
815 TransactionId
816 RecordTransactionCommit(void)
817 {
818         TransactionId xid = GetTopTransactionIdIfAny();
819         bool            markXidCommitted = TransactionIdIsValid(xid);
820         TransactionId latestXid = InvalidTransactionId;
821         int                     nrels;
822         RelFileNode *rels;
823         bool            haveNonTemp;
824         int                     nchildren;
825         TransactionId *children;
826
827         /* Get data needed for commit record */
828         nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
829         nchildren = xactGetCommittedChildren(&children);
830
831         /*
832          * If we haven't been assigned an XID yet, we neither can, nor do we want
833          * to write a COMMIT record.
834          */
835         if (!markXidCommitted)
836         {
837                 /*
838                  * We expect that every smgrscheduleunlink is followed by a catalog
839                  * update, and hence XID assignment, so we shouldn't get here with any
840                  * pending deletes.  Use a real test not just an Assert to check this,
841                  * since it's a bit fragile.
842                  */
843                 if (nrels != 0)
844                         elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
845
846                 /* Can't have child XIDs either; AssignTransactionId enforces this */
847                 Assert(nchildren == 0);
848
849                 /*
850                  * If we didn't create XLOG entries, we're done here; otherwise we
851                  * should flush those entries the same as a commit record.      (An
852                  * example of a possible record that wouldn't cause an XID to be
853                  * assigned is a sequence advance record due to nextval() --- we want
854                  * to flush that to disk before reporting commit.)
855                  */
856                 if (XactLastRecEnd.xrecoff == 0)
857                         goto cleanup;
858         }
859         else
860         {
861                 /*
862                  * Begin commit critical section and insert the commit XLOG record.
863                  */
864                 XLogRecData rdata[3];
865                 int                     lastrdata = 0;
866                 xl_xact_commit xlrec;
867
868                 /* Tell bufmgr and smgr to prepare for commit */
869                 BufmgrCommit();
870
871                 /*
872                  * Mark ourselves as within our "commit critical section".      This
873                  * forces any concurrent checkpoint to wait until we've updated
874                  * pg_clog.  Without this, it is possible for the checkpoint to set
875                  * REDO after the XLOG record but fail to flush the pg_clog update to
876                  * disk, leading to loss of the transaction commit if the system
877                  * crashes a little later.
878                  *
879                  * Note: we could, but don't bother to, set this flag in
880                  * RecordTransactionAbort.      That's because loss of a transaction abort
881                  * is noncritical; the presumption would be that it aborted, anyway.
882                  *
883                  * It's safe to change the inCommit flag of our own backend without
884                  * holding the ProcArrayLock, since we're the only one modifying it.
885                  * This makes checkpoint's determination of which xacts are inCommit a
886                  * bit fuzzy, but it doesn't matter.
887                  */
888                 START_CRIT_SECTION();
889                 MyProc->inCommit = true;
890
891                 SetCurrentTransactionStopTimestamp();
892                 xlrec.xact_time = xactStopTimestamp;
893                 xlrec.nrels = nrels;
894                 xlrec.nsubxacts = nchildren;
895                 rdata[0].data = (char *) (&xlrec);
896                 rdata[0].len = MinSizeOfXactCommit;
897                 rdata[0].buffer = InvalidBuffer;
898                 /* dump rels to delete */
899                 if (nrels > 0)
900                 {
901                         rdata[0].next = &(rdata[1]);
902                         rdata[1].data = (char *) rels;
903                         rdata[1].len = nrels * sizeof(RelFileNode);
904                         rdata[1].buffer = InvalidBuffer;
905                         lastrdata = 1;
906                 }
907                 /* dump committed child Xids */
908                 if (nchildren > 0)
909                 {
910                         rdata[lastrdata].next = &(rdata[2]);
911                         rdata[2].data = (char *) children;
912                         rdata[2].len = nchildren * sizeof(TransactionId);
913                         rdata[2].buffer = InvalidBuffer;
914                         lastrdata = 2;
915                 }
916                 rdata[lastrdata].next = NULL;
917
918                 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
919         }
920
921         /*
922          * Check if we want to commit asynchronously.  If the user has set
923          * synchronous_commit = off, and we're not doing cleanup of any non-temp
924          * rels nor committing any command that wanted to force sync commit, then
925          * we can defer flushing XLOG.  (We must not allow asynchronous commit if
926          * there are any non-temp tables to be deleted, because we might delete
927          * the files before the COMMIT record is flushed to disk.  We do allow
928          * asynchronous commit if all to-be-deleted tables are temporary though,
929          * since they are lost anyway if we crash.)
930          */
931         if (XactSyncCommit || forceSyncCommit || haveNonTemp)
932         {
933                 /*
934                  * Synchronous commit case.
935                  *
936                  * Sleep before flush! So we can flush more than one commit records
937                  * per single fsync.  (The idea is some other backend may do the
938                  * XLogFlush while we're sleeping.  This needs work still, because on
939                  * most Unixen, the minimum select() delay is 10msec or more, which is
940                  * way too long.)
941                  *
942                  * We do not sleep if enableFsync is not turned on, nor if there are
943                  * fewer than CommitSiblings other backends with active transactions.
944                  */
945                 if (CommitDelay > 0 && enableFsync &&
946                         CountActiveBackends() >= CommitSiblings)
947                         pg_usleep(CommitDelay);
948
949                 XLogFlush(XactLastRecEnd);
950
951                 /*
952                  * Now we may update the CLOG, if we wrote a COMMIT record above
953                  */
954                 if (markXidCommitted)
955                 {
956                         TransactionIdCommit(xid);
957                         /* to avoid race conditions, the parent must commit first */
958                         TransactionIdCommitTree(nchildren, children);
959                 }
960         }
961         else
962         {
963                 /*
964                  * Asynchronous commit case.
965                  *
966                  * Report the latest async commit LSN, so that the WAL writer knows to
967                  * flush this commit.
968                  */
969                 XLogSetAsyncCommitLSN(XactLastRecEnd);
970
971                 /*
972                  * We must not immediately update the CLOG, since we didn't flush the
973                  * XLOG. Instead, we store the LSN up to which the XLOG must be
974                  * flushed before the CLOG may be updated.
975                  */
976                 if (markXidCommitted)
977                 {
978                         TransactionIdAsyncCommit(xid, XactLastRecEnd);
979                         /* to avoid race conditions, the parent must commit first */
980                         TransactionIdAsyncCommitTree(nchildren, children, XactLastRecEnd);
981                 }
982         }
983
984         /*
985          * If we entered a commit critical section, leave it now, and let
986          * checkpoints proceed.
987          */
988         if (markXidCommitted)
989         {
990                 MyProc->inCommit = false;
991                 END_CRIT_SECTION();
992         }
993
994         /* Compute latestXid while we have the child XIDs handy */
995         latestXid = TransactionIdLatest(xid, nchildren, children);
996
997         /* Reset XactLastRecEnd until the next transaction writes something */
998         XactLastRecEnd.xrecoff = 0;
999
1000 cleanup:
1001         /* Clean up local data */
1002         if (rels)
1003                 pfree(rels);
1004
1005         return latestXid;
1006 }
1007
1008
1009 /*
1010  *      AtCommit_LocalCache
1011  */
1012 static void
1013 AtCommit_LocalCache(void)
1014 {
1015         /*
1016          * Make catalog changes visible to me for the next command.
1017          */
1018         CommandEndInvalidationMessages();
1019 }
1020
1021 /*
1022  *      AtCommit_Memory
1023  */
1024 static void
1025 AtCommit_Memory(void)
1026 {
1027         /*
1028          * Now that we're "out" of a transaction, have the system allocate things
1029          * in the top memory context instead of per-transaction contexts.
1030          */
1031         MemoryContextSwitchTo(TopMemoryContext);
1032
1033         /*
1034          * Release all transaction-local memory.
1035          */
1036         Assert(TopTransactionContext != NULL);
1037         MemoryContextDelete(TopTransactionContext);
1038         TopTransactionContext = NULL;
1039         CurTransactionContext = NULL;
1040         CurrentTransactionState->curTransactionContext = NULL;
1041 }
1042
1043 /* ----------------------------------------------------------------
1044  *                                              CommitSubTransaction stuff
1045  * ----------------------------------------------------------------
1046  */
1047
1048 /*
1049  * AtSubCommit_Memory
1050  */
1051 static void
1052 AtSubCommit_Memory(void)
1053 {
1054         TransactionState s = CurrentTransactionState;
1055
1056         Assert(s->parent != NULL);
1057
1058         /* Return to parent transaction level's memory context. */
1059         CurTransactionContext = s->parent->curTransactionContext;
1060         MemoryContextSwitchTo(CurTransactionContext);
1061
1062         /*
1063          * Ordinarily we cannot throw away the child's CurTransactionContext,
1064          * since the data it contains will be needed at upper commit.  However, if
1065          * there isn't actually anything in it, we can throw it away.  This avoids
1066          * a small memory leak in the common case of "trivial" subxacts.
1067          */
1068         if (MemoryContextIsEmpty(s->curTransactionContext))
1069         {
1070                 MemoryContextDelete(s->curTransactionContext);
1071                 s->curTransactionContext = NULL;
1072         }
1073 }
1074
1075 /*
1076  * AtSubCommit_childXids
1077  *
1078  * Pass my own XID and my child XIDs up to my parent as committed children.
1079  */
1080 static void
1081 AtSubCommit_childXids(void)
1082 {
1083         TransactionState s = CurrentTransactionState;
1084         int                     new_nChildXids;
1085
1086         Assert(s->parent != NULL);
1087
1088         /*
1089          * The parent childXids array will need to hold my XID and all my
1090          * childXids, in addition to the XIDs already there.
1091          */
1092         new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1093
1094         /* Allocate or enlarge the parent array if necessary */
1095         if (s->parent->maxChildXids < new_nChildXids)
1096         {
1097                 int                             new_maxChildXids;
1098                 TransactionId  *new_childXids;
1099
1100                 /*
1101                  * Make it 2x what's needed right now, to avoid having to enlarge it
1102                  * repeatedly. But we can't go above MaxAllocSize.  (The latter
1103                  * limit is what ensures that we don't need to worry about integer
1104                  * overflow here or in the calculation of new_nChildXids.)
1105                  */
1106                 new_maxChildXids = Min(new_nChildXids * 2,
1107                                                            (int) (MaxAllocSize / sizeof(TransactionId)));
1108
1109                 if (new_maxChildXids < new_nChildXids)
1110                         ereport(ERROR,
1111                                         (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1112                                          errmsg("maximum number of committed subtransactions (%d) exceeded",
1113                                                         (int) (MaxAllocSize / sizeof(TransactionId)))));
1114
1115                 /*
1116                  * We keep the child-XID arrays in TopTransactionContext; this avoids
1117                  * setting up child-transaction contexts for what might be just a few
1118                  * bytes of grandchild XIDs.
1119                  */
1120                 if (s->parent->childXids == NULL)
1121                         new_childXids =
1122                                 MemoryContextAlloc(TopTransactionContext, 
1123                                                                    new_maxChildXids * sizeof(TransactionId));
1124                 else
1125                         new_childXids = repalloc(s->parent->childXids, 
1126                                                                          new_maxChildXids * sizeof(TransactionId));
1127
1128                 s->parent->childXids  = new_childXids;
1129                 s->parent->maxChildXids = new_maxChildXids;
1130         }
1131
1132         /*
1133          * Copy all my XIDs to parent's array.
1134          *
1135          * Note: We rely on the fact that the XID of a child always follows that
1136          * of its parent.  By copying the XID of this subtransaction before the
1137          * XIDs of its children, we ensure that the array stays ordered.  Likewise,
1138          * all XIDs already in the array belong to subtransactions started and
1139          * subcommitted before us, so their XIDs must precede ours.
1140          */
1141         s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1142
1143         if (s->nChildXids > 0)
1144                 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1145                            s->childXids,
1146                            s->nChildXids * sizeof(TransactionId));
1147
1148         s->parent->nChildXids = new_nChildXids;
1149
1150         /* Release child's array to avoid leakage */
1151         if (s->childXids != NULL)
1152                 pfree(s->childXids);
1153         /* We must reset these to avoid double-free if fail later in commit */
1154         s->childXids = NULL;
1155         s->nChildXids = 0;
1156         s->maxChildXids = 0;
1157 }
1158
1159 /*
1160  * RecordSubTransactionCommit
1161  */
1162 static void
1163 RecordSubTransactionCommit(void)
1164 {
1165         TransactionId xid = GetCurrentTransactionIdIfAny();
1166
1167         /*
1168          * We do not log the subcommit in XLOG; it doesn't matter until the
1169          * top-level transaction commits.
1170          *
1171          * We must mark the subtransaction subcommitted in the CLOG if it had a
1172          * valid XID assigned.  If it did not, nobody else will ever know about
1173          * the existence of this subxact.  We don't have to deal with deletions
1174          * scheduled for on-commit here, since they'll be reassigned to our parent
1175          * (who might still abort).
1176          */
1177         if (TransactionIdIsValid(xid))
1178         {
1179                 /* XXX does this really need to be a critical section? */
1180                 START_CRIT_SECTION();
1181
1182                 /* Record subtransaction subcommit */
1183                 TransactionIdSubCommit(xid);
1184
1185                 END_CRIT_SECTION();
1186         }
1187 }
1188
1189 /* ----------------------------------------------------------------
1190  *                                              AbortTransaction stuff
1191  * ----------------------------------------------------------------
1192  */
1193
1194 /*
1195  *      RecordTransactionAbort
1196  *
1197  * Returns latest XID among xact and its children, or InvalidTransactionId
1198  * if the xact has no XID.      (We compute that here just because it's easier.)
1199  */
1200 static TransactionId
1201 RecordTransactionAbort(bool isSubXact)
1202 {
1203         TransactionId xid = GetCurrentTransactionIdIfAny();
1204         TransactionId latestXid;
1205         int                     nrels;
1206         RelFileNode *rels;
1207         int                     nchildren;
1208         TransactionId *children;
1209         XLogRecData rdata[3];
1210         int                     lastrdata = 0;
1211         xl_xact_abort xlrec;
1212
1213         /*
1214          * If we haven't been assigned an XID, nobody will care whether we aborted
1215          * or not.      Hence, we're done in that case.  It does not matter if we have
1216          * rels to delete (note that this routine is not responsible for actually
1217          * deleting 'em).  We cannot have any child XIDs, either.
1218          */
1219         if (!TransactionIdIsValid(xid))
1220         {
1221                 /* Reset XactLastRecEnd until the next transaction writes something */
1222                 if (!isSubXact)
1223                         XactLastRecEnd.xrecoff = 0;
1224                 return InvalidTransactionId;
1225         }
1226
1227         /*
1228          * We have a valid XID, so we should write an ABORT record for it.
1229          *
1230          * We do not flush XLOG to disk here, since the default assumption after a
1231          * crash would be that we aborted, anyway.      For the same reason, we don't
1232          * need to worry about interlocking against checkpoint start.
1233          */
1234
1235         /*
1236          * Check that we haven't aborted halfway through RecordTransactionCommit.
1237          */
1238         if (TransactionIdDidCommit(xid))
1239                 elog(PANIC, "cannot abort transaction %u, it was already committed",
1240                          xid);
1241
1242         /* Fetch the data we need for the abort record */
1243         nrels = smgrGetPendingDeletes(false, &rels, NULL);
1244         nchildren = xactGetCommittedChildren(&children);
1245
1246         /* XXX do we really need a critical section here? */
1247         START_CRIT_SECTION();
1248
1249         /* Write the ABORT record */
1250         if (isSubXact)
1251                 xlrec.xact_time = GetCurrentTimestamp();
1252         else
1253         {
1254                 SetCurrentTransactionStopTimestamp();
1255                 xlrec.xact_time = xactStopTimestamp;
1256         }
1257         xlrec.nrels = nrels;
1258         xlrec.nsubxacts = nchildren;
1259         rdata[0].data = (char *) (&xlrec);
1260         rdata[0].len = MinSizeOfXactAbort;
1261         rdata[0].buffer = InvalidBuffer;
1262         /* dump rels to delete */
1263         if (nrels > 0)
1264         {
1265                 rdata[0].next = &(rdata[1]);
1266                 rdata[1].data = (char *) rels;
1267                 rdata[1].len = nrels * sizeof(RelFileNode);
1268                 rdata[1].buffer = InvalidBuffer;
1269                 lastrdata = 1;
1270         }
1271         /* dump committed child Xids */
1272         if (nchildren > 0)
1273         {
1274                 rdata[lastrdata].next = &(rdata[2]);
1275                 rdata[2].data = (char *) children;
1276                 rdata[2].len = nchildren * sizeof(TransactionId);
1277                 rdata[2].buffer = InvalidBuffer;
1278                 lastrdata = 2;
1279         }
1280         rdata[lastrdata].next = NULL;
1281
1282         (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1283
1284         /*
1285          * Mark the transaction aborted in clog.  This is not absolutely necessary
1286          * but we may as well do it while we are here; also, in the subxact case
1287          * it is helpful because XactLockTableWait makes use of it to avoid
1288          * waiting for already-aborted subtransactions.  It is OK to do it without
1289          * having flushed the ABORT record to disk, because in event of a crash
1290          * we'd be assumed to have aborted anyway.
1291          *
1292          * The ordering here isn't critical but it seems best to mark the parent
1293          * first.  This assures an atomic transition of all the subtransactions to
1294          * aborted state from the point of view of concurrent
1295          * TransactionIdDidAbort calls.
1296          */
1297         TransactionIdAbort(xid);
1298         TransactionIdAbortTree(nchildren, children);
1299
1300         END_CRIT_SECTION();
1301
1302         /* Compute latestXid while we have the child XIDs handy */
1303         latestXid = TransactionIdLatest(xid, nchildren, children);
1304
1305         /*
1306          * If we're aborting a subtransaction, we can immediately remove failed
1307          * XIDs from PGPROC's cache of running child XIDs.  We do that here for
1308          * subxacts, because we already have the child XID array at hand.  For
1309          * main xacts, the equivalent happens just after this function returns.
1310          */
1311         if (isSubXact)
1312                 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1313
1314         /* Reset XactLastRecEnd until the next transaction writes something */
1315         if (!isSubXact)
1316                 XactLastRecEnd.xrecoff = 0;
1317
1318         /* And clean up local data */
1319         if (rels)
1320                 pfree(rels);
1321
1322         return latestXid;
1323 }
1324
1325 /*
1326  *      AtAbort_Memory
1327  */
1328 static void
1329 AtAbort_Memory(void)
1330 {
1331         /*
1332          * Switch into TransactionAbortContext, which should have some free space
1333          * even if nothing else does.  We'll work in this context until we've
1334          * finished cleaning up.
1335          *
1336          * It is barely possible to get here when we've not been able to create
1337          * TransactionAbortContext yet; if so use TopMemoryContext.
1338          */
1339         if (TransactionAbortContext != NULL)
1340                 MemoryContextSwitchTo(TransactionAbortContext);
1341         else
1342                 MemoryContextSwitchTo(TopMemoryContext);
1343 }
1344
1345 /*
1346  * AtSubAbort_Memory
1347  */
1348 static void
1349 AtSubAbort_Memory(void)
1350 {
1351         Assert(TransactionAbortContext != NULL);
1352
1353         MemoryContextSwitchTo(TransactionAbortContext);
1354 }
1355
1356
1357 /*
1358  *      AtAbort_ResourceOwner
1359  */
1360 static void
1361 AtAbort_ResourceOwner(void)
1362 {
1363         /*
1364          * Make sure we have a valid ResourceOwner, if possible (else it will be
1365          * NULL, which is OK)
1366          */
1367         CurrentResourceOwner = TopTransactionResourceOwner;
1368 }
1369
1370 /*
1371  * AtSubAbort_ResourceOwner
1372  */
1373 static void
1374 AtSubAbort_ResourceOwner(void)
1375 {
1376         TransactionState s = CurrentTransactionState;
1377
1378         /* Make sure we have a valid ResourceOwner */
1379         CurrentResourceOwner = s->curTransactionOwner;
1380 }
1381
1382
1383 /*
1384  * AtSubAbort_childXids
1385  */
1386 static void
1387 AtSubAbort_childXids(void)
1388 {
1389         TransactionState s = CurrentTransactionState;
1390
1391         /*
1392          * We keep the child-XID arrays in TopTransactionContext (see
1393          * AtSubCommit_childXids).      This means we'd better free the array
1394          * explicitly at abort to avoid leakage.
1395          */
1396         if (s->childXids != NULL)
1397                 pfree(s->childXids);
1398         s->childXids = NULL;
1399         s->nChildXids = 0;
1400         s->maxChildXids = 0;
1401 }
1402
1403 /* ----------------------------------------------------------------
1404  *                                              CleanupTransaction stuff
1405  * ----------------------------------------------------------------
1406  */
1407
1408 /*
1409  *      AtCleanup_Memory
1410  */
1411 static void
1412 AtCleanup_Memory(void)
1413 {
1414         Assert(CurrentTransactionState->parent == NULL);
1415
1416         /*
1417          * Now that we're "out" of a transaction, have the system allocate things
1418          * in the top memory context instead of per-transaction contexts.
1419          */
1420         MemoryContextSwitchTo(TopMemoryContext);
1421
1422         /*
1423          * Clear the special abort context for next time.
1424          */
1425         if (TransactionAbortContext != NULL)
1426                 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1427
1428         /*
1429          * Release all transaction-local memory.
1430          */
1431         if (TopTransactionContext != NULL)
1432                 MemoryContextDelete(TopTransactionContext);
1433         TopTransactionContext = NULL;
1434         CurTransactionContext = NULL;
1435         CurrentTransactionState->curTransactionContext = NULL;
1436 }
1437
1438
1439 /* ----------------------------------------------------------------
1440  *                                              CleanupSubTransaction stuff
1441  * ----------------------------------------------------------------
1442  */
1443
1444 /*
1445  * AtSubCleanup_Memory
1446  */
1447 static void
1448 AtSubCleanup_Memory(void)
1449 {
1450         TransactionState s = CurrentTransactionState;
1451
1452         Assert(s->parent != NULL);
1453
1454         /* Make sure we're not in an about-to-be-deleted context */
1455         MemoryContextSwitchTo(s->parent->curTransactionContext);
1456         CurTransactionContext = s->parent->curTransactionContext;
1457
1458         /*
1459          * Clear the special abort context for next time.
1460          */
1461         if (TransactionAbortContext != NULL)
1462                 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1463
1464         /*
1465          * Delete the subxact local memory contexts. Its CurTransactionContext can
1466          * go too (note this also kills CurTransactionContexts from any children
1467          * of the subxact).
1468          */
1469         if (s->curTransactionContext)
1470                 MemoryContextDelete(s->curTransactionContext);
1471         s->curTransactionContext = NULL;
1472 }
1473
1474 /* ----------------------------------------------------------------
1475  *                                              interface routines
1476  * ----------------------------------------------------------------
1477  */
1478
1479 /*
1480  *      StartTransaction
1481  */
1482 static void
1483 StartTransaction(void)
1484 {
1485         TransactionState s;
1486         VirtualTransactionId vxid;
1487
1488         /*
1489          * Let's just make sure the state stack is empty
1490          */
1491         s = &TopTransactionStateData;
1492         CurrentTransactionState = s;
1493
1494         /*
1495          * check the current transaction state
1496          */
1497         if (s->state != TRANS_DEFAULT)
1498                 elog(WARNING, "StartTransaction while in %s state",
1499                          TransStateAsString(s->state));
1500
1501         /*
1502          * set the current transaction state information appropriately during
1503          * start processing
1504          */
1505         s->state = TRANS_START;
1506         s->transactionId = InvalidTransactionId;        /* until assigned */
1507
1508         /*
1509          * Make sure we've freed any old snapshot, and reset xact state variables
1510          */
1511         FreeXactSnapshot();
1512         XactIsoLevel = DefaultXactIsoLevel;
1513         XactReadOnly = DefaultXactReadOnly;
1514         forceSyncCommit = false;
1515         MyXactAccessedTempRel = false;
1516
1517         /*
1518          * reinitialize within-transaction counters
1519          */
1520         s->subTransactionId = TopSubTransactionId;
1521         currentSubTransactionId = TopSubTransactionId;
1522         currentCommandId = FirstCommandId;
1523         currentCommandIdUsed = false;
1524
1525         /*
1526          * must initialize resource-management stuff first
1527          */
1528         AtStart_Memory();
1529         AtStart_ResourceOwner();
1530
1531         /*
1532          * Assign a new LocalTransactionId, and combine it with the backendId to
1533          * form a virtual transaction id.
1534          */
1535         vxid.backendId = MyBackendId;
1536         vxid.localTransactionId = GetNextLocalTransactionId();
1537
1538         /*
1539          * Lock the virtual transaction id before we announce it in the proc array
1540          */
1541         VirtualXactLockTableInsert(vxid);
1542
1543         /*
1544          * Advertise it in the proc array.      We assume assignment of
1545          * LocalTransactionID is atomic, and the backendId should be set already.
1546          */
1547         Assert(MyProc->backendId == vxid.backendId);
1548         MyProc->lxid = vxid.localTransactionId;
1549
1550         PG_TRACE1(transaction__start, vxid.localTransactionId);
1551
1552         /*
1553          * set transaction_timestamp() (a/k/a now()).  We want this to be the same
1554          * as the first command's statement_timestamp(), so don't do a fresh
1555          * GetCurrentTimestamp() call (which'd be expensive anyway).  Also, mark
1556          * xactStopTimestamp as unset.
1557          */
1558         xactStartTimestamp = stmtStartTimestamp;
1559         xactStopTimestamp = 0;
1560         pgstat_report_xact_timestamp(xactStartTimestamp);
1561
1562         /*
1563          * initialize current transaction state fields
1564          *
1565          * note: prevXactReadOnly is not used at the outermost level
1566          */
1567         s->nestingLevel = 1;
1568         s->gucNestLevel = 1;
1569         s->childXids = NULL;
1570         s->nChildXids = 0;
1571         s->maxChildXids = 0;
1572         GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt);
1573         /* SecurityDefinerContext should never be set outside a transaction */
1574         Assert(!s->prevSecDefCxt);
1575
1576         /*
1577          * initialize other subsystems for new transaction
1578          */
1579         AtStart_GUC();
1580         AtStart_Inval();
1581         AtStart_Cache();
1582         AfterTriggerBeginXact();
1583
1584         /*
1585          * done with start processing, set current transaction state to "in
1586          * progress"
1587          */
1588         s->state = TRANS_INPROGRESS;
1589
1590         ShowTransactionState("StartTransaction");
1591 }
1592
1593
1594 /*
1595  *      CommitTransaction
1596  *
1597  * NB: if you change this routine, better look at PrepareTransaction too!
1598  */
1599 static void
1600 CommitTransaction(void)
1601 {
1602         TransactionState s = CurrentTransactionState;
1603         TransactionId latestXid;
1604
1605         ShowTransactionState("CommitTransaction");
1606
1607         /*
1608          * check the current transaction state
1609          */
1610         if (s->state != TRANS_INPROGRESS)
1611                 elog(WARNING, "CommitTransaction while in %s state",
1612                          TransStateAsString(s->state));
1613         Assert(s->parent == NULL);
1614
1615         /*
1616          * Do pre-commit processing (most of this stuff requires database access,
1617          * and in fact could still cause an error...)
1618          *
1619          * It is possible for CommitHoldablePortals to invoke functions that queue
1620          * deferred triggers, and it's also possible that triggers create holdable
1621          * cursors.  So we have to loop until there's nothing left to do.
1622          */
1623         for (;;)
1624         {
1625                 /*
1626                  * Fire all currently pending deferred triggers.
1627                  */
1628                 AfterTriggerFireDeferred();
1629
1630                 /*
1631                  * Convert any open holdable cursors into static portals.  If there
1632                  * weren't any, we are done ... otherwise loop back to check if they
1633                  * queued deferred triggers.  Lather, rinse, repeat.
1634                  */
1635                 if (!CommitHoldablePortals())
1636                         break;
1637         }
1638
1639         /* Now we can shut down the deferred-trigger manager */
1640         AfterTriggerEndXact(true);
1641
1642         /* Close any open regular cursors */
1643         AtCommit_Portals();
1644
1645         /*
1646          * Let ON COMMIT management do its thing (must happen after closing
1647          * cursors, to avoid dangling-reference problems)
1648          */
1649         PreCommit_on_commit_actions();
1650
1651         /* close large objects before lower-level cleanup */
1652         AtEOXact_LargeObject(true);
1653
1654         /* NOTIFY commit must come before lower-level cleanup */
1655         AtCommit_Notify();
1656
1657         /*
1658          * Update flat files if we changed pg_database, pg_authid or
1659          * pg_auth_members.  This should be the last step before commit.
1660          */
1661         AtEOXact_UpdateFlatFiles(true);
1662
1663         /* Prevent cancel/die interrupt while cleaning up */
1664         HOLD_INTERRUPTS();
1665
1666         /*
1667          * set the current transaction state information appropriately during
1668          * commit processing
1669          */
1670         s->state = TRANS_COMMIT;
1671
1672         /*
1673          * Here is where we really truly commit.
1674          */
1675         latestXid = RecordTransactionCommit();
1676
1677         PG_TRACE1(transaction__commit, MyProc->lxid);
1678
1679         /*
1680          * Let others know about no transaction in progress by me. Note that this
1681          * must be done _before_ releasing locks we hold and _after_
1682          * RecordTransactionCommit.
1683          */
1684         ProcArrayEndTransaction(MyProc, latestXid);
1685
1686         /*
1687          * This is all post-commit cleanup.  Note that if an error is raised here,
1688          * it's too late to abort the transaction.  This should be just
1689          * noncritical resource releasing.
1690          *
1691          * The ordering of operations is not entirely random.  The idea is:
1692          * release resources visible to other backends (eg, files, buffer pins);
1693          * then release locks; then release backend-local resources. We want to
1694          * release locks at the point where any backend waiting for us will see
1695          * our transaction as being fully cleaned up.
1696          *
1697          * Resources that can be associated with individual queries are handled by
1698          * the ResourceOwner mechanism.  The other calls here are for backend-wide
1699          * state.
1700          */
1701
1702         CallXactCallbacks(XACT_EVENT_COMMIT);
1703
1704         ResourceOwnerRelease(TopTransactionResourceOwner,
1705                                                  RESOURCE_RELEASE_BEFORE_LOCKS,
1706                                                  true, true);
1707
1708         /* Check we've released all buffer pins */
1709         AtEOXact_Buffers(true);
1710
1711         /* Clean up the relation cache */
1712         AtEOXact_RelationCache(true);
1713
1714         /*
1715          * Make catalog changes visible to all backends.  This has to happen after
1716          * relcache references are dropped (see comments for
1717          * AtEOXact_RelationCache), but before locks are released (if anyone is
1718          * waiting for lock on a relation we've modified, we want them to know
1719          * about the catalog change before they start using the relation).
1720          */
1721         AtEOXact_Inval(true);
1722
1723         /*
1724          * Likewise, dropping of files deleted during the transaction is best done
1725          * after releasing relcache and buffer pins.  (This is not strictly
1726          * necessary during commit, since such pins should have been released
1727          * already, but this ordering is definitely critical during abort.)
1728          */
1729         smgrDoPendingDeletes(true);
1730
1731         AtEOXact_MultiXact();
1732
1733         ResourceOwnerRelease(TopTransactionResourceOwner,
1734                                                  RESOURCE_RELEASE_LOCKS,
1735                                                  true, true);
1736         ResourceOwnerRelease(TopTransactionResourceOwner,
1737                                                  RESOURCE_RELEASE_AFTER_LOCKS,
1738                                                  true, true);
1739
1740         /* Check we've released all catcache entries */
1741         AtEOXact_CatCache(true);
1742
1743         AtEOXact_GUC(true, 1);
1744         AtEOXact_SPI(true);
1745         AtEOXact_xml();
1746         AtEOXact_on_commit_actions(true);
1747         AtEOXact_Namespace(true);
1748         /* smgrcommit already done */
1749         AtEOXact_Files();
1750         AtEOXact_ComboCid();
1751         AtEOXact_HashTables(true);
1752         AtEOXact_PgStat(true);
1753         pgstat_report_xact_timestamp(0);
1754
1755         CurrentResourceOwner = NULL;
1756         ResourceOwnerDelete(TopTransactionResourceOwner);
1757         s->curTransactionOwner = NULL;
1758         CurTransactionResourceOwner = NULL;
1759         TopTransactionResourceOwner = NULL;
1760
1761         AtCommit_Memory();
1762
1763         s->transactionId = InvalidTransactionId;
1764         s->subTransactionId = InvalidSubTransactionId;
1765         s->nestingLevel = 0;
1766         s->gucNestLevel = 0;
1767         s->childXids = NULL;
1768         s->nChildXids = 0;
1769         s->maxChildXids = 0;
1770
1771         /*
1772          * done with commit processing, set current transaction state back to
1773          * default
1774          */
1775         s->state = TRANS_DEFAULT;
1776
1777         RESUME_INTERRUPTS();
1778 }
1779
1780
1781 /*
1782  *      PrepareTransaction
1783  *
1784  * NB: if you change this routine, better look at CommitTransaction too!
1785  */
1786 static void
1787 PrepareTransaction(void)
1788 {
1789         TransactionState s = CurrentTransactionState;
1790         TransactionId xid = GetCurrentTransactionId();
1791         GlobalTransaction gxact;
1792         TimestampTz prepared_at;
1793
1794         ShowTransactionState("PrepareTransaction");
1795
1796         /*
1797          * check the current transaction state
1798          */
1799         if (s->state != TRANS_INPROGRESS)
1800                 elog(WARNING, "PrepareTransaction while in %s state",
1801                          TransStateAsString(s->state));
1802         Assert(s->parent == NULL);
1803
1804         /*
1805          * Do pre-commit processing (most of this stuff requires database access,
1806          * and in fact could still cause an error...)
1807          *
1808          * It is possible for PrepareHoldablePortals to invoke functions that
1809          * queue deferred triggers, and it's also possible that triggers create
1810          * holdable cursors.  So we have to loop until there's nothing left to do.
1811          */
1812         for (;;)
1813         {
1814                 /*
1815                  * Fire all currently pending deferred triggers.
1816                  */
1817                 AfterTriggerFireDeferred();
1818
1819                 /*
1820                  * Convert any open holdable cursors into static portals.  If there
1821                  * weren't any, we are done ... otherwise loop back to check if they
1822                  * queued deferred triggers.  Lather, rinse, repeat.
1823                  */
1824                 if (!PrepareHoldablePortals())
1825                         break;
1826         }
1827
1828         /* Now we can shut down the deferred-trigger manager */
1829         AfterTriggerEndXact(true);
1830
1831         /* Close any open regular cursors */
1832         AtCommit_Portals();
1833
1834         /*
1835          * Let ON COMMIT management do its thing (must happen after closing
1836          * cursors, to avoid dangling-reference problems)
1837          */
1838         PreCommit_on_commit_actions();
1839
1840         /* close large objects before lower-level cleanup */
1841         AtEOXact_LargeObject(true);
1842
1843         /* NOTIFY and flatfiles will be handled below */
1844
1845         /*
1846          * Don't allow PREPARE TRANSACTION if we've accessed a temporary table
1847          * in this transaction.  Having the prepared xact hold locks on another
1848          * backend's temp table seems a bad idea --- for instance it would prevent
1849          * the backend from exiting.  There are other problems too, such as how
1850          * to clean up the source backend's local buffers and ON COMMIT state
1851          * if the prepared xact includes a DROP of a temp table.
1852          *
1853          * We must check this after executing any ON COMMIT actions, because
1854          * they might still access a temp relation.
1855          *
1856          * XXX In principle this could be relaxed to allow some useful special
1857          * cases, such as a temp table created and dropped all within the
1858          * transaction.  That seems to require much more bookkeeping though.
1859          */
1860         if (MyXactAccessedTempRel)
1861                 ereport(ERROR,
1862                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1863                                  errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1864
1865         /* Prevent cancel/die interrupt while cleaning up */
1866         HOLD_INTERRUPTS();
1867
1868         /*
1869          * set the current transaction state information appropriately during
1870          * prepare processing
1871          */
1872         s->state = TRANS_PREPARE;
1873
1874         prepared_at = GetCurrentTimestamp();
1875
1876         /* Tell bufmgr and smgr to prepare for commit */
1877         BufmgrCommit();
1878
1879         /*
1880          * Reserve the GID for this transaction. This could fail if the requested
1881          * GID is invalid or already in use.
1882          */
1883         gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1884                                                         GetUserId(), MyDatabaseId);
1885         prepareGID = NULL;
1886
1887         /*
1888          * Collect data for the 2PC state file.  Note that in general, no actual
1889          * state change should happen in the called modules during this step,
1890          * since it's still possible to fail before commit, and in that case we
1891          * want transaction abort to be able to clean up.  (In particular, the
1892          * AtPrepare routines may error out if they find cases they cannot
1893          * handle.)  State cleanup should happen in the PostPrepare routines
1894          * below.  However, some modules can go ahead and clear state here because
1895          * they wouldn't do anything with it during abort anyway.
1896          *
1897          * Note: because the 2PC state file records will be replayed in the same
1898          * order they are made, the order of these calls has to match the order in
1899          * which we want things to happen during COMMIT PREPARED or ROLLBACK
1900          * PREPARED; in particular, pay attention to whether things should happen
1901          * before or after releasing the transaction's locks.
1902          */
1903         StartPrepare(gxact);
1904
1905         AtPrepare_Notify();
1906         AtPrepare_UpdateFlatFiles();
1907         AtPrepare_Inval();
1908         AtPrepare_Locks();
1909         AtPrepare_PgStat();
1910
1911         /*
1912          * Here is where we really truly prepare.
1913          *
1914          * We have to record transaction prepares even if we didn't make any
1915          * updates, because the transaction manager might get confused if we lose
1916          * a global transaction.
1917          */
1918         EndPrepare(gxact);
1919
1920         /*
1921          * Now we clean up backend-internal state and release internal resources.
1922          */
1923
1924         /* Reset XactLastRecEnd until the next transaction writes something */
1925         XactLastRecEnd.xrecoff = 0;
1926
1927         /*
1928          * Let others know about no transaction in progress by me.      This has to be
1929          * done *after* the prepared transaction has been marked valid, else
1930          * someone may think it is unlocked and recyclable.
1931          */
1932         ProcArrayClearTransaction(MyProc);
1933
1934         /*
1935          * This is all post-transaction cleanup.  Note that if an error is raised
1936          * here, it's too late to abort the transaction.  This should be just
1937          * noncritical resource releasing.      See notes in CommitTransaction.
1938          */
1939
1940         CallXactCallbacks(XACT_EVENT_PREPARE);
1941
1942         ResourceOwnerRelease(TopTransactionResourceOwner,
1943                                                  RESOURCE_RELEASE_BEFORE_LOCKS,
1944                                                  true, true);
1945
1946         /* Check we've released all buffer pins */
1947         AtEOXact_Buffers(true);
1948
1949         /* Clean up the relation cache */
1950         AtEOXact_RelationCache(true);
1951
1952         /* notify and flatfiles don't need a postprepare call */
1953
1954         PostPrepare_PgStat();
1955
1956         PostPrepare_Inval();
1957
1958         PostPrepare_smgr();
1959
1960         AtEOXact_MultiXact();
1961
1962         PostPrepare_Locks(xid);
1963
1964         ResourceOwnerRelease(TopTransactionResourceOwner,
1965                                                  RESOURCE_RELEASE_LOCKS,
1966                                                  true, true);
1967         ResourceOwnerRelease(TopTransactionResourceOwner,
1968                                                  RESOURCE_RELEASE_AFTER_LOCKS,
1969                                                  true, true);
1970
1971         /* Check we've released all catcache entries */
1972         AtEOXact_CatCache(true);
1973
1974         /* PREPARE acts the same as COMMIT as far as GUC is concerned */
1975         AtEOXact_GUC(true, 1);
1976         AtEOXact_SPI(true);
1977         AtEOXact_xml();
1978         AtEOXact_on_commit_actions(true);
1979         AtEOXact_Namespace(true);
1980         /* smgrcommit already done */
1981         AtEOXact_Files();
1982         AtEOXact_ComboCid();
1983         AtEOXact_HashTables(true);
1984         /* don't call AtEOXact_PgStat here */
1985
1986         CurrentResourceOwner = NULL;
1987         ResourceOwnerDelete(TopTransactionResourceOwner);
1988         s->curTransactionOwner = NULL;
1989         CurTransactionResourceOwner = NULL;
1990         TopTransactionResourceOwner = NULL;
1991
1992         AtCommit_Memory();
1993
1994         s->transactionId = InvalidTransactionId;
1995         s->subTransactionId = InvalidSubTransactionId;
1996         s->nestingLevel = 0;
1997         s->gucNestLevel = 0;
1998         s->childXids = NULL;
1999         s->nChildXids = 0;
2000         s->maxChildXids = 0;
2001
2002         /*
2003          * done with 1st phase commit processing, set current transaction state
2004          * back to default
2005          */
2006         s->state = TRANS_DEFAULT;
2007
2008         RESUME_INTERRUPTS();
2009 }
2010
2011
2012 /*
2013  *      AbortTransaction
2014  */
2015 static void
2016 AbortTransaction(void)
2017 {
2018         TransactionState s = CurrentTransactionState;
2019         TransactionId latestXid;
2020
2021         /* Prevent cancel/die interrupt while cleaning up */
2022         HOLD_INTERRUPTS();
2023
2024         /* Make sure we have a valid memory context and resource owner */
2025         AtAbort_Memory();
2026         AtAbort_ResourceOwner();
2027
2028         /*
2029          * Release any LW locks we might be holding as quickly as possible.
2030          * (Regular locks, however, must be held till we finish aborting.)
2031          * Releasing LW locks is critical since we might try to grab them again
2032          * while cleaning up!
2033          */
2034         LWLockReleaseAll();
2035
2036         /* Clean up buffer I/O and buffer context locks, too */
2037         AbortBufferIO();
2038         UnlockBuffers();
2039
2040         /*
2041          * Also clean up any open wait for lock, since the lock manager will choke
2042          * if we try to wait for another lock before doing this.
2043          */
2044         LockWaitCancel();
2045
2046         /*
2047          * check the current transaction state
2048          */
2049         if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2050                 elog(WARNING, "AbortTransaction while in %s state",
2051                          TransStateAsString(s->state));
2052         Assert(s->parent == NULL);
2053
2054         /*
2055          * set the current transaction state information appropriately during the
2056          * abort processing
2057          */
2058         s->state = TRANS_ABORT;
2059
2060         /*
2061          * Reset user ID which might have been changed transiently.  We need this
2062          * to clean up in case control escaped out of a SECURITY DEFINER function
2063          * or other local change of CurrentUserId; therefore, the prior value
2064          * of SecurityDefinerContext also needs to be restored.
2065          *
2066          * (Note: it is not necessary to restore session authorization or role
2067          * settings here because those can only be changed via GUC, and GUC will
2068          * take care of rolling them back if need be.)
2069          */
2070         SetUserIdAndContext(s->prevUser, s->prevSecDefCxt);
2071
2072         /*
2073          * do abort processing
2074          */
2075         AfterTriggerEndXact(false);
2076         AtAbort_Portals();
2077         AtEOXact_LargeObject(false);    /* 'false' means it's abort */
2078         AtAbort_Notify();
2079         AtEOXact_UpdateFlatFiles(false);
2080
2081         /*
2082          * Advertise the fact that we aborted in pg_clog (assuming that we got as
2083          * far as assigning an XID to advertise).
2084          */
2085         latestXid = RecordTransactionAbort(false);
2086
2087         PG_TRACE1(transaction__abort, MyProc->lxid);
2088
2089         /*
2090          * Let others know about no transaction in progress by me. Note that this
2091          * must be done _before_ releasing locks we hold and _after_
2092          * RecordTransactionAbort.
2093          */
2094         ProcArrayEndTransaction(MyProc, latestXid);
2095
2096         /*
2097          * Post-abort cleanup.  See notes in CommitTransaction() concerning
2098          * ordering.
2099          */
2100
2101         CallXactCallbacks(XACT_EVENT_ABORT);
2102
2103         ResourceOwnerRelease(TopTransactionResourceOwner,
2104                                                  RESOURCE_RELEASE_BEFORE_LOCKS,
2105                                                  false, true);
2106         AtEOXact_Buffers(false);
2107         AtEOXact_RelationCache(false);
2108         AtEOXact_Inval(false);
2109         smgrDoPendingDeletes(false);
2110         AtEOXact_MultiXact();
2111         ResourceOwnerRelease(TopTransactionResourceOwner,
2112                                                  RESOURCE_RELEASE_LOCKS,
2113                                                  false, true);
2114         ResourceOwnerRelease(TopTransactionResourceOwner,
2115                                                  RESOURCE_RELEASE_AFTER_LOCKS,
2116                                                  false, true);
2117         AtEOXact_CatCache(false);
2118
2119         AtEOXact_GUC(false, 1);
2120         AtEOXact_SPI(false);
2121         AtEOXact_xml();
2122         AtEOXact_on_commit_actions(false);
2123         AtEOXact_Namespace(false);
2124         smgrabort();
2125         AtEOXact_Files();
2126         AtEOXact_ComboCid();
2127         AtEOXact_HashTables(false);
2128         AtEOXact_PgStat(false);
2129         pgstat_report_xact_timestamp(0);
2130
2131         /*
2132          * State remains TRANS_ABORT until CleanupTransaction().
2133          */
2134         RESUME_INTERRUPTS();
2135 }
2136
2137 /*
2138  *      CleanupTransaction
2139  */
2140 static void
2141 CleanupTransaction(void)
2142 {
2143         TransactionState s = CurrentTransactionState;
2144
2145         /*
2146          * State should still be TRANS_ABORT from AbortTransaction().
2147          */
2148         if (s->state != TRANS_ABORT)
2149                 elog(FATAL, "CleanupTransaction: unexpected state %s",
2150                          TransStateAsString(s->state));
2151
2152         /*
2153          * do abort cleanup processing
2154          */
2155         AtCleanup_Portals();            /* now safe to release portal memory */
2156
2157         CurrentResourceOwner = NULL;    /* and resource owner */
2158         if (TopTransactionResourceOwner)
2159                 ResourceOwnerDelete(TopTransactionResourceOwner);
2160         s->curTransactionOwner = NULL;
2161         CurTransactionResourceOwner = NULL;
2162         TopTransactionResourceOwner = NULL;
2163
2164         AtCleanup_Memory();                     /* and transaction memory */
2165
2166         s->transactionId = InvalidTransactionId;
2167         s->subTransactionId = InvalidSubTransactionId;
2168         s->nestingLevel = 0;
2169         s->gucNestLevel = 0;
2170         s->childXids = NULL;
2171         s->nChildXids = 0;
2172         s->maxChildXids = 0;
2173
2174         /*
2175          * done with abort processing, set current transaction state back to
2176          * default
2177          */
2178         s->state = TRANS_DEFAULT;
2179 }
2180
2181 /*
2182  *      StartTransactionCommand
2183  */
2184 void
2185 StartTransactionCommand(void)
2186 {
2187         TransactionState s = CurrentTransactionState;
2188
2189         switch (s->blockState)
2190         {
2191                         /*
2192                          * if we aren't in a transaction block, we just do our usual start
2193                          * transaction.
2194                          */
2195                 case TBLOCK_DEFAULT:
2196                         StartTransaction();
2197                         s->blockState = TBLOCK_STARTED;
2198                         break;
2199
2200                         /*
2201                          * We are somewhere in a transaction block or subtransaction and
2202                          * about to start a new command.  For now we do nothing, but
2203                          * someday we may do command-local resource initialization. (Note
2204                          * that any needed CommandCounterIncrement was done by the
2205                          * previous CommitTransactionCommand.)
2206                          */
2207                 case TBLOCK_INPROGRESS:
2208                 case TBLOCK_SUBINPROGRESS:
2209                         break;
2210
2211                         /*
2212                          * Here we are in a failed transaction block (one of the commands
2213                          * caused an abort) so we do nothing but remain in the abort
2214                          * state.  Eventually we will get a ROLLBACK command which will
2215                          * get us out of this state.  (It is up to other code to ensure
2216                          * that no commands other than ROLLBACK will be processed in these
2217                          * states.)
2218                          */
2219                 case TBLOCK_ABORT:
2220                 case TBLOCK_SUBABORT:
2221                         break;
2222
2223                         /* These cases are invalid. */
2224                 case TBLOCK_STARTED:
2225                 case TBLOCK_BEGIN:
2226                 case TBLOCK_SUBBEGIN:
2227                 case TBLOCK_END:
2228                 case TBLOCK_SUBEND:
2229                 case TBLOCK_ABORT_END:
2230                 case TBLOCK_SUBABORT_END:
2231                 case TBLOCK_ABORT_PENDING:
2232                 case TBLOCK_SUBABORT_PENDING:
2233                 case TBLOCK_SUBRESTART:
2234                 case TBLOCK_SUBABORT_RESTART:
2235                 case TBLOCK_PREPARE:
2236                         elog(ERROR, "StartTransactionCommand: unexpected state %s",
2237                                  BlockStateAsString(s->blockState));
2238                         break;
2239         }
2240
2241         /*
2242          * We must switch to CurTransactionContext before returning. This is
2243          * already done if we called StartTransaction, otherwise not.
2244          */
2245         Assert(CurTransactionContext != NULL);
2246         MemoryContextSwitchTo(CurTransactionContext);
2247 }
2248
2249 /*
2250  *      CommitTransactionCommand
2251  */
2252 void
2253 CommitTransactionCommand(void)
2254 {
2255         TransactionState s = CurrentTransactionState;
2256
2257         switch (s->blockState)
2258         {
2259                         /*
2260                          * This shouldn't happen, because it means the previous
2261                          * StartTransactionCommand didn't set the STARTED state
2262                          * appropriately.
2263                          */
2264                 case TBLOCK_DEFAULT:
2265                         elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2266                                  BlockStateAsString(s->blockState));
2267                         break;
2268
2269                         /*
2270                          * If we aren't in a transaction block, just do our usual
2271                          * transaction commit, and return to the idle state.
2272                          */
2273                 case TBLOCK_STARTED:
2274                         CommitTransaction();
2275                         s->blockState = TBLOCK_DEFAULT;
2276                         break;
2277
2278                         /*
2279                          * We are completing a "BEGIN TRANSACTION" command, so we change
2280                          * to the "transaction block in progress" state and return.  (We
2281                          * assume the BEGIN did nothing to the database, so we need no
2282                          * CommandCounterIncrement.)
2283                          */
2284                 case TBLOCK_BEGIN:
2285                         s->blockState = TBLOCK_INPROGRESS;
2286                         break;
2287
2288                         /*
2289                          * This is the case when we have finished executing a command
2290                          * someplace within a transaction block.  We increment the command
2291                          * counter and return.
2292                          */
2293                 case TBLOCK_INPROGRESS:
2294                 case TBLOCK_SUBINPROGRESS:
2295                         CommandCounterIncrement();
2296                         break;
2297
2298                         /*
2299                          * We are completing a "COMMIT" command.  Do it and return to the
2300                          * idle state.
2301                          */
2302                 case TBLOCK_END:
2303                         CommitTransaction();
2304                         s->blockState = TBLOCK_DEFAULT;
2305                         break;
2306
2307                         /*
2308                          * Here we are in the middle of a transaction block but one of the
2309                          * commands caused an abort so we do nothing but remain in the
2310                          * abort state.  Eventually we will get a ROLLBACK comand.
2311                          */
2312                 case TBLOCK_ABORT:
2313                 case TBLOCK_SUBABORT:
2314                         break;
2315
2316                         /*
2317                          * Here we were in an aborted transaction block and we just got
2318                          * the ROLLBACK command from the user, so clean up the
2319                          * already-aborted transaction and return to the idle state.
2320                          */
2321                 case TBLOCK_ABORT_END:
2322                         CleanupTransaction();
2323                         s->blockState = TBLOCK_DEFAULT;
2324                         break;
2325
2326                         /*
2327                          * Here we were in a perfectly good transaction block but the user
2328                          * told us to ROLLBACK anyway.  We have to abort the transaction
2329                          * and then clean up.
2330                          */
2331                 case TBLOCK_ABORT_PENDING:
2332                         AbortTransaction();
2333                         CleanupTransaction();
2334                         s->blockState = TBLOCK_DEFAULT;
2335                         break;
2336
2337                         /*
2338                          * We are completing a "PREPARE TRANSACTION" command.  Do it and
2339                          * return to the idle state.
2340                          */
2341                 case TBLOCK_PREPARE:
2342                         PrepareTransaction();
2343                         s->blockState = TBLOCK_DEFAULT;
2344                         break;
2345
2346                         /*
2347                          * We were just issued a SAVEPOINT inside a transaction block.
2348                          * Start a subtransaction.      (DefineSavepoint already did
2349                          * PushTransaction, so as to have someplace to put the SUBBEGIN
2350                          * state.)
2351                          */
2352                 case TBLOCK_SUBBEGIN:
2353                         StartSubTransaction();
2354                         s->blockState = TBLOCK_SUBINPROGRESS;
2355                         break;
2356
2357                         /*
2358                          * We were issued a COMMIT or RELEASE command, so we end the
2359                          * current subtransaction and return to the parent transaction.
2360                          * The parent might be ended too, so repeat till we are all the
2361                          * way out or find an INPROGRESS transaction.
2362                          */
2363                 case TBLOCK_SUBEND:
2364                         do
2365                         {
2366                                 CommitSubTransaction();
2367                                 s = CurrentTransactionState;    /* changed by pop */
2368                         } while (s->blockState == TBLOCK_SUBEND);
2369                         /* If we had a COMMIT command, finish off the main xact too */
2370                         if (s->blockState == TBLOCK_END)
2371                         {
2372                                 Assert(s->parent == NULL);
2373                                 CommitTransaction();
2374                                 s->blockState = TBLOCK_DEFAULT;
2375                         }
2376                         else if (s->blockState == TBLOCK_PREPARE)
2377                         {
2378                                 Assert(s->parent == NULL);
2379                                 PrepareTransaction();
2380                                 s->blockState = TBLOCK_DEFAULT;
2381                         }
2382                         else
2383                         {
2384                                 Assert(s->blockState == TBLOCK_INPROGRESS ||
2385                                            s->blockState == TBLOCK_SUBINPROGRESS);
2386                         }
2387                         break;
2388
2389                         /*
2390                          * The current already-failed subtransaction is ending due to a
2391                          * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2392                          * examine the parent (which could be in any of several states).
2393                          */
2394                 case TBLOCK_SUBABORT_END:
2395                         CleanupSubTransaction();
2396                         CommitTransactionCommand();
2397                         break;
2398
2399                         /*
2400                          * As above, but it's not dead yet, so abort first.
2401                          */
2402                 case TBLOCK_SUBABORT_PENDING:
2403                         AbortSubTransaction();
2404                         CleanupSubTransaction();
2405                         CommitTransactionCommand();
2406                         break;
2407
2408                         /*
2409                          * The current subtransaction is the target of a ROLLBACK TO
2410                          * command.  Abort and pop it, then start a new subtransaction
2411                          * with the same name.
2412                          */
2413                 case TBLOCK_SUBRESTART:
2414                         {
2415                                 char       *name;
2416                                 int                     savepointLevel;
2417
2418                                 /* save name and keep Cleanup from freeing it */
2419                                 name = s->name;
2420                                 s->name = NULL;
2421                                 savepointLevel = s->savepointLevel;
2422
2423                                 AbortSubTransaction();
2424                                 CleanupSubTransaction();
2425
2426                                 DefineSavepoint(NULL);
2427                                 s = CurrentTransactionState;    /* changed by push */
2428                                 s->name = name;
2429                                 s->savepointLevel = savepointLevel;
2430
2431                                 /* This is the same as TBLOCK_SUBBEGIN case */
2432                                 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2433                                 StartSubTransaction();
2434                                 s->blockState = TBLOCK_SUBINPROGRESS;
2435                         }
2436                         break;
2437
2438                         /*
2439                          * Same as above, but the subtransaction had already failed, so we
2440                          * don't need AbortSubTransaction.
2441                          */
2442                 case TBLOCK_SUBABORT_RESTART:
2443                         {
2444                                 char       *name;
2445                                 int                     savepointLevel;
2446
2447                                 /* save name and keep Cleanup from freeing it */
2448                                 name = s->name;
2449                                 s->name = NULL;
2450                                 savepointLevel = s->savepointLevel;
2451
2452                                 CleanupSubTransaction();
2453
2454                                 DefineSavepoint(NULL);
2455                                 s = CurrentTransactionState;    /* changed by push */
2456                                 s->name = name;
2457                                 s->savepointLevel = savepointLevel;
2458
2459                                 /* This is the same as TBLOCK_SUBBEGIN case */
2460                                 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2461                                 StartSubTransaction();
2462                                 s->blockState = TBLOCK_SUBINPROGRESS;
2463                         }
2464                         break;
2465         }
2466 }
2467
2468 /*
2469  *      AbortCurrentTransaction
2470  */
2471 void
2472 AbortCurrentTransaction(void)
2473 {
2474         TransactionState s = CurrentTransactionState;
2475
2476         switch (s->blockState)
2477         {
2478                 case TBLOCK_DEFAULT:
2479                         if (s->state == TRANS_DEFAULT)
2480                         {
2481                                 /* we are idle, so nothing to do */
2482                         }
2483                         else
2484                         {
2485                                 /*
2486                                  * We can get here after an error during transaction start
2487                                  * (state will be TRANS_START).  Need to clean up the
2488                                  * incompletely started transaction.  First, adjust the
2489                                  * low-level state to suppress warning message from
2490                                  * AbortTransaction.
2491                                  */
2492                                 if (s->state == TRANS_START)
2493                                         s->state = TRANS_INPROGRESS;
2494                                 AbortTransaction();
2495                                 CleanupTransaction();
2496                         }
2497                         break;
2498
2499                         /*
2500                          * if we aren't in a transaction block, we just do the basic abort
2501                          * & cleanup transaction.
2502                          */
2503                 case TBLOCK_STARTED:
2504                         AbortTransaction();
2505                         CleanupTransaction();
2506                         s->blockState = TBLOCK_DEFAULT;
2507                         break;
2508
2509                         /*
2510                          * If we are in TBLOCK_BEGIN it means something screwed up right
2511                          * after reading "BEGIN TRANSACTION".  We assume that the user
2512                          * will interpret the error as meaning the BEGIN failed to get him
2513                          * into a transaction block, so we should abort and return to idle
2514                          * state.
2515                          */
2516                 case TBLOCK_BEGIN:
2517                         AbortTransaction();
2518                         CleanupTransaction();
2519                         s->blockState = TBLOCK_DEFAULT;
2520                         break;
2521
2522                         /*
2523                          * We are somewhere in a transaction block and we've gotten a
2524                          * failure, so we abort the transaction and set up the persistent
2525                          * ABORT state.  We will stay in ABORT until we get a ROLLBACK.
2526                          */
2527                 case TBLOCK_INPROGRESS:
2528                         AbortTransaction();
2529                         s->blockState = TBLOCK_ABORT;
2530                         /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2531                         break;
2532
2533                         /*
2534                          * Here, we failed while trying to COMMIT.      Clean up the
2535                          * transaction and return to idle state (we do not want to stay in
2536                          * the transaction).
2537                          */
2538                 case TBLOCK_END:
2539                         AbortTransaction();
2540                         CleanupTransaction();
2541                         s->blockState = TBLOCK_DEFAULT;
2542                         break;
2543
2544                         /*
2545                          * Here, we are already in an aborted transaction state and are
2546                          * waiting for a ROLLBACK, but for some reason we failed again! So
2547                          * we just remain in the abort state.
2548                          */
2549                 case TBLOCK_ABORT:
2550                 case TBLOCK_SUBABORT:
2551                         break;
2552
2553                         /*
2554                          * We are in a failed transaction and we got the ROLLBACK command.
2555                          * We have already aborted, we just need to cleanup and go to idle
2556                          * state.
2557                          */
2558                 case TBLOCK_ABORT_END:
2559                         CleanupTransaction();
2560                         s->blockState = TBLOCK_DEFAULT;
2561                         break;
2562
2563                         /*
2564                          * We are in a live transaction and we got a ROLLBACK command.
2565                          * Abort, cleanup, go to idle state.
2566                          */
2567                 case TBLOCK_ABORT_PENDING:
2568                         AbortTransaction();
2569                         CleanupTransaction();
2570                         s->blockState = TBLOCK_DEFAULT;
2571                         break;
2572
2573                         /*
2574                          * Here, we failed while trying to PREPARE.  Clean up the
2575                          * transaction and return to idle state (we do not want to stay in
2576                          * the transaction).
2577                          */
2578                 case TBLOCK_PREPARE:
2579                         AbortTransaction();
2580                         CleanupTransaction();
2581                         s->blockState = TBLOCK_DEFAULT;
2582                         break;
2583
2584                         /*
2585                          * We got an error inside a subtransaction.  Abort just the
2586                          * subtransaction, and go to the persistent SUBABORT state until
2587                          * we get ROLLBACK.
2588                          */
2589                 case TBLOCK_SUBINPROGRESS:
2590                         AbortSubTransaction();
2591                         s->blockState = TBLOCK_SUBABORT;
2592                         break;
2593
2594                         /*
2595                          * If we failed while trying to create a subtransaction, clean up
2596                          * the broken subtransaction and abort the parent.      The same
2597                          * applies if we get a failure while ending a subtransaction.
2598                          */
2599                 case TBLOCK_SUBBEGIN:
2600                 case TBLOCK_SUBEND:
2601                 case TBLOCK_SUBABORT_PENDING:
2602                 case TBLOCK_SUBRESTART:
2603                         AbortSubTransaction();
2604                         CleanupSubTransaction();
2605                         AbortCurrentTransaction();
2606                         break;
2607
2608                         /*
2609                          * Same as above, except the Abort() was already done.
2610                          */
2611                 case TBLOCK_SUBABORT_END:
2612                 case TBLOCK_SUBABORT_RESTART:
2613                         CleanupSubTransaction();
2614                         AbortCurrentTransaction();
2615                         break;
2616         }
2617 }
2618
2619 /*
2620  *      PreventTransactionChain
2621  *
2622  *      This routine is to be called by statements that must not run inside
2623  *      a transaction block, typically because they have non-rollback-able
2624  *      side effects or do internal commits.
2625  *
2626  *      If we have already started a transaction block, issue an error; also issue
2627  *      an error if we appear to be running inside a user-defined function (which
2628  *      could issue more commands and possibly cause a failure after the statement
2629  *      completes).  Subtransactions are verboten too.
2630  *
2631  *      isTopLevel: passed down from ProcessUtility to determine whether we are
2632  *      inside a function or multi-query querystring.  (We will always fail if
2633  *      this is false, but it's convenient to centralize the check here instead of
2634  *      making callers do it.)
2635  *      stmtType: statement type name, for error messages.
2636  */
2637 void
2638 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2639 {
2640         /*
2641          * xact block already started?
2642          */
2643         if (IsTransactionBlock())
2644                 ereport(ERROR,
2645                                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2646                 /* translator: %s represents an SQL statement name */
2647                                  errmsg("%s cannot run inside a transaction block",
2648                                                 stmtType)));
2649
2650         /*
2651          * subtransaction?
2652          */
2653         if (IsSubTransaction())
2654                 ereport(ERROR,
2655                                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2656                 /* translator: %s represents an SQL statement name */
2657                                  errmsg("%s cannot run inside a subtransaction",
2658                                                 stmtType)));
2659
2660         /*
2661          * inside a function call?
2662          */
2663         if (!isTopLevel)
2664                 ereport(ERROR,
2665                                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2666                 /* translator: %s represents an SQL statement name */
2667                                  errmsg("%s cannot be executed from a function or multi-command string",
2668                                                 stmtType)));
2669
2670         /* If we got past IsTransactionBlock test, should be in default state */
2671         if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2672                 CurrentTransactionState->blockState != TBLOCK_STARTED)
2673                 elog(FATAL, "cannot prevent transaction chain");
2674         /* all okay */
2675 }
2676
2677 /*
2678  *      RequireTransactionChain
2679  *
2680  *      This routine is to be called by statements that must run inside
2681  *      a transaction block, because they have no effects that persist past
2682  *      transaction end (and so calling them outside a transaction block
2683  *      is presumably an error).  DECLARE CURSOR is an example.
2684  *
2685  *      If we appear to be running inside a user-defined function, we do not
2686  *      issue an error, since the function could issue more commands that make
2687  *      use of the current statement's results.  Likewise subtransactions.
2688  *      Thus this is an inverse for PreventTransactionChain.
2689  *
2690  *      isTopLevel: passed down from ProcessUtility to determine whether we are
2691  *      inside a function.
2692  *      stmtType: statement type name, for error messages.
2693  */
2694 void
2695 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2696 {
2697         /*
2698          * xact block already started?
2699          */
2700         if (IsTransactionBlock())
2701                 return;
2702
2703         /*
2704          * subtransaction?
2705          */
2706         if (IsSubTransaction())
2707                 return;
2708
2709         /*
2710          * inside a function call?
2711          */
2712         if (!isTopLevel)
2713                 return;
2714
2715         ereport(ERROR,
2716                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2717         /* translator: %s represents an SQL statement name */
2718                          errmsg("%s can only be used in transaction blocks",
2719                                         stmtType)));
2720 }
2721
2722 /*
2723  *      IsInTransactionChain
2724  *
2725  *      This routine is for statements that need to behave differently inside
2726  *      a transaction block than when running as single commands.  ANALYZE is
2727  *      currently the only example.
2728  *
2729  *      isTopLevel: passed down from ProcessUtility to determine whether we are
2730  *      inside a function.
2731  */
2732 bool
2733 IsInTransactionChain(bool isTopLevel)
2734 {
2735         /*
2736          * Return true on same conditions that would make PreventTransactionChain
2737          * error out
2738          */
2739         if (IsTransactionBlock())
2740                 return true;
2741
2742         if (IsSubTransaction())
2743                 return true;
2744
2745         if (!isTopLevel)
2746                 return true;
2747
2748         if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2749                 CurrentTransactionState->blockState != TBLOCK_STARTED)
2750                 return true;
2751
2752         return false;
2753 }
2754
2755
2756 /*
2757  * Register or deregister callback functions for start- and end-of-xact
2758  * operations.
2759  *
2760  * These functions are intended for use by dynamically loaded modules.
2761  * For built-in modules we generally just hardwire the appropriate calls
2762  * (mainly because it's easier to control the order that way, where needed).
2763  *
2764  * At transaction end, the callback occurs post-commit or post-abort, so the
2765  * callback functions can only do noncritical cleanup.
2766  */
2767 void
2768 RegisterXactCallback(XactCallback callback, void *arg)
2769 {
2770         XactCallbackItem *item;
2771
2772         item = (XactCallbackItem *)
2773                 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2774         item->callback = callback;
2775         item->arg = arg;
2776         item->next = Xact_callbacks;
2777         Xact_callbacks = item;
2778 }
2779
2780 void
2781 UnregisterXactCallback(XactCallback callback, void *arg)
2782 {
2783         XactCallbackItem *item;
2784         XactCallbackItem *prev;
2785
2786         prev = NULL;
2787         for (item = Xact_callbacks; item; prev = item, item = item->next)
2788         {
2789                 if (item->callback == callback && item->arg == arg)
2790                 {
2791                         if (prev)
2792                                 prev->next = item->next;
2793                         else
2794                                 Xact_callbacks = item->next;
2795                         pfree(item);
2796                         break;
2797                 }
2798         }
2799 }
2800
2801 static void
2802 CallXactCallbacks(XactEvent event)
2803 {
2804         XactCallbackItem *item;
2805
2806         for (item = Xact_callbacks; item; item = item->next)
2807                 (*item->callback) (event, item->arg);
2808 }
2809
2810
2811 /*
2812  * Register or deregister callback functions for start- and end-of-subxact
2813  * operations.
2814  *
2815  * Pretty much same as above, but for subtransaction events.
2816  *
2817  * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2818  * so the callback functions can only do noncritical cleanup.  At
2819  * subtransaction start, the callback is called when the subtransaction has
2820  * finished initializing.
2821  */
2822 void
2823 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2824 {
2825         SubXactCallbackItem *item;
2826
2827         item = (SubXactCallbackItem *)
2828                 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2829         item->callback = callback;
2830         item->arg = arg;
2831         item->next = SubXact_callbacks;
2832         SubXact_callbacks = item;
2833 }
2834
2835 void
2836 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2837 {
2838         SubXactCallbackItem *item;
2839         SubXactCallbackItem *prev;
2840
2841         prev = NULL;
2842         for (item = SubXact_callbacks; item; prev = item, item = item->next)
2843         {
2844                 if (item->callback == callback && item->arg == arg)
2845                 {
2846                         if (prev)
2847                                 prev->next = item->next;
2848                         else
2849                                 SubXact_callbacks = item->next;
2850                         pfree(item);
2851                         break;
2852                 }
2853         }
2854 }
2855
2856 static void
2857 CallSubXactCallbacks(SubXactEvent event,
2858                                          SubTransactionId mySubid,
2859                                          SubTransactionId parentSubid)
2860 {
2861         SubXactCallbackItem *item;
2862
2863         for (item = SubXact_callbacks; item; item = item->next)
2864                 (*item->callback) (event, mySubid, parentSubid, item->arg);
2865 }
2866
2867
2868 /* ----------------------------------------------------------------
2869  *                                         transaction block support
2870  * ----------------------------------------------------------------
2871  */
2872
2873 /*
2874  *      BeginTransactionBlock
2875  *              This executes a BEGIN command.
2876  */
2877 void
2878 BeginTransactionBlock(void)
2879 {
2880         TransactionState s = CurrentTransactionState;
2881
2882         switch (s->blockState)
2883         {
2884                         /*
2885                          * We are not inside a transaction block, so allow one to begin.
2886                          */
2887                 case TBLOCK_STARTED:
2888                         s->blockState = TBLOCK_BEGIN;
2889                         break;
2890
2891                         /*
2892                          * Already a transaction block in progress.
2893                          */
2894                 case TBLOCK_INPROGRESS:
2895                 case TBLOCK_SUBINPROGRESS:
2896                 case TBLOCK_ABORT:
2897                 case TBLOCK_SUBABORT:
2898                         ereport(WARNING,
2899                                         (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2900                                          errmsg("there is already a transaction in progress")));
2901                         break;
2902
2903                         /* These cases are invalid. */
2904                 case TBLOCK_DEFAULT:
2905                 case TBLOCK_BEGIN:
2906                 case TBLOCK_SUBBEGIN:
2907                 case TBLOCK_END:
2908                 case TBLOCK_SUBEND:
2909                 case TBLOCK_ABORT_END:
2910                 case TBLOCK_SUBABORT_END:
2911                 case TBLOCK_ABORT_PENDING:
2912                 case TBLOCK_SUBABORT_PENDING:
2913                 case TBLOCK_SUBRESTART:
2914                 case TBLOCK_SUBABORT_RESTART:
2915                 case TBLOCK_PREPARE:
2916                         elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2917                                  BlockStateAsString(s->blockState));
2918                         break;
2919         }
2920 }
2921
2922 /*
2923  *      PrepareTransactionBlock
2924  *              This executes a PREPARE command.
2925  *
2926  * Since PREPARE may actually do a ROLLBACK, the result indicates what
2927  * happened: TRUE for PREPARE, FALSE for ROLLBACK.
2928  *
2929  * Note that we don't actually do anything here except change blockState.
2930  * The real work will be done in the upcoming PrepareTransaction().
2931  * We do it this way because it's not convenient to change memory context,
2932  * resource owner, etc while executing inside a Portal.
2933  */
2934 bool
2935 PrepareTransactionBlock(char *gid)
2936 {
2937         TransactionState s;
2938         bool            result;
2939
2940         /* Set up to commit the current transaction */
2941         result = EndTransactionBlock();
2942
2943         /* If successful, change outer tblock state to PREPARE */
2944         if (result)
2945         {
2946                 s = CurrentTransactionState;
2947
2948                 while (s->parent != NULL)
2949                         s = s->parent;
2950
2951                 if (s->blockState == TBLOCK_END)
2952                 {
2953                         /* Save GID where PrepareTransaction can find it again */
2954                         prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
2955
2956                         s->blockState = TBLOCK_PREPARE;
2957                 }
2958                 else
2959                 {
2960                         /*
2961                          * ignore case where we are not in a transaction;
2962                          * EndTransactionBlock already issued a warning.
2963                          */
2964                         Assert(s->blockState == TBLOCK_STARTED);
2965                         /* Don't send back a PREPARE result tag... */
2966                         result = false;
2967                 }
2968         }
2969
2970         return result;
2971 }
2972
2973 /*
2974  *      EndTransactionBlock
2975  *              This executes a COMMIT command.
2976  *
2977  * Since COMMIT may actually do a ROLLBACK, the result indicates what
2978  * happened: TRUE for COMMIT, FALSE for ROLLBACK.
2979  *
2980  * Note that we don't actually do anything here except change blockState.
2981  * The real work will be done in the upcoming CommitTransactionCommand().
2982  * We do it this way because it's not convenient to change memory context,
2983  * resource owner, etc while executing inside a Portal.
2984  */
2985 bool
2986 EndTransactionBlock(void)
2987 {
2988         TransactionState s = CurrentTransactionState;
2989         bool            result = false;
2990
2991         switch (s->blockState)
2992         {
2993                         /*
2994                          * We are in a transaction block, so tell CommitTransactionCommand
2995                          * to COMMIT.
2996                          */
2997                 case TBLOCK_INPROGRESS:
2998                         s->blockState = TBLOCK_END;
2999                         result = true;
3000                         break;
3001
3002                         /*
3003                          * We are in a failed transaction block.  Tell
3004                          * CommitTransactionCommand it's time to exit the block.
3005                          */
3006                 case TBLOCK_ABORT:
3007                         s->blockState = TBLOCK_ABORT_END;
3008                         break;
3009
3010                         /*
3011                          * We are in a live subtransaction block.  Set up to subcommit all
3012                          * open subtransactions and then commit the main transaction.
3013                          */
3014                 case TBLOCK_SUBINPROGRESS:
3015                         while (s->parent != NULL)
3016                         {
3017                                 if (s->blockState == TBLOCK_SUBINPROGRESS)
3018                                         s->blockState = TBLOCK_SUBEND;
3019                                 else
3020                                         elog(FATAL, "EndTransactionBlock: unexpected state %s",
3021                                                  BlockStateAsString(s->blockState));
3022                                 s = s->parent;
3023                         }
3024                         if (s->blockState == TBLOCK_INPROGRESS)
3025                                 s->blockState = TBLOCK_END;
3026                         else
3027                                 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3028                                          BlockStateAsString(s->blockState));
3029                         result = true;
3030                         break;
3031
3032                         /*
3033                          * Here we are inside an aborted subtransaction.  Treat the COMMIT
3034                          * as ROLLBACK: set up to abort everything and exit the main
3035                          * transaction.
3036                          */
3037                 case TBLOCK_SUBABORT:
3038                         while (s->parent != NULL)
3039                         {
3040                                 if (s->blockState == TBLOCK_SUBINPROGRESS)
3041                                         s->blockState = TBLOCK_SUBABORT_PENDING;
3042                                 else if (s->blockState == TBLOCK_SUBABORT)
3043                                         s->blockState = TBLOCK_SUBABORT_END;
3044                                 else
3045                                         elog(FATAL, "EndTransactionBlock: unexpected state %s",
3046                                                  BlockStateAsString(s->blockState));
3047                                 s = s->parent;
3048                         }
3049                         if (s->blockState == TBLOCK_INPROGRESS)
3050                                 s->blockState = TBLOCK_ABORT_PENDING;
3051                         else if (s->blockState == TBLOCK_ABORT)
3052                                 s->blockState = TBLOCK_ABORT_END;
3053                         else
3054                                 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3055                                          BlockStateAsString(s->blockState));
3056                         break;
3057
3058                         /*
3059                          * The user issued COMMIT when not inside a transaction.  Issue a
3060                          * WARNING, staying in TBLOCK_STARTED state.  The upcoming call to
3061                          * CommitTransactionCommand() will then close the transaction and
3062                          * put us back into the default state.
3063                          */
3064                 case TBLOCK_STARTED:
3065                         ereport(WARNING,
3066                                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3067                                          errmsg("there is no transaction in progress")));
3068                         result = true;
3069                         break;
3070
3071                         /* These cases are invalid. */
3072                 case TBLOCK_DEFAULT:
3073                 case TBLOCK_BEGIN:
3074                 case TBLOCK_SUBBEGIN:
3075                 case TBLOCK_END:
3076                 case TBLOCK_SUBEND:
3077                 case TBLOCK_ABORT_END:
3078                 case TBLOCK_SUBABORT_END:
3079                 case TBLOCK_ABORT_PENDING:
3080                 case TBLOCK_SUBABORT_PENDING:
3081                 case TBLOCK_SUBRESTART:
3082                 case TBLOCK_SUBABORT_RESTART:
3083                 case TBLOCK_PREPARE:
3084                         elog(FATAL, "EndTransactionBlock: unexpected state %s",
3085                                  BlockStateAsString(s->blockState));
3086                         break;
3087         }
3088
3089         return result;
3090 }
3091
3092 /*
3093  *      UserAbortTransactionBlock
3094  *              This executes a ROLLBACK command.
3095  *
3096  * As above, we don't actually do anything here except change blockState.
3097  */
3098 void
3099 UserAbortTransactionBlock(void)
3100 {
3101         TransactionState s = CurrentTransactionState;
3102
3103         switch (s->blockState)
3104         {
3105                         /*
3106                          * We are inside a transaction block and we got a ROLLBACK command
3107                          * from the user, so tell CommitTransactionCommand to abort and
3108                          * exit the transaction block.
3109                          */
3110                 case TBLOCK_INPROGRESS:
3111                         s->blockState = TBLOCK_ABORT_PENDING;
3112                         break;
3113
3114                         /*
3115                          * We are inside a failed transaction block and we got a ROLLBACK
3116                          * command from the user.  Abort processing is already done, so
3117                          * CommitTransactionCommand just has to cleanup and go back to
3118                          * idle state.
3119                          */
3120                 case TBLOCK_ABORT:
3121                         s->blockState = TBLOCK_ABORT_END;
3122                         break;
3123
3124                         /*
3125                          * We are inside a subtransaction.      Mark everything up to top
3126                          * level as exitable.
3127                          */
3128                 case TBLOCK_SUBINPROGRESS:
3129                 case TBLOCK_SUBABORT:
3130                         while (s->parent != NULL)
3131                         {
3132                                 if (s->blockState == TBLOCK_SUBINPROGRESS)
3133                                         s->blockState = TBLOCK_SUBABORT_PENDING;
3134                                 else if (s->blockState == TBLOCK_SUBABORT)
3135                                         s->blockState = TBLOCK_SUBABORT_END;
3136                                 else
3137                                         elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3138                                                  BlockStateAsString(s->blockState));
3139                                 s = s->parent;
3140                         }
3141                         if (s->blockState == TBLOCK_INPROGRESS)
3142                                 s->blockState = TBLOCK_ABORT_PENDING;
3143                         else if (s->blockState == TBLOCK_ABORT)
3144                                 s->blockState = TBLOCK_ABORT_END;
3145                         else
3146                                 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3147                                          BlockStateAsString(s->blockState));
3148                         break;
3149
3150                         /*
3151                          * The user issued ABORT when not inside a transaction. Issue a
3152                          * WARNING and go to abort state.  The upcoming call to
3153                          * CommitTransactionCommand() will then put us back into the
3154                          * default state.
3155                          */
3156                 case TBLOCK_STARTED:
3157                         ereport(NOTICE,
3158                                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3159                                          errmsg("there is no transaction in progress")));
3160                         s->blockState = TBLOCK_ABORT_PENDING;
3161                         break;
3162
3163                         /* These cases are invalid. */
3164                 case TBLOCK_DEFAULT:
3165                 case TBLOCK_BEGIN:
3166                 case TBLOCK_SUBBEGIN:
3167                 case TBLOCK_END:
3168                 case TBLOCK_SUBEND:
3169                 case TBLOCK_ABORT_END:
3170                 case TBLOCK_SUBABORT_END:
3171                 case TBLOCK_ABORT_PENDING:
3172                 case TBLOCK_SUBABORT_PENDING:
3173                 case TBLOCK_SUBRESTART:
3174                 case TBLOCK_SUBABORT_RESTART:
3175                 case TBLOCK_PREPARE:
3176                         elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3177                                  BlockStateAsString(s->blockState));
3178                         break;
3179         }
3180 }
3181
3182 /*
3183  * DefineSavepoint
3184  *              This executes a SAVEPOINT command.
3185  */
3186 void
3187 DefineSavepoint(char *name)
3188 {
3189         TransactionState s = CurrentTransactionState;
3190
3191         switch (s->blockState)
3192         {
3193                 case TBLOCK_INPROGRESS:
3194                 case TBLOCK_SUBINPROGRESS:
3195                         /* Normal subtransaction start */
3196                         PushTransaction();
3197                         s = CurrentTransactionState;            /* changed by push */
3198
3199                         /*
3200                          * Savepoint names, like the TransactionState block itself, live
3201                          * in TopTransactionContext.
3202                          */
3203                         if (name)
3204                                 s->name = MemoryContextStrdup(TopTransactionContext, name);
3205                         break;
3206
3207                         /* These cases are invalid. */
3208                 case TBLOCK_DEFAULT:
3209                 case TBLOCK_STARTED:
3210                 case TBLOCK_BEGIN:
3211                 case TBLOCK_SUBBEGIN:
3212                 case TBLOCK_END:
3213                 case TBLOCK_SUBEND:
3214                 case TBLOCK_ABORT:
3215                 case TBLOCK_SUBABORT:
3216                 case TBLOCK_ABORT_END:
3217                 case TBLOCK_SUBABORT_END:
3218                 case TBLOCK_ABORT_PENDING:
3219                 case TBLOCK_SUBABORT_PENDING:
3220                 case TBLOCK_SUBRESTART:
3221                 case TBLOCK_SUBABORT_RESTART:
3222                 case TBLOCK_PREPARE:
3223                         elog(FATAL, "DefineSavepoint: unexpected state %s",
3224                                  BlockStateAsString(s->blockState));
3225                         break;
3226         }
3227 }
3228
3229 /*
3230  * ReleaseSavepoint
3231  *              This executes a RELEASE command.
3232  *
3233  * As above, we don't actually do anything here except change blockState.
3234  */
3235 void
3236 ReleaseSavepoint(List *options)
3237 {
3238         TransactionState s = CurrentTransactionState;
3239         TransactionState target,
3240                                 xact;
3241         ListCell   *cell;
3242         char       *name = NULL;
3243
3244         switch (s->blockState)
3245         {
3246                         /*
3247                          * We can't rollback to a savepoint if there is no savepoint
3248                          * defined.
3249                          */
3250                 case TBLOCK_INPROGRESS:
3251                         ereport(ERROR,
3252                                         (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3253                                          errmsg("no such savepoint")));
3254                         break;
3255
3256                         /*
3257                          * We are in a non-aborted subtransaction.      This is the only valid
3258                          * case.
3259                          */
3260                 case TBLOCK_SUBINPROGRESS:
3261                         break;
3262
3263                         /* These cases are invalid. */
3264                 case TBLOCK_DEFAULT:
3265                 case TBLOCK_STARTED:
3266                 case TBLOCK_BEGIN:
3267                 case TBLOCK_SUBBEGIN:
3268                 case TBLOCK_END:
3269                 case TBLOCK_SUBEND:
3270                 case TBLOCK_ABORT:
3271                 case TBLOCK_SUBABORT:
3272                 case TBLOCK_ABORT_END:
3273                 case TBLOCK_SUBABORT_END:
3274                 case TBLOCK_ABORT_PENDING:
3275                 case TBLOCK_SUBABORT_PENDING:
3276                 case TBLOCK_SUBRESTART:
3277                 case TBLOCK_SUBABORT_RESTART:
3278                 case TBLOCK_PREPARE:
3279                         elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3280                                  BlockStateAsString(s->blockState));
3281                         break;
3282         }
3283
3284         foreach(cell, options)
3285         {
3286                 DefElem    *elem = lfirst(cell);
3287
3288                 if (strcmp(elem->defname, "savepoint_name") == 0)
3289                         name = strVal(elem->arg);
3290         }
3291
3292         Assert(PointerIsValid(name));
3293
3294         for (target = s; PointerIsValid(target); target = target->parent)
3295         {
3296                 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3297                         break;
3298         }
3299
3300         if (!PointerIsValid(target))
3301                 ereport(ERROR,
3302                                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3303                                  errmsg("no such savepoint")));
3304
3305         /* disallow crossing savepoint level boundaries */
3306         if (target->savepointLevel != s->savepointLevel)
3307                 ereport(ERROR,
3308                                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3309                                  errmsg("no such savepoint")));
3310
3311         /*
3312          * Mark "commit pending" all subtransactions up to the target
3313          * subtransaction.      The actual commits will happen when control gets to
3314          * CommitTransactionCommand.
3315          */
3316         xact = CurrentTransactionState;
3317         for (;;)
3318         {
3319                 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3320                 xact->blockState = TBLOCK_SUBEND;
3321                 if (xact == target)
3322                         break;
3323                 xact = xact->parent;
3324                 Assert(PointerIsValid(xact));
3325         }
3326 }
3327
3328 /*
3329  * RollbackToSavepoint
3330  *              This executes a ROLLBACK TO <savepoint> command.
3331  *
3332  * As above, we don't actually do anything here except change blockState.
3333  */
3334 void
3335 RollbackToSavepoint(List *options)
3336 {
3337         TransactionState s = CurrentTransactionState;
3338         TransactionState target,
3339                                 xact;
3340         ListCell   *cell;
3341         char       *name = NULL;
3342
3343         switch (s->blockState)
3344         {
3345                         /*
3346                          * We can't rollback to a savepoint if there is no savepoint
3347                          * defined.
3348                          */
3349                 case TBLOCK_INPROGRESS:
3350                 case TBLOCK_ABORT:
3351                         ereport(ERROR,
3352                                         (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3353                                          errmsg("no such savepoint")));
3354                         break;
3355
3356                         /*
3357                          * There is at least one savepoint, so proceed.
3358                          */
3359                 case TBLOCK_SUBINPROGRESS:
3360                 case TBLOCK_SUBABORT:
3361                         break;
3362
3363                         /* These cases are invalid. */
3364                 case TBLOCK_DEFAULT:
3365                 case TBLOCK_STARTED:
3366                 case TBLOCK_BEGIN:
3367                 case TBLOCK_SUBBEGIN:
3368                 case TBLOCK_END:
3369                 case TBLOCK_SUBEND:
3370                 case TBLOCK_ABORT_END:
3371                 case TBLOCK_SUBABORT_END:
3372                 case TBLOCK_ABORT_PENDING:
3373                 case TBLOCK_SUBABORT_PENDING:
3374                 case TBLOCK_SUBRESTART:
3375                 case TBLOCK_SUBABORT_RESTART:
3376                 case TBLOCK_PREPARE:
3377                         elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3378                                  BlockStateAsString(s->blockState));
3379                         break;
3380         }
3381
3382         foreach(cell, options)
3383         {
3384                 DefElem    *elem = lfirst(cell);
3385
3386                 if (strcmp(elem->defname, "savepoint_name") == 0)
3387                         name = strVal(elem->arg);
3388         }
3389
3390         Assert(PointerIsValid(name));
3391
3392         for (target = s; PointerIsValid(target); target = target->parent)
3393         {
3394                 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3395                         break;
3396         }
3397
3398         if (!PointerIsValid(target))
3399                 ereport(ERROR,
3400                                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3401                                  errmsg("no such savepoint")));
3402
3403         /* disallow crossing savepoint level boundaries */
3404         if (target->savepointLevel != s->savepointLevel)
3405                 ereport(ERROR,
3406                                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3407                                  errmsg("no such savepoint")));
3408
3409         /*
3410          * Mark "abort pending" all subtransactions up to the target
3411          * subtransaction.      The actual aborts will happen when control gets to
3412          * CommitTransactionCommand.
3413          */
3414         xact = CurrentTransactionState;
3415         for (;;)
3416         {
3417                 if (xact == target)
3418                         break;
3419                 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3420                         xact->blockState = TBLOCK_SUBABORT_PENDING;
3421                 else if (xact->blockState == TBLOCK_SUBABORT)
3422                         xact->blockState = TBLOCK_SUBABORT_END;
3423                 else
3424                         elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3425                                  BlockStateAsString(xact->blockState));
3426                 xact = xact->parent;
3427                 Assert(PointerIsValid(xact));
3428         }
3429
3430         /* And mark the target as "restart pending" */
3431         if (xact->blockState == TBLOCK_SUBINPROGRESS)
3432                 xact->blockState = TBLOCK_SUBRESTART;
3433         else if (xact->blockState == TBLOCK_SUBABORT)
3434                 xact->blockState = TBLOCK_SUBABORT_RESTART;
3435         else
3436                 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3437                          BlockStateAsString(xact->blockState));
3438 }
3439
3440 /*
3441  * BeginInternalSubTransaction
3442  *              This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3443  *              TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3444  *              used in functions that might be called when not inside a BEGIN block
3445  *              or when running deferred triggers at COMMIT/PREPARE time.  Also, it
3446  *              automatically does CommitTransactionCommand/StartTransactionCommand
3447  *              instead of expecting the caller to do it.
3448  */
3449 void
3450 BeginInternalSubTransaction(char *name)
3451 {
3452         TransactionState s = CurrentTransactionState;
3453
3454         switch (s->blockState)
3455         {
3456                 case TBLOCK_STARTED:
3457                 case TBLOCK_INPROGRESS:
3458                 case TBLOCK_END:
3459                 case TBLOCK_PREPARE:
3460                 case TBLOCK_SUBINPROGRESS:
3461                         /* Normal subtransaction start */
3462                         PushTransaction();
3463                         s = CurrentTransactionState;            /* changed by push */
3464
3465                         /*
3466                          * Savepoint names, like the TransactionState block itself, live
3467                          * in TopTransactionContext.
3468                          */
3469                         if (name)
3470                                 s->name = MemoryContextStrdup(TopTransactionContext, name);
3471                         break;
3472
3473                         /* These cases are invalid. */
3474                 case TBLOCK_DEFAULT:
3475                 case TBLOCK_BEGIN:
3476                 case TBLOCK_SUBBEGIN:
3477                 case TBLOCK_SUBEND:
3478                 case TBLOCK_ABORT:
3479                 case TBLOCK_SUBABORT:
3480                 case TBLOCK_ABORT_END:
3481                 case TBLOCK_SUBABORT_END:
3482                 case TBLOCK_ABORT_PENDING:
3483                 case TBLOCK_SUBABORT_PENDING:
3484                 case TBLOCK_SUBRESTART:
3485                 case TBLOCK_SUBABORT_RESTART:
3486                         elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3487                                  BlockStateAsString(s->blockState));
3488                         break;
3489         }
3490
3491         CommitTransactionCommand();
3492         StartTransactionCommand();
3493 }
3494
3495 /*
3496  * ReleaseCurrentSubTransaction
3497  *
3498  * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3499  * savepoint name (if any).
3500  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3501  */
3502 void
3503 ReleaseCurrentSubTransaction(void)
3504 {
3505         TransactionState s = CurrentTransactionState;
3506
3507         if (s->blockState != TBLOCK_SUBINPROGRESS)
3508                 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3509                          BlockStateAsString(s->blockState));
3510         Assert(s->state == TRANS_INPROGRESS);
3511         MemoryContextSwitchTo(CurTransactionContext);
3512         CommitSubTransaction();
3513         s = CurrentTransactionState;    /* changed by pop */
3514         Assert(s->state == TRANS_INPROGRESS);
3515 }
3516
3517 /*
3518  * RollbackAndReleaseCurrentSubTransaction
3519  *
3520  * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3521  * of its savepoint name (if any).
3522  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3523  */
3524 void
3525 RollbackAndReleaseCurrentSubTransaction(void)
3526 {
3527         TransactionState s = CurrentTransactionState;
3528
3529         switch (s->blockState)
3530         {
3531                         /* Must be in a subtransaction */
3532                 case TBLOCK_SUBINPROGRESS:
3533                 case TBLOCK_SUBABORT:
3534                         break;
3535
3536                         /* These cases are invalid. */
3537                 case TBLOCK_DEFAULT:
3538                 case TBLOCK_STARTED:
3539                 case TBLOCK_BEGIN:
3540                 case TBLOCK_SUBBEGIN:
3541                 case TBLOCK_INPROGRESS:
3542                 case TBLOCK_END:
3543                 case TBLOCK_SUBEND:
3544                 case TBLOCK_ABORT:
3545                 case TBLOCK_ABORT_END:
3546                 case TBLOCK_SUBABORT_END:
3547                 case TBLOCK_ABORT_PENDING:
3548                 case TBLOCK_SUBABORT_PENDING:
3549                 case TBLOCK_SUBRESTART:
3550                 case TBLOCK_SUBABORT_RESTART:
3551                 case TBLOCK_PREPARE:
3552                         elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3553                                  BlockStateAsString(s->blockState));
3554                         break;
3555         }
3556
3557         /*
3558          * Abort the current subtransaction, if needed.
3559          */
3560         if (s->blockState == TBLOCK_SUBINPROGRESS)
3561                 AbortSubTransaction();
3562
3563         /* And clean it up, too */
3564         CleanupSubTransaction();
3565
3566         s = CurrentTransactionState;    /* changed by pop */
3567         AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3568                                 s->blockState == TBLOCK_INPROGRESS ||
3569                                 s->blockState == TBLOCK_STARTED);
3570 }
3571
3572 /*
3573  *      AbortOutOfAnyTransaction
3574  *
3575  *      This routine is provided for error recovery purposes.  It aborts any
3576  *      active transaction or transaction block, leaving the system in a known
3577  *      idle state.
3578  */
3579 void
3580 AbortOutOfAnyTransaction(void)
3581 {
3582         TransactionState s = CurrentTransactionState;
3583
3584         /*
3585          * Get out of any transaction or nested transaction
3586          */
3587         do
3588         {
3589                 switch (s->blockState)
3590                 {
3591                         case TBLOCK_DEFAULT:
3592                                 /* Not in a transaction, do nothing */
3593                                 break;
3594                         case TBLOCK_STARTED:
3595                         case TBLOCK_BEGIN:
3596                         case TBLOCK_INPROGRESS:
3597                         case TBLOCK_END:
3598                         case TBLOCK_ABORT_PENDING:
3599                         case TBLOCK_PREPARE:
3600                                 /* In a transaction, so clean up */
3601                                 AbortTransaction();
3602                                 CleanupTransaction();
3603                                 s->blockState = TBLOCK_DEFAULT;
3604                                 break;
3605                         case TBLOCK_ABORT:
3606                         case TBLOCK_ABORT_END:
3607                                 /* AbortTransaction already done, still need Cleanup */
3608                                 CleanupTransaction();
3609                                 s->blockState = TBLOCK_DEFAULT;
3610                                 break;
3611
3612                                 /*
3613                                  * In a subtransaction, so clean it up and abort parent too
3614                                  */
3615                         case TBLOCK_SUBBEGIN:
3616                         case TBLOCK_SUBINPROGRESS:
3617                         case TBLOCK_SUBEND:
3618                         case TBLOCK_SUBABORT_PENDING:
3619                         case TBLOCK_SUBRESTART:
3620                                 AbortSubTransaction();
3621                                 CleanupSubTransaction();
3622                                 s = CurrentTransactionState;    /* changed by pop */
3623                                 break;
3624
3625                         case TBLOCK_SUBABORT:
3626                         case TBLOCK_SUBABORT_END:
3627                         case TBLOCK_SUBABORT_RESTART:
3628                                 /* As above, but AbortSubTransaction already done */
3629                                 CleanupSubTransaction();
3630                                 s = CurrentTransactionState;    /* changed by pop */
3631                                 break;
3632                 }
3633         } while (s->blockState != TBLOCK_DEFAULT);
3634
3635         /* Should be out of all subxacts now */
3636         Assert(s->parent == NULL);
3637 }
3638
3639 /*
3640  * IsTransactionBlock --- are we within a transaction block?
3641  */
3642 bool
3643 IsTransactionBlock(void)
3644 {
3645         TransactionState s = CurrentTransactionState;
3646
3647         if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3648                 return false;
3649
3650         return true;
3651 }
3652
3653 /*
3654  * IsTransactionOrTransactionBlock --- are we within either a transaction
3655  * or a transaction block?      (The backend is only really "idle" when this
3656  * returns false.)
3657  *
3658  * This should match up with IsTransactionBlock and IsTransactionState.
3659  */
3660 bool
3661 IsTransactionOrTransactionBlock(void)
3662 {
3663         TransactionState s = CurrentTransactionState;
3664
3665         if (s->blockState == TBLOCK_DEFAULT)
3666                 return false;
3667
3668         return true;
3669 }
3670
3671 /*
3672  * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3673  */
3674 char
3675 TransactionBlockStatusCode(void)
3676 {
3677         TransactionState s = CurrentTransactionState;
3678
3679         switch (s->blockState)
3680         {
3681                 case TBLOCK_DEFAULT:
3682                 case TBLOCK_STARTED:
3683                         return 'I';                     /* idle --- not in transaction */
3684                 case TBLOCK_BEGIN:
3685                 case TBLOCK_SUBBEGIN:
3686                 case TBLOCK_INPROGRESS:
3687                 case TBLOCK_SUBINPROGRESS:
3688                 case TBLOCK_END:
3689                 case TBLOCK_SUBEND:
3690                 case TBLOCK_PREPARE:
3691                         return 'T';                     /* in transaction */
3692                 case TBLOCK_ABORT:
3693                 case TBLOCK_SUBABORT:
3694                 case TBLOCK_ABORT_END:
3695                 case TBLOCK_SUBABORT_END:
3696                 case TBLOCK_ABORT_PENDING:
3697                 case TBLOCK_SUBABORT_PENDING:
3698                 case TBLOCK_SUBRESTART:
3699                 case TBLOCK_SUBABORT_RESTART:
3700                         return 'E';                     /* in failed transaction */
3701         }
3702
3703         /* should never get here */
3704         elog(FATAL, "invalid transaction block state: %s",
3705                  BlockStateAsString(s->blockState));
3706         return 0;                                       /* keep compiler quiet */
3707 }
3708
3709 /*
3710  * IsSubTransaction
3711  */
3712 bool
3713 IsSubTransaction(void)
3714 {
3715         TransactionState s = CurrentTransactionState;
3716
3717         if (s->nestingLevel >= 2)
3718                 return true;
3719
3720         return false;
3721 }
3722
3723 /*
3724  * StartSubTransaction
3725  *
3726  * If you're wondering why this is separate from PushTransaction: it's because
3727  * we can't conveniently do this stuff right inside DefineSavepoint.  The
3728  * SAVEPOINT utility command will be executed inside a Portal, and if we
3729  * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3730  * the Portal will undo those settings.  So we make DefineSavepoint just
3731  * push a dummy transaction block, and when control returns to the main
3732  * idle loop, CommitTransactionCommand will be called, and we'll come here
3733  * to finish starting the subtransaction.
3734  */
3735 static void
3736 StartSubTransaction(void)
3737 {
3738         TransactionState s = CurrentTransactionState;
3739
3740         if (s->state != TRANS_DEFAULT)
3741                 elog(WARNING, "StartSubTransaction while in %s state",
3742                          TransStateAsString(s->state));
3743
3744         s->state = TRANS_START;
3745
3746         /*
3747          * Initialize subsystems for new subtransaction
3748          *
3749          * must initialize resource-management stuff first
3750          */
3751         AtSubStart_Memory();
3752         AtSubStart_ResourceOwner();
3753         AtSubStart_Inval();
3754         AtSubStart_Notify();
3755         AfterTriggerBeginSubXact();
3756
3757         s->state = TRANS_INPROGRESS;
3758
3759         /*
3760          * Call start-of-subxact callbacks
3761          */
3762         CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3763                                                  s->parent->subTransactionId);
3764
3765         ShowTransactionState("StartSubTransaction");
3766 }
3767
3768 /*
3769  * CommitSubTransaction
3770  *
3771  *      The caller has to make sure to always reassign CurrentTransactionState
3772  *      if it has a local pointer to it after calling this function.
3773  */
3774 static void
3775 CommitSubTransaction(void)
3776 {
3777         TransactionState s = CurrentTransactionState;
3778
3779         ShowTransactionState("CommitSubTransaction");
3780
3781         if (s->state != TRANS_INPROGRESS)
3782                 elog(WARNING, "CommitSubTransaction while in %s state",
3783                          TransStateAsString(s->state));
3784
3785         /* Pre-commit processing goes here -- nothing to do at the moment */
3786
3787         s->state = TRANS_COMMIT;
3788
3789         /* Must CCI to ensure commands of subtransaction are seen as done */
3790         CommandCounterIncrement();
3791
3792         /* Mark subtransaction as subcommitted */
3793         RecordSubTransactionCommit();
3794
3795         /* Post-commit cleanup */
3796         if (TransactionIdIsValid(s->transactionId))
3797                 AtSubCommit_childXids();
3798         AfterTriggerEndSubXact(true);
3799         AtSubCommit_Portals(s->subTransactionId,
3800                                                 s->parent->subTransactionId,
3801                                                 s->parent->curTransactionOwner);
3802         AtEOSubXact_LargeObject(true, s->subTransactionId,
3803                                                         s->parent->subTransactionId);
3804         AtSubCommit_Notify();
3805         AtEOSubXact_UpdateFlatFiles(true, s->subTransactionId,
3806                                                                 s->parent->subTransactionId);
3807
3808         CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3809                                                  s->parent->subTransactionId);
3810
3811         ResourceOwnerRelease(s->curTransactionOwner,
3812                                                  RESOURCE_RELEASE_BEFORE_LOCKS,
3813                                                  true, false);
3814         AtEOSubXact_RelationCache(true, s->subTransactionId,
3815                                                           s->parent->subTransactionId);
3816         AtEOSubXact_Inval(true);
3817         AtSubCommit_smgr();
3818
3819         /*
3820          * The only lock we actually release here is the subtransaction XID lock.
3821          * The rest just get transferred to the parent resource owner.
3822          */
3823         CurrentResourceOwner = s->curTransactionOwner;
3824         if (TransactionIdIsValid(s->transactionId))
3825                 XactLockTableDelete(s->transactionId);
3826
3827         ResourceOwnerRelease(s->curTransactionOwner,
3828                                                  RESOURCE_RELEASE_LOCKS,
3829                                                  true, false);
3830         ResourceOwnerRelease(s->curTransactionOwner,
3831                                                  RESOURCE_RELEASE_AFTER_LOCKS,
3832                                                  true, false);
3833
3834         AtEOXact_GUC(true, s->gucNestLevel);
3835         AtEOSubXact_SPI(true, s->subTransactionId);
3836         AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3837                                                                   s->parent->subTransactionId);
3838         AtEOSubXact_Namespace(true, s->subTransactionId,
3839                                                   s->parent->subTransactionId);
3840         AtEOSubXact_Files(true, s->subTransactionId,
3841                                           s->parent->subTransactionId);
3842         AtEOSubXact_HashTables(true, s->nestingLevel);
3843         AtEOSubXact_PgStat(true, s->nestingLevel);
3844
3845         /*
3846          * We need to restore the upper transaction's read-only state, in case the
3847          * upper is read-write while the child is read-only; GUC will incorrectly
3848          * think it should leave the child state in place.
3849          */
3850         XactReadOnly = s->prevXactReadOnly;
3851
3852         CurrentResourceOwner = s->parent->curTransactionOwner;
3853         CurTransactionResourceOwner = s->parent->curTransactionOwner;
3854         ResourceOwnerDelete(s->curTransactionOwner);
3855         s->curTransactionOwner = NULL;
3856
3857         AtSubCommit_Memory();
3858
3859         s->state = TRANS_DEFAULT;
3860
3861         PopTransaction();
3862 }
3863
3864 /*
3865  * AbortSubTransaction
3866  */
3867 static void
3868 AbortSubTransaction(void)
3869 {
3870         TransactionState s = CurrentTransactionState;
3871
3872         /* Prevent cancel/die interrupt while cleaning up */
3873         HOLD_INTERRUPTS();
3874
3875         /* Make sure we have a valid memory context and resource owner */
3876         AtSubAbort_Memory();
3877         AtSubAbort_ResourceOwner();
3878
3879         /*
3880          * Release any LW locks we might be holding as quickly as possible.
3881          * (Regular locks, however, must be held till we finish aborting.)
3882          * Releasing LW locks is critical since we might try to grab them again
3883          * while cleaning up!
3884          *
3885          * FIXME This may be incorrect --- Are there some locks we should keep?
3886          * Buffer locks, for example?  I don't think so but I'm not sure.
3887          */
3888         LWLockReleaseAll();
3889
3890         AbortBufferIO();
3891         UnlockBuffers();
3892
3893         LockWaitCancel();
3894
3895         /*
3896          * check the current transaction state
3897          */
3898         ShowTransactionState("AbortSubTransaction");
3899
3900         if (s->state != TRANS_INPROGRESS)
3901                 elog(WARNING, "AbortSubTransaction while in %s state",
3902                          TransStateAsString(s->state));
3903
3904         s->state = TRANS_ABORT;
3905
3906         /*
3907          * Reset user ID which might have been changed transiently.  (See notes
3908          * in AbortTransaction.)
3909          */
3910         SetUserIdAndContext(s->prevUser, s->prevSecDefCxt);
3911
3912         /*
3913          * We can skip all this stuff if the subxact failed before creating a
3914          * ResourceOwner...
3915          */
3916         if (s->curTransactionOwner)
3917         {
3918                 AfterTriggerEndSubXact(false);
3919                 AtSubAbort_Portals(s->subTransactionId,
3920                                                    s->parent->subTransactionId,
3921                                                    s->parent->curTransactionOwner);
3922                 AtEOSubXact_LargeObject(false, s->subTransactionId,
3923                                                                 s->parent->subTransactionId);
3924                 AtSubAbort_Notify();
3925                 AtEOSubXact_UpdateFlatFiles(false, s->subTransactionId,
3926                                                                         s->parent->subTransactionId);
3927
3928                 /* Advertise the fact that we aborted in pg_clog. */
3929                 (void) RecordTransactionAbort(true);
3930
3931                 /* Post-abort cleanup */
3932                 if (TransactionIdIsValid(s->transactionId))
3933                         AtSubAbort_childXids();
3934
3935                 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
3936                                                          s->parent->subTransactionId);
3937
3938                 ResourceOwnerRelease(s->curTransactionOwner,
3939                                                          RESOURCE_RELEASE_BEFORE_LOCKS,
3940                                                          false, false);
3941                 AtEOSubXact_RelationCache(false, s->subTransactionId,
3942                                                                   s->parent->subTransactionId);
3943                 AtEOSubXact_Inval(false);
3944                 AtSubAbort_smgr();
3945                 ResourceOwnerRelease(s->curTransactionOwner,
3946                                                          RESOURCE_RELEASE_LOCKS,
3947                                                          false, false);
3948                 ResourceOwnerRelease(s->curTransactionOwner,
3949                                                          RESOURCE_RELEASE_AFTER_LOCKS,
3950                                                          false, false);
3951
3952                 AtEOXact_GUC(false, s->gucNestLevel);
3953                 AtEOSubXact_SPI(false, s->subTransactionId);
3954                 AtEOXact_xml();
3955                 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
3956                                                                           s->parent->subTransactionId);
3957                 AtEOSubXact_Namespace(false, s->subTransactionId,
3958                                                           s->parent->subTransactionId);
3959                 AtEOSubXact_Files(false, s->subTransactionId,
3960                                                   s->parent->subTransactionId);
3961                 AtEOSubXact_HashTables(false, s->nestingLevel);
3962                 AtEOSubXact_PgStat(false, s->nestingLevel);
3963         }
3964
3965         /*
3966          * Restore the upper transaction's read-only state, too.  This should be
3967          * redundant with GUC's cleanup but we may as well do it for consistency
3968          * with the commit case.
3969          */
3970         XactReadOnly = s->prevXactReadOnly;
3971
3972         RESUME_INTERRUPTS();
3973 }
3974
3975 /*
3976  * CleanupSubTransaction
3977  *
3978  *      The caller has to make sure to always reassign CurrentTransactionState
3979  *      if it has a local pointer to it after calling this function.
3980  */
3981 static void
3982 CleanupSubTransaction(void)
3983 {
3984         TransactionState s = CurrentTransactionState;
3985
3986         ShowTransactionState("CleanupSubTransaction");
3987
3988         if (s->state != TRANS_ABORT)
3989                 elog(WARNING, "CleanupSubTransaction while in %s state",
3990                          TransStateAsString(s->state));
3991
3992         AtSubCleanup_Portals(s->subTransactionId);
3993
3994         CurrentResourceOwner = s->parent->curTransactionOwner;
3995         CurTransactionResourceOwner = s->parent->curTransactionOwner;
3996         if (s->curTransactionOwner)
3997                 ResourceOwnerDelete(s->curTransactionOwner);
3998         s->curTransactionOwner = NULL;
3999
4000         AtSubCleanup_Memory();
4001
4002         s->state = TRANS_DEFAULT;
4003
4004         PopTransaction();
4005 }
4006
4007 /*
4008  * PushTransaction
4009  *              Create transaction state stack entry for a subtransaction
4010  *
4011  *      The caller has to make sure to always reassign CurrentTransactionState
4012  *      if it has a local pointer to it after calling this function.
4013  */
4014 static void
4015 PushTransaction(void)
4016 {
4017         TransactionState p = CurrentTransactionState;
4018         TransactionState s;
4019
4020         /*
4021          * We keep subtransaction state nodes in TopTransactionContext.
4022          */
4023         s = (TransactionState)
4024                 MemoryContextAllocZero(TopTransactionContext,
4025                                                            sizeof(TransactionStateData));
4026
4027         /*
4028          * Assign a subtransaction ID, watching out for counter wraparound.
4029          */
4030         currentSubTransactionId += 1;
4031         if (currentSubTransactionId == InvalidSubTransactionId)
4032         {
4033                 currentSubTransactionId -= 1;
4034                 pfree(s);
4035                 ereport(ERROR,
4036                                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4037                                  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4038         }
4039
4040         /*
4041          * We can now stack a minimally valid subtransaction without fear of
4042          * failure.
4043          */
4044         s->transactionId = InvalidTransactionId;        /* until assigned */
4045         s->subTransactionId = currentSubTransactionId;
4046         s->parent = p;
4047         s->nestingLevel = p->nestingLevel + 1;
4048         s->gucNestLevel = NewGUCNestLevel();
4049         s->savepointLevel = p->savepointLevel;
4050         s->state = TRANS_DEFAULT;
4051         s->blockState = TBLOCK_SUBBEGIN;
4052         GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt);
4053         s->prevXactReadOnly = XactReadOnly;
4054
4055         CurrentTransactionState = s;
4056
4057         /*
4058          * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4059          * with the subtransaction from here on out; in particular they should not
4060          * assume that it necessarily has a transaction context, resource owner,
4061          * or XID.
4062          */
4063 }
4064
4065 /*
4066  * PopTransaction
4067  *              Pop back to parent transaction state
4068  *
4069  *      The caller has to make sure to always reassign CurrentTransactionState
4070  *      if it has a local pointer to it after calling this function.
4071  */
4072 static void
4073 PopTransaction(void)
4074 {
4075         TransactionState s = CurrentTransactionState;
4076
4077         if (s->state != TRANS_DEFAULT)
4078                 elog(WARNING, "PopTransaction while in %s state",
4079                          TransStateAsString(s->state));
4080
4081         if (s->parent == NULL)
4082                 elog(FATAL, "PopTransaction with no parent");
4083
4084         CurrentTransactionState = s->parent;
4085
4086         /* Let's just make sure CurTransactionContext is good */
4087         CurTransactionContext = s->parent->curTransactionContext;
4088         MemoryContextSwitchTo(CurTransactionContext);
4089
4090         /* Ditto for ResourceOwner links */
4091         CurTransactionResourceOwner = s->parent->curTransactionOwner;
4092         CurrentResourceOwner = s->parent->curTransactionOwner;
4093
4094         /* Free the old child structure */
4095         if (s->name)
4096                 pfree(s->name);
4097         pfree(s);
4098 }
4099
4100 /*
4101  * ShowTransactionState
4102  *              Debug support
4103  */
4104 static void
4105 ShowTransactionState(const char *str)
4106 {
4107         /* skip work if message will definitely not be printed */
4108         if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4109         {
4110                 elog(DEBUG3, "%s", str);
4111                 ShowTransactionStateRec(CurrentTransactionState);
4112         }
4113 }
4114
4115 /*
4116  * ShowTransactionStateRec
4117  *              Recursive subroutine for ShowTransactionState
4118  */
4119 static void
4120 ShowTransactionStateRec(TransactionState s)
4121 {
4122         StringInfoData buf;
4123
4124         initStringInfo(&buf);
4125
4126         if (s->nChildXids > 0)
4127         {
4128                 int i;
4129
4130                 appendStringInfo(&buf, "%u", s->childXids[0]);
4131                 for (i = 1; i < s->nChildXids; i++)
4132                         appendStringInfo(&buf, " %u", s->childXids[i]);
4133         }
4134
4135         if (s->parent)
4136                 ShowTransactionStateRec(s->parent);
4137
4138         /* use ereport to suppress computation if msg will not be printed */
4139         ereport(DEBUG3,
4140                         (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4141                                                          PointerIsValid(s->name) ? s->name : "unnamed",
4142                                                          BlockStateAsString(s->blockState),
4143                                                          TransStateAsString(s->state),
4144                                                          (unsigned int) s->transactionId,
4145                                                          (unsigned int) s->subTransactionId,
4146                                                          (unsigned int) currentCommandId,
4147                                                          currentCommandIdUsed ? " (used)" : "",
4148                                                          s->nestingLevel, buf.data)));
4149
4150         pfree(buf.data);
4151 }
4152
4153 /*
4154  * BlockStateAsString
4155  *              Debug support
4156  */
4157 static const char *
4158 BlockStateAsString(TBlockState blockState)
4159 {
4160         switch (blockState)
4161         {
4162                 case TBLOCK_DEFAULT:
4163                         return "DEFAULT";
4164                 case TBLOCK_STARTED:
4165                         return "STARTED";
4166                 case TBLOCK_BEGIN:
4167                         return "BEGIN";
4168                 case TBLOCK_INPROGRESS:
4169                         return "INPROGRESS";
4170                 case TBLOCK_END:
4171                         return "END";
4172                 case TBLOCK_ABORT:
4173                         return "ABORT";
4174                 case TBLOCK_ABORT_END:
4175                         return "ABORT END";
4176                 case TBLOCK_ABORT_PENDING:
4177                         return "ABORT PEND";
4178                 case TBLOCK_PREPARE:
4179                         return "PREPARE";
4180                 case TBLOCK_SUBBEGIN:
4181                         return "SUB BEGIN";
4182                 case TBLOCK_SUBINPROGRESS:
4183                         return "SUB INPROGRS";
4184                 case TBLOCK_SUBEND:
4185                         return "SUB END";
4186                 case TBLOCK_SUBABORT:
4187                         return "SUB ABORT";
4188                 case TBLOCK_SUBABORT_END:
4189                         return "SUB ABORT END";
4190                 case TBLOCK_SUBABORT_PENDING:
4191                         return "SUB ABRT PEND";
4192                 case TBLOCK_SUBRESTART:
4193                         return "SUB RESTART";
4194                 case TBLOCK_SUBABORT_RESTART:
4195                         return "SUB AB RESTRT";
4196         }
4197         return "UNRECOGNIZED";
4198 }
4199
4200 /*
4201  * TransStateAsString
4202  *              Debug support
4203  */
4204 static const char *
4205 TransStateAsString(TransState state)
4206 {
4207         switch (state)
4208         {
4209                 case TRANS_DEFAULT:
4210                         return "DEFAULT";
4211                 case TRANS_START:
4212                         return "START";
4213                 case TRANS_INPROGRESS:
4214                         return "INPROGR";
4215                 case TRANS_COMMIT:
4216                         return "COMMIT";
4217                 case TRANS_ABORT:
4218                         return "ABORT";
4219                 case TRANS_PREPARE:
4220                         return "PREPARE";
4221         }
4222         return "UNRECOGNIZED";
4223 }
4224
4225 /*
4226  * xactGetCommittedChildren
4227  *
4228  * Gets the list of committed children of the current transaction.      The return
4229  * value is the number of child transactions.  *ptr is set to point to an
4230  * array of TransactionIds.  The array is allocated in TopTransactionContext;
4231  * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4232  * If there are no subxacts, *ptr is set to NULL.
4233  */
4234 int
4235 xactGetCommittedChildren(TransactionId **ptr)
4236 {
4237         TransactionState s = CurrentTransactionState;
4238
4239         if (s->nChildXids == 0)
4240                 *ptr = NULL;
4241         else
4242                 *ptr = s->childXids;
4243
4244         return s->nChildXids;
4245 }
4246
4247 /*
4248  *      XLOG support routines
4249  */
4250
4251 static void
4252 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid)
4253 {
4254         TransactionId *sub_xids;
4255         TransactionId max_xid;
4256         int                     i;
4257
4258         TransactionIdCommit(xid);
4259
4260         /* Mark committed subtransactions as committed */
4261         sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4262         TransactionIdCommitTree(xlrec->nsubxacts, sub_xids);
4263
4264         /* Make sure nextXid is beyond any XID mentioned in the record */
4265         max_xid = xid;
4266         for (i = 0; i < xlrec->nsubxacts; i++)
4267         {
4268                 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4269                         max_xid = sub_xids[i];
4270         }
4271         if (TransactionIdFollowsOrEquals(max_xid,
4272                                                                          ShmemVariableCache->nextXid))
4273         {
4274                 ShmemVariableCache->nextXid = max_xid;
4275                 TransactionIdAdvance(ShmemVariableCache->nextXid);
4276         }
4277
4278         /* Make sure files supposed to be dropped are dropped */
4279         for (i = 0; i < xlrec->nrels; i++)
4280         {
4281                 XLogDropRelation(xlrec->xnodes[i]);
4282                 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4283         }
4284 }
4285
4286 static void
4287 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4288 {
4289         TransactionId *sub_xids;
4290         TransactionId max_xid;
4291         int                     i;
4292
4293         TransactionIdAbort(xid);
4294
4295         /* Mark subtransactions as aborted */
4296         sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4297         TransactionIdAbortTree(xlrec->nsubxacts, sub_xids);
4298
4299         /* Make sure nextXid is beyond any XID mentioned in the record */
4300         max_xid = xid;
4301         for (i = 0; i < xlrec->nsubxacts; i++)
4302         {
4303                 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4304                         max_xid = sub_xids[i];
4305         }
4306         if (TransactionIdFollowsOrEquals(max_xid,
4307                                                                          ShmemVariableCache->nextXid))
4308         {
4309                 ShmemVariableCache->nextXid = max_xid;
4310                 TransactionIdAdvance(ShmemVariableCache->nextXid);
4311         }
4312
4313         /* Make sure files supposed to be dropped are dropped */
4314         for (i = 0; i < xlrec->nrels; i++)
4315         {
4316                 XLogDropRelation(xlrec->xnodes[i]);
4317                 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4318         }
4319 }
4320
4321 void
4322 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4323 {
4324         uint8           info = record->xl_info & ~XLR_INFO_MASK;
4325
4326         if (info == XLOG_XACT_COMMIT)
4327         {
4328                 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4329
4330                 xact_redo_commit(xlrec, record->xl_xid);
4331         }
4332         else if (info == XLOG_XACT_ABORT)
4333         {
4334                 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4335
4336                 xact_redo_abort(xlrec, record->xl_xid);
4337         }
4338         else if (info == XLOG_XACT_PREPARE)
4339         {
4340                 /* the record contents are exactly the 2PC file */
4341                 RecreateTwoPhaseFile(record->xl_xid,
4342                                                          XLogRecGetData(record), record->xl_len);
4343         }
4344         else if (info == XLOG_XACT_COMMIT_PREPARED)
4345         {
4346                 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4347
4348                 xact_redo_commit(&xlrec->crec, xlrec->xid);
4349                 RemoveTwoPhaseFile(xlrec->xid, false);
4350         }
4351         else if (info == XLOG_XACT_ABORT_PREPARED)
4352         {
4353                 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4354
4355                 xact_redo_abort(&xlrec->arec, xlrec->xid);
4356                 RemoveTwoPhaseFile(xlrec->xid, false);
4357         }
4358         else
4359                 elog(PANIC, "xact_redo: unknown op code %u", info);
4360 }
4361
4362 static void
4363 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4364 {
4365         int                     i;
4366
4367         appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4368         if (xlrec->nrels > 0)
4369         {
4370                 appendStringInfo(buf, "; rels:");
4371                 for (i = 0; i < xlrec->nrels; i++)
4372                 {
4373                         RelFileNode rnode = xlrec->xnodes[i];
4374
4375                         appendStringInfo(buf, " %u/%u/%u",
4376                                                          rnode.spcNode, rnode.dbNode, rnode.relNode);
4377                 }
4378         }
4379         if (xlrec->nsubxacts > 0)
4380         {
4381                 TransactionId *xacts = (TransactionId *)
4382                 &xlrec->xnodes[xlrec->nrels];
4383
4384                 appendStringInfo(buf, "; subxacts:");
4385                 for (i = 0; i < xlrec->nsubxacts; i++)
4386                         appendStringInfo(buf, " %u", xacts[i]);
4387         }
4388 }
4389
4390 static void
4391 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4392 {
4393         int                     i;
4394
4395         appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4396         if (xlrec->nrels > 0)
4397         {
4398                 appendStringInfo(buf, "; rels:");
4399                 for (i = 0; i < xlrec->nrels; i++)
4400                 {
4401                         RelFileNode rnode = xlrec->xnodes[i];
4402
4403                         appendStringInfo(buf, " %u/%u/%u",
4404                                                          rnode.spcNode, rnode.dbNode, rnode.relNode);
4405                 }
4406         }
4407         if (xlrec->nsubxacts > 0)
4408         {
4409                 TransactionId *xacts = (TransactionId *)
4410                 &xlrec->xnodes[xlrec->nrels];
4411
4412                 appendStringInfo(buf, "; subxacts:");
4413                 for (i = 0; i < xlrec->nsubxacts; i++)
4414                         appendStringInfo(buf, " %u", xacts[i]);
4415         }
4416 }
4417
4418 void
4419 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4420 {
4421         uint8           info = xl_info & ~XLR_INFO_MASK;
4422
4423         if (info == XLOG_XACT_COMMIT)
4424         {
4425                 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4426
4427                 appendStringInfo(buf, "commit: ");
4428                 xact_desc_commit(buf, xlrec);
4429         }
4430         else if (info == XLOG_XACT_ABORT)
4431         {
4432                 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4433
4434                 appendStringInfo(buf, "abort: ");
4435                 xact_desc_abort(buf, xlrec);
4436         }
4437         else if (info == XLOG_XACT_PREPARE)
4438         {
4439                 appendStringInfo(buf, "prepare");
4440         }
4441         else if (info == XLOG_XACT_COMMIT_PREPARED)
4442         {
4443                 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4444
4445                 appendStringInfo(buf, "commit %u: ", xlrec->xid);
4446                 xact_desc_commit(buf, &xlrec->crec);
4447         }
4448         else if (info == XLOG_XACT_ABORT_PREPARED)
4449         {
4450                 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4451
4452                 appendStringInfo(buf, "abort %u: ", xlrec->xid);
4453                 xact_desc_abort(buf, &xlrec->arec);
4454         }
4455         else
4456                 appendStringInfo(buf, "UNKNOWN");
4457 }