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