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