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