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