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