Header And Logo

PostgreSQL
| The world's most advanced open source database.

xact.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * xact.c
00004  *    top level transaction system support routines
00005  *
00006  * See src/backend/access/transam/README for more information.
00007  *
00008  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00009  * Portions Copyright (c) 1994, Regents of the University of California
00010  *
00011  *
00012  * IDENTIFICATION
00013  *    src/backend/access/transam/xact.c
00014  *
00015  *-------------------------------------------------------------------------
00016  */
00017 
00018 #include "postgres.h"
00019 
00020 #include <time.h>
00021 #include <unistd.h>
00022 
00023 #include "access/multixact.h"
00024 #include "access/subtrans.h"
00025 #include "access/transam.h"
00026 #include "access/twophase.h"
00027 #include "access/xact.h"
00028 #include "access/xlogutils.h"
00029 #include "catalog/catalog.h"
00030 #include "catalog/namespace.h"
00031 #include "catalog/storage.h"
00032 #include "commands/async.h"
00033 #include "commands/tablecmds.h"
00034 #include "commands/trigger.h"
00035 #include "executor/spi.h"
00036 #include "libpq/be-fsstubs.h"
00037 #include "miscadmin.h"
00038 #include "pgstat.h"
00039 #include "replication/walsender.h"
00040 #include "replication/syncrep.h"
00041 #include "storage/fd.h"
00042 #include "storage/lmgr.h"
00043 #include "storage/predicate.h"
00044 #include "storage/proc.h"
00045 #include "storage/procarray.h"
00046 #include "storage/sinvaladt.h"
00047 #include "storage/smgr.h"
00048 #include "utils/catcache.h"
00049 #include "utils/combocid.h"
00050 #include "utils/guc.h"
00051 #include "utils/inval.h"
00052 #include "utils/memutils.h"
00053 #include "utils/relmapper.h"
00054 #include "utils/snapmgr.h"
00055 #include "utils/timestamp.h"
00056 #include "pg_trace.h"
00057 
00058 
00059 /*
00060  *  User-tweakable parameters
00061  */
00062 int         DefaultXactIsoLevel = XACT_READ_COMMITTED;
00063 int         XactIsoLevel;
00064 
00065 bool        DefaultXactReadOnly = false;
00066 bool        XactReadOnly;
00067 
00068 bool        DefaultXactDeferrable = false;
00069 bool        XactDeferrable;
00070 
00071 int         synchronous_commit = SYNCHRONOUS_COMMIT_ON;
00072 
00073 /*
00074  * MyXactAccessedTempRel is set when a temporary relation is accessed.
00075  * We don't allow PREPARE TRANSACTION in that case.  (This is global
00076  * so that it can be set from heapam.c.)
00077  */
00078 bool        MyXactAccessedTempRel = false;
00079 
00080 
00081 /*
00082  *  transaction states - transaction state from server perspective
00083  */
00084 typedef enum TransState
00085 {
00086     TRANS_DEFAULT,              /* idle */
00087     TRANS_START,                /* transaction starting */
00088     TRANS_INPROGRESS,           /* inside a valid transaction */
00089     TRANS_COMMIT,               /* commit in progress */
00090     TRANS_ABORT,                /* abort in progress */
00091     TRANS_PREPARE               /* prepare in progress */
00092 } TransState;
00093 
00094 /*
00095  *  transaction block states - transaction state of client queries
00096  *
00097  * Note: the subtransaction states are used only for non-topmost
00098  * transactions; the others appear only in the topmost transaction.
00099  */
00100 typedef enum TBlockState
00101 {
00102     /* not-in-transaction-block states */
00103     TBLOCK_DEFAULT,             /* idle */
00104     TBLOCK_STARTED,             /* running single-query transaction */
00105 
00106     /* transaction block states */
00107     TBLOCK_BEGIN,               /* starting transaction block */
00108     TBLOCK_INPROGRESS,          /* live transaction */
00109     TBLOCK_END,                 /* COMMIT received */
00110     TBLOCK_ABORT,               /* failed xact, awaiting ROLLBACK */
00111     TBLOCK_ABORT_END,           /* failed xact, ROLLBACK received */
00112     TBLOCK_ABORT_PENDING,       /* live xact, ROLLBACK received */
00113     TBLOCK_PREPARE,             /* live xact, PREPARE received */
00114 
00115     /* subtransaction states */
00116     TBLOCK_SUBBEGIN,            /* starting a subtransaction */
00117     TBLOCK_SUBINPROGRESS,       /* live subtransaction */
00118     TBLOCK_SUBRELEASE,          /* RELEASE received */
00119     TBLOCK_SUBCOMMIT,           /* COMMIT received while TBLOCK_SUBINPROGRESS */
00120     TBLOCK_SUBABORT,            /* failed subxact, awaiting ROLLBACK */
00121     TBLOCK_SUBABORT_END,        /* failed subxact, ROLLBACK received */
00122     TBLOCK_SUBABORT_PENDING,    /* live subxact, ROLLBACK received */
00123     TBLOCK_SUBRESTART,          /* live subxact, ROLLBACK TO received */
00124     TBLOCK_SUBABORT_RESTART     /* failed subxact, ROLLBACK TO received */
00125 } TBlockState;
00126 
00127 /*
00128  *  transaction state structure
00129  */
00130 typedef struct TransactionStateData
00131 {
00132     TransactionId transactionId;    /* my XID, or Invalid if none */
00133     SubTransactionId subTransactionId;  /* my subxact ID */
00134     char       *name;           /* savepoint name, if any */
00135     int         savepointLevel; /* savepoint level */
00136     TransState  state;          /* low-level state */
00137     TBlockState blockState;     /* high-level state */
00138     int         nestingLevel;   /* transaction nesting depth */
00139     int         gucNestLevel;   /* GUC context nesting depth */
00140     MemoryContext curTransactionContext;        /* my xact-lifetime context */
00141     ResourceOwner curTransactionOwner;  /* my query resources */
00142     TransactionId *childXids;   /* subcommitted child XIDs, in XID order */
00143     int         nChildXids;     /* # of subcommitted child XIDs */
00144     int         maxChildXids;   /* allocated size of childXids[] */
00145     Oid         prevUser;       /* previous CurrentUserId setting */
00146     int         prevSecContext; /* previous SecurityRestrictionContext */
00147     bool        prevXactReadOnly;       /* entry-time xact r/o state */
00148     bool        startedInRecovery;      /* did we start in recovery? */
00149     struct TransactionStateData *parent;        /* back link to parent */
00150 } TransactionStateData;
00151 
00152 typedef TransactionStateData *TransactionState;
00153 
00154 /*
00155  * CurrentTransactionState always points to the current transaction state
00156  * block.  It will point to TopTransactionStateData when not in a
00157  * transaction at all, or when in a top-level transaction.
00158  */
00159 static TransactionStateData TopTransactionStateData = {
00160     0,                          /* transaction id */
00161     0,                          /* subtransaction id */
00162     NULL,                       /* savepoint name */
00163     0,                          /* savepoint level */
00164     TRANS_DEFAULT,              /* transaction state */
00165     TBLOCK_DEFAULT,             /* transaction block state from the client
00166                                  * perspective */
00167     0,                          /* transaction nesting depth */
00168     0,                          /* GUC context nesting depth */
00169     NULL,                       /* cur transaction context */
00170     NULL,                       /* cur transaction resource owner */
00171     NULL,                       /* subcommitted child Xids */
00172     0,                          /* # of subcommitted child Xids */
00173     0,                          /* allocated size of childXids[] */
00174     InvalidOid,                 /* previous CurrentUserId setting */
00175     0,                          /* previous SecurityRestrictionContext */
00176     false,                      /* entry-time xact r/o state */
00177     false,                      /* startedInRecovery */
00178     NULL                        /* link to parent state block */
00179 };
00180 
00181 /*
00182  * unreportedXids holds XIDs of all subtransactions that have not yet been
00183  * reported in a XLOG_XACT_ASSIGNMENT record.
00184  */
00185 static int  nUnreportedXids;
00186 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
00187 
00188 static TransactionState CurrentTransactionState = &TopTransactionStateData;
00189 
00190 /*
00191  * The subtransaction ID and command ID assignment counters are global
00192  * to a whole transaction, so we do not keep them in the state stack.
00193  */
00194 static SubTransactionId currentSubTransactionId;
00195 static CommandId currentCommandId;
00196 static bool currentCommandIdUsed;
00197 
00198 /*
00199  * xactStartTimestamp is the value of transaction_timestamp().
00200  * stmtStartTimestamp is the value of statement_timestamp().
00201  * xactStopTimestamp is the time at which we log a commit or abort WAL record.
00202  * These do not change as we enter and exit subtransactions, so we don't
00203  * keep them inside the TransactionState stack.
00204  */
00205 static TimestampTz xactStartTimestamp;
00206 static TimestampTz stmtStartTimestamp;
00207 static TimestampTz xactStopTimestamp;
00208 
00209 /*
00210  * GID to be used for preparing the current transaction.  This is also
00211  * global to a whole transaction, so we don't keep it in the state stack.
00212  */
00213 static char *prepareGID;
00214 
00215 /*
00216  * Some commands want to force synchronous commit.
00217  */
00218 static bool forceSyncCommit = false;
00219 
00220 /*
00221  * Private context for transaction-abort work --- we reserve space for this
00222  * at startup to ensure that AbortTransaction and AbortSubTransaction can work
00223  * when we've run out of memory.
00224  */
00225 static MemoryContext TransactionAbortContext = NULL;
00226 
00227 /*
00228  * List of add-on start- and end-of-xact callbacks
00229  */
00230 typedef struct XactCallbackItem
00231 {
00232     struct XactCallbackItem *next;
00233     XactCallback callback;
00234     void       *arg;
00235 } XactCallbackItem;
00236 
00237 static XactCallbackItem *Xact_callbacks = NULL;
00238 
00239 /*
00240  * List of add-on start- and end-of-subxact callbacks
00241  */
00242 typedef struct SubXactCallbackItem
00243 {
00244     struct SubXactCallbackItem *next;
00245     SubXactCallback callback;
00246     void       *arg;
00247 } SubXactCallbackItem;
00248 
00249 static SubXactCallbackItem *SubXact_callbacks = NULL;
00250 
00251 
00252 /* local function prototypes */
00253 static void AssignTransactionId(TransactionState s);
00254 static void AbortTransaction(void);
00255 static void AtAbort_Memory(void);
00256 static void AtCleanup_Memory(void);
00257 static void AtAbort_ResourceOwner(void);
00258 static void AtCCI_LocalCache(void);
00259 static void AtCommit_Memory(void);
00260 static void AtStart_Cache(void);
00261 static void AtStart_Memory(void);
00262 static void AtStart_ResourceOwner(void);
00263 static void CallXactCallbacks(XactEvent event);
00264 static void CallSubXactCallbacks(SubXactEvent event,
00265                      SubTransactionId mySubid,
00266                      SubTransactionId parentSubid);
00267 static void CleanupTransaction(void);
00268 static void CommitTransaction(void);
00269 static TransactionId RecordTransactionAbort(bool isSubXact);
00270 static void StartTransaction(void);
00271 
00272 static void StartSubTransaction(void);
00273 static void CommitSubTransaction(void);
00274 static void AbortSubTransaction(void);
00275 static void CleanupSubTransaction(void);
00276 static void PushTransaction(void);
00277 static void PopTransaction(void);
00278 
00279 static void AtSubAbort_Memory(void);
00280 static void AtSubCleanup_Memory(void);
00281 static void AtSubAbort_ResourceOwner(void);
00282 static void AtSubCommit_Memory(void);
00283 static void AtSubStart_Memory(void);
00284 static void AtSubStart_ResourceOwner(void);
00285 
00286 static void ShowTransactionState(const char *str);
00287 static void ShowTransactionStateRec(TransactionState state);
00288 static const char *BlockStateAsString(TBlockState blockState);
00289 static const char *TransStateAsString(TransState state);
00290 
00291 
00292 /* ----------------------------------------------------------------
00293  *  transaction state accessors
00294  * ----------------------------------------------------------------
00295  */
00296 
00297 /*
00298  *  IsTransactionState
00299  *
00300  *  This returns true if we are inside a valid transaction; that is,
00301  *  it is safe to initiate database access, take heavyweight locks, etc.
00302  */
00303 bool
00304 IsTransactionState(void)
00305 {
00306     TransactionState s = CurrentTransactionState;
00307 
00308     /*
00309      * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states.  However, we
00310      * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
00311      * TRANS_PREPARE since it might be too soon or too late within those
00312      * transition states to do anything interesting.  Hence, the only "valid"
00313      * state is TRANS_INPROGRESS.
00314      */
00315     return (s->state == TRANS_INPROGRESS);
00316 }
00317 
00318 /*
00319  *  IsAbortedTransactionBlockState
00320  *
00321  *  This returns true if we are within an aborted transaction block.
00322  */
00323 bool
00324 IsAbortedTransactionBlockState(void)
00325 {
00326     TransactionState s = CurrentTransactionState;
00327 
00328     if (s->blockState == TBLOCK_ABORT ||
00329         s->blockState == TBLOCK_SUBABORT)
00330         return true;
00331 
00332     return false;
00333 }
00334 
00335 
00336 /*
00337  *  GetTopTransactionId
00338  *
00339  * This will return the XID of the main transaction, assigning one if
00340  * it's not yet set.  Be careful to call this only inside a valid xact.
00341  */
00342 TransactionId
00343 GetTopTransactionId(void)
00344 {
00345     if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
00346         AssignTransactionId(&TopTransactionStateData);
00347     return TopTransactionStateData.transactionId;
00348 }
00349 
00350 /*
00351  *  GetTopTransactionIdIfAny
00352  *
00353  * This will return the XID of the main transaction, if one is assigned.
00354  * It will return InvalidTransactionId if we are not currently inside a
00355  * transaction, or inside a transaction that hasn't yet been assigned an XID.
00356  */
00357 TransactionId
00358 GetTopTransactionIdIfAny(void)
00359 {
00360     return TopTransactionStateData.transactionId;
00361 }
00362 
00363 /*
00364  *  GetCurrentTransactionId
00365  *
00366  * This will return the XID of the current transaction (main or sub
00367  * transaction), assigning one if it's not yet set.  Be careful to call this
00368  * only inside a valid xact.
00369  */
00370 TransactionId
00371 GetCurrentTransactionId(void)
00372 {
00373     TransactionState s = CurrentTransactionState;
00374 
00375     if (!TransactionIdIsValid(s->transactionId))
00376         AssignTransactionId(s);
00377     return s->transactionId;
00378 }
00379 
00380 /*
00381  *  GetCurrentTransactionIdIfAny
00382  *
00383  * This will return the XID of the current sub xact, if one is assigned.
00384  * It will return InvalidTransactionId if we are not currently inside a
00385  * transaction, or inside a transaction that hasn't been assigned an XID yet.
00386  */
00387 TransactionId
00388 GetCurrentTransactionIdIfAny(void)
00389 {
00390     return CurrentTransactionState->transactionId;
00391 }
00392 
00393 /*
00394  *  GetStableLatestTransactionId
00395  *
00396  * Get the transaction's XID if it has one, else read the next-to-be-assigned
00397  * XID.  Once we have a value, return that same value for the remainder of the
00398  * current transaction.  This is meant to provide the reference point for the
00399  * age(xid) function, but might be useful for other maintenance tasks as well.
00400  */
00401 TransactionId
00402 GetStableLatestTransactionId(void)
00403 {
00404     static LocalTransactionId lxid = InvalidLocalTransactionId;
00405     static TransactionId stablexid = InvalidTransactionId;
00406 
00407     if (lxid != MyProc->lxid)
00408     {
00409         lxid = MyProc->lxid;
00410         stablexid = GetTopTransactionIdIfAny();
00411         if (!TransactionIdIsValid(stablexid))
00412             stablexid = ReadNewTransactionId();
00413     }
00414 
00415     Assert(TransactionIdIsValid(stablexid));
00416 
00417     return stablexid;
00418 }
00419 
00420 /*
00421  * AssignTransactionId
00422  *
00423  * Assigns a new permanent XID to the given TransactionState.
00424  * We do not assign XIDs to transactions until/unless this is called.
00425  * Also, any parent TransactionStates that don't yet have XIDs are assigned
00426  * one; this maintains the invariant that a child transaction has an XID
00427  * following its parent's.
00428  */
00429 static void
00430 AssignTransactionId(TransactionState s)
00431 {
00432     bool        isSubXact = (s->parent != NULL);
00433     ResourceOwner currentOwner;
00434 
00435     /* Assert that caller didn't screw up */
00436     Assert(!TransactionIdIsValid(s->transactionId));
00437     Assert(s->state == TRANS_INPROGRESS);
00438 
00439     /*
00440      * Ensure parent(s) have XIDs, so that a child always has an XID later
00441      * than its parent.  Musn't recurse here, or we might get a stack overflow
00442      * if we're at the bottom of a huge stack of subtransactions none of which
00443      * have XIDs yet.
00444      */
00445     if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
00446     {
00447         TransactionState p = s->parent;
00448         TransactionState *parents;
00449         size_t      parentOffset = 0;
00450 
00451         parents = palloc(sizeof(TransactionState) * s->nestingLevel);
00452         while (p != NULL && !TransactionIdIsValid(p->transactionId))
00453         {
00454             parents[parentOffset++] = p;
00455             p = p->parent;
00456         }
00457 
00458         /*
00459          * This is technically a recursive call, but the recursion will never
00460          * be more than one layer deep.
00461          */
00462         while (parentOffset != 0)
00463             AssignTransactionId(parents[--parentOffset]);
00464 
00465         pfree(parents);
00466     }
00467 
00468     /*
00469      * Generate a new Xid and record it in PG_PROC and pg_subtrans.
00470      *
00471      * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
00472      * shared storage other than PG_PROC; because if there's no room for it in
00473      * PG_PROC, the subtrans entry is needed to ensure that other backends see
00474      * the Xid as "running".  See GetNewTransactionId.
00475      */
00476     s->transactionId = GetNewTransactionId(isSubXact);
00477 
00478     if (isSubXact)
00479         SubTransSetParent(s->transactionId, s->parent->transactionId, false);
00480 
00481     /*
00482      * If it's a top-level transaction, the predicate locking system needs to
00483      * be told about it too.
00484      */
00485     if (!isSubXact)
00486         RegisterPredicateLockingXid(s->transactionId);
00487 
00488     /*
00489      * Acquire lock on the transaction XID.  (We assume this cannot block.) We
00490      * have to ensure that the lock is assigned to the transaction's own
00491      * ResourceOwner.
00492      */
00493     currentOwner = CurrentResourceOwner;
00494     PG_TRY();
00495     {
00496         CurrentResourceOwner = s->curTransactionOwner;
00497         XactLockTableInsert(s->transactionId);
00498     }
00499     PG_CATCH();
00500     {
00501         /* Ensure CurrentResourceOwner is restored on error */
00502         CurrentResourceOwner = currentOwner;
00503         PG_RE_THROW();
00504     }
00505     PG_END_TRY();
00506     CurrentResourceOwner = currentOwner;
00507 
00508     /*
00509      * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
00510      * top-level transaction we issue a WAL record for the assignment. We
00511      * include the top-level xid and all the subxids that have not yet been
00512      * reported using XLOG_XACT_ASSIGNMENT records.
00513      *
00514      * This is required to limit the amount of shared memory required in a hot
00515      * standby server to keep track of in-progress XIDs. See notes for
00516      * RecordKnownAssignedTransactionIds().
00517      *
00518      * We don't keep track of the immediate parent of each subxid, only the
00519      * top-level transaction that each subxact belongs to. This is correct in
00520      * recovery only because aborted subtransactions are separately WAL
00521      * logged.
00522      */
00523     if (isSubXact && XLogStandbyInfoActive())
00524     {
00525         unreportedXids[nUnreportedXids] = s->transactionId;
00526         nUnreportedXids++;
00527 
00528         /*
00529          * ensure this test matches similar one in
00530          * RecoverPreparedTransactions()
00531          */
00532         if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
00533         {
00534             XLogRecData rdata[2];
00535             xl_xact_assignment xlrec;
00536 
00537             /*
00538              * xtop is always set by now because we recurse up transaction
00539              * stack to the highest unassigned xid and then come back down
00540              */
00541             xlrec.xtop = GetTopTransactionId();
00542             Assert(TransactionIdIsValid(xlrec.xtop));
00543             xlrec.nsubxacts = nUnreportedXids;
00544 
00545             rdata[0].data = (char *) &xlrec;
00546             rdata[0].len = MinSizeOfXactAssignment;
00547             rdata[0].buffer = InvalidBuffer;
00548             rdata[0].next = &rdata[1];
00549 
00550             rdata[1].data = (char *) unreportedXids;
00551             rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
00552             rdata[1].buffer = InvalidBuffer;
00553             rdata[1].next = NULL;
00554 
00555             (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
00556 
00557             nUnreportedXids = 0;
00558         }
00559     }
00560 }
00561 
00562 /*
00563  *  GetCurrentSubTransactionId
00564  */
00565 SubTransactionId
00566 GetCurrentSubTransactionId(void)
00567 {
00568     TransactionState s = CurrentTransactionState;
00569 
00570     return s->subTransactionId;
00571 }
00572 
00573 /*
00574  *  SubTransactionIsActive
00575  *
00576  * Test if the specified subxact ID is still active.  Note caller is
00577  * responsible for checking whether this ID is relevant to the current xact.
00578  */
00579 bool
00580 SubTransactionIsActive(SubTransactionId subxid)
00581 {
00582     TransactionState s;
00583 
00584     for (s = CurrentTransactionState; s != NULL; s = s->parent)
00585     {
00586         if (s->state == TRANS_ABORT)
00587             continue;
00588         if (s->subTransactionId == subxid)
00589             return true;
00590     }
00591     return false;
00592 }
00593 
00594 
00595 /*
00596  *  GetCurrentCommandId
00597  *
00598  * "used" must be TRUE if the caller intends to use the command ID to mark
00599  * inserted/updated/deleted tuples.  FALSE means the ID is being fetched
00600  * for read-only purposes (ie, as a snapshot validity cutoff).  See
00601  * CommandCounterIncrement() for discussion.
00602  */
00603 CommandId
00604 GetCurrentCommandId(bool used)
00605 {
00606     /* this is global to a transaction, not subtransaction-local */
00607     if (used)
00608         currentCommandIdUsed = true;
00609     return currentCommandId;
00610 }
00611 
00612 /*
00613  *  GetCurrentTransactionStartTimestamp
00614  */
00615 TimestampTz
00616 GetCurrentTransactionStartTimestamp(void)
00617 {
00618     return xactStartTimestamp;
00619 }
00620 
00621 /*
00622  *  GetCurrentStatementStartTimestamp
00623  */
00624 TimestampTz
00625 GetCurrentStatementStartTimestamp(void)
00626 {
00627     return stmtStartTimestamp;
00628 }
00629 
00630 /*
00631  *  GetCurrentTransactionStopTimestamp
00632  *
00633  * We return current time if the transaction stop time hasn't been set
00634  * (which can happen if we decide we don't need to log an XLOG record).
00635  */
00636 TimestampTz
00637 GetCurrentTransactionStopTimestamp(void)
00638 {
00639     if (xactStopTimestamp != 0)
00640         return xactStopTimestamp;
00641     return GetCurrentTimestamp();
00642 }
00643 
00644 /*
00645  *  SetCurrentStatementStartTimestamp
00646  */
00647 void
00648 SetCurrentStatementStartTimestamp(void)
00649 {
00650     stmtStartTimestamp = GetCurrentTimestamp();
00651 }
00652 
00653 /*
00654  *  SetCurrentTransactionStopTimestamp
00655  */
00656 static inline void
00657 SetCurrentTransactionStopTimestamp(void)
00658 {
00659     xactStopTimestamp = GetCurrentTimestamp();
00660 }
00661 
00662 /*
00663  *  GetCurrentTransactionNestLevel
00664  *
00665  * Note: this will return zero when not inside any transaction, one when
00666  * inside a top-level transaction, etc.
00667  */
00668 int
00669 GetCurrentTransactionNestLevel(void)
00670 {
00671     TransactionState s = CurrentTransactionState;
00672 
00673     return s->nestingLevel;
00674 }
00675 
00676 
00677 /*
00678  *  TransactionIdIsCurrentTransactionId
00679  */
00680 bool
00681 TransactionIdIsCurrentTransactionId(TransactionId xid)
00682 {
00683     TransactionState s;
00684 
00685     /*
00686      * We always say that BootstrapTransactionId is "not my transaction ID"
00687      * even when it is (ie, during bootstrap).  Along with the fact that
00688      * transam.c always treats BootstrapTransactionId as already committed,
00689      * this causes the tqual.c routines to see all tuples as committed, which
00690      * is what we need during bootstrap.  (Bootstrap mode only inserts tuples,
00691      * it never updates or deletes them, so all tuples can be presumed good
00692      * immediately.)
00693      *
00694      * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
00695      * not my transaction ID, so we can just return "false" immediately for
00696      * any non-normal XID.
00697      */
00698     if (!TransactionIdIsNormal(xid))
00699         return false;
00700 
00701     /*
00702      * We will return true for the Xid of the current subtransaction, any of
00703      * its subcommitted children, any of its parents, or any of their
00704      * previously subcommitted children.  However, a transaction being aborted
00705      * is no longer "current", even though it may still have an entry on the
00706      * state stack.
00707      */
00708     for (s = CurrentTransactionState; s != NULL; s = s->parent)
00709     {
00710         int         low,
00711                     high;
00712 
00713         if (s->state == TRANS_ABORT)
00714             continue;
00715         if (!TransactionIdIsValid(s->transactionId))
00716             continue;           /* it can't have any child XIDs either */
00717         if (TransactionIdEquals(xid, s->transactionId))
00718             return true;
00719         /* As the childXids array is ordered, we can use binary search */
00720         low = 0;
00721         high = s->nChildXids - 1;
00722         while (low <= high)
00723         {
00724             int         middle;
00725             TransactionId probe;
00726 
00727             middle = low + (high - low) / 2;
00728             probe = s->childXids[middle];
00729             if (TransactionIdEquals(probe, xid))
00730                 return true;
00731             else if (TransactionIdPrecedes(probe, xid))
00732                 low = middle + 1;
00733             else
00734                 high = middle - 1;
00735         }
00736     }
00737 
00738     return false;
00739 }
00740 
00741 /*
00742  *  TransactionStartedDuringRecovery
00743  *
00744  * Returns true if the current transaction started while recovery was still
00745  * in progress. Recovery might have ended since so RecoveryInProgress() might
00746  * return false already.
00747  */
00748 bool
00749 TransactionStartedDuringRecovery(void)
00750 {
00751     return CurrentTransactionState->startedInRecovery;
00752 }
00753 
00754 /*
00755  *  CommandCounterIncrement
00756  */
00757 void
00758 CommandCounterIncrement(void)
00759 {
00760     /*
00761      * If the current value of the command counter hasn't been "used" to mark
00762      * tuples, we need not increment it, since there's no need to distinguish
00763      * a read-only command from others.  This helps postpone command counter
00764      * overflow, and keeps no-op CommandCounterIncrement operations cheap.
00765      */
00766     if (currentCommandIdUsed)
00767     {
00768         currentCommandId += 1;
00769         if (currentCommandId == FirstCommandId) /* check for overflow */
00770         {
00771             currentCommandId -= 1;
00772             ereport(ERROR,
00773                     (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00774                      errmsg("cannot have more than 2^32-1 commands in a transaction")));
00775         }
00776         currentCommandIdUsed = false;
00777 
00778         /* Propagate new command ID into static snapshots */
00779         SnapshotSetCommandId(currentCommandId);
00780 
00781         /*
00782          * Make any catalog changes done by the just-completed command visible
00783          * in the local syscache.  We obviously don't need to do this after a
00784          * read-only command.  (But see hacks in inval.c to make real sure we
00785          * don't think a command that queued inval messages was read-only.)
00786          */
00787         AtCCI_LocalCache();
00788     }
00789 }
00790 
00791 /*
00792  * ForceSyncCommit
00793  *
00794  * Interface routine to allow commands to force a synchronous commit of the
00795  * current top-level transaction
00796  */
00797 void
00798 ForceSyncCommit(void)
00799 {
00800     forceSyncCommit = true;
00801 }
00802 
00803 
00804 /* ----------------------------------------------------------------
00805  *                      StartTransaction stuff
00806  * ----------------------------------------------------------------
00807  */
00808 
00809 /*
00810  *  AtStart_Cache
00811  */
00812 static void
00813 AtStart_Cache(void)
00814 {
00815     AcceptInvalidationMessages();
00816 }
00817 
00818 /*
00819  *  AtStart_Memory
00820  */
00821 static void
00822 AtStart_Memory(void)
00823 {
00824     TransactionState s = CurrentTransactionState;
00825 
00826     /*
00827      * If this is the first time through, create a private context for
00828      * AbortTransaction to work in.  By reserving some space now, we can
00829      * insulate AbortTransaction from out-of-memory scenarios.  Like
00830      * ErrorContext, we set it up with slow growth rate and a nonzero minimum
00831      * size, so that space will be reserved immediately.
00832      */
00833     if (TransactionAbortContext == NULL)
00834         TransactionAbortContext =
00835             AllocSetContextCreate(TopMemoryContext,
00836                                   "TransactionAbortContext",
00837                                   32 * 1024,
00838                                   32 * 1024,
00839                                   32 * 1024);
00840 
00841     /*
00842      * We shouldn't have a transaction context already.
00843      */
00844     Assert(TopTransactionContext == NULL);
00845 
00846     /*
00847      * Create a toplevel context for the transaction.
00848      */
00849     TopTransactionContext =
00850         AllocSetContextCreate(TopMemoryContext,
00851                               "TopTransactionContext",
00852                               ALLOCSET_DEFAULT_MINSIZE,
00853                               ALLOCSET_DEFAULT_INITSIZE,
00854                               ALLOCSET_DEFAULT_MAXSIZE);
00855 
00856     /*
00857      * In a top-level transaction, CurTransactionContext is the same as
00858      * TopTransactionContext.
00859      */
00860     CurTransactionContext = TopTransactionContext;
00861     s->curTransactionContext = CurTransactionContext;
00862 
00863     /* Make the CurTransactionContext active. */
00864     MemoryContextSwitchTo(CurTransactionContext);
00865 }
00866 
00867 /*
00868  *  AtStart_ResourceOwner
00869  */
00870 static void
00871 AtStart_ResourceOwner(void)
00872 {
00873     TransactionState s = CurrentTransactionState;
00874 
00875     /*
00876      * We shouldn't have a transaction resource owner already.
00877      */
00878     Assert(TopTransactionResourceOwner == NULL);
00879 
00880     /*
00881      * Create a toplevel resource owner for the transaction.
00882      */
00883     s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
00884 
00885     TopTransactionResourceOwner = s->curTransactionOwner;
00886     CurTransactionResourceOwner = s->curTransactionOwner;
00887     CurrentResourceOwner = s->curTransactionOwner;
00888 }
00889 
00890 /* ----------------------------------------------------------------
00891  *                      StartSubTransaction stuff
00892  * ----------------------------------------------------------------
00893  */
00894 
00895 /*
00896  * AtSubStart_Memory
00897  */
00898 static void
00899 AtSubStart_Memory(void)
00900 {
00901     TransactionState s = CurrentTransactionState;
00902 
00903     Assert(CurTransactionContext != NULL);
00904 
00905     /*
00906      * Create a CurTransactionContext, which will be used to hold data that
00907      * survives subtransaction commit but disappears on subtransaction abort.
00908      * We make it a child of the immediate parent's CurTransactionContext.
00909      */
00910     CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
00911                                                   "CurTransactionContext",
00912                                                   ALLOCSET_DEFAULT_MINSIZE,
00913                                                   ALLOCSET_DEFAULT_INITSIZE,
00914                                                   ALLOCSET_DEFAULT_MAXSIZE);
00915     s->curTransactionContext = CurTransactionContext;
00916 
00917     /* Make the CurTransactionContext active. */
00918     MemoryContextSwitchTo(CurTransactionContext);
00919 }
00920 
00921 /*
00922  * AtSubStart_ResourceOwner
00923  */
00924 static void
00925 AtSubStart_ResourceOwner(void)
00926 {
00927     TransactionState s = CurrentTransactionState;
00928 
00929     Assert(s->parent != NULL);
00930 
00931     /*
00932      * Create a resource owner for the subtransaction.  We make it a child of
00933      * the immediate parent's resource owner.
00934      */
00935     s->curTransactionOwner =
00936         ResourceOwnerCreate(s->parent->curTransactionOwner,
00937                             "SubTransaction");
00938 
00939     CurTransactionResourceOwner = s->curTransactionOwner;
00940     CurrentResourceOwner = s->curTransactionOwner;
00941 }
00942 
00943 /* ----------------------------------------------------------------
00944  *                      CommitTransaction stuff
00945  * ----------------------------------------------------------------
00946  */
00947 
00948 /*
00949  *  RecordTransactionCommit
00950  *
00951  * Returns latest XID among xact and its children, or InvalidTransactionId
00952  * if the xact has no XID.  (We compute that here just because it's easier.)
00953  */
00954 static TransactionId
00955 RecordTransactionCommit(void)
00956 {
00957     TransactionId xid = GetTopTransactionIdIfAny();
00958     bool        markXidCommitted = TransactionIdIsValid(xid);
00959     TransactionId latestXid = InvalidTransactionId;
00960     int         nrels;
00961     RelFileNode *rels;
00962     int         nchildren;
00963     TransactionId *children;
00964     int         nmsgs = 0;
00965     SharedInvalidationMessage *invalMessages = NULL;
00966     bool        RelcacheInitFileInval = false;
00967     bool        wrote_xlog;
00968 
00969     /* Get data needed for commit record */
00970     nrels = smgrGetPendingDeletes(true, &rels);
00971     nchildren = xactGetCommittedChildren(&children);
00972     if (XLogStandbyInfoActive())
00973         nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
00974                                                      &RelcacheInitFileInval);
00975     wrote_xlog = (XactLastRecEnd != 0);
00976 
00977     /*
00978      * If we haven't been assigned an XID yet, we neither can, nor do we want
00979      * to write a COMMIT record.
00980      */
00981     if (!markXidCommitted)
00982     {
00983         /*
00984          * We expect that every smgrscheduleunlink is followed by a catalog
00985          * update, and hence XID assignment, so we shouldn't get here with any
00986          * pending deletes.  Use a real test not just an Assert to check this,
00987          * since it's a bit fragile.
00988          */
00989         if (nrels != 0)
00990             elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
00991 
00992         /* Can't have child XIDs either; AssignTransactionId enforces this */
00993         Assert(nchildren == 0);
00994 
00995         /*
00996          * If we didn't create XLOG entries, we're done here; otherwise we
00997          * should flush those entries the same as a commit record.  (An
00998          * example of a possible record that wouldn't cause an XID to be
00999          * assigned is a sequence advance record due to nextval() --- we want
01000          * to flush that to disk before reporting commit.)
01001          */
01002         if (!wrote_xlog)
01003             goto cleanup;
01004     }
01005     else
01006     {
01007         /*
01008          * Begin commit critical section and insert the commit XLOG record.
01009          */
01010         /* Tell bufmgr and smgr to prepare for commit */
01011         BufmgrCommit();
01012 
01013         /*
01014          * Mark ourselves as within our "commit critical section".  This
01015          * forces any concurrent checkpoint to wait until we've updated
01016          * pg_clog.  Without this, it is possible for the checkpoint to set
01017          * REDO after the XLOG record but fail to flush the pg_clog update to
01018          * disk, leading to loss of the transaction commit if the system
01019          * crashes a little later.
01020          *
01021          * Note: we could, but don't bother to, set this flag in
01022          * RecordTransactionAbort.  That's because loss of a transaction abort
01023          * is noncritical; the presumption would be that it aborted, anyway.
01024          *
01025          * It's safe to change the delayChkpt flag of our own backend without
01026          * holding the ProcArrayLock, since we're the only one modifying it.
01027          * This makes checkpoint's determination of which xacts are delayChkpt a
01028          * bit fuzzy, but it doesn't matter.
01029          */
01030         START_CRIT_SECTION();
01031         MyPgXact->delayChkpt = true;
01032 
01033         SetCurrentTransactionStopTimestamp();
01034 
01035         /*
01036          * Do we need the long commit record? If not, use the compact format.
01037          */
01038         if (nrels > 0 || nmsgs > 0 || RelcacheInitFileInval || forceSyncCommit)
01039         {
01040             XLogRecData rdata[4];
01041             int         lastrdata = 0;
01042             xl_xact_commit xlrec;
01043 
01044             /*
01045              * Set flags required for recovery processing of commits.
01046              */
01047             xlrec.xinfo = 0;
01048             if (RelcacheInitFileInval)
01049                 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
01050             if (forceSyncCommit)
01051                 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
01052 
01053             xlrec.dbId = MyDatabaseId;
01054             xlrec.tsId = MyDatabaseTableSpace;
01055 
01056             xlrec.xact_time = xactStopTimestamp;
01057             xlrec.nrels = nrels;
01058             xlrec.nsubxacts = nchildren;
01059             xlrec.nmsgs = nmsgs;
01060             rdata[0].data = (char *) (&xlrec);
01061             rdata[0].len = MinSizeOfXactCommit;
01062             rdata[0].buffer = InvalidBuffer;
01063             /* dump rels to delete */
01064             if (nrels > 0)
01065             {
01066                 rdata[0].next = &(rdata[1]);
01067                 rdata[1].data = (char *) rels;
01068                 rdata[1].len = nrels * sizeof(RelFileNode);
01069                 rdata[1].buffer = InvalidBuffer;
01070                 lastrdata = 1;
01071             }
01072             /* dump committed child Xids */
01073             if (nchildren > 0)
01074             {
01075                 rdata[lastrdata].next = &(rdata[2]);
01076                 rdata[2].data = (char *) children;
01077                 rdata[2].len = nchildren * sizeof(TransactionId);
01078                 rdata[2].buffer = InvalidBuffer;
01079                 lastrdata = 2;
01080             }
01081             /* dump shared cache invalidation messages */
01082             if (nmsgs > 0)
01083             {
01084                 rdata[lastrdata].next = &(rdata[3]);
01085                 rdata[3].data = (char *) invalMessages;
01086                 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
01087                 rdata[3].buffer = InvalidBuffer;
01088                 lastrdata = 3;
01089             }
01090             rdata[lastrdata].next = NULL;
01091 
01092             (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
01093         }
01094         else
01095         {
01096             XLogRecData rdata[2];
01097             int         lastrdata = 0;
01098             xl_xact_commit_compact xlrec;
01099 
01100             xlrec.xact_time = xactStopTimestamp;
01101             xlrec.nsubxacts = nchildren;
01102             rdata[0].data = (char *) (&xlrec);
01103             rdata[0].len = MinSizeOfXactCommitCompact;
01104             rdata[0].buffer = InvalidBuffer;
01105             /* dump committed child Xids */
01106             if (nchildren > 0)
01107             {
01108                 rdata[0].next = &(rdata[1]);
01109                 rdata[1].data = (char *) children;
01110                 rdata[1].len = nchildren * sizeof(TransactionId);
01111                 rdata[1].buffer = InvalidBuffer;
01112                 lastrdata = 1;
01113             }
01114             rdata[lastrdata].next = NULL;
01115 
01116             (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT_COMPACT, rdata);
01117         }
01118     }
01119 
01120     /*
01121      * Check if we want to commit asynchronously.  We can allow the XLOG flush
01122      * to happen asynchronously if synchronous_commit=off, or if the current
01123      * transaction has not performed any WAL-logged operation.  The latter
01124      * case can arise if the current transaction wrote only to temporary
01125      * and/or unlogged tables.  In case of a crash, the loss of such a
01126      * transaction will be irrelevant since temp tables will be lost anyway,
01127      * and unlogged tables will be truncated.  (Given the foregoing, you might
01128      * think that it would be unnecessary to emit the XLOG record at all in
01129      * this case, but we don't currently try to do that.  It would certainly
01130      * cause problems at least in Hot Standby mode, where the
01131      * KnownAssignedXids machinery requires tracking every XID assignment.  It
01132      * might be OK to skip it only when wal_level < hot_standby, but for now
01133      * we don't.)
01134      *
01135      * However, if we're doing cleanup of any non-temp rels or committing any
01136      * command that wanted to force sync commit, then we must flush XLOG
01137      * immediately.  (We must not allow asynchronous commit if there are any
01138      * non-temp tables to be deleted, because we might delete the files before
01139      * the COMMIT record is flushed to disk.  We do allow asynchronous commit
01140      * if all to-be-deleted tables are temporary though, since they are lost
01141      * anyway if we crash.)
01142      */
01143     if ((wrote_xlog && synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
01144         forceSyncCommit || nrels > 0)
01145     {
01146         XLogFlush(XactLastRecEnd);
01147 
01148         /*
01149          * Now we may update the CLOG, if we wrote a COMMIT record above
01150          */
01151         if (markXidCommitted)
01152             TransactionIdCommitTree(xid, nchildren, children);
01153     }
01154     else
01155     {
01156         /*
01157          * Asynchronous commit case:
01158          *
01159          * This enables possible committed transaction loss in the case of a
01160          * postmaster crash because WAL buffers are left unwritten. Ideally we
01161          * could issue the WAL write without the fsync, but some
01162          * wal_sync_methods do not allow separate write/fsync.
01163          *
01164          * Report the latest async commit LSN, so that the WAL writer knows to
01165          * flush this commit.
01166          */
01167         XLogSetAsyncXactLSN(XactLastRecEnd);
01168 
01169         /*
01170          * We must not immediately update the CLOG, since we didn't flush the
01171          * XLOG. Instead, we store the LSN up to which the XLOG must be
01172          * flushed before the CLOG may be updated.
01173          */
01174         if (markXidCommitted)
01175             TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
01176     }
01177 
01178     /*
01179      * If we entered a commit critical section, leave it now, and let
01180      * checkpoints proceed.
01181      */
01182     if (markXidCommitted)
01183     {
01184         MyPgXact->delayChkpt = false;
01185         END_CRIT_SECTION();
01186     }
01187 
01188     /* Compute latestXid while we have the child XIDs handy */
01189     latestXid = TransactionIdLatest(xid, nchildren, children);
01190 
01191     /*
01192      * Wait for synchronous replication, if required.
01193      *
01194      * Note that at this stage we have marked clog, but still show as running
01195      * in the procarray and continue to hold locks.
01196      */
01197     if (wrote_xlog)
01198         SyncRepWaitForLSN(XactLastRecEnd);
01199 
01200     /* Reset XactLastRecEnd until the next transaction writes something */
01201     XactLastRecEnd = 0;
01202 
01203 cleanup:
01204     /* Clean up local data */
01205     if (rels)
01206         pfree(rels);
01207 
01208     return latestXid;
01209 }
01210 
01211 
01212 /*
01213  *  AtCCI_LocalCache
01214  */
01215 static void
01216 AtCCI_LocalCache(void)
01217 {
01218     /*
01219      * Make any pending relation map changes visible.  We must do this before
01220      * processing local sinval messages, so that the map changes will get
01221      * reflected into the relcache when relcache invals are processed.
01222      */
01223     AtCCI_RelationMap();
01224 
01225     /*
01226      * Make catalog changes visible to me for the next command.
01227      */
01228     CommandEndInvalidationMessages();
01229 }
01230 
01231 /*
01232  *  AtCommit_Memory
01233  */
01234 static void
01235 AtCommit_Memory(void)
01236 {
01237     /*
01238      * Now that we're "out" of a transaction, have the system allocate things
01239      * in the top memory context instead of per-transaction contexts.
01240      */
01241     MemoryContextSwitchTo(TopMemoryContext);
01242 
01243     /*
01244      * Release all transaction-local memory.
01245      */
01246     Assert(TopTransactionContext != NULL);
01247     MemoryContextDelete(TopTransactionContext);
01248     TopTransactionContext = NULL;
01249     CurTransactionContext = NULL;
01250     CurrentTransactionState->curTransactionContext = NULL;
01251 }
01252 
01253 /* ----------------------------------------------------------------
01254  *                      CommitSubTransaction stuff
01255  * ----------------------------------------------------------------
01256  */
01257 
01258 /*
01259  * AtSubCommit_Memory
01260  */
01261 static void
01262 AtSubCommit_Memory(void)
01263 {
01264     TransactionState s = CurrentTransactionState;
01265 
01266     Assert(s->parent != NULL);
01267 
01268     /* Return to parent transaction level's memory context. */
01269     CurTransactionContext = s->parent->curTransactionContext;
01270     MemoryContextSwitchTo(CurTransactionContext);
01271 
01272     /*
01273      * Ordinarily we cannot throw away the child's CurTransactionContext,
01274      * since the data it contains will be needed at upper commit.  However, if
01275      * there isn't actually anything in it, we can throw it away.  This avoids
01276      * a small memory leak in the common case of "trivial" subxacts.
01277      */
01278     if (MemoryContextIsEmpty(s->curTransactionContext))
01279     {
01280         MemoryContextDelete(s->curTransactionContext);
01281         s->curTransactionContext = NULL;
01282     }
01283 }
01284 
01285 /*
01286  * AtSubCommit_childXids
01287  *
01288  * Pass my own XID and my child XIDs up to my parent as committed children.
01289  */
01290 static void
01291 AtSubCommit_childXids(void)
01292 {
01293     TransactionState s = CurrentTransactionState;
01294     int         new_nChildXids;
01295 
01296     Assert(s->parent != NULL);
01297 
01298     /*
01299      * The parent childXids array will need to hold my XID and all my
01300      * childXids, in addition to the XIDs already there.
01301      */
01302     new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
01303 
01304     /* Allocate or enlarge the parent array if necessary */
01305     if (s->parent->maxChildXids < new_nChildXids)
01306     {
01307         int         new_maxChildXids;
01308         TransactionId *new_childXids;
01309 
01310         /*
01311          * Make it 2x what's needed right now, to avoid having to enlarge it
01312          * repeatedly. But we can't go above MaxAllocSize.  (The latter limit
01313          * is what ensures that we don't need to worry about integer overflow
01314          * here or in the calculation of new_nChildXids.)
01315          */
01316         new_maxChildXids = Min(new_nChildXids * 2,
01317                                (int) (MaxAllocSize / sizeof(TransactionId)));
01318 
01319         if (new_maxChildXids < new_nChildXids)
01320             ereport(ERROR,
01321                     (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
01322                      errmsg("maximum number of committed subtransactions (%d) exceeded",
01323                             (int) (MaxAllocSize / sizeof(TransactionId)))));
01324 
01325         /*
01326          * We keep the child-XID arrays in TopTransactionContext; this avoids
01327          * setting up child-transaction contexts for what might be just a few
01328          * bytes of grandchild XIDs.
01329          */
01330         if (s->parent->childXids == NULL)
01331             new_childXids =
01332                 MemoryContextAlloc(TopTransactionContext,
01333                                    new_maxChildXids * sizeof(TransactionId));
01334         else
01335             new_childXids = repalloc(s->parent->childXids,
01336                                    new_maxChildXids * sizeof(TransactionId));
01337 
01338         s->parent->childXids = new_childXids;
01339         s->parent->maxChildXids = new_maxChildXids;
01340     }
01341 
01342     /*
01343      * Copy all my XIDs to parent's array.
01344      *
01345      * Note: We rely on the fact that the XID of a child always follows that
01346      * of its parent.  By copying the XID of this subtransaction before the
01347      * XIDs of its children, we ensure that the array stays ordered. Likewise,
01348      * all XIDs already in the array belong to subtransactions started and
01349      * subcommitted before us, so their XIDs must precede ours.
01350      */
01351     s->parent->childXids[s->parent->nChildXids] = s->transactionId;
01352 
01353     if (s->nChildXids > 0)
01354         memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
01355                s->childXids,
01356                s->nChildXids * sizeof(TransactionId));
01357 
01358     s->parent->nChildXids = new_nChildXids;
01359 
01360     /* Release child's array to avoid leakage */
01361     if (s->childXids != NULL)
01362         pfree(s->childXids);
01363     /* We must reset these to avoid double-free if fail later in commit */
01364     s->childXids = NULL;
01365     s->nChildXids = 0;
01366     s->maxChildXids = 0;
01367 }
01368 
01369 /* ----------------------------------------------------------------
01370  *                      AbortTransaction stuff
01371  * ----------------------------------------------------------------
01372  */
01373 
01374 /*
01375  *  RecordTransactionAbort
01376  *
01377  * Returns latest XID among xact and its children, or InvalidTransactionId
01378  * if the xact has no XID.  (We compute that here just because it's easier.)
01379  */
01380 static TransactionId
01381 RecordTransactionAbort(bool isSubXact)
01382 {
01383     TransactionId xid = GetCurrentTransactionIdIfAny();
01384     TransactionId latestXid;
01385     int         nrels;
01386     RelFileNode *rels;
01387     int         nchildren;
01388     TransactionId *children;
01389     XLogRecData rdata[3];
01390     int         lastrdata = 0;
01391     xl_xact_abort xlrec;
01392 
01393     /*
01394      * If we haven't been assigned an XID, nobody will care whether we aborted
01395      * or not.  Hence, we're done in that case.  It does not matter if we have
01396      * rels to delete (note that this routine is not responsible for actually
01397      * deleting 'em).  We cannot have any child XIDs, either.
01398      */
01399     if (!TransactionIdIsValid(xid))
01400     {
01401         /* Reset XactLastRecEnd until the next transaction writes something */
01402         if (!isSubXact)
01403             XactLastRecEnd = 0;
01404         return InvalidTransactionId;
01405     }
01406 
01407     /*
01408      * We have a valid XID, so we should write an ABORT record for it.
01409      *
01410      * We do not flush XLOG to disk here, since the default assumption after a
01411      * crash would be that we aborted, anyway.  For the same reason, we don't
01412      * need to worry about interlocking against checkpoint start.
01413      */
01414 
01415     /*
01416      * Check that we haven't aborted halfway through RecordTransactionCommit.
01417      */
01418     if (TransactionIdDidCommit(xid))
01419         elog(PANIC, "cannot abort transaction %u, it was already committed",
01420              xid);
01421 
01422     /* Fetch the data we need for the abort record */
01423     nrels = smgrGetPendingDeletes(false, &rels);
01424     nchildren = xactGetCommittedChildren(&children);
01425 
01426     /* XXX do we really need a critical section here? */
01427     START_CRIT_SECTION();
01428 
01429     /* Write the ABORT record */
01430     if (isSubXact)
01431         xlrec.xact_time = GetCurrentTimestamp();
01432     else
01433     {
01434         SetCurrentTransactionStopTimestamp();
01435         xlrec.xact_time = xactStopTimestamp;
01436     }
01437     xlrec.nrels = nrels;
01438     xlrec.nsubxacts = nchildren;
01439     rdata[0].data = (char *) (&xlrec);
01440     rdata[0].len = MinSizeOfXactAbort;
01441     rdata[0].buffer = InvalidBuffer;
01442     /* dump rels to delete */
01443     if (nrels > 0)
01444     {
01445         rdata[0].next = &(rdata[1]);
01446         rdata[1].data = (char *) rels;
01447         rdata[1].len = nrels * sizeof(RelFileNode);
01448         rdata[1].buffer = InvalidBuffer;
01449         lastrdata = 1;
01450     }
01451     /* dump committed child Xids */
01452     if (nchildren > 0)
01453     {
01454         rdata[lastrdata].next = &(rdata[2]);
01455         rdata[2].data = (char *) children;
01456         rdata[2].len = nchildren * sizeof(TransactionId);
01457         rdata[2].buffer = InvalidBuffer;
01458         lastrdata = 2;
01459     }
01460     rdata[lastrdata].next = NULL;
01461 
01462     (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
01463 
01464     /*
01465      * Report the latest async abort LSN, so that the WAL writer knows to
01466      * flush this abort. There's nothing to be gained by delaying this, since
01467      * WALWriter may as well do this when it can. This is important with
01468      * streaming replication because if we don't flush WAL regularly we will
01469      * find that large aborts leave us with a long backlog for when commits
01470      * occur after the abort, increasing our window of data loss should
01471      * problems occur at that point.
01472      */
01473     if (!isSubXact)
01474         XLogSetAsyncXactLSN(XactLastRecEnd);
01475 
01476     /*
01477      * Mark the transaction aborted in clog.  This is not absolutely necessary
01478      * but we may as well do it while we are here; also, in the subxact case
01479      * it is helpful because XactLockTableWait makes use of it to avoid
01480      * waiting for already-aborted subtransactions.  It is OK to do it without
01481      * having flushed the ABORT record to disk, because in event of a crash
01482      * we'd be assumed to have aborted anyway.
01483      */
01484     TransactionIdAbortTree(xid, nchildren, children);
01485 
01486     END_CRIT_SECTION();
01487 
01488     /* Compute latestXid while we have the child XIDs handy */
01489     latestXid = TransactionIdLatest(xid, nchildren, children);
01490 
01491     /*
01492      * If we're aborting a subtransaction, we can immediately remove failed
01493      * XIDs from PGPROC's cache of running child XIDs.  We do that here for
01494      * subxacts, because we already have the child XID array at hand.  For
01495      * main xacts, the equivalent happens just after this function returns.
01496      */
01497     if (isSubXact)
01498         XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
01499 
01500     /* Reset XactLastRecEnd until the next transaction writes something */
01501     if (!isSubXact)
01502         XactLastRecEnd = 0;
01503 
01504     /* And clean up local data */
01505     if (rels)
01506         pfree(rels);
01507 
01508     return latestXid;
01509 }
01510 
01511 /*
01512  *  AtAbort_Memory
01513  */
01514 static void
01515 AtAbort_Memory(void)
01516 {
01517     /*
01518      * Switch into TransactionAbortContext, which should have some free space
01519      * even if nothing else does.  We'll work in this context until we've
01520      * finished cleaning up.
01521      *
01522      * It is barely possible to get here when we've not been able to create
01523      * TransactionAbortContext yet; if so use TopMemoryContext.
01524      */
01525     if (TransactionAbortContext != NULL)
01526         MemoryContextSwitchTo(TransactionAbortContext);
01527     else
01528         MemoryContextSwitchTo(TopMemoryContext);
01529 }
01530 
01531 /*
01532  * AtSubAbort_Memory
01533  */
01534 static void
01535 AtSubAbort_Memory(void)
01536 {
01537     Assert(TransactionAbortContext != NULL);
01538 
01539     MemoryContextSwitchTo(TransactionAbortContext);
01540 }
01541 
01542 
01543 /*
01544  *  AtAbort_ResourceOwner
01545  */
01546 static void
01547 AtAbort_ResourceOwner(void)
01548 {
01549     /*
01550      * Make sure we have a valid ResourceOwner, if possible (else it will be
01551      * NULL, which is OK)
01552      */
01553     CurrentResourceOwner = TopTransactionResourceOwner;
01554 }
01555 
01556 /*
01557  * AtSubAbort_ResourceOwner
01558  */
01559 static void
01560 AtSubAbort_ResourceOwner(void)
01561 {
01562     TransactionState s = CurrentTransactionState;
01563 
01564     /* Make sure we have a valid ResourceOwner */
01565     CurrentResourceOwner = s->curTransactionOwner;
01566 }
01567 
01568 
01569 /*
01570  * AtSubAbort_childXids
01571  */
01572 static void
01573 AtSubAbort_childXids(void)
01574 {
01575     TransactionState s = CurrentTransactionState;
01576 
01577     /*
01578      * We keep the child-XID arrays in TopTransactionContext (see
01579      * AtSubCommit_childXids).  This means we'd better free the array
01580      * explicitly at abort to avoid leakage.
01581      */
01582     if (s->childXids != NULL)
01583         pfree(s->childXids);
01584     s->childXids = NULL;
01585     s->nChildXids = 0;
01586     s->maxChildXids = 0;
01587 
01588     /*
01589      * We could prune the unreportedXids array here. But we don't bother. That
01590      * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
01591      * would likely introduce more CPU time into the more common paths, so we
01592      * choose not to do that.
01593      */
01594 }
01595 
01596 /* ----------------------------------------------------------------
01597  *                      CleanupTransaction stuff
01598  * ----------------------------------------------------------------
01599  */
01600 
01601 /*
01602  *  AtCleanup_Memory
01603  */
01604 static void
01605 AtCleanup_Memory(void)
01606 {
01607     Assert(CurrentTransactionState->parent == NULL);
01608 
01609     /*
01610      * Now that we're "out" of a transaction, have the system allocate things
01611      * in the top memory context instead of per-transaction contexts.
01612      */
01613     MemoryContextSwitchTo(TopMemoryContext);
01614 
01615     /*
01616      * Clear the special abort context for next time.
01617      */
01618     if (TransactionAbortContext != NULL)
01619         MemoryContextResetAndDeleteChildren(TransactionAbortContext);
01620 
01621     /*
01622      * Release all transaction-local memory.
01623      */
01624     if (TopTransactionContext != NULL)
01625         MemoryContextDelete(TopTransactionContext);
01626     TopTransactionContext = NULL;
01627     CurTransactionContext = NULL;
01628     CurrentTransactionState->curTransactionContext = NULL;
01629 }
01630 
01631 
01632 /* ----------------------------------------------------------------
01633  *                      CleanupSubTransaction stuff
01634  * ----------------------------------------------------------------
01635  */
01636 
01637 /*
01638  * AtSubCleanup_Memory
01639  */
01640 static void
01641 AtSubCleanup_Memory(void)
01642 {
01643     TransactionState s = CurrentTransactionState;
01644 
01645     Assert(s->parent != NULL);
01646 
01647     /* Make sure we're not in an about-to-be-deleted context */
01648     MemoryContextSwitchTo(s->parent->curTransactionContext);
01649     CurTransactionContext = s->parent->curTransactionContext;
01650 
01651     /*
01652      * Clear the special abort context for next time.
01653      */
01654     if (TransactionAbortContext != NULL)
01655         MemoryContextResetAndDeleteChildren(TransactionAbortContext);
01656 
01657     /*
01658      * Delete the subxact local memory contexts. Its CurTransactionContext can
01659      * go too (note this also kills CurTransactionContexts from any children
01660      * of the subxact).
01661      */
01662     if (s->curTransactionContext)
01663         MemoryContextDelete(s->curTransactionContext);
01664     s->curTransactionContext = NULL;
01665 }
01666 
01667 /* ----------------------------------------------------------------
01668  *                      interface routines
01669  * ----------------------------------------------------------------
01670  */
01671 
01672 /*
01673  *  StartTransaction
01674  */
01675 static void
01676 StartTransaction(void)
01677 {
01678     TransactionState s;
01679     VirtualTransactionId vxid;
01680 
01681     /*
01682      * Let's just make sure the state stack is empty
01683      */
01684     s = &TopTransactionStateData;
01685     CurrentTransactionState = s;
01686 
01687     /*
01688      * check the current transaction state
01689      */
01690     if (s->state != TRANS_DEFAULT)
01691         elog(WARNING, "StartTransaction while in %s state",
01692              TransStateAsString(s->state));
01693 
01694     /*
01695      * set the current transaction state information appropriately during
01696      * start processing
01697      */
01698     s->state = TRANS_START;
01699     s->transactionId = InvalidTransactionId;    /* until assigned */
01700 
01701     /*
01702      * Make sure we've reset xact state variables
01703      *
01704      * If recovery is still in progress, mark this transaction as read-only.
01705      * We have lower level defences in XLogInsert and elsewhere to stop us
01706      * from modifying data during recovery, but this gives the normal
01707      * indication to the user that the transaction is read-only.
01708      */
01709     if (RecoveryInProgress())
01710     {
01711         s->startedInRecovery = true;
01712         XactReadOnly = true;
01713     }
01714     else
01715     {
01716         s->startedInRecovery = false;
01717         XactReadOnly = DefaultXactReadOnly;
01718     }
01719     XactDeferrable = DefaultXactDeferrable;
01720     XactIsoLevel = DefaultXactIsoLevel;
01721     forceSyncCommit = false;
01722     MyXactAccessedTempRel = false;
01723 
01724     /*
01725      * reinitialize within-transaction counters
01726      */
01727     s->subTransactionId = TopSubTransactionId;
01728     currentSubTransactionId = TopSubTransactionId;
01729     currentCommandId = FirstCommandId;
01730     currentCommandIdUsed = false;
01731 
01732     /*
01733      * initialize reported xid accounting
01734      */
01735     nUnreportedXids = 0;
01736 
01737     /*
01738      * must initialize resource-management stuff first
01739      */
01740     AtStart_Memory();
01741     AtStart_ResourceOwner();
01742 
01743     /*
01744      * Assign a new LocalTransactionId, and combine it with the backendId to
01745      * form a virtual transaction id.
01746      */
01747     vxid.backendId = MyBackendId;
01748     vxid.localTransactionId = GetNextLocalTransactionId();
01749 
01750     /*
01751      * Lock the virtual transaction id before we announce it in the proc array
01752      */
01753     VirtualXactLockTableInsert(vxid);
01754 
01755     /*
01756      * Advertise it in the proc array.  We assume assignment of
01757      * LocalTransactionID is atomic, and the backendId should be set already.
01758      */
01759     Assert(MyProc->backendId == vxid.backendId);
01760     MyProc->lxid = vxid.localTransactionId;
01761 
01762     TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
01763 
01764     /*
01765      * set transaction_timestamp() (a/k/a now()).  We want this to be the same
01766      * as the first command's statement_timestamp(), so don't do a fresh
01767      * GetCurrentTimestamp() call (which'd be expensive anyway).  Also, mark
01768      * xactStopTimestamp as unset.
01769      */
01770     xactStartTimestamp = stmtStartTimestamp;
01771     xactStopTimestamp = 0;
01772     pgstat_report_xact_timestamp(xactStartTimestamp);
01773 
01774     /*
01775      * initialize current transaction state fields
01776      *
01777      * note: prevXactReadOnly is not used at the outermost level
01778      */
01779     s->nestingLevel = 1;
01780     s->gucNestLevel = 1;
01781     s->childXids = NULL;
01782     s->nChildXids = 0;
01783     s->maxChildXids = 0;
01784     GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
01785     /* SecurityRestrictionContext should never be set outside a transaction */
01786     Assert(s->prevSecContext == 0);
01787 
01788     /*
01789      * initialize other subsystems for new transaction
01790      */
01791     AtStart_GUC();
01792     AtStart_Inval();
01793     AtStart_Cache();
01794     AfterTriggerBeginXact();
01795 
01796     /*
01797      * done with start processing, set current transaction state to "in
01798      * progress"
01799      */
01800     s->state = TRANS_INPROGRESS;
01801 
01802     ShowTransactionState("StartTransaction");
01803 }
01804 
01805 
01806 /*
01807  *  CommitTransaction
01808  *
01809  * NB: if you change this routine, better look at PrepareTransaction too!
01810  */
01811 static void
01812 CommitTransaction(void)
01813 {
01814     TransactionState s = CurrentTransactionState;
01815     TransactionId latestXid;
01816 
01817     ShowTransactionState("CommitTransaction");
01818 
01819     /*
01820      * check the current transaction state
01821      */
01822     if (s->state != TRANS_INPROGRESS)
01823         elog(WARNING, "CommitTransaction while in %s state",
01824              TransStateAsString(s->state));
01825     Assert(s->parent == NULL);
01826 
01827     /*
01828      * Do pre-commit processing that involves calling user-defined code, such
01829      * as triggers.  Since closing cursors could queue trigger actions,
01830      * triggers could open cursors, etc, we have to keep looping until there's
01831      * nothing left to do.
01832      */
01833     for (;;)
01834     {
01835         /*
01836          * Fire all currently pending deferred triggers.
01837          */
01838         AfterTriggerFireDeferred();
01839 
01840         /*
01841          * Close open portals (converting holdable ones into static portals).
01842          * If there weren't any, we are done ... otherwise loop back to check
01843          * if they queued deferred triggers.  Lather, rinse, repeat.
01844          */
01845         if (!PreCommit_Portals(false))
01846             break;
01847     }
01848 
01849     CallXactCallbacks(XACT_EVENT_PRE_COMMIT);
01850 
01851     /*
01852      * The remaining actions cannot call any user-defined code, so it's safe
01853      * to start shutting down within-transaction services.  But note that most
01854      * of this stuff could still throw an error, which would switch us into
01855      * the transaction-abort path.
01856      */
01857 
01858     /* Shut down the deferred-trigger manager */
01859     AfterTriggerEndXact(true);
01860 
01861     /*
01862      * Let ON COMMIT management do its thing (must happen after closing
01863      * cursors, to avoid dangling-reference problems)
01864      */
01865     PreCommit_on_commit_actions();
01866 
01867     /* close large objects before lower-level cleanup */
01868     AtEOXact_LargeObject(true);
01869 
01870     /*
01871      * Mark serializable transaction as complete for predicate locking
01872      * purposes.  This should be done as late as we can put it and still allow
01873      * errors to be raised for failure patterns found at commit.
01874      */
01875     PreCommit_CheckForSerializationFailure();
01876 
01877     /*
01878      * Insert notifications sent by NOTIFY commands into the queue.  This
01879      * should be late in the pre-commit sequence to minimize time spent
01880      * holding the notify-insertion lock.
01881      */
01882     PreCommit_Notify();
01883 
01884     /* Prevent cancel/die interrupt while cleaning up */
01885     HOLD_INTERRUPTS();
01886 
01887     /* Commit updates to the relation map --- do this as late as possible */
01888     AtEOXact_RelationMap(true);
01889 
01890     /*
01891      * set the current transaction state information appropriately during
01892      * commit processing
01893      */
01894     s->state = TRANS_COMMIT;
01895 
01896     /*
01897      * Here is where we really truly commit.
01898      */
01899     latestXid = RecordTransactionCommit();
01900 
01901     TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
01902 
01903     /*
01904      * Let others know about no transaction in progress by me. Note that this
01905      * must be done _before_ releasing locks we hold and _after_
01906      * RecordTransactionCommit.
01907      */
01908     ProcArrayEndTransaction(MyProc, latestXid);
01909 
01910     /*
01911      * This is all post-commit cleanup.  Note that if an error is raised here,
01912      * it's too late to abort the transaction.  This should be just
01913      * noncritical resource releasing.
01914      *
01915      * The ordering of operations is not entirely random.  The idea is:
01916      * release resources visible to other backends (eg, files, buffer pins);
01917      * then release locks; then release backend-local resources. We want to
01918      * release locks at the point where any backend waiting for us will see
01919      * our transaction as being fully cleaned up.
01920      *
01921      * Resources that can be associated with individual queries are handled by
01922      * the ResourceOwner mechanism.  The other calls here are for backend-wide
01923      * state.
01924      */
01925 
01926     CallXactCallbacks(XACT_EVENT_COMMIT);
01927 
01928     ResourceOwnerRelease(TopTransactionResourceOwner,
01929                          RESOURCE_RELEASE_BEFORE_LOCKS,
01930                          true, true);
01931 
01932     /* Check we've released all buffer pins */
01933     AtEOXact_Buffers(true);
01934 
01935     /* Clean up the relation cache */
01936     AtEOXact_RelationCache(true);
01937 
01938     /*
01939      * Make catalog changes visible to all backends.  This has to happen after
01940      * relcache references are dropped (see comments for
01941      * AtEOXact_RelationCache), but before locks are released (if anyone is
01942      * waiting for lock on a relation we've modified, we want them to know
01943      * about the catalog change before they start using the relation).
01944      */
01945     AtEOXact_Inval(true);
01946 
01947     AtEOXact_MultiXact();
01948 
01949     ResourceOwnerRelease(TopTransactionResourceOwner,
01950                          RESOURCE_RELEASE_LOCKS,
01951                          true, true);
01952     ResourceOwnerRelease(TopTransactionResourceOwner,
01953                          RESOURCE_RELEASE_AFTER_LOCKS,
01954                          true, true);
01955 
01956     /*
01957      * Likewise, dropping of files deleted during the transaction is best done
01958      * after releasing relcache and buffer pins.  (This is not strictly
01959      * necessary during commit, since such pins should have been released
01960      * already, but this ordering is definitely critical during abort.)  Since
01961      * this may take many seconds, also delay until after releasing locks.
01962      * Other backends will observe the attendant catalog changes and not
01963      * attempt to access affected files.
01964      */
01965     smgrDoPendingDeletes(true);
01966 
01967     /* Check we've released all catcache entries */
01968     AtEOXact_CatCache(true);
01969 
01970     AtCommit_Notify();
01971     AtEOXact_GUC(true, 1);
01972     AtEOXact_SPI(true);
01973     AtEOXact_on_commit_actions(true);
01974     AtEOXact_Namespace(true);
01975     AtEOXact_SMgr();
01976     AtEOXact_Files();
01977     AtEOXact_ComboCid();
01978     AtEOXact_HashTables(true);
01979     AtEOXact_PgStat(true);
01980     AtEOXact_Snapshot(true);
01981     pgstat_report_xact_timestamp(0);
01982 
01983     CurrentResourceOwner = NULL;
01984     ResourceOwnerDelete(TopTransactionResourceOwner);
01985     s->curTransactionOwner = NULL;
01986     CurTransactionResourceOwner = NULL;
01987     TopTransactionResourceOwner = NULL;
01988 
01989     AtCommit_Memory();
01990 
01991     s->transactionId = InvalidTransactionId;
01992     s->subTransactionId = InvalidSubTransactionId;
01993     s->nestingLevel = 0;
01994     s->gucNestLevel = 0;
01995     s->childXids = NULL;
01996     s->nChildXids = 0;
01997     s->maxChildXids = 0;
01998 
01999     /*
02000      * done with commit processing, set current transaction state back to
02001      * default
02002      */
02003     s->state = TRANS_DEFAULT;
02004 
02005     RESUME_INTERRUPTS();
02006 }
02007 
02008 
02009 /*
02010  *  PrepareTransaction
02011  *
02012  * NB: if you change this routine, better look at CommitTransaction too!
02013  */
02014 static void
02015 PrepareTransaction(void)
02016 {
02017     TransactionState s = CurrentTransactionState;
02018     TransactionId xid = GetCurrentTransactionId();
02019     GlobalTransaction gxact;
02020     TimestampTz prepared_at;
02021 
02022     ShowTransactionState("PrepareTransaction");
02023 
02024     /*
02025      * check the current transaction state
02026      */
02027     if (s->state != TRANS_INPROGRESS)
02028         elog(WARNING, "PrepareTransaction while in %s state",
02029              TransStateAsString(s->state));
02030     Assert(s->parent == NULL);
02031 
02032     /*
02033      * Do pre-commit processing that involves calling user-defined code, such
02034      * as triggers.  Since closing cursors could queue trigger actions,
02035      * triggers could open cursors, etc, we have to keep looping until there's
02036      * nothing left to do.
02037      */
02038     for (;;)
02039     {
02040         /*
02041          * Fire all currently pending deferred triggers.
02042          */
02043         AfterTriggerFireDeferred();
02044 
02045         /*
02046          * Close open portals (converting holdable ones into static portals).
02047          * If there weren't any, we are done ... otherwise loop back to check
02048          * if they queued deferred triggers.  Lather, rinse, repeat.
02049          */
02050         if (!PreCommit_Portals(true))
02051             break;
02052     }
02053 
02054     CallXactCallbacks(XACT_EVENT_PRE_PREPARE);
02055 
02056     /*
02057      * The remaining actions cannot call any user-defined code, so it's safe
02058      * to start shutting down within-transaction services.  But note that most
02059      * of this stuff could still throw an error, which would switch us into
02060      * the transaction-abort path.
02061      */
02062 
02063     /* Shut down the deferred-trigger manager */
02064     AfterTriggerEndXact(true);
02065 
02066     /*
02067      * Let ON COMMIT management do its thing (must happen after closing
02068      * cursors, to avoid dangling-reference problems)
02069      */
02070     PreCommit_on_commit_actions();
02071 
02072     /* close large objects before lower-level cleanup */
02073     AtEOXact_LargeObject(true);
02074 
02075     /*
02076      * Mark serializable transaction as complete for predicate locking
02077      * purposes.  This should be done as late as we can put it and still allow
02078      * errors to be raised for failure patterns found at commit.
02079      */
02080     PreCommit_CheckForSerializationFailure();
02081 
02082     /* NOTIFY will be handled below */
02083 
02084     /*
02085      * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
02086      * this transaction.  Having the prepared xact hold locks on another
02087      * backend's temp table seems a bad idea --- for instance it would prevent
02088      * the backend from exiting.  There are other problems too, such as how to
02089      * clean up the source backend's local buffers and ON COMMIT state if the
02090      * prepared xact includes a DROP of a temp table.
02091      *
02092      * We must check this after executing any ON COMMIT actions, because they
02093      * might still access a temp relation.
02094      *
02095      * XXX In principle this could be relaxed to allow some useful special
02096      * cases, such as a temp table created and dropped all within the
02097      * transaction.  That seems to require much more bookkeeping though.
02098      */
02099     if (MyXactAccessedTempRel)
02100         ereport(ERROR,
02101                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02102                  errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
02103 
02104     /*
02105      * Likewise, don't allow PREPARE after pg_export_snapshot.  This could be
02106      * supported if we added cleanup logic to twophase.c, but for now it
02107      * doesn't seem worth the trouble.
02108      */
02109     if (XactHasExportedSnapshots())
02110         ereport(ERROR,
02111                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02112         errmsg("cannot PREPARE a transaction that has exported snapshots")));
02113 
02114     /* Prevent cancel/die interrupt while cleaning up */
02115     HOLD_INTERRUPTS();
02116 
02117     /*
02118      * set the current transaction state information appropriately during
02119      * prepare processing
02120      */
02121     s->state = TRANS_PREPARE;
02122 
02123     prepared_at = GetCurrentTimestamp();
02124 
02125     /* Tell bufmgr and smgr to prepare for commit */
02126     BufmgrCommit();
02127 
02128     /*
02129      * Reserve the GID for this transaction. This could fail if the requested
02130      * GID is invalid or already in use.
02131      */
02132     gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
02133                             GetUserId(), MyDatabaseId);
02134     prepareGID = NULL;
02135 
02136     /*
02137      * Collect data for the 2PC state file.  Note that in general, no actual
02138      * state change should happen in the called modules during this step,
02139      * since it's still possible to fail before commit, and in that case we
02140      * want transaction abort to be able to clean up.  (In particular, the
02141      * AtPrepare routines may error out if they find cases they cannot
02142      * handle.)  State cleanup should happen in the PostPrepare routines
02143      * below.  However, some modules can go ahead and clear state here because
02144      * they wouldn't do anything with it during abort anyway.
02145      *
02146      * Note: because the 2PC state file records will be replayed in the same
02147      * order they are made, the order of these calls has to match the order in
02148      * which we want things to happen during COMMIT PREPARED or ROLLBACK
02149      * PREPARED; in particular, pay attention to whether things should happen
02150      * before or after releasing the transaction's locks.
02151      */
02152     StartPrepare(gxact);
02153 
02154     AtPrepare_Notify();
02155     AtPrepare_Locks();
02156     AtPrepare_PredicateLocks();
02157     AtPrepare_PgStat();
02158     AtPrepare_MultiXact();
02159     AtPrepare_RelationMap();
02160 
02161     /*
02162      * Here is where we really truly prepare.
02163      *
02164      * We have to record transaction prepares even if we didn't make any
02165      * updates, because the transaction manager might get confused if we lose
02166      * a global transaction.
02167      */
02168     EndPrepare(gxact);
02169 
02170     /*
02171      * Now we clean up backend-internal state and release internal resources.
02172      */
02173 
02174     /* Reset XactLastRecEnd until the next transaction writes something */
02175     XactLastRecEnd = 0;
02176 
02177     /*
02178      * Let others know about no transaction in progress by me.  This has to be
02179      * done *after* the prepared transaction has been marked valid, else
02180      * someone may think it is unlocked and recyclable.
02181      */
02182     ProcArrayClearTransaction(MyProc);
02183 
02184     /*
02185      * This is all post-transaction cleanup.  Note that if an error is raised
02186      * here, it's too late to abort the transaction.  This should be just
02187      * noncritical resource releasing.  See notes in CommitTransaction.
02188      */
02189 
02190     CallXactCallbacks(XACT_EVENT_PREPARE);
02191 
02192     ResourceOwnerRelease(TopTransactionResourceOwner,
02193                          RESOURCE_RELEASE_BEFORE_LOCKS,
02194                          true, true);
02195 
02196     /* Check we've released all buffer pins */
02197     AtEOXact_Buffers(true);
02198 
02199     /* Clean up the relation cache */
02200     AtEOXact_RelationCache(true);
02201 
02202     /* notify doesn't need a postprepare call */
02203 
02204     PostPrepare_PgStat();
02205 
02206     PostPrepare_Inval();
02207 
02208     PostPrepare_smgr();
02209 
02210     PostPrepare_MultiXact(xid);
02211 
02212     PostPrepare_Locks(xid);
02213     PostPrepare_PredicateLocks(xid);
02214 
02215     ResourceOwnerRelease(TopTransactionResourceOwner,
02216                          RESOURCE_RELEASE_LOCKS,
02217                          true, true);
02218     ResourceOwnerRelease(TopTransactionResourceOwner,
02219                          RESOURCE_RELEASE_AFTER_LOCKS,
02220                          true, true);
02221 
02222     /* Check we've released all catcache entries */
02223     AtEOXact_CatCache(true);
02224 
02225     /* PREPARE acts the same as COMMIT as far as GUC is concerned */
02226     AtEOXact_GUC(true, 1);
02227     AtEOXact_SPI(true);
02228     AtEOXact_on_commit_actions(true);
02229     AtEOXact_Namespace(true);
02230     AtEOXact_SMgr();
02231     AtEOXact_Files();
02232     AtEOXact_ComboCid();
02233     AtEOXact_HashTables(true);
02234     /* don't call AtEOXact_PgStat here */
02235     AtEOXact_Snapshot(true);
02236 
02237     CurrentResourceOwner = NULL;
02238     ResourceOwnerDelete(TopTransactionResourceOwner);
02239     s->curTransactionOwner = NULL;
02240     CurTransactionResourceOwner = NULL;
02241     TopTransactionResourceOwner = NULL;
02242 
02243     AtCommit_Memory();
02244 
02245     s->transactionId = InvalidTransactionId;
02246     s->subTransactionId = InvalidSubTransactionId;
02247     s->nestingLevel = 0;
02248     s->gucNestLevel = 0;
02249     s->childXids = NULL;
02250     s->nChildXids = 0;
02251     s->maxChildXids = 0;
02252 
02253     /*
02254      * done with 1st phase commit processing, set current transaction state
02255      * back to default
02256      */
02257     s->state = TRANS_DEFAULT;
02258 
02259     RESUME_INTERRUPTS();
02260 }
02261 
02262 
02263 /*
02264  *  AbortTransaction
02265  */
02266 static void
02267 AbortTransaction(void)
02268 {
02269     TransactionState s = CurrentTransactionState;
02270     TransactionId latestXid;
02271 
02272     /* Prevent cancel/die interrupt while cleaning up */
02273     HOLD_INTERRUPTS();
02274 
02275     /* Make sure we have a valid memory context and resource owner */
02276     AtAbort_Memory();
02277     AtAbort_ResourceOwner();
02278 
02279     /*
02280      * Release any LW locks we might be holding as quickly as possible.
02281      * (Regular locks, however, must be held till we finish aborting.)
02282      * Releasing LW locks is critical since we might try to grab them again
02283      * while cleaning up!
02284      */
02285     LWLockReleaseAll();
02286 
02287     /* Clean up buffer I/O and buffer context locks, too */
02288     AbortBufferIO();
02289     UnlockBuffers();
02290 
02291     /*
02292      * Also clean up any open wait for lock, since the lock manager will choke
02293      * if we try to wait for another lock before doing this.
02294      */
02295     LockErrorCleanup();
02296 
02297     /*
02298      * check the current transaction state
02299      */
02300     if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
02301         elog(WARNING, "AbortTransaction while in %s state",
02302              TransStateAsString(s->state));
02303     Assert(s->parent == NULL);
02304 
02305     /*
02306      * set the current transaction state information appropriately during the
02307      * abort processing
02308      */
02309     s->state = TRANS_ABORT;
02310 
02311     /*
02312      * Reset user ID which might have been changed transiently.  We need this
02313      * to clean up in case control escaped out of a SECURITY DEFINER function
02314      * or other local change of CurrentUserId; therefore, the prior value of
02315      * SecurityRestrictionContext also needs to be restored.
02316      *
02317      * (Note: it is not necessary to restore session authorization or role
02318      * settings here because those can only be changed via GUC, and GUC will
02319      * take care of rolling them back if need be.)
02320      */
02321     SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
02322 
02323     /*
02324      * do abort processing
02325      */
02326     AfterTriggerEndXact(false); /* 'false' means it's abort */
02327     AtAbort_Portals();
02328     AtEOXact_LargeObject(false);
02329     AtAbort_Notify();
02330     AtEOXact_RelationMap(false);
02331 
02332     /*
02333      * Advertise the fact that we aborted in pg_clog (assuming that we got as
02334      * far as assigning an XID to advertise).
02335      */
02336     latestXid = RecordTransactionAbort(false);
02337 
02338     TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
02339 
02340     /*
02341      * Let others know about no transaction in progress by me. Note that this
02342      * must be done _before_ releasing locks we hold and _after_
02343      * RecordTransactionAbort.
02344      */
02345     ProcArrayEndTransaction(MyProc, latestXid);
02346 
02347     /*
02348      * Post-abort cleanup.  See notes in CommitTransaction() concerning
02349      * ordering.  We can skip all of it if the transaction failed before
02350      * creating a resource owner.
02351      */
02352     if (TopTransactionResourceOwner != NULL)
02353     {
02354         CallXactCallbacks(XACT_EVENT_ABORT);
02355 
02356         ResourceOwnerRelease(TopTransactionResourceOwner,
02357                              RESOURCE_RELEASE_BEFORE_LOCKS,
02358                              false, true);
02359         AtEOXact_Buffers(false);
02360         AtEOXact_RelationCache(false);
02361         AtEOXact_Inval(false);
02362         AtEOXact_MultiXact();
02363         ResourceOwnerRelease(TopTransactionResourceOwner,
02364                              RESOURCE_RELEASE_LOCKS,
02365                              false, true);
02366         ResourceOwnerRelease(TopTransactionResourceOwner,
02367                              RESOURCE_RELEASE_AFTER_LOCKS,
02368                              false, true);
02369         smgrDoPendingDeletes(false);
02370         AtEOXact_CatCache(false);
02371 
02372         AtEOXact_GUC(false, 1);
02373         AtEOXact_SPI(false);
02374         AtEOXact_on_commit_actions(false);
02375         AtEOXact_Namespace(false);
02376         AtEOXact_SMgr();
02377         AtEOXact_Files();
02378         AtEOXact_ComboCid();
02379         AtEOXact_HashTables(false);
02380         AtEOXact_PgStat(false);
02381         pgstat_report_xact_timestamp(0);
02382     }
02383 
02384     /*
02385      * State remains TRANS_ABORT until CleanupTransaction().
02386      */
02387     RESUME_INTERRUPTS();
02388 }
02389 
02390 /*
02391  *  CleanupTransaction
02392  */
02393 static void
02394 CleanupTransaction(void)
02395 {
02396     TransactionState s = CurrentTransactionState;
02397 
02398     /*
02399      * State should still be TRANS_ABORT from AbortTransaction().
02400      */
02401     if (s->state != TRANS_ABORT)
02402         elog(FATAL, "CleanupTransaction: unexpected state %s",
02403              TransStateAsString(s->state));
02404 
02405     /*
02406      * do abort cleanup processing
02407      */
02408     AtCleanup_Portals();        /* now safe to release portal memory */
02409     AtEOXact_Snapshot(false);   /* and release the transaction's snapshots */
02410 
02411     CurrentResourceOwner = NULL;    /* and resource owner */
02412     if (TopTransactionResourceOwner)
02413         ResourceOwnerDelete(TopTransactionResourceOwner);
02414     s->curTransactionOwner = NULL;
02415     CurTransactionResourceOwner = NULL;
02416     TopTransactionResourceOwner = NULL;
02417 
02418     AtCleanup_Memory();         /* and transaction memory */
02419 
02420     s->transactionId = InvalidTransactionId;
02421     s->subTransactionId = InvalidSubTransactionId;
02422     s->nestingLevel = 0;
02423     s->gucNestLevel = 0;
02424     s->childXids = NULL;
02425     s->nChildXids = 0;
02426     s->maxChildXids = 0;
02427 
02428     /*
02429      * done with abort processing, set current transaction state back to
02430      * default
02431      */
02432     s->state = TRANS_DEFAULT;
02433 }
02434 
02435 /*
02436  *  StartTransactionCommand
02437  */
02438 void
02439 StartTransactionCommand(void)
02440 {
02441     TransactionState s = CurrentTransactionState;
02442 
02443     switch (s->blockState)
02444     {
02445             /*
02446              * if we aren't in a transaction block, we just do our usual start
02447              * transaction.
02448              */
02449         case TBLOCK_DEFAULT:
02450             StartTransaction();
02451             s->blockState = TBLOCK_STARTED;
02452             break;
02453 
02454             /*
02455              * We are somewhere in a transaction block or subtransaction and
02456              * about to start a new command.  For now we do nothing, but
02457              * someday we may do command-local resource initialization. (Note
02458              * that any needed CommandCounterIncrement was done by the
02459              * previous CommitTransactionCommand.)
02460              */
02461         case TBLOCK_INPROGRESS:
02462         case TBLOCK_SUBINPROGRESS:
02463             break;
02464 
02465             /*
02466              * Here we are in a failed transaction block (one of the commands
02467              * caused an abort) so we do nothing but remain in the abort
02468              * state.  Eventually we will get a ROLLBACK command which will
02469              * get us out of this state.  (It is up to other code to ensure
02470              * that no commands other than ROLLBACK will be processed in these
02471              * states.)
02472              */
02473         case TBLOCK_ABORT:
02474         case TBLOCK_SUBABORT:
02475             break;
02476 
02477             /* These cases are invalid. */
02478         case TBLOCK_STARTED:
02479         case TBLOCK_BEGIN:
02480         case TBLOCK_SUBBEGIN:
02481         case TBLOCK_END:
02482         case TBLOCK_SUBRELEASE:
02483         case TBLOCK_SUBCOMMIT:
02484         case TBLOCK_ABORT_END:
02485         case TBLOCK_SUBABORT_END:
02486         case TBLOCK_ABORT_PENDING:
02487         case TBLOCK_SUBABORT_PENDING:
02488         case TBLOCK_SUBRESTART:
02489         case TBLOCK_SUBABORT_RESTART:
02490         case TBLOCK_PREPARE:
02491             elog(ERROR, "StartTransactionCommand: unexpected state %s",
02492                  BlockStateAsString(s->blockState));
02493             break;
02494     }
02495 
02496     /*
02497      * We must switch to CurTransactionContext before returning. This is
02498      * already done if we called StartTransaction, otherwise not.
02499      */
02500     Assert(CurTransactionContext != NULL);
02501     MemoryContextSwitchTo(CurTransactionContext);
02502 }
02503 
02504 /*
02505  *  CommitTransactionCommand
02506  */
02507 void
02508 CommitTransactionCommand(void)
02509 {
02510     TransactionState s = CurrentTransactionState;
02511 
02512     switch (s->blockState)
02513     {
02514             /*
02515              * This shouldn't happen, because it means the previous
02516              * StartTransactionCommand didn't set the STARTED state
02517              * appropriately.
02518              */
02519         case TBLOCK_DEFAULT:
02520             elog(FATAL, "CommitTransactionCommand: unexpected state %s",
02521                  BlockStateAsString(s->blockState));
02522             break;
02523 
02524             /*
02525              * If we aren't in a transaction block, just do our usual
02526              * transaction commit, and return to the idle state.
02527              */
02528         case TBLOCK_STARTED:
02529             CommitTransaction();
02530             s->blockState = TBLOCK_DEFAULT;
02531             break;
02532 
02533             /*
02534              * We are completing a "BEGIN TRANSACTION" command, so we change
02535              * to the "transaction block in progress" state and return.  (We
02536              * assume the BEGIN did nothing to the database, so we need no
02537              * CommandCounterIncrement.)
02538              */
02539         case TBLOCK_BEGIN:
02540             s->blockState = TBLOCK_INPROGRESS;
02541             break;
02542 
02543             /*
02544              * This is the case when we have finished executing a command
02545              * someplace within a transaction block.  We increment the command
02546              * counter and return.
02547              */
02548         case TBLOCK_INPROGRESS:
02549         case TBLOCK_SUBINPROGRESS:
02550             CommandCounterIncrement();
02551             break;
02552 
02553             /*
02554              * We are completing a "COMMIT" command.  Do it and return to the
02555              * idle state.
02556              */
02557         case TBLOCK_END:
02558             CommitTransaction();
02559             s->blockState = TBLOCK_DEFAULT;
02560             break;
02561 
02562             /*
02563              * Here we are in the middle of a transaction block but one of the
02564              * commands caused an abort so we do nothing but remain in the
02565              * abort state.  Eventually we will get a ROLLBACK comand.
02566              */
02567         case TBLOCK_ABORT:
02568         case TBLOCK_SUBABORT:
02569             break;
02570 
02571             /*
02572              * Here we were in an aborted transaction block and we just got
02573              * the ROLLBACK command from the user, so clean up the
02574              * already-aborted transaction and return to the idle state.
02575              */
02576         case TBLOCK_ABORT_END:
02577             CleanupTransaction();
02578             s->blockState = TBLOCK_DEFAULT;
02579             break;
02580 
02581             /*
02582              * Here we were in a perfectly good transaction block but the user
02583              * told us to ROLLBACK anyway.  We have to abort the transaction
02584              * and then clean up.
02585              */
02586         case TBLOCK_ABORT_PENDING:
02587             AbortTransaction();
02588             CleanupTransaction();
02589             s->blockState = TBLOCK_DEFAULT;
02590             break;
02591 
02592             /*
02593              * We are completing a "PREPARE TRANSACTION" command.  Do it and
02594              * return to the idle state.
02595              */
02596         case TBLOCK_PREPARE:
02597             PrepareTransaction();
02598             s->blockState = TBLOCK_DEFAULT;
02599             break;
02600 
02601             /*
02602              * We were just issued a SAVEPOINT inside a transaction block.
02603              * Start a subtransaction.  (DefineSavepoint already did
02604              * PushTransaction, so as to have someplace to put the SUBBEGIN
02605              * state.)
02606              */
02607         case TBLOCK_SUBBEGIN:
02608             StartSubTransaction();
02609             s->blockState = TBLOCK_SUBINPROGRESS;
02610             break;
02611 
02612             /*
02613              * We were issued a RELEASE command, so we end the current
02614              * subtransaction and return to the parent transaction. The parent
02615              * might be ended too, so repeat till we find an INPROGRESS
02616              * transaction or subtransaction.
02617              */
02618         case TBLOCK_SUBRELEASE:
02619             do
02620             {
02621                 CommitSubTransaction();
02622                 s = CurrentTransactionState;    /* changed by pop */
02623             } while (s->blockState == TBLOCK_SUBRELEASE);
02624 
02625             Assert(s->blockState == TBLOCK_INPROGRESS ||
02626                    s->blockState == TBLOCK_SUBINPROGRESS);
02627             break;
02628 
02629             /*
02630              * We were issued a COMMIT, so we end the current subtransaction
02631              * hierarchy and perform final commit. We do this by rolling up
02632              * any subtransactions into their parent, which leads to O(N^2)
02633              * operations with respect to resource owners - this isn't that
02634              * bad until we approach a thousands of savepoints but is
02635              * necessary for correctness should after triggers create new
02636              * resource owners.
02637              */
02638         case TBLOCK_SUBCOMMIT:
02639             do
02640             {
02641                 CommitSubTransaction();
02642                 s = CurrentTransactionState;    /* changed by pop */
02643             } while (s->blockState == TBLOCK_SUBCOMMIT);
02644             /* If we had a COMMIT command, finish off the main xact too */
02645             if (s->blockState == TBLOCK_END)
02646             {
02647                 Assert(s->parent == NULL);
02648                 CommitTransaction();
02649                 s->blockState = TBLOCK_DEFAULT;
02650             }
02651             else if (s->blockState == TBLOCK_PREPARE)
02652             {
02653                 Assert(s->parent == NULL);
02654                 PrepareTransaction();
02655                 s->blockState = TBLOCK_DEFAULT;
02656             }
02657             else
02658                 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
02659                      BlockStateAsString(s->blockState));
02660             break;
02661 
02662             /*
02663              * The current already-failed subtransaction is ending due to a
02664              * ROLLBACK or ROLLBACK TO command, so pop it and recursively
02665              * examine the parent (which could be in any of several states).
02666              */
02667         case TBLOCK_SUBABORT_END:
02668             CleanupSubTransaction();
02669             CommitTransactionCommand();
02670             break;
02671 
02672             /*
02673              * As above, but it's not dead yet, so abort first.
02674              */
02675         case TBLOCK_SUBABORT_PENDING:
02676             AbortSubTransaction();
02677             CleanupSubTransaction();
02678             CommitTransactionCommand();
02679             break;
02680 
02681             /*
02682              * The current subtransaction is the target of a ROLLBACK TO
02683              * command.  Abort and pop it, then start a new subtransaction
02684              * with the same name.
02685              */
02686         case TBLOCK_SUBRESTART:
02687             {
02688                 char       *name;
02689                 int         savepointLevel;
02690 
02691                 /* save name and keep Cleanup from freeing it */
02692                 name = s->name;
02693                 s->name = NULL;
02694                 savepointLevel = s->savepointLevel;
02695 
02696                 AbortSubTransaction();
02697                 CleanupSubTransaction();
02698 
02699                 DefineSavepoint(NULL);
02700                 s = CurrentTransactionState;    /* changed by push */
02701                 s->name = name;
02702                 s->savepointLevel = savepointLevel;
02703 
02704                 /* This is the same as TBLOCK_SUBBEGIN case */
02705                 AssertState(s->blockState == TBLOCK_SUBBEGIN);
02706                 StartSubTransaction();
02707                 s->blockState = TBLOCK_SUBINPROGRESS;
02708             }
02709             break;
02710 
02711             /*
02712              * Same as above, but the subtransaction had already failed, so we
02713              * don't need AbortSubTransaction.
02714              */
02715         case TBLOCK_SUBABORT_RESTART:
02716             {
02717                 char       *name;
02718                 int         savepointLevel;
02719 
02720                 /* save name and keep Cleanup from freeing it */
02721                 name = s->name;
02722                 s->name = NULL;
02723                 savepointLevel = s->savepointLevel;
02724 
02725                 CleanupSubTransaction();
02726 
02727                 DefineSavepoint(NULL);
02728                 s = CurrentTransactionState;    /* changed by push */
02729                 s->name = name;
02730                 s->savepointLevel = savepointLevel;
02731 
02732                 /* This is the same as TBLOCK_SUBBEGIN case */
02733                 AssertState(s->blockState == TBLOCK_SUBBEGIN);
02734                 StartSubTransaction();
02735                 s->blockState = TBLOCK_SUBINPROGRESS;
02736             }
02737             break;
02738     }
02739 }
02740 
02741 /*
02742  *  AbortCurrentTransaction
02743  */
02744 void
02745 AbortCurrentTransaction(void)
02746 {
02747     TransactionState s = CurrentTransactionState;
02748 
02749     switch (s->blockState)
02750     {
02751         case TBLOCK_DEFAULT:
02752             if (s->state == TRANS_DEFAULT)
02753             {
02754                 /* we are idle, so nothing to do */
02755             }
02756             else
02757             {
02758                 /*
02759                  * We can get here after an error during transaction start
02760                  * (state will be TRANS_START).  Need to clean up the
02761                  * incompletely started transaction.  First, adjust the
02762                  * low-level state to suppress warning message from
02763                  * AbortTransaction.
02764                  */
02765                 if (s->state == TRANS_START)
02766                     s->state = TRANS_INPROGRESS;
02767                 AbortTransaction();
02768                 CleanupTransaction();
02769             }
02770             break;
02771 
02772             /*
02773              * if we aren't in a transaction block, we just do the basic abort
02774              * & cleanup transaction.
02775              */
02776         case TBLOCK_STARTED:
02777             AbortTransaction();
02778             CleanupTransaction();
02779             s->blockState = TBLOCK_DEFAULT;
02780             break;
02781 
02782             /*
02783              * If we are in TBLOCK_BEGIN it means something screwed up right
02784              * after reading "BEGIN TRANSACTION".  We assume that the user
02785              * will interpret the error as meaning the BEGIN failed to get him
02786              * into a transaction block, so we should abort and return to idle
02787              * state.
02788              */
02789         case TBLOCK_BEGIN:
02790             AbortTransaction();
02791             CleanupTransaction();
02792             s->blockState = TBLOCK_DEFAULT;
02793             break;
02794 
02795             /*
02796              * We are somewhere in a transaction block and we've gotten a
02797              * failure, so we abort the transaction and set up the persistent
02798              * ABORT state.  We will stay in ABORT until we get a ROLLBACK.
02799              */
02800         case TBLOCK_INPROGRESS:
02801             AbortTransaction();
02802             s->blockState = TBLOCK_ABORT;
02803             /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
02804             break;
02805 
02806             /*
02807              * Here, we failed while trying to COMMIT.  Clean up the
02808              * transaction and return to idle state (we do not want to stay in
02809              * the transaction).
02810              */
02811         case TBLOCK_END:
02812             AbortTransaction();
02813             CleanupTransaction();
02814             s->blockState = TBLOCK_DEFAULT;
02815             break;
02816 
02817             /*
02818              * Here, we are already in an aborted transaction state and are
02819              * waiting for a ROLLBACK, but for some reason we failed again! So
02820              * we just remain in the abort state.
02821              */
02822         case TBLOCK_ABORT:
02823         case TBLOCK_SUBABORT:
02824             break;
02825 
02826             /*
02827              * We are in a failed transaction and we got the ROLLBACK command.
02828              * We have already aborted, we just need to cleanup and go to idle
02829              * state.
02830              */
02831         case TBLOCK_ABORT_END:
02832             CleanupTransaction();
02833             s->blockState = TBLOCK_DEFAULT;
02834             break;
02835 
02836             /*
02837              * We are in a live transaction and we got a ROLLBACK command.
02838              * Abort, cleanup, go to idle state.
02839              */
02840         case TBLOCK_ABORT_PENDING:
02841             AbortTransaction();
02842             CleanupTransaction();
02843             s->blockState = TBLOCK_DEFAULT;
02844             break;
02845 
02846             /*
02847              * Here, we failed while trying to PREPARE.  Clean up the
02848              * transaction and return to idle state (we do not want to stay in
02849              * the transaction).
02850              */
02851         case TBLOCK_PREPARE:
02852             AbortTransaction();
02853             CleanupTransaction();
02854             s->blockState = TBLOCK_DEFAULT;
02855             break;
02856 
02857             /*
02858              * We got an error inside a subtransaction.  Abort just the
02859              * subtransaction, and go to the persistent SUBABORT state until
02860              * we get ROLLBACK.
02861              */
02862         case TBLOCK_SUBINPROGRESS:
02863             AbortSubTransaction();
02864             s->blockState = TBLOCK_SUBABORT;
02865             break;
02866 
02867             /*
02868              * If we failed while trying to create a subtransaction, clean up
02869              * the broken subtransaction and abort the parent.  The same
02870              * applies if we get a failure while ending a subtransaction.
02871              */
02872         case TBLOCK_SUBBEGIN:
02873         case TBLOCK_SUBRELEASE:
02874         case TBLOCK_SUBCOMMIT:
02875         case TBLOCK_SUBABORT_PENDING:
02876         case TBLOCK_SUBRESTART:
02877             AbortSubTransaction();
02878             CleanupSubTransaction();
02879             AbortCurrentTransaction();
02880             break;
02881 
02882             /*
02883              * Same as above, except the Abort() was already done.
02884              */
02885         case TBLOCK_SUBABORT_END:
02886         case TBLOCK_SUBABORT_RESTART:
02887             CleanupSubTransaction();
02888             AbortCurrentTransaction();
02889             break;
02890     }
02891 }
02892 
02893 /*
02894  *  PreventTransactionChain
02895  *
02896  *  This routine is to be called by statements that must not run inside
02897  *  a transaction block, typically because they have non-rollback-able
02898  *  side effects or do internal commits.
02899  *
02900  *  If we have already started a transaction block, issue an error; also issue
02901  *  an error if we appear to be running inside a user-defined function (which
02902  *  could issue more commands and possibly cause a failure after the statement
02903  *  completes).  Subtransactions are verboten too.
02904  *
02905  *  isTopLevel: passed down from ProcessUtility to determine whether we are
02906  *  inside a function or multi-query querystring.  (We will always fail if
02907  *  this is false, but it's convenient to centralize the check here instead of
02908  *  making callers do it.)
02909  *  stmtType: statement type name, for error messages.
02910  */
02911 void
02912 PreventTransactionChain(bool isTopLevel, const char *stmtType)
02913 {
02914     /*
02915      * xact block already started?
02916      */
02917     if (IsTransactionBlock())
02918         ereport(ERROR,
02919                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
02920         /* translator: %s represents an SQL statement name */
02921                  errmsg("%s cannot run inside a transaction block",
02922                         stmtType)));
02923 
02924     /*
02925      * subtransaction?
02926      */
02927     if (IsSubTransaction())
02928         ereport(ERROR,
02929                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
02930         /* translator: %s represents an SQL statement name */
02931                  errmsg("%s cannot run inside a subtransaction",
02932                         stmtType)));
02933 
02934     /*
02935      * inside a function call?
02936      */
02937     if (!isTopLevel)
02938         ereport(ERROR,
02939                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
02940         /* translator: %s represents an SQL statement name */
02941                  errmsg("%s cannot be executed from a function or multi-command string",
02942                         stmtType)));
02943 
02944     /* If we got past IsTransactionBlock test, should be in default state */
02945     if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
02946         CurrentTransactionState->blockState != TBLOCK_STARTED)
02947         elog(FATAL, "cannot prevent transaction chain");
02948     /* all okay */
02949 }
02950 
02951 /*
02952  *  RequireTransactionChain
02953  *
02954  *  This routine is to be called by statements that must run inside
02955  *  a transaction block, because they have no effects that persist past
02956  *  transaction end (and so calling them outside a transaction block
02957  *  is presumably an error).  DECLARE CURSOR is an example.
02958  *
02959  *  If we appear to be running inside a user-defined function, we do not
02960  *  issue an error, since the function could issue more commands that make
02961  *  use of the current statement's results.  Likewise subtransactions.
02962  *  Thus this is an inverse for PreventTransactionChain.
02963  *
02964  *  isTopLevel: passed down from ProcessUtility to determine whether we are
02965  *  inside a function.
02966  *  stmtType: statement type name, for error messages.
02967  */
02968 void
02969 RequireTransactionChain(bool isTopLevel, const char *stmtType)
02970 {
02971     /*
02972      * xact block already started?
02973      */
02974     if (IsTransactionBlock())
02975         return;
02976 
02977     /*
02978      * subtransaction?
02979      */
02980     if (IsSubTransaction())
02981         return;
02982 
02983     /*
02984      * inside a function call?
02985      */
02986     if (!isTopLevel)
02987         return;
02988 
02989     ereport(ERROR,
02990             (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
02991     /* translator: %s represents an SQL statement name */
02992              errmsg("%s can only be used in transaction blocks",
02993                     stmtType)));
02994 }
02995 
02996 /*
02997  *  IsInTransactionChain
02998  *
02999  *  This routine is for statements that need to behave differently inside
03000  *  a transaction block than when running as single commands.  ANALYZE is
03001  *  currently the only example.
03002  *
03003  *  isTopLevel: passed down from ProcessUtility to determine whether we are
03004  *  inside a function.
03005  */
03006 bool
03007 IsInTransactionChain(bool isTopLevel)
03008 {
03009     /*
03010      * Return true on same conditions that would make PreventTransactionChain
03011      * error out
03012      */
03013     if (IsTransactionBlock())
03014         return true;
03015 
03016     if (IsSubTransaction())
03017         return true;
03018 
03019     if (!isTopLevel)
03020         return true;
03021 
03022     if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
03023         CurrentTransactionState->blockState != TBLOCK_STARTED)
03024         return true;
03025 
03026     return false;
03027 }
03028 
03029 
03030 /*
03031  * Register or deregister callback functions for start- and end-of-xact
03032  * operations.
03033  *
03034  * These functions are intended for use by dynamically loaded modules.
03035  * For built-in modules we generally just hardwire the appropriate calls
03036  * (mainly because it's easier to control the order that way, where needed).
03037  *
03038  * At transaction end, the callback occurs post-commit or post-abort, so the
03039  * callback functions can only do noncritical cleanup.
03040  */
03041 void
03042 RegisterXactCallback(XactCallback callback, void *arg)
03043 {
03044     XactCallbackItem *item;
03045 
03046     item = (XactCallbackItem *)
03047         MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
03048     item->callback = callback;
03049     item->arg = arg;
03050     item->next = Xact_callbacks;
03051     Xact_callbacks = item;
03052 }
03053 
03054 void
03055 UnregisterXactCallback(XactCallback callback, void *arg)
03056 {
03057     XactCallbackItem *item;
03058     XactCallbackItem *prev;
03059 
03060     prev = NULL;
03061     for (item = Xact_callbacks; item; prev = item, item = item->next)
03062     {
03063         if (item->callback == callback && item->arg == arg)
03064         {
03065             if (prev)
03066                 prev->next = item->next;
03067             else
03068                 Xact_callbacks = item->next;
03069             pfree(item);
03070             break;
03071         }
03072     }
03073 }
03074 
03075 static void
03076 CallXactCallbacks(XactEvent event)
03077 {
03078     XactCallbackItem *item;
03079 
03080     for (item = Xact_callbacks; item; item = item->next)
03081         (*item->callback) (event, item->arg);
03082 }
03083 
03084 
03085 /*
03086  * Register or deregister callback functions for start- and end-of-subxact
03087  * operations.
03088  *
03089  * Pretty much same as above, but for subtransaction events.
03090  *
03091  * At subtransaction end, the callback occurs post-subcommit or post-subabort,
03092  * so the callback functions can only do noncritical cleanup.  At
03093  * subtransaction start, the callback is called when the subtransaction has
03094  * finished initializing.
03095  */
03096 void
03097 RegisterSubXactCallback(SubXactCallback callback, void *arg)
03098 {
03099     SubXactCallbackItem *item;
03100 
03101     item = (SubXactCallbackItem *)
03102         MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
03103     item->callback = callback;
03104     item->arg = arg;
03105     item->next = SubXact_callbacks;
03106     SubXact_callbacks = item;
03107 }
03108 
03109 void
03110 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
03111 {
03112     SubXactCallbackItem *item;
03113     SubXactCallbackItem *prev;
03114 
03115     prev = NULL;
03116     for (item = SubXact_callbacks; item; prev = item, item = item->next)
03117     {
03118         if (item->callback == callback && item->arg == arg)
03119         {
03120             if (prev)
03121                 prev->next = item->next;
03122             else
03123                 SubXact_callbacks = item->next;
03124             pfree(item);
03125             break;
03126         }
03127     }
03128 }
03129 
03130 static void
03131 CallSubXactCallbacks(SubXactEvent event,
03132                      SubTransactionId mySubid,
03133                      SubTransactionId parentSubid)
03134 {
03135     SubXactCallbackItem *item;
03136 
03137     for (item = SubXact_callbacks; item; item = item->next)
03138         (*item->callback) (event, mySubid, parentSubid, item->arg);
03139 }
03140 
03141 
03142 /* ----------------------------------------------------------------
03143  *                     transaction block support
03144  * ----------------------------------------------------------------
03145  */
03146 
03147 /*
03148  *  BeginTransactionBlock
03149  *      This executes a BEGIN command.
03150  */
03151 void
03152 BeginTransactionBlock(void)
03153 {
03154     TransactionState s = CurrentTransactionState;
03155 
03156     switch (s->blockState)
03157     {
03158             /*
03159              * We are not inside a transaction block, so allow one to begin.
03160              */
03161         case TBLOCK_STARTED:
03162             s->blockState = TBLOCK_BEGIN;
03163             break;
03164 
03165             /*
03166              * Already a transaction block in progress.
03167              */
03168         case TBLOCK_INPROGRESS:
03169         case TBLOCK_SUBINPROGRESS:
03170         case TBLOCK_ABORT:
03171         case TBLOCK_SUBABORT:
03172             ereport(WARNING,
03173                     (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
03174                      errmsg("there is already a transaction in progress")));
03175             break;
03176 
03177             /* These cases are invalid. */
03178         case TBLOCK_DEFAULT:
03179         case TBLOCK_BEGIN:
03180         case TBLOCK_SUBBEGIN:
03181         case TBLOCK_END:
03182         case TBLOCK_SUBRELEASE:
03183         case TBLOCK_SUBCOMMIT:
03184         case TBLOCK_ABORT_END:
03185         case TBLOCK_SUBABORT_END:
03186         case TBLOCK_ABORT_PENDING:
03187         case TBLOCK_SUBABORT_PENDING:
03188         case TBLOCK_SUBRESTART:
03189         case TBLOCK_SUBABORT_RESTART:
03190         case TBLOCK_PREPARE:
03191             elog(FATAL, "BeginTransactionBlock: unexpected state %s",
03192                  BlockStateAsString(s->blockState));
03193             break;
03194     }
03195 }
03196 
03197 /*
03198  *  PrepareTransactionBlock
03199  *      This executes a PREPARE command.
03200  *
03201  * Since PREPARE may actually do a ROLLBACK, the result indicates what
03202  * happened: TRUE for PREPARE, FALSE for ROLLBACK.
03203  *
03204  * Note that we don't actually do anything here except change blockState.
03205  * The real work will be done in the upcoming PrepareTransaction().
03206  * We do it this way because it's not convenient to change memory context,
03207  * resource owner, etc while executing inside a Portal.
03208  */
03209 bool
03210 PrepareTransactionBlock(char *gid)
03211 {
03212     TransactionState s;
03213     bool        result;
03214 
03215     /* Set up to commit the current transaction */
03216     result = EndTransactionBlock();
03217 
03218     /* If successful, change outer tblock state to PREPARE */
03219     if (result)
03220     {
03221         s = CurrentTransactionState;
03222 
03223         while (s->parent != NULL)
03224             s = s->parent;
03225 
03226         if (s->blockState == TBLOCK_END)
03227         {
03228             /* Save GID where PrepareTransaction can find it again */
03229             prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
03230 
03231             s->blockState = TBLOCK_PREPARE;
03232         }
03233         else
03234         {
03235             /*
03236              * ignore case where we are not in a transaction;
03237              * EndTransactionBlock already issued a warning.
03238              */
03239             Assert(s->blockState == TBLOCK_STARTED);
03240             /* Don't send back a PREPARE result tag... */
03241             result = false;
03242         }
03243     }
03244 
03245     return result;
03246 }
03247 
03248 /*
03249  *  EndTransactionBlock
03250  *      This executes a COMMIT command.
03251  *
03252  * Since COMMIT may actually do a ROLLBACK, the result indicates what
03253  * happened: TRUE for COMMIT, FALSE for ROLLBACK.
03254  *
03255  * Note that we don't actually do anything here except change blockState.
03256  * The real work will be done in the upcoming CommitTransactionCommand().
03257  * We do it this way because it's not convenient to change memory context,
03258  * resource owner, etc while executing inside a Portal.
03259  */
03260 bool
03261 EndTransactionBlock(void)
03262 {
03263     TransactionState s = CurrentTransactionState;
03264     bool        result = false;
03265 
03266     switch (s->blockState)
03267     {
03268             /*
03269              * We are in a transaction block, so tell CommitTransactionCommand
03270              * to COMMIT.
03271              */
03272         case TBLOCK_INPROGRESS:
03273             s->blockState = TBLOCK_END;
03274             result = true;
03275             break;
03276 
03277             /*
03278              * We are in a failed transaction block.  Tell
03279              * CommitTransactionCommand it's time to exit the block.
03280              */
03281         case TBLOCK_ABORT:
03282             s->blockState = TBLOCK_ABORT_END;
03283             break;
03284 
03285             /*
03286              * We are in a live subtransaction block.  Set up to subcommit all
03287              * open subtransactions and then commit the main transaction.
03288              */
03289         case TBLOCK_SUBINPROGRESS:
03290             while (s->parent != NULL)
03291             {
03292                 if (s->blockState == TBLOCK_SUBINPROGRESS)
03293                     s->blockState = TBLOCK_SUBCOMMIT;
03294                 else
03295                     elog(FATAL, "EndTransactionBlock: unexpected state %s",
03296                          BlockStateAsString(s->blockState));
03297                 s = s->parent;
03298             }
03299             if (s->blockState == TBLOCK_INPROGRESS)
03300                 s->blockState = TBLOCK_END;
03301             else
03302                 elog(FATAL, "EndTransactionBlock: unexpected state %s",
03303                      BlockStateAsString(s->blockState));
03304             result = true;
03305             break;
03306 
03307             /*
03308              * Here we are inside an aborted subtransaction.  Treat the COMMIT
03309              * as ROLLBACK: set up to abort everything and exit the main
03310              * transaction.
03311              */
03312         case TBLOCK_SUBABORT:
03313             while (s->parent != NULL)
03314             {
03315                 if (s->blockState == TBLOCK_SUBINPROGRESS)
03316                     s->blockState = TBLOCK_SUBABORT_PENDING;
03317                 else if (s->blockState == TBLOCK_SUBABORT)
03318                     s->blockState = TBLOCK_SUBABORT_END;
03319                 else
03320                     elog(FATAL, "EndTransactionBlock: unexpected state %s",
03321                          BlockStateAsString(s->blockState));
03322                 s = s->parent;
03323             }
03324             if (s->blockState == TBLOCK_INPROGRESS)
03325                 s->blockState = TBLOCK_ABORT_PENDING;
03326             else if (s->blockState == TBLOCK_ABORT)
03327                 s->blockState = TBLOCK_ABORT_END;
03328             else
03329                 elog(FATAL, "EndTransactionBlock: unexpected state %s",
03330                      BlockStateAsString(s->blockState));
03331             break;
03332 
03333             /*
03334              * The user issued COMMIT when not inside a transaction.  Issue a
03335              * WARNING, staying in TBLOCK_STARTED state.  The upcoming call to
03336              * CommitTransactionCommand() will then close the transaction and
03337              * put us back into the default state.
03338              */
03339         case TBLOCK_STARTED:
03340             ereport(WARNING,
03341                     (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
03342                      errmsg("there is no transaction in progress")));
03343             result = true;
03344             break;
03345 
03346             /* These cases are invalid. */
03347         case TBLOCK_DEFAULT:
03348         case TBLOCK_BEGIN:
03349         case TBLOCK_SUBBEGIN:
03350         case TBLOCK_END:
03351         case TBLOCK_SUBRELEASE:
03352         case TBLOCK_SUBCOMMIT:
03353         case TBLOCK_ABORT_END:
03354         case TBLOCK_SUBABORT_END:
03355         case TBLOCK_ABORT_PENDING:
03356         case TBLOCK_SUBABORT_PENDING:
03357         case TBLOCK_SUBRESTART:
03358         case TBLOCK_SUBABORT_RESTART:
03359         case TBLOCK_PREPARE:
03360             elog(FATAL, "EndTransactionBlock: unexpected state %s",
03361                  BlockStateAsString(s->blockState));
03362             break;
03363     }
03364 
03365     return result;
03366 }
03367 
03368 /*
03369  *  UserAbortTransactionBlock
03370  *      This executes a ROLLBACK command.
03371  *
03372  * As above, we don't actually do anything here except change blockState.
03373  */
03374 void
03375 UserAbortTransactionBlock(void)
03376 {
03377     TransactionState s = CurrentTransactionState;
03378 
03379     switch (s->blockState)
03380     {
03381             /*
03382              * We are inside a transaction block and we got a ROLLBACK command
03383              * from the user, so tell CommitTransactionCommand to abort and
03384              * exit the transaction block.
03385              */
03386         case TBLOCK_INPROGRESS:
03387             s->blockState = TBLOCK_ABORT_PENDING;
03388             break;
03389 
03390             /*
03391              * We are inside a failed transaction block and we got a ROLLBACK
03392              * command from the user.  Abort processing is already done, so
03393              * CommitTransactionCommand just has to cleanup and go back to
03394              * idle state.
03395              */
03396         case TBLOCK_ABORT:
03397             s->blockState = TBLOCK_ABORT_END;
03398             break;
03399 
03400             /*
03401              * We are inside a subtransaction.  Mark everything up to top
03402              * level as exitable.
03403              */
03404         case TBLOCK_SUBINPROGRESS:
03405         case TBLOCK_SUBABORT:
03406             while (s->parent != NULL)
03407             {
03408                 if (s->blockState == TBLOCK_SUBINPROGRESS)
03409                     s->blockState = TBLOCK_SUBABORT_PENDING;
03410                 else if (s->blockState == TBLOCK_SUBABORT)
03411                     s->blockState = TBLOCK_SUBABORT_END;
03412                 else
03413                     elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
03414                          BlockStateAsString(s->blockState));
03415                 s = s->parent;
03416             }
03417             if (s->blockState == TBLOCK_INPROGRESS)
03418                 s->blockState = TBLOCK_ABORT_PENDING;
03419             else if (s->blockState == TBLOCK_ABORT)
03420                 s->blockState = TBLOCK_ABORT_END;
03421             else
03422                 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
03423                      BlockStateAsString(s->blockState));
03424             break;
03425 
03426             /*
03427              * The user issued ABORT when not inside a transaction. Issue a
03428              * NOTICE and go to abort state.  The upcoming call to
03429              * CommitTransactionCommand() will then put us back into the
03430              * default state.
03431              */
03432         case TBLOCK_STARTED:
03433             ereport(NOTICE,
03434                     (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
03435                      errmsg("there is no transaction in progress")));
03436             s->blockState = TBLOCK_ABORT_PENDING;
03437             break;
03438 
03439             /* These cases are invalid. */
03440         case TBLOCK_DEFAULT:
03441         case TBLOCK_BEGIN:
03442         case TBLOCK_SUBBEGIN:
03443         case TBLOCK_END:
03444         case TBLOCK_SUBRELEASE:
03445         case TBLOCK_SUBCOMMIT:
03446         case TBLOCK_ABORT_END:
03447         case TBLOCK_SUBABORT_END:
03448         case TBLOCK_ABORT_PENDING:
03449         case TBLOCK_SUBABORT_PENDING:
03450         case TBLOCK_SUBRESTART:
03451         case TBLOCK_SUBABORT_RESTART:
03452         case TBLOCK_PREPARE:
03453             elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
03454                  BlockStateAsString(s->blockState));
03455             break;
03456     }
03457 }
03458 
03459 /*
03460  * DefineSavepoint
03461  *      This executes a SAVEPOINT command.
03462  */
03463 void
03464 DefineSavepoint(char *name)
03465 {
03466     TransactionState s = CurrentTransactionState;
03467 
03468     switch (s->blockState)
03469     {
03470         case TBLOCK_INPROGRESS:
03471         case TBLOCK_SUBINPROGRESS:
03472             /* Normal subtransaction start */
03473             PushTransaction();
03474             s = CurrentTransactionState;        /* changed by push */
03475 
03476             /*
03477              * Savepoint names, like the TransactionState block itself, live
03478              * in TopTransactionContext.
03479              */
03480             if (name)
03481                 s->name = MemoryContextStrdup(TopTransactionContext, name);
03482             break;
03483 
03484             /* These cases are invalid. */
03485         case TBLOCK_DEFAULT:
03486         case TBLOCK_STARTED:
03487         case TBLOCK_BEGIN:
03488         case TBLOCK_SUBBEGIN:
03489         case TBLOCK_END:
03490         case TBLOCK_SUBRELEASE:
03491         case TBLOCK_SUBCOMMIT:
03492         case TBLOCK_ABORT:
03493         case TBLOCK_SUBABORT:
03494         case TBLOCK_ABORT_END:
03495         case TBLOCK_SUBABORT_END:
03496         case TBLOCK_ABORT_PENDING:
03497         case TBLOCK_SUBABORT_PENDING:
03498         case TBLOCK_SUBRESTART:
03499         case TBLOCK_SUBABORT_RESTART:
03500         case TBLOCK_PREPARE:
03501             elog(FATAL, "DefineSavepoint: unexpected state %s",
03502                  BlockStateAsString(s->blockState));
03503             break;
03504     }
03505 }
03506 
03507 /*
03508  * ReleaseSavepoint
03509  *      This executes a RELEASE command.
03510  *
03511  * As above, we don't actually do anything here except change blockState.
03512  */
03513 void
03514 ReleaseSavepoint(List *options)
03515 {
03516     TransactionState s = CurrentTransactionState;
03517     TransactionState target,
03518                 xact;
03519     ListCell   *cell;
03520     char       *name = NULL;
03521 
03522     switch (s->blockState)
03523     {
03524             /*
03525              * We can't rollback to a savepoint if there is no savepoint
03526              * defined.
03527              */
03528         case TBLOCK_INPROGRESS:
03529             ereport(ERROR,
03530                     (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
03531                      errmsg("no such savepoint")));
03532             break;
03533 
03534             /*
03535              * We are in a non-aborted subtransaction.  This is the only valid
03536              * case.
03537              */
03538         case TBLOCK_SUBINPROGRESS:
03539             break;
03540 
03541             /* These cases are invalid. */
03542         case TBLOCK_DEFAULT:
03543         case TBLOCK_STARTED:
03544         case TBLOCK_BEGIN:
03545         case TBLOCK_SUBBEGIN:
03546         case TBLOCK_END:
03547         case TBLOCK_SUBRELEASE:
03548         case TBLOCK_SUBCOMMIT:
03549         case TBLOCK_ABORT:
03550         case TBLOCK_SUBABORT:
03551         case TBLOCK_ABORT_END:
03552         case TBLOCK_SUBABORT_END:
03553         case TBLOCK_ABORT_PENDING:
03554         case TBLOCK_SUBABORT_PENDING:
03555         case TBLOCK_SUBRESTART:
03556         case TBLOCK_SUBABORT_RESTART:
03557         case TBLOCK_PREPARE:
03558             elog(FATAL, "ReleaseSavepoint: unexpected state %s",
03559                  BlockStateAsString(s->blockState));
03560             break;
03561     }
03562 
03563     foreach(cell, options)
03564     {
03565         DefElem    *elem = lfirst(cell);
03566 
03567         if (strcmp(elem->defname, "savepoint_name") == 0)
03568             name = strVal(elem->arg);
03569     }
03570 
03571     Assert(PointerIsValid(name));
03572 
03573     for (target = s; PointerIsValid(target); target = target->parent)
03574     {
03575         if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
03576             break;
03577     }
03578 
03579     if (!PointerIsValid(target))
03580         ereport(ERROR,
03581                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
03582                  errmsg("no such savepoint")));
03583 
03584     /* disallow crossing savepoint level boundaries */
03585     if (target->savepointLevel != s->savepointLevel)
03586         ereport(ERROR,
03587                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
03588                  errmsg("no such savepoint")));
03589 
03590     /*
03591      * Mark "commit pending" all subtransactions up to the target
03592      * subtransaction.  The actual commits will happen when control gets to
03593      * CommitTransactionCommand.
03594      */
03595     xact = CurrentTransactionState;
03596     for (;;)
03597     {
03598         Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
03599         xact->blockState = TBLOCK_SUBRELEASE;
03600         if (xact == target)
03601             break;
03602         xact = xact->parent;
03603         Assert(PointerIsValid(xact));
03604     }
03605 }
03606 
03607 /*
03608  * RollbackToSavepoint
03609  *      This executes a ROLLBACK TO <savepoint> command.
03610  *
03611  * As above, we don't actually do anything here except change blockState.
03612  */
03613 void
03614 RollbackToSavepoint(List *options)
03615 {
03616     TransactionState s = CurrentTransactionState;
03617     TransactionState target,
03618                 xact;
03619     ListCell   *cell;
03620     char       *name = NULL;
03621 
03622     switch (s->blockState)
03623     {
03624             /*
03625              * We can't rollback to a savepoint if there is no savepoint
03626              * defined.
03627              */
03628         case TBLOCK_INPROGRESS:
03629         case TBLOCK_ABORT:
03630             ereport(ERROR,
03631                     (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
03632                      errmsg("no such savepoint")));
03633             break;
03634 
03635             /*
03636              * There is at least one savepoint, so proceed.
03637              */
03638         case TBLOCK_SUBINPROGRESS:
03639         case TBLOCK_SUBABORT:
03640             break;
03641 
03642             /* These cases are invalid. */
03643         case TBLOCK_DEFAULT:
03644         case TBLOCK_STARTED:
03645         case TBLOCK_BEGIN:
03646         case TBLOCK_SUBBEGIN:
03647         case TBLOCK_END:
03648         case TBLOCK_SUBRELEASE:
03649         case TBLOCK_SUBCOMMIT:
03650         case TBLOCK_ABORT_END:
03651         case TBLOCK_SUBABORT_END:
03652         case TBLOCK_ABORT_PENDING:
03653         case TBLOCK_SUBABORT_PENDING:
03654         case TBLOCK_SUBRESTART:
03655         case TBLOCK_SUBABORT_RESTART:
03656         case TBLOCK_PREPARE:
03657             elog(FATAL, "RollbackToSavepoint: unexpected state %s",
03658                  BlockStateAsString(s->blockState));
03659             break;
03660     }
03661 
03662     foreach(cell, options)
03663     {
03664         DefElem    *elem = lfirst(cell);
03665 
03666         if (strcmp(elem->defname, "savepoint_name") == 0)
03667             name = strVal(elem->arg);
03668     }
03669 
03670     Assert(PointerIsValid(name));
03671 
03672     for (target = s; PointerIsValid(target); target = target->parent)
03673     {
03674         if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
03675             break;
03676     }
03677 
03678     if (!PointerIsValid(target))
03679         ereport(ERROR,
03680                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
03681                  errmsg("no such savepoint")));
03682 
03683     /* disallow crossing savepoint level boundaries */
03684     if (target->savepointLevel != s->savepointLevel)
03685         ereport(ERROR,
03686                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
03687                  errmsg("no such savepoint")));
03688 
03689     /*
03690      * Mark "abort pending" all subtransactions up to the target
03691      * subtransaction.  The actual aborts will happen when control gets to
03692      * CommitTransactionCommand.
03693      */
03694     xact = CurrentTransactionState;
03695     for (;;)
03696     {
03697         if (xact == target)
03698             break;
03699         if (xact->blockState == TBLOCK_SUBINPROGRESS)
03700             xact->blockState = TBLOCK_SUBABORT_PENDING;
03701         else if (xact->blockState == TBLOCK_SUBABORT)
03702             xact->blockState = TBLOCK_SUBABORT_END;
03703         else
03704             elog(FATAL, "RollbackToSavepoint: unexpected state %s",
03705                  BlockStateAsString(xact->blockState));
03706         xact = xact->parent;
03707         Assert(PointerIsValid(xact));
03708     }
03709 
03710     /* And mark the target as "restart pending" */
03711     if (xact->blockState == TBLOCK_SUBINPROGRESS)
03712         xact->blockState = TBLOCK_SUBRESTART;
03713     else if (xact->blockState == TBLOCK_SUBABORT)
03714         xact->blockState = TBLOCK_SUBABORT_RESTART;
03715     else
03716         elog(FATAL, "RollbackToSavepoint: unexpected state %s",
03717              BlockStateAsString(xact->blockState));
03718 }
03719 
03720 /*
03721  * BeginInternalSubTransaction
03722  *      This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
03723  *      TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
03724  *      used in functions that might be called when not inside a BEGIN block
03725  *      or when running deferred triggers at COMMIT/PREPARE time.  Also, it
03726  *      automatically does CommitTransactionCommand/StartTransactionCommand
03727  *      instead of expecting the caller to do it.
03728  */
03729 void
03730 BeginInternalSubTransaction(char *name)
03731 {
03732     TransactionState s = CurrentTransactionState;
03733 
03734     switch (s->blockState)
03735     {
03736         case TBLOCK_STARTED:
03737         case TBLOCK_INPROGRESS:
03738         case TBLOCK_END:
03739         case TBLOCK_PREPARE:
03740         case TBLOCK_SUBINPROGRESS:
03741             /* Normal subtransaction start */
03742             PushTransaction();
03743             s = CurrentTransactionState;        /* changed by push */
03744 
03745             /*
03746              * Savepoint names, like the TransactionState block itself, live
03747              * in TopTransactionContext.
03748              */
03749             if (name)
03750                 s->name = MemoryContextStrdup(TopTransactionContext, name);
03751             break;
03752 
03753             /* These cases are invalid. */
03754         case TBLOCK_DEFAULT:
03755         case TBLOCK_BEGIN:
03756         case TBLOCK_SUBBEGIN:
03757         case TBLOCK_SUBRELEASE:
03758         case TBLOCK_SUBCOMMIT:
03759         case TBLOCK_ABORT:
03760         case TBLOCK_SUBABORT:
03761         case TBLOCK_ABORT_END:
03762         case TBLOCK_SUBABORT_END:
03763         case TBLOCK_ABORT_PENDING:
03764         case TBLOCK_SUBABORT_PENDING:
03765         case TBLOCK_SUBRESTART:
03766         case TBLOCK_SUBABORT_RESTART:
03767             elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
03768                  BlockStateAsString(s->blockState));
03769             break;
03770     }
03771 
03772     CommitTransactionCommand();
03773     StartTransactionCommand();
03774 }
03775 
03776 /*
03777  * ReleaseCurrentSubTransaction
03778  *
03779  * RELEASE (ie, commit) the innermost subtransaction, regardless of its
03780  * savepoint name (if any).
03781  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
03782  */
03783 void
03784 ReleaseCurrentSubTransaction(void)
03785 {
03786     TransactionState s = CurrentTransactionState;
03787 
03788     if (s->blockState != TBLOCK_SUBINPROGRESS)
03789         elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
03790              BlockStateAsString(s->blockState));
03791     Assert(s->state == TRANS_INPROGRESS);
03792     MemoryContextSwitchTo(CurTransactionContext);
03793     CommitSubTransaction();
03794     s = CurrentTransactionState;    /* changed by pop */
03795     Assert(s->state == TRANS_INPROGRESS);
03796 }
03797 
03798 /*
03799  * RollbackAndReleaseCurrentSubTransaction
03800  *
03801  * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
03802  * of its savepoint name (if any).
03803  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
03804  */
03805 void
03806 RollbackAndReleaseCurrentSubTransaction(void)
03807 {
03808     TransactionState s = CurrentTransactionState;
03809 
03810     switch (s->blockState)
03811     {
03812             /* Must be in a subtransaction */
03813         case TBLOCK_SUBINPROGRESS:
03814         case TBLOCK_SUBABORT:
03815             break;
03816 
03817             /* These cases are invalid. */
03818         case TBLOCK_DEFAULT:
03819         case TBLOCK_STARTED:
03820         case TBLOCK_BEGIN:
03821         case TBLOCK_SUBBEGIN:
03822         case TBLOCK_INPROGRESS:
03823         case TBLOCK_END:
03824         case TBLOCK_SUBRELEASE:
03825         case TBLOCK_SUBCOMMIT:
03826         case TBLOCK_ABORT:
03827         case TBLOCK_ABORT_END:
03828         case TBLOCK_SUBABORT_END:
03829         case TBLOCK_ABORT_PENDING:
03830         case TBLOCK_SUBABORT_PENDING:
03831         case TBLOCK_SUBRESTART:
03832         case TBLOCK_SUBABORT_RESTART:
03833         case TBLOCK_PREPARE:
03834             elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
03835                  BlockStateAsString(s->blockState));
03836             break;
03837     }
03838 
03839     /*
03840      * Abort the current subtransaction, if needed.
03841      */
03842     if (s->blockState == TBLOCK_SUBINPROGRESS)
03843         AbortSubTransaction();
03844 
03845     /* And clean it up, too */
03846     CleanupSubTransaction();
03847 
03848     s = CurrentTransactionState;    /* changed by pop */
03849     AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
03850                 s->blockState == TBLOCK_INPROGRESS ||
03851                 s->blockState == TBLOCK_STARTED);
03852 }
03853 
03854 /*
03855  *  AbortOutOfAnyTransaction
03856  *
03857  *  This routine is provided for error recovery purposes.  It aborts any
03858  *  active transaction or transaction block, leaving the system in a known
03859  *  idle state.
03860  */
03861 void
03862 AbortOutOfAnyTransaction(void)
03863 {
03864     TransactionState s = CurrentTransactionState;
03865 
03866     /*
03867      * Get out of any transaction or nested transaction
03868      */
03869     do
03870     {
03871         switch (s->blockState)
03872         {
03873             case TBLOCK_DEFAULT:
03874                 if (s->state == TRANS_DEFAULT)
03875                 {
03876                     /* Not in a transaction, do nothing */
03877                 }
03878                 else
03879                 {
03880                     /*
03881                      * We can get here after an error during transaction start
03882                      * (state will be TRANS_START).  Need to clean up the
03883                      * incompletely started transaction.  First, adjust the
03884                      * low-level state to suppress warning message from
03885                      * AbortTransaction.
03886                      */
03887                     if (s->state == TRANS_START)
03888                         s->state = TRANS_INPROGRESS;
03889                     AbortTransaction();
03890                     CleanupTransaction();
03891                 }
03892                 break;
03893             case TBLOCK_STARTED:
03894             case TBLOCK_BEGIN:
03895             case TBLOCK_INPROGRESS:
03896             case TBLOCK_END:
03897             case TBLOCK_ABORT_PENDING:
03898             case TBLOCK_PREPARE:
03899                 /* In a transaction, so clean up */
03900                 AbortTransaction();
03901                 CleanupTransaction();
03902                 s->blockState = TBLOCK_DEFAULT;
03903                 break;
03904             case TBLOCK_ABORT:
03905             case TBLOCK_ABORT_END:
03906                 /* AbortTransaction already done, still need Cleanup */
03907                 CleanupTransaction();
03908                 s->blockState = TBLOCK_DEFAULT;
03909                 break;
03910 
03911                 /*
03912                  * In a subtransaction, so clean it up and abort parent too
03913                  */
03914             case TBLOCK_SUBBEGIN:
03915             case TBLOCK_SUBINPROGRESS:
03916             case TBLOCK_SUBRELEASE:
03917             case TBLOCK_SUBCOMMIT:
03918             case TBLOCK_SUBABORT_PENDING:
03919             case TBLOCK_SUBRESTART:
03920                 AbortSubTransaction();
03921                 CleanupSubTransaction();
03922                 s = CurrentTransactionState;    /* changed by pop */
03923                 break;
03924 
03925             case TBLOCK_SUBABORT:
03926             case TBLOCK_SUBABORT_END:
03927             case TBLOCK_SUBABORT_RESTART:
03928                 /* As above, but AbortSubTransaction already done */
03929                 CleanupSubTransaction();
03930                 s = CurrentTransactionState;    /* changed by pop */
03931                 break;
03932         }
03933     } while (s->blockState != TBLOCK_DEFAULT);
03934 
03935     /* Should be out of all subxacts now */
03936     Assert(s->parent == NULL);
03937 }
03938 
03939 /*
03940  * IsTransactionBlock --- are we within a transaction block?
03941  */
03942 bool
03943 IsTransactionBlock(void)
03944 {
03945     TransactionState s = CurrentTransactionState;
03946 
03947     if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
03948         return false;
03949 
03950     return true;
03951 }
03952 
03953 /*
03954  * IsTransactionOrTransactionBlock --- are we within either a transaction
03955  * or a transaction block?  (The backend is only really "idle" when this
03956  * returns false.)
03957  *
03958  * This should match up with IsTransactionBlock and IsTransactionState.
03959  */
03960 bool
03961 IsTransactionOrTransactionBlock(void)
03962 {
03963     TransactionState s = CurrentTransactionState;
03964 
03965     if (s->blockState == TBLOCK_DEFAULT)
03966         return false;
03967 
03968     return true;
03969 }
03970 
03971 /*
03972  * TransactionBlockStatusCode - return status code to send in ReadyForQuery
03973  */
03974 char
03975 TransactionBlockStatusCode(void)
03976 {
03977     TransactionState s = CurrentTransactionState;
03978 
03979     switch (s->blockState)
03980     {
03981         case TBLOCK_DEFAULT:
03982         case TBLOCK_STARTED:
03983             return 'I';         /* idle --- not in transaction */
03984         case TBLOCK_BEGIN:
03985         case TBLOCK_SUBBEGIN:
03986         case TBLOCK_INPROGRESS:
03987         case TBLOCK_SUBINPROGRESS:
03988         case TBLOCK_END:
03989         case TBLOCK_SUBRELEASE:
03990         case TBLOCK_SUBCOMMIT:
03991         case TBLOCK_PREPARE:
03992             return 'T';         /* in transaction */
03993         case TBLOCK_ABORT:
03994         case TBLOCK_SUBABORT:
03995         case TBLOCK_ABORT_END:
03996         case TBLOCK_SUBABORT_END:
03997         case TBLOCK_ABORT_PENDING:
03998         case TBLOCK_SUBABORT_PENDING:
03999         case TBLOCK_SUBRESTART:
04000         case TBLOCK_SUBABORT_RESTART:
04001             return 'E';         /* in failed transaction */
04002     }
04003 
04004     /* should never get here */
04005     elog(FATAL, "invalid transaction block state: %s",
04006          BlockStateAsString(s->blockState));
04007     return 0;                   /* keep compiler quiet */
04008 }
04009 
04010 /*
04011  * IsSubTransaction
04012  */
04013 bool
04014 IsSubTransaction(void)
04015 {
04016     TransactionState s = CurrentTransactionState;
04017 
04018     if (s->nestingLevel >= 2)
04019         return true;
04020 
04021     return false;
04022 }
04023 
04024 /*
04025  * StartSubTransaction
04026  *
04027  * If you're wondering why this is separate from PushTransaction: it's because
04028  * we can't conveniently do this stuff right inside DefineSavepoint.  The
04029  * SAVEPOINT utility command will be executed inside a Portal, and if we
04030  * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
04031  * the Portal will undo those settings.  So we make DefineSavepoint just
04032  * push a dummy transaction block, and when control returns to the main
04033  * idle loop, CommitTransactionCommand will be called, and we'll come here
04034  * to finish starting the subtransaction.
04035  */
04036 static void
04037 StartSubTransaction(void)
04038 {
04039     TransactionState s = CurrentTransactionState;
04040 
04041     if (s->state != TRANS_DEFAULT)
04042         elog(WARNING, "StartSubTransaction while in %s state",
04043              TransStateAsString(s->state));
04044 
04045     s->state = TRANS_START;
04046 
04047     /*
04048      * Initialize subsystems for new subtransaction
04049      *
04050      * must initialize resource-management stuff first
04051      */
04052     AtSubStart_Memory();
04053     AtSubStart_ResourceOwner();
04054     AtSubStart_Inval();
04055     AtSubStart_Notify();
04056     AfterTriggerBeginSubXact();
04057 
04058     s->state = TRANS_INPROGRESS;
04059 
04060     /*
04061      * Call start-of-subxact callbacks
04062      */
04063     CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
04064                          s->parent->subTransactionId);
04065 
04066     ShowTransactionState("StartSubTransaction");
04067 }
04068 
04069 /*
04070  * CommitSubTransaction
04071  *
04072  *  The caller has to make sure to always reassign CurrentTransactionState
04073  *  if it has a local pointer to it after calling this function.
04074  */
04075 static void
04076 CommitSubTransaction(void)
04077 {
04078     TransactionState s = CurrentTransactionState;
04079 
04080     ShowTransactionState("CommitSubTransaction");
04081 
04082     if (s->state != TRANS_INPROGRESS)
04083         elog(WARNING, "CommitSubTransaction while in %s state",
04084              TransStateAsString(s->state));
04085 
04086     /* Pre-commit processing goes here */
04087 
04088     CallSubXactCallbacks(SUBXACT_EVENT_PRE_COMMIT_SUB, s->subTransactionId,
04089                          s->parent->subTransactionId);
04090 
04091     /* Do the actual "commit", such as it is */
04092     s->state = TRANS_COMMIT;
04093 
04094     /* Must CCI to ensure commands of subtransaction are seen as done */
04095     CommandCounterIncrement();
04096 
04097     /*
04098      * Prior to 8.4 we marked subcommit in clog at this point.  We now only
04099      * perform that step, if required, as part of the atomic update of the
04100      * whole transaction tree at top level commit or abort.
04101      */
04102 
04103     /* Post-commit cleanup */
04104     if (TransactionIdIsValid(s->transactionId))
04105         AtSubCommit_childXids();
04106     AfterTriggerEndSubXact(true);
04107     AtSubCommit_Portals(s->subTransactionId,
04108                         s->parent->subTransactionId,
04109                         s->parent->curTransactionOwner);
04110     AtEOSubXact_LargeObject(true, s->subTransactionId,
04111                             s->parent->subTransactionId);
04112     AtSubCommit_Notify();
04113 
04114     CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
04115                          s->parent->subTransactionId);
04116 
04117     ResourceOwnerRelease(s->curTransactionOwner,
04118                          RESOURCE_RELEASE_BEFORE_LOCKS,
04119                          true, false);
04120     AtEOSubXact_RelationCache(true, s->subTransactionId,
04121                               s->parent->subTransactionId);
04122     AtEOSubXact_Inval(true);
04123     AtSubCommit_smgr();
04124 
04125     /*
04126      * The only lock we actually release here is the subtransaction XID lock.
04127      */
04128     CurrentResourceOwner = s->curTransactionOwner;
04129     if (TransactionIdIsValid(s->transactionId))
04130         XactLockTableDelete(s->transactionId);
04131 
04132     /*
04133      * Other locks should get transferred to their parent resource owner.
04134      */
04135     ResourceOwnerRelease(s->curTransactionOwner,
04136                          RESOURCE_RELEASE_LOCKS,
04137                          true, false);
04138     ResourceOwnerRelease(s->curTransactionOwner,
04139                          RESOURCE_RELEASE_AFTER_LOCKS,
04140                          true, false);
04141 
04142     AtEOXact_GUC(true, s->gucNestLevel);
04143     AtEOSubXact_SPI(true, s->subTransactionId);
04144     AtEOSubXact_on_commit_actions(true, s->subTransactionId,
04145                                   s->parent->subTransactionId);
04146     AtEOSubXact_Namespace(true, s->subTransactionId,
04147                           s->parent->subTransactionId);
04148     AtEOSubXact_Files(true, s->subTransactionId,
04149                       s->parent->subTransactionId);
04150     AtEOSubXact_HashTables(true, s->nestingLevel);
04151     AtEOSubXact_PgStat(true, s->nestingLevel);
04152     AtSubCommit_Snapshot(s->nestingLevel);
04153 
04154     /*
04155      * We need to restore the upper transaction's read-only state, in case the
04156      * upper is read-write while the child is read-only; GUC will incorrectly
04157      * think it should leave the child state in place.
04158      */
04159     XactReadOnly = s->prevXactReadOnly;
04160 
04161     CurrentResourceOwner = s->parent->curTransactionOwner;
04162     CurTransactionResourceOwner = s->parent->curTransactionOwner;
04163     ResourceOwnerDelete(s->curTransactionOwner);
04164     s->curTransactionOwner = NULL;
04165 
04166     AtSubCommit_Memory();
04167 
04168     s->state = TRANS_DEFAULT;
04169 
04170     PopTransaction();
04171 }
04172 
04173 /*
04174  * AbortSubTransaction
04175  */
04176 static void
04177 AbortSubTransaction(void)
04178 {
04179     TransactionState s = CurrentTransactionState;
04180 
04181     /* Prevent cancel/die interrupt while cleaning up */
04182     HOLD_INTERRUPTS();
04183 
04184     /* Make sure we have a valid memory context and resource owner */
04185     AtSubAbort_Memory();
04186     AtSubAbort_ResourceOwner();
04187 
04188     /*
04189      * Release any LW locks we might be holding as quickly as possible.
04190      * (Regular locks, however, must be held till we finish aborting.)
04191      * Releasing LW locks is critical since we might try to grab them again
04192      * while cleaning up!
04193      *
04194      * FIXME This may be incorrect --- Are there some locks we should keep?
04195      * Buffer locks, for example?  I don't think so but I'm not sure.
04196      */
04197     LWLockReleaseAll();
04198 
04199     AbortBufferIO();
04200     UnlockBuffers();
04201 
04202     LockErrorCleanup();
04203 
04204     /*
04205      * check the current transaction state
04206      */
04207     ShowTransactionState("AbortSubTransaction");
04208 
04209     if (s->state != TRANS_INPROGRESS)
04210         elog(WARNING, "AbortSubTransaction while in %s state",
04211              TransStateAsString(s->state));
04212 
04213     s->state = TRANS_ABORT;
04214 
04215     /*
04216      * Reset user ID which might have been changed transiently.  (See notes in
04217      * AbortTransaction.)
04218      */
04219     SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
04220 
04221     /*
04222      * We can skip all this stuff if the subxact failed before creating a
04223      * ResourceOwner...
04224      */
04225     if (s->curTransactionOwner)
04226     {
04227         AfterTriggerEndSubXact(false);
04228         AtSubAbort_Portals(s->subTransactionId,
04229                            s->parent->subTransactionId,
04230                            s->parent->curTransactionOwner);
04231         AtEOSubXact_LargeObject(false, s->subTransactionId,
04232                                 s->parent->subTransactionId);
04233         AtSubAbort_Notify();
04234 
04235         /* Advertise the fact that we aborted in pg_clog. */
04236         (void) RecordTransactionAbort(true);
04237 
04238         /* Post-abort cleanup */
04239         if (TransactionIdIsValid(s->transactionId))
04240             AtSubAbort_childXids();
04241 
04242         CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
04243                              s->parent->subTransactionId);
04244 
04245         ResourceOwnerRelease(s->curTransactionOwner,
04246                              RESOURCE_RELEASE_BEFORE_LOCKS,
04247                              false, false);
04248         AtEOSubXact_RelationCache(false, s->subTransactionId,
04249                                   s->parent->subTransactionId);
04250         AtEOSubXact_Inval(false);
04251         ResourceOwnerRelease(s->curTransactionOwner,
04252                              RESOURCE_RELEASE_LOCKS,
04253                              false, false);
04254         ResourceOwnerRelease(s->curTransactionOwner,
04255                              RESOURCE_RELEASE_AFTER_LOCKS,
04256                              false, false);
04257         AtSubAbort_smgr();
04258 
04259         AtEOXact_GUC(false, s->gucNestLevel);
04260         AtEOSubXact_SPI(false, s->subTransactionId);
04261         AtEOSubXact_on_commit_actions(false, s->subTransactionId,
04262                                       s->parent->subTransactionId);
04263         AtEOSubXact_Namespace(false, s->subTransactionId,
04264                               s->parent->subTransactionId);
04265         AtEOSubXact_Files(false, s->subTransactionId,
04266                           s->parent->subTransactionId);
04267         AtEOSubXact_HashTables(false, s->nestingLevel);
04268         AtEOSubXact_PgStat(false, s->nestingLevel);
04269         AtSubAbort_Snapshot(s->nestingLevel);
04270     }
04271 
04272     /*
04273      * Restore the upper transaction's read-only state, too.  This should be
04274      * redundant with GUC's cleanup but we may as well do it for consistency
04275      * with the commit case.
04276      */
04277     XactReadOnly = s->prevXactReadOnly;
04278 
04279     RESUME_INTERRUPTS();
04280 }
04281 
04282 /*
04283  * CleanupSubTransaction
04284  *
04285  *  The caller has to make sure to always reassign CurrentTransactionState
04286  *  if it has a local pointer to it after calling this function.
04287  */
04288 static void
04289 CleanupSubTransaction(void)
04290 {
04291     TransactionState s = CurrentTransactionState;
04292 
04293     ShowTransactionState("CleanupSubTransaction");
04294 
04295     if (s->state != TRANS_ABORT)
04296         elog(WARNING, "CleanupSubTransaction while in %s state",
04297              TransStateAsString(s->state));
04298 
04299     AtSubCleanup_Portals(s->subTransactionId);
04300 
04301     CurrentResourceOwner = s->parent->curTransactionOwner;
04302     CurTransactionResourceOwner = s->parent->curTransactionOwner;
04303     if (s->curTransactionOwner)
04304         ResourceOwnerDelete(s->curTransactionOwner);
04305     s->curTransactionOwner = NULL;
04306 
04307     AtSubCleanup_Memory();
04308 
04309     s->state = TRANS_DEFAULT;
04310 
04311     PopTransaction();
04312 }
04313 
04314 /*
04315  * PushTransaction
04316  *      Create transaction state stack entry for a subtransaction
04317  *
04318  *  The caller has to make sure to always reassign CurrentTransactionState
04319  *  if it has a local pointer to it after calling this function.
04320  */
04321 static void
04322 PushTransaction(void)
04323 {
04324     TransactionState p = CurrentTransactionState;
04325     TransactionState s;
04326 
04327     /*
04328      * We keep subtransaction state nodes in TopTransactionContext.
04329      */
04330     s = (TransactionState)
04331         MemoryContextAllocZero(TopTransactionContext,
04332                                sizeof(TransactionStateData));
04333 
04334     /*
04335      * Assign a subtransaction ID, watching out for counter wraparound.
04336      */
04337     currentSubTransactionId += 1;
04338     if (currentSubTransactionId == InvalidSubTransactionId)
04339     {
04340         currentSubTransactionId -= 1;
04341         pfree(s);
04342         ereport(ERROR,
04343                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
04344                  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
04345     }
04346 
04347     /*
04348      * We can now stack a minimally valid subtransaction without fear of
04349      * failure.
04350      */
04351     s->transactionId = InvalidTransactionId;    /* until assigned */
04352     s->subTransactionId = currentSubTransactionId;
04353     s->parent = p;
04354     s->nestingLevel = p->nestingLevel + 1;
04355     s->gucNestLevel = NewGUCNestLevel();
04356     s->savepointLevel = p->savepointLevel;
04357     s->state = TRANS_DEFAULT;
04358     s->blockState = TBLOCK_SUBBEGIN;
04359     GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
04360     s->prevXactReadOnly = XactReadOnly;
04361 
04362     CurrentTransactionState = s;
04363 
04364     /*
04365      * AbortSubTransaction and CleanupSubTransaction have to be able to cope
04366      * with the subtransaction from here on out; in particular they should not
04367      * assume that it necessarily has a transaction context, resource owner,
04368      * or XID.
04369      */
04370 }
04371 
04372 /*
04373  * PopTransaction
04374  *      Pop back to parent transaction state
04375  *
04376  *  The caller has to make sure to always reassign CurrentTransactionState
04377  *  if it has a local pointer to it after calling this function.
04378  */
04379 static void
04380 PopTransaction(void)
04381 {
04382     TransactionState s = CurrentTransactionState;
04383 
04384     if (s->state != TRANS_DEFAULT)
04385         elog(WARNING, "PopTransaction while in %s state",
04386              TransStateAsString(s->state));
04387 
04388     if (s->parent == NULL)
04389         elog(FATAL, "PopTransaction with no parent");
04390 
04391     CurrentTransactionState = s->parent;
04392 
04393     /* Let's just make sure CurTransactionContext is good */
04394     CurTransactionContext = s->parent->curTransactionContext;
04395     MemoryContextSwitchTo(CurTransactionContext);
04396 
04397     /* Ditto for ResourceOwner links */
04398     CurTransactionResourceOwner = s->parent->curTransactionOwner;
04399     CurrentResourceOwner = s->parent->curTransactionOwner;
04400 
04401     /* Free the old child structure */
04402     if (s->name)
04403         pfree(s->name);
04404     pfree(s);
04405 }
04406 
04407 /*
04408  * ShowTransactionState
04409  *      Debug support
04410  */
04411 static void
04412 ShowTransactionState(const char *str)
04413 {
04414     /* skip work if message will definitely not be printed */
04415     if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
04416     {
04417         elog(DEBUG3, "%s", str);
04418         ShowTransactionStateRec(CurrentTransactionState);
04419     }
04420 }
04421 
04422 /*
04423  * ShowTransactionStateRec
04424  *      Recursive subroutine for ShowTransactionState
04425  */
04426 static void
04427 ShowTransactionStateRec(TransactionState s)
04428 {
04429     StringInfoData buf;
04430 
04431     initStringInfo(&buf);
04432 
04433     if (s->nChildXids > 0)
04434     {
04435         int         i;
04436 
04437         appendStringInfo(&buf, "%u", s->childXids[0]);
04438         for (i = 1; i < s->nChildXids; i++)
04439             appendStringInfo(&buf, " %u", s->childXids[i]);
04440     }
04441 
04442     if (s->parent)
04443         ShowTransactionStateRec(s->parent);
04444 
04445     /* use ereport to suppress computation if msg will not be printed */
04446     ereport(DEBUG3,
04447             (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
04448                              PointerIsValid(s->name) ? s->name : "unnamed",
04449                              BlockStateAsString(s->blockState),
04450                              TransStateAsString(s->state),
04451                              (unsigned int) s->transactionId,
04452                              (unsigned int) s->subTransactionId,
04453                              (unsigned int) currentCommandId,
04454                              currentCommandIdUsed ? " (used)" : "",
04455                              s->nestingLevel, buf.data)));
04456 
04457     pfree(buf.data);
04458 }
04459 
04460 /*
04461  * BlockStateAsString
04462  *      Debug support
04463  */
04464 static const char *
04465 BlockStateAsString(TBlockState blockState)
04466 {
04467     switch (blockState)
04468     {
04469         case TBLOCK_DEFAULT:
04470             return "DEFAULT";
04471         case TBLOCK_STARTED:
04472             return "STARTED";
04473         case TBLOCK_BEGIN:
04474             return "BEGIN";
04475         case TBLOCK_INPROGRESS:
04476             return "INPROGRESS";
04477         case TBLOCK_END:
04478             return "END";
04479         case TBLOCK_ABORT:
04480             return "ABORT";
04481         case TBLOCK_ABORT_END:
04482             return "ABORT END";
04483         case TBLOCK_ABORT_PENDING:
04484             return "ABORT PEND";
04485         case TBLOCK_PREPARE:
04486             return "PREPARE";
04487         case TBLOCK_SUBBEGIN:
04488             return "SUB BEGIN";
04489         case TBLOCK_SUBINPROGRESS:
04490             return "SUB INPROGRS";
04491         case TBLOCK_SUBRELEASE:
04492             return "SUB RELEASE";
04493         case TBLOCK_SUBCOMMIT:
04494             return "SUB COMMIT";
04495         case TBLOCK_SUBABORT:
04496             return "SUB ABORT";
04497         case TBLOCK_SUBABORT_END:
04498             return "SUB ABORT END";
04499         case TBLOCK_SUBABORT_PENDING:
04500             return "SUB ABRT PEND";
04501         case TBLOCK_SUBRESTART:
04502             return "SUB RESTART";
04503         case TBLOCK_SUBABORT_RESTART:
04504             return "SUB AB RESTRT";
04505     }
04506     return "UNRECOGNIZED";
04507 }
04508 
04509 /*
04510  * TransStateAsString
04511  *      Debug support
04512  */
04513 static const char *
04514 TransStateAsString(TransState state)
04515 {
04516     switch (state)
04517     {
04518         case TRANS_DEFAULT:
04519             return "DEFAULT";
04520         case TRANS_START:
04521             return "START";
04522         case TRANS_INPROGRESS:
04523             return "INPROGR";
04524         case TRANS_COMMIT:
04525             return "COMMIT";
04526         case TRANS_ABORT:
04527             return "ABORT";
04528         case TRANS_PREPARE:
04529             return "PREPARE";
04530     }
04531     return "UNRECOGNIZED";
04532 }
04533 
04534 /*
04535  * xactGetCommittedChildren
04536  *
04537  * Gets the list of committed children of the current transaction.  The return
04538  * value is the number of child transactions.  *ptr is set to point to an
04539  * array of TransactionIds.  The array is allocated in TopTransactionContext;
04540  * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
04541  * If there are no subxacts, *ptr is set to NULL.
04542  */
04543 int
04544 xactGetCommittedChildren(TransactionId **ptr)
04545 {
04546     TransactionState s = CurrentTransactionState;
04547 
04548     if (s->nChildXids == 0)
04549         *ptr = NULL;
04550     else
04551         *ptr = s->childXids;
04552 
04553     return s->nChildXids;
04554 }
04555 
04556 /*
04557  *  XLOG support routines
04558  */
04559 
04560 /*
04561  * Before 9.0 this was a fairly short function, but now it performs many
04562  * actions for which the order of execution is critical.
04563  */
04564 static void
04565 xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
04566                           TransactionId *sub_xids, int nsubxacts,
04567                           SharedInvalidationMessage *inval_msgs, int nmsgs,
04568                           RelFileNode *xnodes, int nrels,
04569                           Oid dbId, Oid tsId,
04570                           uint32 xinfo)
04571 {
04572     TransactionId max_xid;
04573     int         i;
04574 
04575     max_xid = TransactionIdLatest(xid, nsubxacts, sub_xids);
04576 
04577     /*
04578      * Make sure nextXid is beyond any XID mentioned in the record.
04579      *
04580      * We don't expect anyone else to modify nextXid, hence we don't need to
04581      * hold a lock while checking this. We still acquire the lock to modify
04582      * it, though.
04583      */
04584     if (TransactionIdFollowsOrEquals(max_xid,
04585                                      ShmemVariableCache->nextXid))
04586     {
04587         LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
04588         ShmemVariableCache->nextXid = max_xid;
04589         TransactionIdAdvance(ShmemVariableCache->nextXid);
04590         LWLockRelease(XidGenLock);
04591     }
04592 
04593     if (standbyState == STANDBY_DISABLED)
04594     {
04595         /*
04596          * Mark the transaction committed in pg_clog.
04597          */
04598         TransactionIdCommitTree(xid, nsubxacts, sub_xids);
04599     }
04600     else
04601     {
04602         /*
04603          * If a transaction completion record arrives that has as-yet
04604          * unobserved subtransactions then this will not have been fully
04605          * handled by the call to RecordKnownAssignedTransactionIds() in the
04606          * main recovery loop in xlog.c. So we need to do bookkeeping again to
04607          * cover that case. This is confusing and it is easy to think this
04608          * call is irrelevant, which has happened three times in development
04609          * already. Leave it in.
04610          */
04611         RecordKnownAssignedTransactionIds(max_xid);
04612 
04613         /*
04614          * Mark the transaction committed in pg_clog. We use async commit
04615          * protocol during recovery to provide information on database
04616          * consistency for when users try to set hint bits. It is important
04617          * that we do not set hint bits until the minRecoveryPoint is past
04618          * this commit record. This ensures that if we crash we don't see hint
04619          * bits set on changes made by transactions that haven't yet
04620          * recovered. It's unlikely but it's good to be safe.
04621          */
04622         TransactionIdAsyncCommitTree(xid, nsubxacts, sub_xids, lsn);
04623 
04624         /*
04625          * We must mark clog before we update the ProcArray.
04626          */
04627         ExpireTreeKnownAssignedTransactionIds(xid, nsubxacts, sub_xids, max_xid);
04628 
04629         /*
04630          * Send any cache invalidations attached to the commit. We must
04631          * maintain the same order of invalidation then release locks as
04632          * occurs in CommitTransaction().
04633          */
04634         ProcessCommittedInvalidationMessages(inval_msgs, nmsgs,
04635                                   XactCompletionRelcacheInitFileInval(xinfo),
04636                                              dbId, tsId);
04637 
04638         /*
04639          * Release locks, if any. We do this for both two phase and normal one
04640          * phase transactions. In effect we are ignoring the prepare phase and
04641          * just going straight to lock release. At commit we release all locks
04642          * via their top-level xid only, so no need to provide subxact list,
04643          * which will save time when replaying commits.
04644          */
04645         StandbyReleaseLockTree(xid, 0, NULL);
04646     }
04647 
04648     /* Make sure files supposed to be dropped are dropped */
04649     if (nrels > 0)
04650     {
04651         /*
04652          * First update minimum recovery point to cover this WAL record. Once
04653          * a relation is deleted, there's no going back. The buffer manager
04654          * enforces the WAL-first rule for normal updates to relation files,
04655          * so that the minimum recovery point is always updated before the
04656          * corresponding change in the data file is flushed to disk, but we
04657          * have to do the same here since we're bypassing the buffer manager.
04658          *
04659          * Doing this before deleting the files means that if a deletion fails
04660          * for some reason, you cannot start up the system even after restart,
04661          * until you fix the underlying situation so that the deletion will
04662          * succeed. Alternatively, we could update the minimum recovery point
04663          * after deletion, but that would leave a small window where the
04664          * WAL-first rule would be violated.
04665          */
04666         XLogFlush(lsn);
04667 
04668         for (i = 0; i < nrels; i++)
04669         {
04670             SMgrRelation srel = smgropen(xnodes[i], InvalidBackendId);
04671             ForkNumber  fork;
04672 
04673             for (fork = 0; fork <= MAX_FORKNUM; fork++)
04674                 XLogDropRelation(xnodes[i], fork);
04675             smgrdounlink(srel, true);
04676             smgrclose(srel);
04677         }
04678     }
04679 
04680     /*
04681      * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
04682      * in normal operation. For example, in CREATE DATABASE, we copy all files
04683      * from the template database, and then commit the transaction. If we
04684      * crash after all the files have been copied but before the commit, you
04685      * have files in the data directory without an entry in pg_database. To
04686      * minimize the window
04687      * for that, we use ForceSyncCommit() to rush the commit record to disk as
04688      * quick as possible. We have the same window during recovery, and forcing
04689      * an XLogFlush() (which updates minRecoveryPoint during recovery) helps
04690      * to reduce that problem window, for any user that requested
04691      * ForceSyncCommit().
04692      */
04693     if (XactCompletionForceSyncCommit(xinfo))
04694         XLogFlush(lsn);
04695 
04696 }
04697 
04698 /*
04699  * Utility function to call xact_redo_commit_internal after breaking down xlrec
04700  */
04701 static void
04702 xact_redo_commit(xl_xact_commit *xlrec,
04703                  TransactionId xid, XLogRecPtr lsn)
04704 {
04705     TransactionId *subxacts;
04706     SharedInvalidationMessage *inval_msgs;
04707 
04708     /* subxid array follows relfilenodes */
04709     subxacts = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
04710     /* invalidation messages array follows subxids */
04711     inval_msgs = (SharedInvalidationMessage *) &(subxacts[xlrec->nsubxacts]);
04712 
04713     xact_redo_commit_internal(xid, lsn, subxacts, xlrec->nsubxacts,
04714                               inval_msgs, xlrec->nmsgs,
04715                               xlrec->xnodes, xlrec->nrels,
04716                               xlrec->dbId,
04717                               xlrec->tsId,
04718                               xlrec->xinfo);
04719 }
04720 
04721 /*
04722  * Utility function to call xact_redo_commit_internal  for compact form of message.
04723  */
04724 static void
04725 xact_redo_commit_compact(xl_xact_commit_compact *xlrec,
04726                          TransactionId xid, XLogRecPtr lsn)
04727 {
04728     xact_redo_commit_internal(xid, lsn, xlrec->subxacts, xlrec->nsubxacts,
04729                               NULL, 0,  /* inval msgs */
04730                               NULL, 0,  /* relfilenodes */
04731                               InvalidOid,       /* dbId */
04732                               InvalidOid,       /* tsId */
04733                               0);       /* xinfo */
04734 }
04735 
04736 /*
04737  * Be careful with the order of execution, as with xact_redo_commit().
04738  * The two functions are similar but differ in key places.
04739  *
04740  * Note also that an abort can be for a subtransaction and its children,
04741  * not just for a top level abort. That means we have to consider
04742  * topxid != xid, whereas in commit we would find topxid == xid always
04743  * because subtransaction commit is never WAL logged.
04744  */
04745 static void
04746 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
04747 {
04748     TransactionId *sub_xids;
04749     TransactionId max_xid;
04750     int         i;
04751 
04752     sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
04753     max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
04754 
04755     /*
04756      * Make sure nextXid is beyond any XID mentioned in the record.
04757      *
04758      * We don't expect anyone else to modify nextXid, hence we don't need to
04759      * hold a lock while checking this. We still acquire the lock to modify
04760      * it, though.
04761      */
04762     if (TransactionIdFollowsOrEquals(max_xid,
04763                                      ShmemVariableCache->nextXid))
04764     {
04765         LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
04766         ShmemVariableCache->nextXid = max_xid;
04767         TransactionIdAdvance(ShmemVariableCache->nextXid);
04768         LWLockRelease(XidGenLock);
04769     }
04770 
04771     if (standbyState == STANDBY_DISABLED)
04772     {
04773         /* Mark the transaction aborted in pg_clog, no need for async stuff */
04774         TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
04775     }
04776     else
04777     {
04778         /*
04779          * If a transaction completion record arrives that has as-yet
04780          * unobserved subtransactions then this will not have been fully
04781          * handled by the call to RecordKnownAssignedTransactionIds() in the
04782          * main recovery loop in xlog.c. So we need to do bookkeeping again to
04783          * cover that case. This is confusing and it is easy to think this
04784          * call is irrelevant, which has happened three times in development
04785          * already. Leave it in.
04786          */
04787         RecordKnownAssignedTransactionIds(max_xid);
04788 
04789         /* Mark the transaction aborted in pg_clog, no need for async stuff */
04790         TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
04791 
04792         /*
04793          * We must update the ProcArray after we have marked clog.
04794          */
04795         ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids, max_xid);
04796 
04797         /*
04798          * There are no flat files that need updating, nor invalidation
04799          * messages to send or undo.
04800          */
04801 
04802         /*
04803          * Release locks, if any. There are no invalidations to send.
04804          */
04805         StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
04806     }
04807 
04808     /* Make sure files supposed to be dropped are dropped */
04809     for (i = 0; i < xlrec->nrels; i++)
04810     {
04811         SMgrRelation srel = smgropen(xlrec->xnodes[i], InvalidBackendId);
04812         ForkNumber  fork;
04813 
04814         for (fork = 0; fork <= MAX_FORKNUM; fork++)
04815             XLogDropRelation(xlrec->xnodes[i], fork);
04816         smgrdounlink(srel, true);
04817         smgrclose(srel);
04818     }
04819 }
04820 
04821 void
04822 xact_redo(XLogRecPtr lsn, XLogRecord *record)
04823 {
04824     uint8       info = record->xl_info & ~XLR_INFO_MASK;
04825 
04826     /* Backup blocks are not used in xact records */
04827     Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
04828 
04829     if (info == XLOG_XACT_COMMIT_COMPACT)
04830     {
04831         xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) XLogRecGetData(record);
04832 
04833         xact_redo_commit_compact(xlrec, record->xl_xid, lsn);
04834     }
04835     else if (info == XLOG_XACT_COMMIT)
04836     {
04837         xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
04838 
04839         xact_redo_commit(xlrec, record->xl_xid, lsn);
04840     }
04841     else if (info == XLOG_XACT_ABORT)
04842     {
04843         xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
04844 
04845         xact_redo_abort(xlrec, record->xl_xid);
04846     }
04847     else if (info == XLOG_XACT_PREPARE)
04848     {
04849         /* the record contents are exactly the 2PC file */
04850         RecreateTwoPhaseFile(record->xl_xid,
04851                              XLogRecGetData(record), record->xl_len);
04852     }
04853     else if (info == XLOG_XACT_COMMIT_PREPARED)
04854     {
04855         xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
04856 
04857         xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
04858         RemoveTwoPhaseFile(xlrec->xid, false);
04859     }
04860     else if (info == XLOG_XACT_ABORT_PREPARED)
04861     {
04862         xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
04863 
04864         xact_redo_abort(&xlrec->arec, xlrec->xid);
04865         RemoveTwoPhaseFile(xlrec->xid, false);
04866     }
04867     else if (info == XLOG_XACT_ASSIGNMENT)
04868     {
04869         xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
04870 
04871         if (standbyState >= STANDBY_INITIALIZED)
04872             ProcArrayApplyXidAssignment(xlrec->xtop,
04873                                         xlrec->nsubxacts, xlrec->xsub);
04874     }
04875     else
04876         elog(PANIC, "xact_redo: unknown op code %u", info);
04877 }