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