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