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