OSDN Git Service

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