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