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