LCOV - differential code coverage report
Current view: top level - src/backend/access/transam - xact.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 86.9 % 1867 1622 36 163 46 56 1037 37 492 140 1066 3 28
Current Date: 2023-04-08 17:13:01 Functions: 93.5 % 107 100 7 100 7 98 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 87.5 % 16 14 2 1 12 1 1 1
Legend: Lines: hit not hit (120,180] days: 100.0 % 11 11 11 2 1
(180,240] days: 100.0 % 4 4 4
(240..) days: 86.8 % 1836 1593 36 161 46 56 1036 10 491 136 1056
Function coverage date bins:
(60,120] days: 0.0 % 1 0 1
(240..) days: 47.4 % 211 100 7 100 7 97

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * xact.c
                                  4                 :  *    top level transaction system support routines
                                  5                 :  *
                                  6                 :  * See src/backend/access/transam/README for more information.
                                  7                 :  *
                                  8                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  9                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                 10                 :  *
                                 11                 :  *
                                 12                 :  * IDENTIFICATION
                                 13                 :  *    src/backend/access/transam/xact.c
                                 14                 :  *
                                 15                 :  *-------------------------------------------------------------------------
                                 16                 :  */
                                 17                 : 
                                 18                 : #include "postgres.h"
                                 19                 : 
                                 20                 : #include <time.h>
                                 21                 : #include <unistd.h>
                                 22                 : 
                                 23                 : #include "access/commit_ts.h"
                                 24                 : #include "access/multixact.h"
                                 25                 : #include "access/parallel.h"
                                 26                 : #include "access/subtrans.h"
                                 27                 : #include "access/transam.h"
                                 28                 : #include "access/twophase.h"
                                 29                 : #include "access/xact.h"
                                 30                 : #include "access/xlog.h"
                                 31                 : #include "access/xloginsert.h"
                                 32                 : #include "access/xlogrecovery.h"
                                 33                 : #include "access/xlogutils.h"
                                 34                 : #include "catalog/index.h"
                                 35                 : #include "catalog/namespace.h"
                                 36                 : #include "catalog/pg_enum.h"
                                 37                 : #include "catalog/storage.h"
                                 38                 : #include "commands/async.h"
                                 39                 : #include "commands/tablecmds.h"
                                 40                 : #include "commands/trigger.h"
                                 41                 : #include "common/pg_prng.h"
                                 42                 : #include "executor/spi.h"
                                 43                 : #include "libpq/be-fsstubs.h"
                                 44                 : #include "libpq/pqsignal.h"
                                 45                 : #include "miscadmin.h"
                                 46                 : #include "pg_trace.h"
                                 47                 : #include "pgstat.h"
                                 48                 : #include "replication/logical.h"
                                 49                 : #include "replication/logicallauncher.h"
                                 50                 : #include "replication/logicalworker.h"
                                 51                 : #include "replication/origin.h"
                                 52                 : #include "replication/snapbuild.h"
                                 53                 : #include "replication/syncrep.h"
                                 54                 : #include "replication/walsender.h"
                                 55                 : #include "storage/condition_variable.h"
                                 56                 : #include "storage/fd.h"
                                 57                 : #include "storage/lmgr.h"
                                 58                 : #include "storage/md.h"
                                 59                 : #include "storage/predicate.h"
                                 60                 : #include "storage/proc.h"
                                 61                 : #include "storage/procarray.h"
                                 62                 : #include "storage/sinvaladt.h"
                                 63                 : #include "storage/smgr.h"
                                 64                 : #include "utils/builtins.h"
                                 65                 : #include "utils/catcache.h"
                                 66                 : #include "utils/combocid.h"
                                 67                 : #include "utils/guc.h"
                                 68                 : #include "utils/inval.h"
                                 69                 : #include "utils/memutils.h"
                                 70                 : #include "utils/relmapper.h"
                                 71                 : #include "utils/snapmgr.h"
                                 72                 : #include "utils/timeout.h"
                                 73                 : #include "utils/timestamp.h"
                                 74                 : 
                                 75                 : /*
                                 76                 :  *  User-tweakable parameters
                                 77                 :  */
                                 78                 : int         DefaultXactIsoLevel = XACT_READ_COMMITTED;
                                 79                 : int         XactIsoLevel = XACT_READ_COMMITTED;
                                 80                 : 
                                 81                 : bool        DefaultXactReadOnly = false;
                                 82                 : bool        XactReadOnly;
                                 83                 : 
                                 84                 : bool        DefaultXactDeferrable = false;
                                 85                 : bool        XactDeferrable;
                                 86                 : 
                                 87                 : int         synchronous_commit = SYNCHRONOUS_COMMIT_ON;
                                 88                 : 
                                 89                 : /*
                                 90                 :  * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
                                 91                 :  * transaction.  Currently, it is used in logical decoding.  It's possible
                                 92                 :  * that such transactions can get aborted while the decoding is ongoing in
                                 93                 :  * which case we skip decoding that particular transaction.  To ensure that we
                                 94                 :  * check whether the CheckXidAlive is aborted after fetching the tuple from
                                 95                 :  * system tables.  We also ensure that during logical decoding we never
                                 96                 :  * directly access the tableam or heap APIs because we are checking for the
                                 97                 :  * concurrent aborts only in systable_* APIs.
                                 98                 :  */
                                 99                 : TransactionId CheckXidAlive = InvalidTransactionId;
                                100                 : bool        bsysscan = false;
                                101                 : 
                                102                 : /*
                                103                 :  * When running as a parallel worker, we place only a single
                                104                 :  * TransactionStateData on the parallel worker's state stack, and the XID
                                105                 :  * reflected there will be that of the *innermost* currently-active
                                106                 :  * subtransaction in the backend that initiated parallelism.  However,
                                107                 :  * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
                                108                 :  * need to return the same answers in the parallel worker as they would have
                                109                 :  * in the user backend, so we need some additional bookkeeping.
                                110                 :  *
                                111                 :  * XactTopFullTransactionId stores the XID of our toplevel transaction, which
                                112                 :  * will be the same as TopTransactionStateData.fullTransactionId in an
                                113                 :  * ordinary backend; but in a parallel backend, which does not have the entire
                                114                 :  * transaction state, it will instead be copied from the backend that started
                                115                 :  * the parallel operation.
                                116                 :  *
                                117                 :  * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
                                118                 :  * backend, but in a parallel backend, nParallelCurrentXids will contain the
                                119                 :  * number of XIDs that need to be considered current, and ParallelCurrentXids
                                120                 :  * will contain the XIDs themselves.  This includes all XIDs that were current
                                121                 :  * or sub-committed in the parent at the time the parallel operation began.
                                122                 :  * The XIDs are stored sorted in numerical order (not logical order) to make
                                123                 :  * lookups as fast as possible.
                                124                 :  */
                                125                 : static FullTransactionId XactTopFullTransactionId = {InvalidTransactionId};
                                126                 : static int  nParallelCurrentXids = 0;
                                127                 : static TransactionId *ParallelCurrentXids;
                                128                 : 
                                129                 : /*
                                130                 :  * Miscellaneous flag bits to record events which occur on the top level
                                131                 :  * transaction. These flags are only persisted in MyXactFlags and are intended
                                132                 :  * so we remember to do certain things later on in the transaction. This is
                                133                 :  * globally accessible, so can be set from anywhere in the code that requires
                                134                 :  * recording flags.
                                135                 :  */
                                136                 : int         MyXactFlags;
                                137                 : 
                                138                 : /*
                                139                 :  *  transaction states - transaction state from server perspective
                                140                 :  */
                                141                 : typedef enum TransState
                                142                 : {
                                143                 :     TRANS_DEFAULT,              /* idle */
                                144                 :     TRANS_START,                /* transaction starting */
                                145                 :     TRANS_INPROGRESS,           /* inside a valid transaction */
                                146                 :     TRANS_COMMIT,               /* commit in progress */
                                147                 :     TRANS_ABORT,                /* abort in progress */
                                148                 :     TRANS_PREPARE               /* prepare in progress */
                                149                 : } TransState;
                                150                 : 
                                151                 : /*
                                152                 :  *  transaction block states - transaction state of client queries
                                153                 :  *
                                154                 :  * Note: the subtransaction states are used only for non-topmost
                                155                 :  * transactions; the others appear only in the topmost transaction.
                                156                 :  */
                                157                 : typedef enum TBlockState
                                158                 : {
                                159                 :     /* not-in-transaction-block states */
                                160                 :     TBLOCK_DEFAULT,             /* idle */
                                161                 :     TBLOCK_STARTED,             /* running single-query transaction */
                                162                 : 
                                163                 :     /* transaction block states */
                                164                 :     TBLOCK_BEGIN,               /* starting transaction block */
                                165                 :     TBLOCK_INPROGRESS,          /* live transaction */
                                166                 :     TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
                                167                 :     TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
                                168                 :     TBLOCK_END,                 /* COMMIT received */
                                169                 :     TBLOCK_ABORT,               /* failed xact, awaiting ROLLBACK */
                                170                 :     TBLOCK_ABORT_END,           /* failed xact, ROLLBACK received */
                                171                 :     TBLOCK_ABORT_PENDING,       /* live xact, ROLLBACK received */
                                172                 :     TBLOCK_PREPARE,             /* live xact, PREPARE received */
                                173                 : 
                                174                 :     /* subtransaction states */
                                175                 :     TBLOCK_SUBBEGIN,            /* starting a subtransaction */
                                176                 :     TBLOCK_SUBINPROGRESS,       /* live subtransaction */
                                177                 :     TBLOCK_SUBRELEASE,          /* RELEASE received */
                                178                 :     TBLOCK_SUBCOMMIT,           /* COMMIT received while TBLOCK_SUBINPROGRESS */
                                179                 :     TBLOCK_SUBABORT,            /* failed subxact, awaiting ROLLBACK */
                                180                 :     TBLOCK_SUBABORT_END,        /* failed subxact, ROLLBACK received */
                                181                 :     TBLOCK_SUBABORT_PENDING,    /* live subxact, ROLLBACK received */
                                182                 :     TBLOCK_SUBRESTART,          /* live subxact, ROLLBACK TO received */
                                183                 :     TBLOCK_SUBABORT_RESTART     /* failed subxact, ROLLBACK TO received */
                                184                 : } TBlockState;
                                185                 : 
                                186                 : /*
                                187                 :  *  transaction state structure
                                188                 :  */
                                189                 : typedef struct TransactionStateData
                                190                 : {
                                191                 :     FullTransactionId fullTransactionId;    /* my FullTransactionId */
                                192                 :     SubTransactionId subTransactionId;  /* my subxact ID */
                                193                 :     char       *name;           /* savepoint name, if any */
                                194                 :     int         savepointLevel; /* savepoint level */
                                195                 :     TransState  state;          /* low-level state */
                                196                 :     TBlockState blockState;     /* high-level state */
                                197                 :     int         nestingLevel;   /* transaction nesting depth */
                                198                 :     int         gucNestLevel;   /* GUC context nesting depth */
                                199                 :     MemoryContext curTransactionContext;    /* my xact-lifetime context */
                                200                 :     ResourceOwner curTransactionOwner;  /* my query resources */
                                201                 :     TransactionId *childXids;   /* subcommitted child XIDs, in XID order */
                                202                 :     int         nChildXids;     /* # of subcommitted child XIDs */
                                203                 :     int         maxChildXids;   /* allocated size of childXids[] */
                                204                 :     Oid         prevUser;       /* previous CurrentUserId setting */
                                205                 :     int         prevSecContext; /* previous SecurityRestrictionContext */
                                206                 :     bool        prevXactReadOnly;   /* entry-time xact r/o state */
                                207                 :     bool        startedInRecovery;  /* did we start in recovery? */
                                208                 :     bool        didLogXid;      /* has xid been included in WAL record? */
                                209                 :     int         parallelModeLevel;  /* Enter/ExitParallelMode counter */
                                210                 :     bool        chain;          /* start a new block after this one */
                                211                 :     bool        topXidLogged;   /* for a subxact: is top-level XID logged? */
                                212                 :     struct TransactionStateData *parent;    /* back link to parent */
                                213                 : } TransactionStateData;
                                214                 : 
                                215                 : typedef TransactionStateData *TransactionState;
                                216                 : 
                                217                 : /*
                                218                 :  * Serialized representation used to transmit transaction state to parallel
                                219                 :  * workers through shared memory.
                                220                 :  */
                                221                 : typedef struct SerializedTransactionState
                                222                 : {
                                223                 :     int         xactIsoLevel;
                                224                 :     bool        xactDeferrable;
                                225                 :     FullTransactionId topFullTransactionId;
                                226                 :     FullTransactionId currentFullTransactionId;
                                227                 :     CommandId   currentCommandId;
                                228                 :     int         nParallelCurrentXids;
                                229                 :     TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER];
                                230                 : } SerializedTransactionState;
                                231                 : 
                                232                 : /* The size of SerializedTransactionState, not including the final array. */
                                233                 : #define SerializedTransactionStateHeaderSize \
                                234                 :     offsetof(SerializedTransactionState, parallelCurrentXids)
                                235                 : 
                                236                 : /*
                                237                 :  * CurrentTransactionState always points to the current transaction state
                                238                 :  * block.  It will point to TopTransactionStateData when not in a
                                239                 :  * transaction at all, or when in a top-level transaction.
                                240                 :  */
                                241                 : static TransactionStateData TopTransactionStateData = {
                                242                 :     .state = TRANS_DEFAULT,
                                243                 :     .blockState = TBLOCK_DEFAULT,
                                244                 :     .topXidLogged = false,
                                245                 : };
                                246                 : 
                                247                 : /*
                                248                 :  * unreportedXids holds XIDs of all subtransactions that have not yet been
                                249                 :  * reported in an XLOG_XACT_ASSIGNMENT record.
                                250                 :  */
                                251                 : static int  nUnreportedXids;
                                252                 : static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
                                253                 : 
                                254                 : static TransactionState CurrentTransactionState = &TopTransactionStateData;
                                255                 : 
                                256                 : /*
                                257                 :  * The subtransaction ID and command ID assignment counters are global
                                258                 :  * to a whole transaction, so we do not keep them in the state stack.
                                259                 :  */
                                260                 : static SubTransactionId currentSubTransactionId;
                                261                 : static CommandId currentCommandId;
                                262                 : static bool currentCommandIdUsed;
                                263                 : 
                                264                 : /*
                                265                 :  * xactStartTimestamp is the value of transaction_timestamp().
                                266                 :  * stmtStartTimestamp is the value of statement_timestamp().
                                267                 :  * xactStopTimestamp is the time at which we log a commit / abort WAL record,
                                268                 :  * or if that was skipped, the time of the first subsequent
                                269                 :  * GetCurrentTransactionStopTimestamp() call.
                                270                 :  *
                                271                 :  * These do not change as we enter and exit subtransactions, so we don't
                                272                 :  * keep them inside the TransactionState stack.
                                273                 :  */
                                274                 : static TimestampTz xactStartTimestamp;
                                275                 : static TimestampTz stmtStartTimestamp;
                                276                 : static TimestampTz xactStopTimestamp;
                                277                 : 
                                278                 : /*
                                279                 :  * GID to be used for preparing the current transaction.  This is also
                                280                 :  * global to a whole transaction, so we don't keep it in the state stack.
                                281                 :  */
                                282                 : static char *prepareGID;
                                283                 : 
                                284                 : /*
                                285                 :  * Some commands want to force synchronous commit.
                                286                 :  */
                                287                 : static bool forceSyncCommit = false;
                                288                 : 
                                289                 : /* Flag for logging statements in a transaction. */
                                290                 : bool        xact_is_sampled = false;
                                291                 : 
                                292                 : /*
                                293                 :  * Private context for transaction-abort work --- we reserve space for this
                                294                 :  * at startup to ensure that AbortTransaction and AbortSubTransaction can work
                                295                 :  * when we've run out of memory.
                                296                 :  */
                                297                 : static MemoryContext TransactionAbortContext = NULL;
                                298                 : 
                                299                 : /*
                                300                 :  * List of add-on start- and end-of-xact callbacks
                                301                 :  */
                                302                 : typedef struct XactCallbackItem
                                303                 : {
                                304                 :     struct XactCallbackItem *next;
                                305                 :     XactCallback callback;
                                306                 :     void       *arg;
                                307                 : } XactCallbackItem;
                                308                 : 
                                309                 : static XactCallbackItem *Xact_callbacks = NULL;
                                310                 : 
                                311                 : /*
                                312                 :  * List of add-on start- and end-of-subxact callbacks
                                313                 :  */
                                314                 : typedef struct SubXactCallbackItem
                                315                 : {
                                316                 :     struct SubXactCallbackItem *next;
                                317                 :     SubXactCallback callback;
                                318                 :     void       *arg;
                                319                 : } SubXactCallbackItem;
                                320                 : 
                                321                 : static SubXactCallbackItem *SubXact_callbacks = NULL;
                                322                 : 
                                323                 : 
                                324                 : /* local function prototypes */
                                325                 : static void AssignTransactionId(TransactionState s);
                                326                 : static void AbortTransaction(void);
                                327                 : static void AtAbort_Memory(void);
                                328                 : static void AtCleanup_Memory(void);
                                329                 : static void AtAbort_ResourceOwner(void);
                                330                 : static void AtCCI_LocalCache(void);
                                331                 : static void AtCommit_Memory(void);
                                332                 : static void AtStart_Cache(void);
                                333                 : static void AtStart_Memory(void);
                                334                 : static void AtStart_ResourceOwner(void);
                                335                 : static void CallXactCallbacks(XactEvent event);
                                336                 : static void CallSubXactCallbacks(SubXactEvent event,
                                337                 :                                  SubTransactionId mySubid,
                                338                 :                                  SubTransactionId parentSubid);
                                339                 : static void CleanupTransaction(void);
                                340                 : static void CheckTransactionBlock(bool isTopLevel, bool throwError,
                                341                 :                                   const char *stmtType);
                                342                 : static void CommitTransaction(void);
                                343                 : static TransactionId RecordTransactionAbort(bool isSubXact);
                                344                 : static void StartTransaction(void);
                                345                 : 
                                346                 : static void StartSubTransaction(void);
                                347                 : static void CommitSubTransaction(void);
                                348                 : static void AbortSubTransaction(void);
                                349                 : static void CleanupSubTransaction(void);
                                350                 : static void PushTransaction(void);
                                351                 : static void PopTransaction(void);
                                352                 : 
                                353                 : static void AtSubAbort_Memory(void);
                                354                 : static void AtSubCleanup_Memory(void);
                                355                 : static void AtSubAbort_ResourceOwner(void);
                                356                 : static void AtSubCommit_Memory(void);
                                357                 : static void AtSubStart_Memory(void);
                                358                 : static void AtSubStart_ResourceOwner(void);
                                359                 : 
                                360                 : static void ShowTransactionState(const char *str);
                                361                 : static void ShowTransactionStateRec(const char *str, TransactionState s);
                                362                 : static const char *BlockStateAsString(TBlockState blockState);
                                363                 : static const char *TransStateAsString(TransState state);
                                364                 : 
                                365                 : 
                                366                 : /* ----------------------------------------------------------------
                                367                 :  *  transaction state accessors
                                368                 :  * ----------------------------------------------------------------
                                369                 :  */
                                370                 : 
                                371                 : /*
                                372                 :  *  IsTransactionState
                                373                 :  *
                                374                 :  *  This returns true if we are inside a valid transaction; that is,
                                375                 :  *  it is safe to initiate database access, take heavyweight locks, etc.
                                376                 :  */
                                377                 : bool
 9646 bruce                     378 GIC    84355117 : IsTransactionState(void)
                                379                 : {
 9345                           380        84355117 :     TransactionState s = CurrentTransactionState;
                                381                 : 
 9345 bruce                     382 ECB             :     /*
                                383                 :      * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states.  However, we
 5624                           384                 :      * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
                                385                 :      * TRANS_PREPARE since it might be too soon or too late within those
                                386                 :      * transition states to do anything interesting.  Hence, the only "valid"
                                387                 :      * state is TRANS_INPROGRESS.
                                388                 :      */
 5785 tgl                       389 GIC    84355117 :     return (s->state == TRANS_INPROGRESS);
                                390                 : }
                                391                 : 
                                392                 : /*
 7452 bruce                     393 ECB             :  *  IsAbortedTransactionBlockState
                                394                 :  *
                                395                 :  *  This returns true if we are within an aborted transaction block.
                                396                 :  */
                                397                 : bool
 8202 tgl                       398 GIC      984167 : IsAbortedTransactionBlockState(void)
                                399                 : {
 9345 bruce                     400          984167 :     TransactionState s = CurrentTransactionState;
                                401                 : 
 6797 bruce                     402 CBC      984167 :     if (s->blockState == TBLOCK_ABORT ||
 6856 tgl                       403 GIC      982840 :         s->blockState == TBLOCK_SUBABORT)
 9345 bruce                     404 CBC        1609 :         return true;
                                405                 : 
                                406          982558 :     return false;
 9770 scrappy                   407 ECB             : }
                                408                 : 
                                409                 : 
 6856 tgl                       410                 : /*
                                411                 :  *  GetTopTransactionId
                                412                 :  *
                                413                 :  * This will return the XID of the main transaction, assigning one if
                                414                 :  * it's not yet set.  Be careful to call this only inside a valid xact.
                                415                 :  */
                                416                 : TransactionId
 6856 tgl                       417 GIC       28513 : GetTopTransactionId(void)
                                418                 : {
 1473 tmunro                    419           28513 :     if (!FullTransactionIdIsValid(XactTopFullTransactionId))
 5695 tgl                       420             442 :         AssignTransactionId(&TopTransactionStateData);
 1473 tmunro                    421 CBC       28513 :     return XidFromFullTransactionId(XactTopFullTransactionId);
                                422                 : }
 6856 tgl                       423 ECB             : 
 5695                           424                 : /*
                                425                 :  *  GetTopTransactionIdIfAny
                                426                 :  *
                                427                 :  * This will return the XID of the main transaction, if one is assigned.
                                428                 :  * It will return InvalidTransactionId if we are not currently inside a
                                429                 :  * transaction, or inside a transaction that hasn't yet been assigned an XID.
                                430                 :  */
                                431                 : TransactionId
 5695 tgl                       432 GIC    59035627 : GetTopTransactionIdIfAny(void)
                                433                 : {
 1473 tmunro                    434        59035627 :     return XidFromFullTransactionId(XactTopFullTransactionId);
                                435                 : }
 6856 tgl                       436 ECB             : 
                                437                 : /*
 7452 bruce                     438                 :  *  GetCurrentTransactionId
                                439                 :  *
                                440                 :  * This will return the XID of the current transaction (main or sub
                                441                 :  * transaction), assigning one if it's not yet set.  Be careful to call this
                                442                 :  * only inside a valid xact.
                                443                 :  */
                                444                 : TransactionId
 8202 tgl                       445 GIC    14968177 : GetCurrentTransactionId(void)
                                446                 : {
 9345 bruce                     447        14968177 :     TransactionState s = CurrentTransactionState;
                                448                 : 
 1473 tmunro                    449 CBC    14968177 :     if (!FullTransactionIdIsValid(s->fullTransactionId))
 5695 tgl                       450 GIC      297768 :         AssignTransactionId(s);
 1473 tmunro                    451 CBC    14968177 :     return XidFromFullTransactionId(s->fullTransactionId);
                                452                 : }
 6779 tgl                       453 ECB             : 
 5695                           454                 : /*
                                455                 :  *  GetCurrentTransactionIdIfAny
                                456                 :  *
                                457                 :  * This will return the XID of the current sub xact, if one is assigned.
                                458                 :  * It will return InvalidTransactionId if we are not currently inside a
                                459                 :  * transaction, or inside a transaction that hasn't been assigned an XID yet.
                                460                 :  */
                                461                 : TransactionId
 5695 tgl                       462 GIC    19431086 : GetCurrentTransactionIdIfAny(void)
                                463                 : {
 1473 tmunro                    464        19431086 :     return XidFromFullTransactionId(CurrentTransactionState->fullTransactionId);
                                465                 : }
 1473 tmunro                    466 ECB             : 
                                467                 : /*
                                468                 :  *  GetTopFullTransactionId
                                469                 :  *
                                470                 :  * This will return the FullTransactionId of the main transaction, assigning
                                471                 :  * one if it's not yet set.  Be careful to call this only inside a valid xact.
                                472                 :  */
                                473                 : FullTransactionId
 1473 tmunro                    474 GIC        2865 : GetTopFullTransactionId(void)
                                475                 : {
                                476            2865 :     if (!FullTransactionIdIsValid(XactTopFullTransactionId))
                                477            2068 :         AssignTransactionId(&TopTransactionStateData);
 1473 tmunro                    478 CBC        2865 :     return XactTopFullTransactionId;
                                479                 : }
 1473 tmunro                    480 ECB             : 
                                481                 : /*
                                482                 :  *  GetTopFullTransactionIdIfAny
                                483                 :  *
                                484                 :  * This will return the FullTransactionId of the main transaction, if one is
                                485                 :  * assigned.  It will return InvalidFullTransactionId if we are not currently
                                486                 :  * inside a transaction, or inside a transaction that hasn't yet been assigned
                                487                 :  * one.
                                488                 :  */
                                489                 : FullTransactionId
 1473 tmunro                    490 GIC          12 : GetTopFullTransactionIdIfAny(void)
                                491                 : {
                                492              12 :     return XactTopFullTransactionId;
                                493                 : }
 1473 tmunro                    494 ECB             : 
                                495                 : /*
                                496                 :  *  GetCurrentFullTransactionId
                                497                 :  *
                                498                 :  * This will return the FullTransactionId of the current transaction (main or
                                499                 :  * sub transaction), assigning one if it's not yet set.  Be careful to call
                                500                 :  * this only inside a valid xact.
                                501                 :  */
                                502                 : FullTransactionId
 1473 tmunro                    503 UIC           0 : GetCurrentFullTransactionId(void)
                                504                 : {
                                505               0 :     TransactionState s = CurrentTransactionState;
                                506                 : 
 1473 tmunro                    507 UBC           0 :     if (!FullTransactionIdIsValid(s->fullTransactionId))
 1473 tmunro                    508 UIC           0 :         AssignTransactionId(s);
 1473 tmunro                    509 UBC           0 :     return s->fullTransactionId;
                                510                 : }
 1473 tmunro                    511 EUB             : 
                                512                 : /*
                                513                 :  *  GetCurrentFullTransactionIdIfAny
                                514                 :  *
                                515                 :  * This will return the FullTransactionId of the current sub xact, if one is
                                516                 :  * assigned.  It will return InvalidFullTransactionId if we are not currently
                                517                 :  * inside a transaction, or inside a transaction that hasn't been assigned one
                                518                 :  * yet.
                                519                 :  */
                                520                 : FullTransactionId
 1473 tmunro                    521 UIC           0 : GetCurrentFullTransactionIdIfAny(void)
                                522                 : {
                                523               0 :     return CurrentTransactionState->fullTransactionId;
                                524                 : }
 5695 tgl                       525 EUB             : 
                                526                 : /*
 3407 rhaas                     527                 :  *  MarkCurrentTransactionIdLoggedIfAny
                                528                 :  *
                                529                 :  * Remember that the current xid - if it is assigned - now has been wal logged.
                                530                 :  */
                                531                 : void
 3407 rhaas                     532 GIC    19399402 : MarkCurrentTransactionIdLoggedIfAny(void)
                                533                 : {
 1473 tmunro                    534        19399402 :     if (FullTransactionIdIsValid(CurrentTransactionState->fullTransactionId))
 3407 rhaas                     535        18866959 :         CurrentTransactionState->didLogXid = true;
 3407 rhaas                     536 CBC    19399402 : }
                                537                 : 
  523 akapila                   538 ECB             : /*
                                539                 :  * IsSubxactTopXidLogPending
                                540                 :  *
                                541                 :  * This is used to decide whether we need to WAL log the top-level XID for
                                542                 :  * operation in a subtransaction.  We require that for logical decoding, see
                                543                 :  * LogicalDecodingProcessRecord.
                                544                 :  *
                                545                 :  * This returns true if wal_level >= logical and we are inside a valid
                                546                 :  * subtransaction, for which the assignment was not yet written to any WAL
                                547                 :  * record.
                                548                 :  */
                                549                 : bool
  523 akapila                   550 GIC    19404628 : IsSubxactTopXidLogPending(void)
                                551                 : {
                                552                 :     /* check whether it is already logged */
                                553        19404628 :     if (CurrentTransactionState->topXidLogged)
  523 akapila                   554 CBC      102108 :         return false;
                                555                 : 
                                556                 :     /* wal_level has to be logical */
                                557        19302520 :     if (!XLogLogicalInfoActive())
                                558        18494195 :         return false;
                                559                 : 
                                560                 :     /* we need to be in a transaction state */
                                561          808325 :     if (!IsTransactionState())
                                562            4156 :         return false;
                                563                 : 
                                564                 :     /* it has to be a subtransaction */
                                565          804169 :     if (!IsSubTransaction())
                                566          803693 :         return false;
                                567                 : 
                                568                 :     /* the subtransaction has to have a XID assigned */
                                569             476 :     if (!TransactionIdIsValid(GetCurrentTransactionIdIfAny()))
                                570               6 :         return false;
                                571                 : 
  523 akapila                   572 GIC         470 :     return true;
  523 akapila                   573 ECB             : }
                                574                 : 
                                575                 : /*
                                576                 :  * MarkSubxactTopXidLogged
                                577                 :  *
                                578                 :  * Remember that the top transaction id for the current subtransaction is WAL
                                579                 :  * logged now.
                                580                 :  */
                                581                 : void
  523 akapila                   582 GIC         234 : MarkSubxactTopXidLogged(void)
                                583                 : {
                                584             234 :     Assert(IsSubxactTopXidLogPending());
                                585                 : 
  523 akapila                   586 CBC         234 :     CurrentTransactionState->topXidLogged = true;
  523 akapila                   587 GIC         234 : }
 3407 rhaas                     588 ECB             : 
                                589                 : /*
 3984 simon                     590                 :  *  GetStableLatestTransactionId
 3985                           591                 :  *
                                592                 :  * Get the transaction's XID if it has one, else read the next-to-be-assigned
                                593                 :  * XID.  Once we have a value, return that same value for the remainder of the
                                594                 :  * current transaction.  This is meant to provide the reference point for the
                                595                 :  * age(xid) function, but might be useful for other maintenance tasks as well.
                                596                 :  */
                                597                 : TransactionId
 3985 simon                     598 GIC         113 : GetStableLatestTransactionId(void)
                                599                 : {
                                600                 :     static LocalTransactionId lxid = InvalidLocalTransactionId;
                                601                 :     static TransactionId stablexid = InvalidTransactionId;
 3985 simon                     602 ECB             : 
 3984 simon                     603 GIC         113 :     if (lxid != MyProc->lxid)
                                604                 :     {
 3985                           605               1 :         lxid = MyProc->lxid;
 3984                           606               1 :         stablexid = GetTopTransactionIdIfAny();
 3984 simon                     607 CBC           1 :         if (!TransactionIdIsValid(stablexid))
  783 tmunro                    608 GIC           1 :             stablexid = ReadNextTransactionId();
 3985 simon                     609 ECB             :     }
                                610                 : 
 3984 simon                     611 CBC         113 :     Assert(TransactionIdIsValid(stablexid));
 3984 simon                     612 ECB             : 
 3985 simon                     613 GIC         113 :     return stablexid;
                                614                 : }
 3985 simon                     615 ECB             : 
                                616                 : /*
 5695 tgl                       617                 :  * AssignTransactionId
                                618                 :  *
                                619                 :  * Assigns a new permanent FullTransactionId to the given TransactionState.
                                620                 :  * We do not assign XIDs to transactions until/unless this is called.
                                621                 :  * Also, any parent TransactionStates that don't yet have XIDs are assigned
                                622                 :  * one; this maintains the invariant that a child transaction has an XID
                                623                 :  * following its parent's.
                                624                 :  */
                                625                 : static void
 5695 tgl                       626 GIC      301436 : AssignTransactionId(TransactionState s)
                                627                 : {
 5624 bruce                     628          301436 :     bool        isSubXact = (s->parent != NULL);
                                629                 :     ResourceOwner currentOwner;
 3260 bruce                     630 CBC      301436 :     bool        log_unknown_top = false;
                                631                 : 
 5695 tgl                       632 ECB             :     /* Assert that caller didn't screw up */
 1473 tmunro                    633 GIC      301436 :     Assert(!FullTransactionIdIsValid(s->fullTransactionId));
 6779 tgl                       634 CBC      301436 :     Assert(s->state == TRANS_INPROGRESS);
                                635                 : 
                                636                 :     /*
 2878 bruce                     637 ECB             :      * Workers synchronize transaction state at the beginning of each parallel
                                638                 :      * operation, so we can't account for new XIDs at this point.
                                639                 :      */
 2732 rhaas                     640 GIC      301436 :     if (IsInParallelMode() || IsParallelWorker())
 2901 rhaas                     641 UIC           0 :         elog(ERROR, "cannot assign XIDs during a parallel operation");
                                642                 : 
                                643                 :     /*
 5695 tgl                       644 ECB             :      * Ensure parent(s) have XIDs, so that a child always has an XID later
 1418 tgl                       645 EUB             :      * than its parent.  Mustn't recurse here, or we might get a stack
                                646                 :      * overflow if we're at the bottom of a huge stack of subtransactions none
                                647                 :      * of which have XIDs yet.
                                648                 :      */
 1473 tmunro                    649 GIC      301436 :     if (isSubXact && !FullTransactionIdIsValid(s->parent->fullTransactionId))
                                650                 :     {
 4382 bruce                     651             619 :         TransactionState p = s->parent;
                                652                 :         TransactionState *parents;
 4382 bruce                     653 CBC         619 :         size_t      parentOffset = 0;
                                654                 : 
                                655             619 :         parents = palloc(sizeof(TransactionState) * s->nestingLevel);
 1473 tmunro                    656 GIC        1777 :         while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId))
 4643 rhaas                     657 ECB             :         {
 4643 rhaas                     658 GIC        1158 :             parents[parentOffset++] = p;
 4643 rhaas                     659 CBC        1158 :             p = p->parent;
 4643 rhaas                     660 ECB             :         }
                                661                 : 
                                662                 :         /*
 4382 bruce                     663                 :          * This is technically a recursive call, but the recursion will never
                                664                 :          * be more than one layer deep.
                                665                 :          */
 4643 rhaas                     666 GIC        1777 :         while (parentOffset != 0)
                                667            1158 :             AssignTransactionId(parents[--parentOffset]);
                                668                 : 
                                669             619 :         pfree(parents);
 4643 rhaas                     670 ECB             :     }
 6779 tgl                       671                 : 
                                672                 :     /*
 3407 rhaas                     673                 :      * When wal_level=logical, guarantee that a subtransaction's xid can only
                                674                 :      * be seen in the WAL stream if its toplevel xid has been logged before.
                                675                 :      * If necessary we log an xact_assignment record with fewer than
                                676                 :      * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
                                677                 :      * for a transaction even though it appears in a WAL record, we just might
                                678                 :      * superfluously log something. That can happen when an xid is included
                                679                 :      * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
                                680                 :      * xl_standby_locks.
                                681                 :      */
 3407 rhaas                     682 GIC      301436 :     if (isSubXact && XLogLogicalInfoActive() &&
                                683             317 :         !TopTransactionStateData.didLogXid)
                                684              23 :         log_unknown_top = true;
                                685                 : 
 6779 tgl                       686 ECB             :     /*
                                687                 :      * Generate a new FullTransactionId and record its xid in PGPROC and
 1473 tmunro                    688                 :      * pg_subtrans.
                                689                 :      *
                                690                 :      * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
                                691                 :      * shared storage other than PGPROC; because if there's no room for it in
                                692                 :      * PGPROC, the subtrans entry is needed to ensure that other backends see
                                693                 :      * the Xid as "running".  See GetNewTransactionId.
                                694                 :      */
 1473 tmunro                    695 GIC      301436 :     s->fullTransactionId = GetNewTransactionId(isSubXact);
 2901 rhaas                     696          301436 :     if (!isSubXact)
 1473 tmunro                    697          298022 :         XactTopFullTransactionId = s->fullTransactionId;
                                698                 : 
 5695 tgl                       699 CBC      301436 :     if (isSubXact)
 1473 tmunro                    700            3414 :         SubTransSetParent(XidFromFullTransactionId(s->fullTransactionId),
                                701            3414 :                           XidFromFullTransactionId(s->parent->fullTransactionId));
                                702                 : 
 4356 tgl                       703 ECB             :     /*
                                704                 :      * If it's a top-level transaction, the predicate locking system needs to
                                705                 :      * be told about it too.
                                706                 :      */
 4356 tgl                       707 GIC      301436 :     if (!isSubXact)
 1473 tmunro                    708          298022 :         RegisterPredicateLockingXid(XidFromFullTransactionId(s->fullTransactionId));
                                709                 : 
                                710                 :     /*
 5624 bruce                     711 ECB             :      * Acquire lock on the transaction XID.  (We assume this cannot block.) We
                                712                 :      * have to ensure that the lock is assigned to the transaction's own
                                713                 :      * ResourceOwner.
                                714                 :      */
 6779 tgl                       715 GIC      301436 :     currentOwner = CurrentResourceOwner;
 2006                           716          301436 :     CurrentResourceOwner = s->curTransactionOwner;
                                717                 : 
 1473 tmunro                    718          301436 :     XactLockTableInsert(XidFromFullTransactionId(s->fullTransactionId));
 2006 tgl                       719 ECB             : 
 6779 tgl                       720 CBC      301436 :     CurrentResourceOwner = currentOwner;
                                721                 : 
 4859 simon                     722 ECB             :     /*
                                723                 :      * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
                                724                 :      * top-level transaction we issue a WAL record for the assignment. We
                                725                 :      * include the top-level xid and all the subxids that have not yet been
                                726                 :      * reported using XLOG_XACT_ASSIGNMENT records.
                                727                 :      *
                                728                 :      * This is required to limit the amount of shared memory required in a hot
                                729                 :      * standby server to keep track of in-progress XIDs. See notes for
                                730                 :      * RecordKnownAssignedTransactionIds().
                                731                 :      *
                                732                 :      * We don't keep track of the immediate parent of each subxid, only the
                                733                 :      * top-level transaction that each subxact belongs to. This is correct in
                                734                 :      * recovery only because aborted subtransactions are separately WAL
                                735                 :      * logged.
                                736                 :      *
                                737                 :      * This is correct even for the case where several levels above us didn't
                                738                 :      * have an xid assigned as we recursed up to them beforehand.
                                739                 :      */
 4859 simon                     740 GIC      301436 :     if (isSubXact && XLogStandbyInfoActive())
                                741                 :     {
 1473 tmunro                    742            2898 :         unreportedXids[nUnreportedXids] = XidFromFullTransactionId(s->fullTransactionId);
 4859 simon                     743            2898 :         nUnreportedXids++;
 4859 simon                     744 ECB             : 
                                745                 :         /*
 4790 bruce                     746                 :          * ensure this test matches similar one in
                                747                 :          * RecoverPreparedTransactions()
                                748                 :          */
 3407 rhaas                     749 GIC        2898 :         if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS ||
                                750                 :             log_unknown_top)
                                751                 :         {
                                752                 :             xl_xact_assignment xlrec;
 4859 simon                     753 ECB             : 
                                754                 :             /*
                                755                 :              * xtop is always set by now because we recurse up transaction
                                756                 :              * stack to the highest unassigned xid and then come back down
                                757                 :              */
 4859 simon                     758 GIC          52 :             xlrec.xtop = GetTopTransactionId();
                                759              52 :             Assert(TransactionIdIsValid(xlrec.xtop));
                                760              52 :             xlrec.nsubxacts = nUnreportedXids;
                                761                 : 
 3062 heikki.linnakangas        762 CBC          52 :             XLogBeginInsert();
                                763              52 :             XLogRegisterData((char *) &xlrec, MinSizeOfXactAssignment);
                                764              52 :             XLogRegisterData((char *) unreportedXids,
                                765                 :                              nUnreportedXids * sizeof(TransactionId));
 4859 simon                     766 ECB             : 
 3062 heikki.linnakangas        767 CBC          52 :             (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
 4859 simon                     768 ECB             : 
 4859 simon                     769 GIC          52 :             nUnreportedXids = 0;
                                770                 :             /* mark top, not current xact as having been logged */
 3407 rhaas                     771 CBC          52 :             TopTransactionStateData.didLogXid = true;
                                772                 :         }
 4859 simon                     773 ECB             :     }
 4859 simon                     774 GIC      301436 : }
 6779 tgl                       775 ECB             : 
                                776                 : /*
                                777                 :  *  GetCurrentSubTransactionId
                                778                 :  */
                                779                 : SubTransactionId
 6779 tgl                       780 GIC     2118084 : GetCurrentSubTransactionId(void)
                                781                 : {
                                782         2118084 :     TransactionState s = CurrentTransactionState;
                                783                 : 
 6779 tgl                       784 CBC     2118084 :     return s->subTransactionId;
                                785                 : }
 9770 scrappy                   786 ECB             : 
                                787                 : /*
 3689 tgl                       788                 :  *  SubTransactionIsActive
                                789                 :  *
                                790                 :  * Test if the specified subxact ID is still active.  Note caller is
                                791                 :  * responsible for checking whether this ID is relevant to the current xact.
                                792                 :  */
                                793                 : bool
 3689 tgl                       794 GIC       28513 : SubTransactionIsActive(SubTransactionId subxid)
                                795                 : {
                                796                 :     TransactionState s;
                                797                 : 
 3689 tgl                       798 CBC       28519 :     for (s = CurrentTransactionState; s != NULL; s = s->parent)
                                799                 :     {
 3689 tgl                       800 GIC       28519 :         if (s->state == TRANS_ABORT)
 3689 tgl                       801 UIC           0 :             continue;
 3689 tgl                       802 CBC       28519 :         if (s->subTransactionId == subxid)
 3689 tgl                       803 GIC       28513 :             return true;
 3689 tgl                       804 ECB             :     }
 3689 tgl                       805 UBC           0 :     return false;
 3689 tgl                       806 ECB             : }
                                807                 : 
                                808                 : 
 7331 bruce                     809 EUB             : /*
                                810                 :  *  GetCurrentCommandId
                                811                 :  *
                                812                 :  * "used" must be true if the caller intends to use the command ID to mark
                                813                 :  * inserted/updated/deleted tuples.  false means the ID is being fetched
                                814                 :  * for read-only purposes (ie, as a snapshot validity cutoff).  See
                                815                 :  * CommandCounterIncrement() for discussion.
                                816                 :  */
                                817                 : CommandId
 5609 tgl                       818 GIC    10677844 : GetCurrentCommandId(bool used)
                                819                 : {
                                820                 :     /* this is global to a transaction, not subtransaction-local */
                                821        10677844 :     if (used)
 2901 rhaas                     822 ECB             :     {
                                823                 :         /*
                                824                 :          * Forbid setting currentCommandIdUsed in a parallel worker, because
 1029 andres                    825                 :          * we have no provision for communicating this back to the leader.  We
                                826                 :          * could relax this restriction when currentCommandIdUsed was already
                                827                 :          * true at the start of the parallel operation.
                                828                 :          */
 1935 rhaas                     829 GIC     7964924 :         Assert(!IsParallelWorker());
 5609 tgl                       830         7964924 :         currentCommandIdUsed = true;
                                831                 :     }
 6779                           832        10677844 :     return currentCommandId;
 9770 scrappy                   833 ECB             : }
                                834                 : 
                                835                 : /*
 1646 tgl                       836                 :  *  SetParallelStartTimestamps
                                837                 :  *
                                838                 :  * In a parallel worker, we should inherit the parent transaction's
                                839                 :  * timestamps rather than setting our own.  The parallel worker
                                840                 :  * infrastructure must call this to provide those values before
                                841                 :  * calling StartTransaction() or SetCurrentStatementStartTimestamp().
                                842                 :  */
                                843                 : void
 1646 tgl                       844 GIC        1298 : SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
                                845                 : {
                                846            1298 :     Assert(IsParallelWorker());
                                847            1298 :     xactStartTimestamp = xact_ts;
 1646 tgl                       848 CBC        1298 :     stmtStartTimestamp = stmt_ts;
 1646 tgl                       849 GIC        1298 : }
 1646 tgl                       850 ECB             : 
 7331 bruce                     851                 : /*
 6493 tgl                       852                 :  *  GetCurrentTransactionStartTimestamp
 7863 lockhart                  853                 :  */
                                854                 : TimestampTz
 6493 tgl                       855 GIC       42330 : GetCurrentTransactionStartTimestamp(void)
                                856                 : {
                                857           42330 :     return xactStartTimestamp;
                                858                 : }
 6856 tgl                       859 ECB             : 
                                860                 : /*
 6193 bruce                     861                 :  *  GetCurrentStatementStartTimestamp
                                862                 :  */
                                863                 : TimestampTz
 6193 bruce                     864 GIC     1435587 : GetCurrentStatementStartTimestamp(void)
                                865                 : {
                                866         1435587 :     return stmtStartTimestamp;
                                867                 : }
 6193 bruce                     868 ECB             : 
                                869                 : /*
 5823 tgl                       870                 :  *  GetCurrentTransactionStopTimestamp
                                871                 :  *
                                872                 :  * If the transaction stop time hasn't already been set, which can happen if
                                873                 :  * we decided we don't need to log an XLOG record, set xactStopTimestamp.
                                874                 :  */
                                875                 : TimestampTz
 5823 tgl                       876 GIC     1424210 : GetCurrentTransactionStopTimestamp(void)
                                877                 : {
  177 andres                    878 GNC     1424210 :     TransactionState s PG_USED_FOR_ASSERTS_ONLY = CurrentTransactionState;
                                879                 : 
                                880                 :     /* should only be called after commit / abort processing */
                                881         1424210 :     Assert(s->state == TRANS_DEFAULT ||
                                882                 :            s->state == TRANS_COMMIT ||
                                883                 :            s->state == TRANS_ABORT ||
                                884                 :            s->state == TRANS_PREPARE);
                                885                 : 
                                886         1424210 :     if (xactStopTimestamp == 0)
                                887          424026 :         xactStopTimestamp = GetCurrentTimestamp();
                                888                 : 
                                889         1424210 :     return xactStopTimestamp;
                                890                 : }
 5823 tgl                       891 ECB             : 
                                892                 : /*
                                893                 :  *  SetCurrentStatementStartTimestamp
 1646                           894                 :  *
                                895                 :  * In a parallel worker, this should already have been provided by a call
                                896                 :  * to SetParallelStartTimestamps().
                                897                 :  */
                                898                 : void
 6193 bruce                     899 CBC      637446 : SetCurrentStatementStartTimestamp(void)
 6193 bruce                     900 ECB             : {
 1646 tgl                       901 GIC      637446 :     if (!IsParallelWorker())
 1646 tgl                       902 CBC      636148 :         stmtStartTimestamp = GetCurrentTimestamp();
                                903                 :     else
 1646 tgl                       904 GIC        1298 :         Assert(stmtStartTimestamp != 0);
 6193 bruce                     905          637446 : }
                                906                 : 
                                907                 : /*
 6856 tgl                       908 ECB             :  *  GetCurrentTransactionNestLevel
                                909                 :  *
                                910                 :  * Note: this will return zero when not inside any transaction, one when
                                911                 :  * inside a top-level transaction, etc.
                                912                 :  */
                                913                 : int
 6856 tgl                       914 GIC    24331693 : GetCurrentTransactionNestLevel(void)
                                915                 : {
                                916        24331693 :     TransactionState s = CurrentTransactionState;
                                917                 : 
 6856 tgl                       918 CBC    24331693 :     return s->nestingLevel;
                                919                 : }
 7863 lockhart                  920 ECB             : 
                                921                 : 
 7331 bruce                     922                 : /*
                                923                 :  *  TransactionIdIsCurrentTransactionId
                                924                 :  */
                                925                 : bool
 9770 scrappy                   926 GIC    62262724 : TransactionIdIsCurrentTransactionId(TransactionId xid)
                                927                 : {
                                928                 :     TransactionState s;
                                929                 : 
 6622 tgl                       930 ECB             :     /*
                                931                 :      * We always say that BootstrapTransactionId is "not my transaction ID"
                                932                 :      * even when it is (ie, during bootstrap).  Along with the fact that
                                933                 :      * transam.c always treats BootstrapTransactionId as already committed,
                                934                 :      * this causes the heapam_visibility.c routines to see all tuples as
                                935                 :      * committed, which is what we need during bootstrap.  (Bootstrap mode
                                936                 :      * only inserts tuples, it never updates or deletes them, so all tuples
                                937                 :      * can be presumed good immediately.)
                                938                 :      *
                                939                 :      * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
                                940                 :      * not my transaction ID, so we can just return "false" immediately for
                                941                 :      * any non-normal XID.
                                942                 :      */
 5999 tgl                       943 GIC    62262724 :     if (!TransactionIdIsNormal(xid))
 9345 bruce                     944         3817403 :         return false;
                                945                 : 
 1245 tmunro                    946        58445321 :     if (TransactionIdEquals(xid, GetTopTransactionIdIfAny()))
 1245 tmunro                    947 CBC    44041255 :         return true;
 1245 tmunro                    948 ECB             : 
                                949                 :     /*
 2878 bruce                     950                 :      * In parallel workers, the XIDs we must consider as current are stored in
                                951                 :      * ParallelCurrentXids rather than the transaction-state stack.  Note that
                                952                 :      * the XIDs in this array are sorted numerically rather than according to
                                953                 :      * transactionIdPrecedes order.
                                954                 :      */
 2901 rhaas                     955 GIC    14404066 :     if (nParallelCurrentXids > 0)
                                956                 :     {
                                957                 :         int         low,
                                958                 :                     high;
 2901 rhaas                     959 ECB             : 
 2901 rhaas                     960 GIC     3692512 :         low = 0;
                                961         3692512 :         high = nParallelCurrentXids - 1;
                                962        14595278 :         while (low <= high)
                                963                 :         {
 2901 rhaas                     964 ECB             :             int         middle;
                                965                 :             TransactionId probe;
                                966                 : 
 2901 rhaas                     967 GIC    14508016 :             middle = low + (high - low) / 2;
                                968        14508016 :             probe = ParallelCurrentXids[middle];
                                969        14508016 :             if (probe == xid)
                                970         3605250 :                 return true;
 2901 rhaas                     971 CBC    10902766 :             else if (probe < xid)
                                972        10815504 :                 low = middle + 1;
 2901 rhaas                     973 ECB             :             else
 2901 rhaas                     974 CBC       87262 :                 high = middle - 1;
 2901 rhaas                     975 ECB             :         }
 2901 rhaas                     976 CBC       87262 :         return false;
                                977                 :     }
 2901 rhaas                     978 ECB             : 
                                979                 :     /*
 6385 bruce                     980                 :      * We will return true for the Xid of the current subtransaction, any of
                                981                 :      * its subcommitted children, any of its parents, or any of their
                                982                 :      * previously subcommitted children.  However, a transaction being aborted
                                983                 :      * is no longer "current", even though it may still have an entry on the
                                984                 :      * state stack.
                                985                 :      */
 6798 tgl                       986 GIC    21395185 :     for (s = CurrentTransactionState; s != NULL; s = s->parent)
                                987                 :     {
                                988                 :         int         low,
                                989                 :                     high;
 9770 scrappy                   990 ECB             : 
 6798 tgl                       991 GIC    10755113 :         if (s->state == TRANS_ABORT)
 6798 tgl                       992 UIC           0 :             continue;
 1473 tmunro                    993 GIC    10755113 :         if (!FullTransactionIdIsValid(s->fullTransactionId))
 6779 tgl                       994         6923042 :             continue;           /* it can't have any child XIDs either */
 1473 tmunro                    995 CBC     3832071 :         if (TransactionIdEquals(xid, XidFromFullTransactionId(s->fullTransactionId)))
 6856 tgl                       996 GBC       68472 :             return true;
 5501 tgl                       997 ECB             :         /* As the childXids array is ordered, we can use binary search */
 5501 tgl                       998 CBC     3763599 :         low = 0;
                                999         3763599 :         high = s->nChildXids - 1;
                               1000         3764479 :         while (low <= high)
                               1001                 :         {
 5050 bruce                    1002 ECB             :             int         middle;
                               1003                 :             TransactionId probe;
 5501 tgl                      1004                 : 
 5501 tgl                      1005 GIC        3890 :             middle = low + (high - low) / 2;
                               1006            3890 :             probe = s->childXids[middle];
                               1007            3890 :             if (TransactionIdEquals(probe, xid))
 6856                          1008            3010 :                 return true;
 5501 tgl                      1009 CBC         880 :             else if (TransactionIdPrecedes(probe, xid))
                               1010             803 :                 low = middle + 1;
 5501 tgl                      1011 ECB             :             else
 5501 tgl                      1012 CBC          77 :                 high = middle - 1;
 6856 tgl                      1013 ECB             :         }
                               1014                 :     }
                               1015                 : 
 6856 tgl                      1016 CBC    10640072 :     return false;
                               1017                 : }
                               1018                 : 
                               1019                 : /*
 4859 simon                    1020 ECB             :  *  TransactionStartedDuringRecovery
                               1021                 :  *
                               1022                 :  * Returns true if the current transaction started while recovery was still
                               1023                 :  * in progress. Recovery might have ended since so RecoveryInProgress() might
                               1024                 :  * return false already.
                               1025                 :  */
                               1026                 : bool
 4859 simon                    1027 GIC     8907096 : TransactionStartedDuringRecovery(void)
                               1028                 : {
                               1029         8907096 :     return CurrentTransactionState->startedInRecovery;
                               1030                 : }
 9770 scrappy                  1031 ECB             : 
                               1032                 : /*
 2901 rhaas                    1033                 :  *  EnterParallelMode
                               1034                 :  */
                               1035                 : void
 2901 rhaas                    1036 GIC        2987 : EnterParallelMode(void)
                               1037                 : {
                               1038            2987 :     TransactionState s = CurrentTransactionState;
                               1039                 : 
 2901 rhaas                    1040 CBC        2987 :     Assert(s->parallelModeLevel >= 0);
                               1041                 : 
                               1042            2987 :     ++s->parallelModeLevel;
 2901 rhaas                    1043 GIC        2987 : }
 2901 rhaas                    1044 ECB             : 
                               1045                 : /*
                               1046                 :  *  ExitParallelMode
                               1047                 :  */
                               1048                 : void
 2901 rhaas                    1049 GIC        1686 : ExitParallelMode(void)
                               1050                 : {
                               1051            1686 :     TransactionState s = CurrentTransactionState;
                               1052                 : 
 2901 rhaas                    1053 CBC        1686 :     Assert(s->parallelModeLevel > 0);
 2901 rhaas                    1054 GIC        1686 :     Assert(s->parallelModeLevel > 1 || !ParallelContextActive());
 2901 rhaas                    1055 ECB             : 
 2901 rhaas                    1056 GIC        1686 :     --s->parallelModeLevel;
 2901 rhaas                    1057 CBC        1686 : }
 2901 rhaas                    1058 ECB             : 
                               1059                 : /*
                               1060                 :  *  IsInParallelMode
                               1061                 :  *
                               1062                 :  * Are we in a parallel operation, as either the leader or a worker?  Check
                               1063                 :  * this to prohibit operations that change backend-local state expected to
                               1064                 :  * match across all workers.  Mere caches usually don't require such a
                               1065                 :  * restriction.  State modified in a strict push/pop fashion, such as the
                               1066                 :  * active snapshot stack, is often fine.
                               1067                 :  */
                               1068                 : bool
 2901 rhaas                    1069 GIC     6169064 : IsInParallelMode(void)
                               1070                 : {
                               1071         6169064 :     return CurrentTransactionState->parallelModeLevel != 0;
                               1072                 : }
 2901 rhaas                    1073 ECB             : 
                               1074                 : /*
 7452 bruce                    1075                 :  *  CommandCounterIncrement
                               1076                 :  */
                               1077                 : void
 8202 tgl                      1078 GIC     1900778 : CommandCounterIncrement(void)
                               1079                 : {
                               1080                 :     /*
                               1081                 :      * If the current value of the command counter hasn't been "used" to mark
 5050 bruce                    1082 ECB             :      * tuples, we need not increment it, since there's no need to distinguish
                               1083                 :      * a read-only command from others.  This helps postpone command counter
                               1084                 :      * overflow, and keeps no-op CommandCounterIncrement operations cheap.
                               1085                 :      */
 5609 tgl                      1086 GIC     1900778 :     if (currentCommandIdUsed)
                               1087                 :     {
                               1088                 :         /*
                               1089                 :          * Workers synchronize transaction state at the beginning of each
 2901 rhaas                    1090 ECB             :          * parallel operation, so we can't account for new commands after that
                               1091                 :          * point.
                               1092                 :          */
 2732 rhaas                    1093 GIC     1206274 :         if (IsInParallelMode() || IsParallelWorker())
 2901 rhaas                    1094 UIC           0 :             elog(ERROR, "cannot start commands during a parallel operation");
                               1095                 : 
 5609 tgl                      1096 GIC     1206274 :         currentCommandId += 1;
 3499 rhaas                    1097 CBC     1206274 :         if (currentCommandId == InvalidCommandId)
 5609 tgl                      1098 EUB             :         {
 5609 tgl                      1099 UIC           0 :             currentCommandId -= 1;
 5609 tgl                      1100 LBC           0 :             ereport(ERROR,
 5609 tgl                      1101 ECB             :                     (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                               1102                 :                      errmsg("cannot have more than 2^32-2 commands in a transaction")));
 5609 tgl                      1103 EUB             :         }
 5609 tgl                      1104 GBC     1206274 :         currentCommandIdUsed = false;
                               1105                 : 
                               1106                 :         /* Propagate new command ID into static snapshots */
 5445 alvherre                 1107 GIC     1206274 :         SnapshotSetCommandId(currentCommandId);
 5050 bruce                    1108 ECB             : 
                               1109                 :         /*
                               1110                 :          * Make any catalog changes done by the just-completed command visible
                               1111                 :          * in the local syscache.  We obviously don't need to do this after a
                               1112                 :          * read-only command.  (But see hacks in inval.c to make real sure we
                               1113                 :          * don't think a command that queued inval messages was read-only.)
                               1114                 :          */
 4809 tgl                      1115 GIC     1206274 :         AtCCI_LocalCache();
                               1116                 :     }
 9770 scrappy                  1117         1900775 : }
                               1118                 : 
 5730 tgl                      1119 ECB             : /*
                               1120                 :  * ForceSyncCommit
                               1121                 :  *
                               1122                 :  * Interface routine to allow commands to force a synchronous commit of the
                               1123                 :  * current top-level transaction.  Currently, two-phase commit does not
                               1124                 :  * persist and restore this variable.  So long as all callers use
                               1125                 :  * PreventInTransactionBlock(), that omission has no consequences.
                               1126                 :  */
                               1127                 : void
 5730 tgl                      1128 GIC         878 : ForceSyncCommit(void)
                               1129                 : {
                               1130             878 :     forceSyncCommit = true;
                               1131             878 : }
 5730 tgl                      1132 ECB             : 
                               1133                 : 
 9770 scrappy                  1134                 : /* ----------------------------------------------------------------
 9345 bruce                    1135                 :  *                      StartTransaction stuff
                               1136                 :  * ----------------------------------------------------------------
                               1137                 :  */
                               1138                 : 
                               1139                 : /*
                               1140                 :  *  AtStart_Cache
                               1141                 :  */
                               1142                 : static void
 8202 tgl                      1143 GIC      485395 : AtStart_Cache(void)
                               1144                 : {
 7964                          1145          485395 :     AcceptInvalidationMessages();
 9770 scrappy                  1146          485395 : }
 9770 scrappy                  1147 ECB             : 
                               1148                 : /*
 7452 bruce                    1149                 :  *  AtStart_Memory
 9770 scrappy                  1150                 :  */
                               1151                 : static void
 8202 tgl                      1152 GIC      485395 : AtStart_Memory(void)
                               1153                 : {
 6856                          1154          485395 :     TransactionState s = CurrentTransactionState;
                               1155                 : 
 5981 tgl                      1156 ECB             :     /*
                               1157                 :      * If this is the first time through, create a private context for
                               1158                 :      * AbortTransaction to work in.  By reserving some space now, we can
                               1159                 :      * insulate AbortTransaction from out-of-memory scenarios.  Like
                               1160                 :      * ErrorContext, we set it up with slow growth rate and a nonzero minimum
                               1161                 :      * size, so that space will be reserved immediately.
                               1162                 :      */
 5981 tgl                      1163 GIC      485395 :     if (TransactionAbortContext == NULL)
                               1164           11433 :         TransactionAbortContext =
 1640                          1165           11433 :             AllocSetContextCreate(TopMemoryContext,
                               1166                 :                                   "TransactionAbortContext",
 1640 tgl                      1167 ECB             :                                   32 * 1024,
                               1168                 :                                   32 * 1024,
                               1169                 :                                   32 * 1024);
                               1170                 : 
                               1171                 :     /*
                               1172                 :      * We shouldn't have a transaction context already.
                               1173                 :      */
 8320 tgl                      1174 GIC      485395 :     Assert(TopTransactionContext == NULL);
                               1175                 : 
                               1176                 :     /*
                               1177                 :      * Create a toplevel context for the transaction.
 9345 bruce                    1178 ECB             :      */
 8320 tgl                      1179 GIC      485395 :     TopTransactionContext =
                               1180          485395 :         AllocSetContextCreate(TopMemoryContext,
                               1181                 :                               "TopTransactionContext",
                               1182                 :                               ALLOCSET_DEFAULT_SIZES);
 9345 bruce                    1183 ECB             : 
 6856 tgl                      1184                 :     /*
                               1185                 :      * In a top-level transaction, CurTransactionContext is the same as
                               1186                 :      * TopTransactionContext.
                               1187                 :      */
 6856 tgl                      1188 GIC      485395 :     CurTransactionContext = TopTransactionContext;
                               1189          485395 :     s->curTransactionContext = CurTransactionContext;
                               1190                 : 
                               1191                 :     /* Make the CurTransactionContext active. */
 6856 tgl                      1192 CBC      485395 :     MemoryContextSwitchTo(CurTransactionContext);
 9770 scrappy                  1193          485395 : }
                               1194                 : 
                               1195                 : /*
 6840 tgl                      1196 ECB             :  *  AtStart_ResourceOwner
                               1197                 :  */
                               1198                 : static void
 6840 tgl                      1199 GIC      485395 : AtStart_ResourceOwner(void)
                               1200                 : {
                               1201          485395 :     TransactionState s = CurrentTransactionState;
                               1202                 : 
 6840 tgl                      1203 ECB             :     /*
                               1204                 :      * We shouldn't have a transaction resource owner already.
                               1205                 :      */
 6840 tgl                      1206 GIC      485395 :     Assert(TopTransactionResourceOwner == NULL);
                               1207                 : 
                               1208                 :     /*
                               1209                 :      * Create a toplevel resource owner for the transaction.
 6840 tgl                      1210 ECB             :      */
 6840 tgl                      1211 GIC      485395 :     s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
                               1212                 : 
                               1213          485395 :     TopTransactionResourceOwner = s->curTransactionOwner;
                               1214          485395 :     CurTransactionResourceOwner = s->curTransactionOwner;
 6840 tgl                      1215 CBC      485395 :     CurrentResourceOwner = s->curTransactionOwner;
 6840 tgl                      1216 GIC      485395 : }
 6840 tgl                      1217 ECB             : 
 6856                          1218                 : /* ----------------------------------------------------------------
                               1219                 :  *                      StartSubTransaction stuff
                               1220                 :  * ----------------------------------------------------------------
                               1221                 :  */
                               1222                 : 
                               1223                 : /*
                               1224                 :  * AtSubStart_Memory
                               1225                 :  */
                               1226                 : static void
 6856 tgl                      1227 GIC        8783 : AtSubStart_Memory(void)
                               1228                 : {
                               1229            8783 :     TransactionState s = CurrentTransactionState;
                               1230                 : 
 6856 tgl                      1231 CBC        8783 :     Assert(CurTransactionContext != NULL);
                               1232                 : 
 6856 tgl                      1233 ECB             :     /*
                               1234                 :      * Create a CurTransactionContext, which will be used to hold data that
 6385 bruce                    1235                 :      * survives subtransaction commit but disappears on subtransaction abort.
                               1236                 :      * We make it a child of the immediate parent's CurTransactionContext.
                               1237                 :      */
 6856 tgl                      1238 GIC        8783 :     CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
                               1239                 :                                                   "CurTransactionContext",
                               1240                 :                                                   ALLOCSET_DEFAULT_SIZES);
                               1241            8783 :     s->curTransactionContext = CurTransactionContext;
 6856 tgl                      1242 ECB             : 
                               1243                 :     /* Make the CurTransactionContext active. */
 6856 tgl                      1244 GIC        8783 :     MemoryContextSwitchTo(CurTransactionContext);
 6856 tgl                      1245 CBC        8783 : }
                               1246                 : 
                               1247                 : /*
 6840 tgl                      1248 ECB             :  * AtSubStart_ResourceOwner
                               1249                 :  */
                               1250                 : static void
 6840 tgl                      1251 GIC        8783 : AtSubStart_ResourceOwner(void)
                               1252                 : {
                               1253            8783 :     TransactionState s = CurrentTransactionState;
                               1254                 : 
 6840 tgl                      1255 CBC        8783 :     Assert(s->parent != NULL);
                               1256                 : 
 6840 tgl                      1257 ECB             :     /*
                               1258                 :      * Create a resource owner for the subtransaction.  We make it a child of
 6385 bruce                    1259                 :      * the immediate parent's resource owner.
                               1260                 :      */
 6840 tgl                      1261 GIC        8783 :     s->curTransactionOwner =
                               1262            8783 :         ResourceOwnerCreate(s->parent->curTransactionOwner,
                               1263                 :                             "SubTransaction");
                               1264                 : 
 6840 tgl                      1265 CBC        8783 :     CurTransactionResourceOwner = s->curTransactionOwner;
                               1266            8783 :     CurrentResourceOwner = s->curTransactionOwner;
 6840 tgl                      1267 GIC        8783 : }
                               1268                 : 
 9770 scrappy                  1269 ECB             : /* ----------------------------------------------------------------
 9345 bruce                    1270                 :  *                      CommitTransaction stuff
 9770 scrappy                  1271                 :  * ----------------------------------------------------------------
                               1272                 :  */
                               1273                 : 
                               1274                 : /*
                               1275                 :  *  RecordTransactionCommit
                               1276                 :  *
                               1277                 :  * Returns latest XID among xact and its children, or InvalidTransactionId
                               1278                 :  * if the xact has no XID.  (We compute that here just because it's easier.)
                               1279                 :  *
                               1280                 :  * If you change this function, see RecordTransactionCommitPrepared also.
                               1281                 :  */
                               1282                 : static TransactionId
 4808 tgl                      1283 GIC      463648 : RecordTransactionCommit(void)
                               1284                 : {
 5695                          1285          463648 :     TransactionId xid = GetTopTransactionIdIfAny();
 5624 bruce                    1286          463648 :     bool        markXidCommitted = TransactionIdIsValid(xid);
 5692 tgl                      1287 CBC      463648 :     TransactionId latestXid = InvalidTransactionId;
                               1288                 :     int         nrels;
                               1289                 :     RelFileLocator *rels;
 6856 tgl                      1290 ECB             :     int         nchildren;
                               1291                 :     TransactionId *children;
  368 andres                   1292 GIC      463648 :     int         ndroppedstats = 0;
                               1293          463648 :     xl_xact_stats_item *droppedstats = NULL;
 4622 rhaas                    1294          463648 :     int         nmsgs = 0;
 4859 simon                    1295          463648 :     SharedInvalidationMessage *invalMessages = NULL;
 4622 rhaas                    1296 CBC      463648 :     bool        RelcacheInitFileInval = false;
 4493 rhaas                    1297 ECB             :     bool        wrote_xlog;
 6856 tgl                      1298                 : 
  990 akapila                  1299                 :     /*
                               1300                 :      * Log pending invalidations for logical decoding of in-progress
                               1301                 :      * transactions.  Normally for DDLs, we log this at each command end,
                               1302                 :      * however, for certain cases where we directly update the system table
                               1303                 :      * without a transaction block, the invalidations are not logged till this
                               1304                 :      * time.
                               1305                 :      */
  990 akapila                  1306 GIC      463648 :     if (XLogLogicalInfoActive())
                               1307           12504 :         LogLogicalInvalidations();
                               1308                 : 
                               1309                 :     /* Get data needed for commit record */
 4622 rhaas                    1310 CBC      463648 :     nrels = smgrGetPendingDeletes(true, &rels);
 6840 tgl                      1311          463648 :     nchildren = xactGetCommittedChildren(&children);
  368 andres                   1312 GIC      463648 :     ndroppedstats = pgstat_get_transactional_drops(true, &droppedstats);
 4622 rhaas                    1313          463648 :     if (XLogStandbyInfoActive())
 4622 rhaas                    1314 CBC      396281 :         nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
 4622 rhaas                    1315 ECB             :                                                      &RelcacheInitFileInval);
 3941 heikki.linnakangas       1316 CBC      463648 :     wrote_xlog = (XactLastRecEnd != 0);
 4790 bruce                    1317 ECB             : 
 7897 tgl                      1318                 :     /*
                               1319                 :      * If we haven't been assigned an XID yet, we neither can, nor do we want
 5624 bruce                    1320                 :      * to write a COMMIT record.
                               1321                 :      */
 5695 tgl                      1322 GIC      463648 :     if (!markXidCommitted)
                               1323                 :     {
                               1324                 :         /*
                               1325                 :          * We expect that every RelationDropStorage is followed by a catalog
 5624 bruce                    1326 ECB             :          * update, and hence XID assignment, so we shouldn't get here with any
                               1327                 :          * pending deletes. Same is true for dropping stats.
                               1328                 :          *
                               1329                 :          * Use a real test not just an Assert to check this, since it's a bit
                               1330                 :          * fragile.
                               1331                 :          */
  368 andres                   1332 GIC      170150 :         if (nrels != 0 || ndroppedstats != 0)
 5695 tgl                      1333 UIC           0 :             elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
                               1334                 : 
                               1335                 :         /* Can't have child XIDs either; AssignTransactionId enforces this */
 5695 tgl                      1336 CBC      170150 :         Assert(nchildren == 0);
 5624 bruce                    1337 EUB             : 
                               1338                 :         /*
                               1339                 :          * Transactions without an assigned xid can contain invalidation
 2542 andres                   1340 ECB             :          * messages (e.g. explicit relcache invalidations or catcache
                               1341                 :          * invalidations for inplace updates); standbys need to process those.
                               1342                 :          * We can't emit a commit record without an xid, and we don't want to
                               1343                 :          * force assigning an xid, because that'd be problematic for e.g.
                               1344                 :          * vacuum.  Hence we emit a bespoke record for the invalidations. We
                               1345                 :          * don't want to use that in case a commit record is emitted, so they
                               1346                 :          * happen synchronously with commits (besides not wanting to emit more
                               1347                 :          * WAL records).
                               1348                 :          */
 2542 andres                   1349 GIC      170150 :         if (nmsgs != 0)
                               1350                 :         {
                               1351           43462 :             LogStandbyInvalidations(nmsgs, invalMessages,
                               1352                 :                                     RelcacheInitFileInval);
 2495 rhaas                    1353 CBC       43462 :             wrote_xlog = true;  /* not strictly necessary */
                               1354                 :         }
 2542 andres                   1355 ECB             : 
                               1356                 :         /*
 5695 tgl                      1357                 :          * If we didn't create XLOG entries, we're done here; otherwise we
                               1358                 :          * should trigger flushing those entries the same as a commit record
                               1359                 :          * would.  This will primarily happen for HOT pruning and the like; we
                               1360                 :          * want these to be flushed to disk in due time.
                               1361                 :          */
 4493 rhaas                    1362 GIC      170150 :         if (!wrote_xlog)
 5695 tgl                      1363          122495 :             goto cleanup;
                               1364                 :     }
                               1365                 :     else
 5695 tgl                      1366 ECB             :     {
 2749 alvherre                 1367                 :         bool        replorigin;
                               1368                 : 
                               1369                 :         /*
                               1370                 :          * Are we using the replication origins feature?  Or, in other words,
                               1371                 :          * are we replaying remote actions?
                               1372                 :          */
 2749 alvherre                 1373 GIC      294329 :         replorigin = (replorigin_session_origin != InvalidRepOriginId &&
                               1374             831 :                       replorigin_session_origin != DoNotReplicateId);
                               1375                 : 
                               1376                 :         /*
                               1377                 :          * Mark ourselves as within our "commit critical section".  This
                               1378                 :          * forces any concurrent checkpoint to wait until we've updated
                               1379                 :          * pg_xact.  Without this, it is possible for the checkpoint to set
                               1380                 :          * REDO after the XLOG record but fail to flush the pg_xact update to
                               1381                 :          * disk, leading to loss of the transaction commit if the system
                               1382                 :          * crashes a little later.
                               1383                 :          *
                               1384                 :          * Note: we could, but don't bother to, set this flag in
                               1385                 :          * RecordTransactionAbort.  That's because loss of a transaction abort
                               1386                 :          * is noncritical; the presumption would be that it aborted, anyway.
                               1387                 :          *
                               1388                 :          * It's safe to change the delayChkptFlags flag of our own backend
                               1389                 :          * without holding the ProcArrayLock, since we're the only one
                               1390                 :          * modifying it.  This makes checkpoint's determination of which xacts
  366 rhaas                    1391 ECB             :          * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
 6815 tgl                      1392                 :          */
  366 rhaas                    1393 CBC      293498 :         Assert((MyProc->delayChkptFlags & DELAY_CHKPT_START) == 0);
 5695 tgl                      1394 GIC      293498 :         START_CRIT_SECTION();
  366 rhaas                    1395          293498 :         MyProc->delayChkptFlags |= DELAY_CHKPT_START;
                               1396                 : 
                               1397                 :         /*
                               1398                 :          * Insert the commit XLOG record.
                               1399                 :          */
  177 andres                   1400 GNC      293498 :         XactLogCommitRecord(GetCurrentTransactionStopTimestamp(),
                               1401                 :                             nchildren, children, nrels, rels,
                               1402                 :                             ndroppedstats, droppedstats,
                               1403                 :                             nmsgs, invalMessages,
                               1404                 :                             RelcacheInitFileInval,
                               1405                 :                             MyXactFlags,
                               1406                 :                             InvalidTransactionId, NULL /* plain commit */ );
 8202 vadim4o                  1407 ECB             : 
 2749 alvherre                 1408 GIC      293498 :         if (replorigin)
 2749 alvherre                 1409 ECB             :             /* Move LSNs forward for this replication origin */
 2750 alvherre                 1410 GIC         831 :             replorigin_session_advance(replorigin_session_origin_lsn,
                               1411                 :                                        XactLastRecEnd);
                               1412                 : 
                               1413                 :         /*
                               1414                 :          * Record commit timestamp.  The value comes from plain commit
                               1415                 :          * timestamp if there's no replication origin; otherwise, the
                               1416                 :          * timestamp was already set in replorigin_session_origin_timestamp by
                               1417                 :          * replication.
                               1418                 :          *
                               1419                 :          * We don't need to WAL-log anything here, as the commit record
                               1420                 :          * written above already contains the data.
                               1421                 :          */
 2749 alvherre                 1422 ECB             : 
 2749 alvherre                 1423 CBC      293498 :         if (!replorigin || replorigin_session_origin_timestamp == 0)
  177 andres                   1424 GNC      292741 :             replorigin_session_origin_timestamp = GetCurrentTransactionStopTimestamp();
 2749 alvherre                 1425 ECB             : 
 3049 alvherre                 1426 GIC      293498 :         TransactionTreeSetCommitTsData(xid, nchildren, children,
                               1427                 :                                        replorigin_session_origin_timestamp,
                               1428                 :                                        replorigin_session_origin);
                               1429                 :     }
                               1430                 : 
                               1431                 :     /*
                               1432                 :      * Check if we want to commit asynchronously.  We can allow the XLOG flush
                               1433                 :      * to happen asynchronously if synchronous_commit=off, or if the current
                               1434                 :      * transaction has not performed any WAL-logged operation or didn't assign
                               1435                 :      * an xid.  The transaction can end up not writing any WAL, even if it has
                               1436                 :      * an xid, if it only wrote to temporary and/or unlogged tables.  It can
                               1437                 :      * end up having written WAL without an xid if it did HOT pruning.  In
                               1438                 :      * case of a crash, the loss of such a transaction will be irrelevant;
                               1439                 :      * temp tables will be lost anyway, unlogged tables will be truncated and
                               1440                 :      * HOT pruning will be done again later. (Given the foregoing, you might
                               1441                 :      * think that it would be unnecessary to emit the XLOG record at all in
                               1442                 :      * this case, but we don't currently try to do that.  It would certainly
                               1443                 :      * cause problems at least in Hot Standby mode, where the
                               1444                 :      * KnownAssignedXids machinery requires tracking every XID assignment.  It
                               1445                 :      * might be OK to skip it only when wal_level < replica, but for now we
                               1446                 :      * don't.)
                               1447                 :      *
                               1448                 :      * However, if we're doing cleanup of any non-temp rels or committing any
                               1449                 :      * command that wanted to force sync commit, then we must flush XLOG
                               1450                 :      * immediately.  (We must not allow asynchronous commit if there are any
                               1451                 :      * non-temp tables to be deleted, because we might delete the files before
                               1452                 :      * the COMMIT record is flushed to disk.  We do allow asynchronous commit
                               1453                 :      * if all to-be-deleted tables are temporary though, since they are lost
                               1454                 :      * anyway if we crash.)
 5695 tgl                      1455 ECB             :      */
 2964 andres                   1456 CBC      341153 :     if ((wrote_xlog && markXidCommitted &&
                               1457          341153 :          synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
 4388 rhaas                    1458 GIC       54637 :         forceSyncCommit || nrels > 0)
 5695 tgl                      1459 ECB             :     {
 5695 tgl                      1460 GIC      286533 :         XLogFlush(XactLastRecEnd);
                               1461                 : 
                               1462                 :         /*
                               1463                 :          * Now we may update the CLOG, if we wrote a COMMIT record above
 5695 tgl                      1464 ECB             :          */
 5695 tgl                      1465 CBC      286533 :         if (markXidCommitted)
 5284 alvherre                 1466 GIC      286533 :             TransactionIdCommitTree(xid, nchildren, children);
                               1467                 :     }
                               1468                 :     else
                               1469                 :     {
                               1470                 :         /*
                               1471                 :          * Asynchronous commit case:
                               1472                 :          *
                               1473                 :          * This enables possible committed transaction loss in the case of a
                               1474                 :          * postmaster crash because WAL buffers are left unwritten. Ideally we
                               1475                 :          * could issue the WAL write without the fsync, but some
                               1476                 :          * wal_sync_methods do not allow separate write/fsync.
                               1477                 :          *
                               1478                 :          * Report the latest async commit LSN, so that the WAL writer knows to
                               1479                 :          * flush this commit.
 7551 tgl                      1480 ECB             :          */
 4637 simon                    1481 GIC       54620 :         XLogSetAsyncXactLSN(XactLastRecEnd);
                               1482                 : 
                               1483                 :         /*
                               1484                 :          * We must not immediately update the CLOG, since we didn't flush the
                               1485                 :          * XLOG. Instead, we store the LSN up to which the XLOG must be
                               1486                 :          * flushed before the CLOG may be updated.
 5695 tgl                      1487 ECB             :          */
 5695 tgl                      1488 CBC       54620 :         if (markXidCommitted)
 5284 alvherre                 1489 GIC        6965 :             TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
                               1490                 :     }
                               1491                 : 
                               1492                 :     /*
                               1493                 :      * If we entered a commit critical section, leave it now, and let
                               1494                 :      * checkpoints proceed.
 5695 tgl                      1495 ECB             :      */
 5695 tgl                      1496 GIC      341153 :     if (markXidCommitted)
 5695 tgl                      1497 ECB             :     {
  366 rhaas                    1498 CBC      293498 :         MyProc->delayChkptFlags &= ~DELAY_CHKPT_START;
 8122 tgl                      1499 GIC      293498 :         END_CRIT_SECTION();
                               1500                 :     }
                               1501                 : 
 5692 tgl                      1502 ECB             :     /* Compute latestXid while we have the child XIDs handy */
 5692 tgl                      1503 GIC      341153 :     latestXid = TransactionIdLatest(xid, nchildren, children);
                               1504                 : 
                               1505                 :     /*
                               1506                 :      * Wait for synchronous replication, if required. Similar to the decision
                               1507                 :      * above about using committing asynchronously we only want to wait if
                               1508                 :      * this backend assigned an xid and wrote WAL.  No need to wait if an xid
                               1509                 :      * was assigned due to temporary/unlogged tables or due to HOT pruning.
                               1510                 :      *
                               1511                 :      * Note that at this stage we have marked clog, but still show as running
                               1512                 :      * in the procarray and continue to hold locks.
 4417 simon                    1513 ECB             :      */
 2964 andres                   1514 CBC      341153 :     if (wrote_xlog && markXidCommitted)
 2567 rhaas                    1515 GIC      289582 :         SyncRepWaitForLSN(XactLastRecEnd, true);
                               1516                 : 
 2902 andres                   1517 ECB             :     /* remember end of last commit record */
 2902 andres                   1518 GIC      341153 :     XactLastCommitEnd = XactLastRecEnd;
                               1519                 : 
 5695 tgl                      1520 ECB             :     /* Reset XactLastRecEnd until the next transaction writes something */
 3941 heikki.linnakangas       1521 CBC      341153 :     XactLastRecEnd = 0;
 5695 tgl                      1522 GIC      463648 : cleanup:
 5695 tgl                      1523 ECB             :     /* Clean up local data */
 6505 tgl                      1524 CBC      463648 :     if (rels)
                               1525            7391 :         pfree(rels);
  368 andres                   1526          463648 :     if (ndroppedstats)
  368 andres                   1527 GIC        8934 :         pfree(droppedstats);
 5692 tgl                      1528 ECB             : 
 5692 tgl                      1529 GIC      463648 :     return latestXid;
                               1530                 : }
                               1531                 : 
                               1532                 : 
                               1533                 : /*
                               1534                 :  *  AtCCI_LocalCache
                               1535                 :  */
 8490 inoue                    1536 ECB             : static void
 4809 tgl                      1537 GIC     1206274 : AtCCI_LocalCache(void)
                               1538                 : {
                               1539                 :     /*
                               1540                 :      * Make any pending relation map changes visible.  We must do this before
                               1541                 :      * processing local sinval messages, so that the map changes will get
                               1542                 :      * reflected into the relcache when relcache invals are processed.
 4809 tgl                      1543 ECB             :      */
 4809 tgl                      1544 GIC     1206274 :     AtCCI_RelationMap();
                               1545                 : 
                               1546                 :     /*
                               1547                 :      * Make catalog changes visible to me for the next command.
 8490 inoue                    1548 ECB             :      */
 6856 tgl                      1549 CBC     1206274 :     CommandEndInvalidationMessages();
 8490 inoue                    1550 GIC     1206271 : }
                               1551                 : 
                               1552                 : /*
                               1553                 :  *  AtCommit_Memory
                               1554                 :  */
 9364 bruce                    1555 ECB             : static void
 8202 tgl                      1556 GIC      465297 : AtCommit_Memory(void)
                               1557                 : {
                               1558                 :     /*
                               1559                 :      * Now that we're "out" of a transaction, have the system allocate things
                               1560                 :      * in the top memory context instead of per-transaction contexts.
 8732 tgl                      1561 ECB             :      */
 8320 tgl                      1562 GIC      465297 :     MemoryContextSwitchTo(TopMemoryContext);
                               1563                 : 
                               1564                 :     /*
                               1565                 :      * Release all transaction-local memory.
 9345 bruce                    1566 ECB             :      */
 8316 tgl                      1567 CBC      465297 :     Assert(TopTransactionContext != NULL);
 8320                          1568          465297 :     MemoryContextDelete(TopTransactionContext);
                               1569          465297 :     TopTransactionContext = NULL;
 6856                          1570          465297 :     CurTransactionContext = NULL;
                               1571          465297 :     CurrentTransactionState->curTransactionContext = NULL;
 6856 tgl                      1572 GIC      465297 : }
                               1573                 : 
                               1574                 : /* ----------------------------------------------------------------
                               1575                 :  *                      CommitSubTransaction stuff
                               1576                 :  * ----------------------------------------------------------------
                               1577                 :  */
                               1578                 : 
                               1579                 : /*
                               1580                 :  * AtSubCommit_Memory
                               1581                 :  */
 6856 tgl                      1582 ECB             : static void
 6856 tgl                      1583 GIC        4315 : AtSubCommit_Memory(void)
 6856 tgl                      1584 ECB             : {
 6856 tgl                      1585 GIC        4315 :     TransactionState s = CurrentTransactionState;
 6856 tgl                      1586 ECB             : 
 6856 tgl                      1587 GIC        4315 :     Assert(s->parent != NULL);
                               1588                 : 
 6856 tgl                      1589 ECB             :     /* Return to parent transaction level's memory context. */
 6856 tgl                      1590 CBC        4315 :     CurTransactionContext = s->parent->curTransactionContext;
 6856 tgl                      1591 GIC        4315 :     MemoryContextSwitchTo(CurTransactionContext);
                               1592                 : 
                               1593                 :     /*
                               1594                 :      * Ordinarily we cannot throw away the child's CurTransactionContext,
                               1595                 :      * since the data it contains will be needed at upper commit.  However, if
                               1596                 :      * there isn't actually anything in it, we can throw it away.  This avoids
                               1597                 :      * a small memory leak in the common case of "trivial" subxacts.
 6779 tgl                      1598 ECB             :      */
 6779 tgl                      1599 GIC        4315 :     if (MemoryContextIsEmpty(s->curTransactionContext))
 6779 tgl                      1600 ECB             :     {
 6779 tgl                      1601 CBC        4301 :         MemoryContextDelete(s->curTransactionContext);
 6779 tgl                      1602 GIC        4301 :         s->curTransactionContext = NULL;
 6779 tgl                      1603 ECB             :     }
 6856 tgl                      1604 GIC        4315 : }
                               1605                 : 
                               1606                 : /*
                               1607                 :  * AtSubCommit_childXids
                               1608                 :  *
                               1609                 :  * Pass my own XID and my child XIDs up to my parent as committed children.
                               1610                 :  */
 6856 tgl                      1611 ECB             : static void
 6856 tgl                      1612 GIC        2804 : AtSubCommit_childXids(void)
 6856 tgl                      1613 ECB             : {
 6856 tgl                      1614 GIC        2804 :     TransactionState s = CurrentTransactionState;
                               1615                 :     int         new_nChildXids;
 6856 tgl                      1616 ECB             : 
 6856 tgl                      1617 GIC        2804 :     Assert(s->parent != NULL);
                               1618                 : 
                               1619                 :     /*
                               1620                 :      * The parent childXids array will need to hold my XID and all my
                               1621                 :      * childXids, in addition to the XIDs already there.
 6779 tgl                      1622 ECB             :      */
 5501 tgl                      1623 GIC        2804 :     new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
                               1624                 : 
 5501 tgl                      1625 ECB             :     /* Allocate or enlarge the parent array if necessary */
 5501 tgl                      1626 GIC        2804 :     if (s->parent->maxChildXids < new_nChildXids)
                               1627                 :     {
                               1628                 :         int         new_maxChildXids;
                               1629                 :         TransactionId *new_childXids;
                               1630                 : 
                               1631                 :         /*
                               1632                 :          * Make it 2x what's needed right now, to avoid having to enlarge it
                               1633                 :          * repeatedly. But we can't go above MaxAllocSize.  (The latter limit
                               1634                 :          * is what ensures that we don't need to worry about integer overflow
                               1635                 :          * here or in the calculation of new_nChildXids.)
 6779 tgl                      1636 ECB             :          */
 5501 tgl                      1637 GIC        1673 :         new_maxChildXids = Min(new_nChildXids * 2,
                               1638                 :                                (int) (MaxAllocSize / sizeof(TransactionId)));
 5501 tgl                      1639 ECB             : 
 5501 tgl                      1640 GBC        1673 :         if (new_maxChildXids < new_nChildXids)
 5501 tgl                      1641 UIC           0 :             ereport(ERROR,
                               1642                 :                     (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                               1643                 :                      errmsg("maximum number of committed subtransactions (%d) exceeded",
                               1644                 :                             (int) (MaxAllocSize / sizeof(TransactionId)))));
                               1645                 : 
                               1646                 :         /*
                               1647                 :          * We keep the child-XID arrays in TopTransactionContext; this avoids
                               1648                 :          * setting up child-transaction contexts for what might be just a few
                               1649                 :          * bytes of grandchild XIDs.
 5501 tgl                      1650 ECB             :          */
 5501 tgl                      1651 GIC        1673 :         if (s->parent->childXids == NULL)
 5501 tgl                      1652 ECB             :             new_childXids =
 5050 bruce                    1653 GIC        1642 :                 MemoryContextAlloc(TopTransactionContext,
                               1654                 :                                    new_maxChildXids * sizeof(TransactionId));
 5501 tgl                      1655 ECB             :         else
 5050 bruce                    1656 GIC          31 :             new_childXids = repalloc(s->parent->childXids,
                               1657                 :                                      new_maxChildXids * sizeof(TransactionId));
 5501 tgl                      1658 ECB             : 
 5050 bruce                    1659 CBC        1673 :         s->parent->childXids = new_childXids;
 5501 tgl                      1660 GIC        1673 :         s->parent->maxChildXids = new_maxChildXids;
                               1661                 :     }
                               1662                 : 
                               1663                 :     /*
                               1664                 :      * Copy all my XIDs to parent's array.
                               1665                 :      *
                               1666                 :      * Note: We rely on the fact that the XID of a child always follows that
                               1667                 :      * of its parent.  By copying the XID of this subtransaction before the
                               1668                 :      * XIDs of its children, we ensure that the array stays ordered. Likewise,
                               1669                 :      * all XIDs already in the array belong to subtransactions started and
                               1670                 :      * subcommitted before us, so their XIDs must precede ours.
 5501 tgl                      1671 ECB             :      */
 1473 tmunro                   1672 GIC        2804 :     s->parent->childXids[s->parent->nChildXids] = XidFromFullTransactionId(s->fullTransactionId);
 5501 tgl                      1673 ECB             : 
 5501 tgl                      1674 CBC        2804 :     if (s->nChildXids > 0)
                               1675            1008 :         memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
                               1676            1008 :                s->childXids,
 5501 tgl                      1677 GIC        1008 :                s->nChildXids * sizeof(TransactionId));
 5501 tgl                      1678 ECB             : 
 5501 tgl                      1679 GIC        2804 :     s->parent->nChildXids = new_nChildXids;
                               1680                 : 
 5501 tgl                      1681 ECB             :     /* Release child's array to avoid leakage */
 5501 tgl                      1682 CBC        2804 :     if (s->childXids != NULL)
 5501 tgl                      1683 GIC        1008 :         pfree(s->childXids);
 5501 tgl                      1684 ECB             :     /* We must reset these to avoid double-free if fail later in commit */
 5501 tgl                      1685 CBC        2804 :     s->childXids = NULL;
                               1686            2804 :     s->nChildXids = 0;
                               1687            2804 :     s->maxChildXids = 0;
 6856 tgl                      1688 GIC        2804 : }
                               1689                 : 
                               1690                 : /* ----------------------------------------------------------------
                               1691                 :  *                      AbortTransaction stuff
                               1692                 :  * ----------------------------------------------------------------
                               1693                 :  */
                               1694                 : 
                               1695                 : /*
                               1696                 :  *  RecordTransactionAbort
                               1697                 :  *
                               1698                 :  * Returns latest XID among xact and its children, or InvalidTransactionId
                               1699                 :  * if the xact has no XID.  (We compute that here just because it's easier.)
                               1700                 :  */
 5692 tgl                      1701 ECB             : static TransactionId
 5695 tgl                      1702 GIC       24563 : RecordTransactionAbort(bool isSubXact)
 9770 scrappy                  1703 ECB             : {
 5695 tgl                      1704 GIC       24563 :     TransactionId xid = GetCurrentTransactionIdIfAny();
                               1705                 :     TransactionId latestXid;
                               1706                 :     int         nrels;
                               1707                 :     RelFileLocator *rels;
  368 andres                   1708 CBC       24563 :     int         ndroppedstats = 0;
  368 andres                   1709 GIC       24563 :     xl_xact_stats_item *droppedstats = NULL;
                               1710                 :     int         nchildren;
                               1711                 :     TransactionId *children;
                               1712                 :     TimestampTz xact_time;
                               1713                 :     bool        replorigin;
                               1714                 : 
                               1715                 :     /*
                               1716                 :      * If we haven't been assigned an XID, nobody will care whether we aborted
                               1717                 :      * or not.  Hence, we're done in that case.  It does not matter if we have
                               1718                 :      * rels to delete (note that this routine is not responsible for actually
                               1719                 :      * deleting 'em).  We cannot have any child XIDs, either.
                               1720                 :      */
 5695 tgl                      1721 CBC       24563 :     if (!TransactionIdIsValid(xid))
                               1722                 :     {
                               1723                 :         /* Reset XactLastRecEnd until the next transaction writes something */
                               1724           19783 :         if (!isSubXact)
 3941 heikki.linnakangas       1725           15925 :             XactLastRecEnd = 0;
 5692 tgl                      1726           19783 :         return InvalidTransactionId;
                               1727                 :     }
                               1728                 : 
                               1729                 :     /*
                               1730                 :      * We have a valid XID, so we should write an ABORT record for it.
                               1731                 :      *
                               1732                 :      * We do not flush XLOG to disk here, since the default assumption after a
                               1733                 :      * crash would be that we aborted, anyway.  For the same reason, we don't
                               1734                 :      * need to worry about interlocking against checkpoint start.
                               1735                 :      */
                               1736                 : 
                               1737                 :     /*
                               1738                 :      * Check that we haven't aborted halfway through RecordTransactionCommit.
                               1739                 :      */
 5695                          1740            4780 :     if (TransactionIdDidCommit(xid))
 5695 tgl                      1741 UBC           0 :         elog(PANIC, "cannot abort transaction %u, it was already committed",
                               1742                 :              xid);
                               1743                 : 
                               1744                 :     /*
                               1745                 :      * Are we using the replication origins feature?  Or, in other words, are
                               1746                 :      * we replaying remote actions?
                               1747                 :      */
   90 akapila                  1748 GNC        4812 :     replorigin = (replorigin_session_origin != InvalidRepOriginId &&
                               1749              32 :                   replorigin_session_origin != DoNotReplicateId);
                               1750                 : 
                               1751                 :     /* Fetch the data we need for the abort record */
 4622 rhaas                    1752 GIC        4780 :     nrels = smgrGetPendingDeletes(false, &rels);
 5695 tgl                      1753            4780 :     nchildren = xactGetCommittedChildren(&children);
  368 andres                   1754            4780 :     ndroppedstats = pgstat_get_transactional_drops(false, &droppedstats);
 7551 tgl                      1755 ECB             : 
 5695                          1756                 :     /* XXX do we really need a critical section here? */
 5695 tgl                      1757 GIC        4780 :     START_CRIT_SECTION();
                               1758                 : 
 5695 tgl                      1759 ECB             :     /* Write the ABORT record */
 5695 tgl                      1760 CBC        4780 :     if (isSubXact)
 2947 andres                   1761             610 :         xact_time = GetCurrentTimestamp();
                               1762                 :     else
                               1763                 :     {
  177 andres                   1764 GNC        4170 :         xact_time = GetCurrentTransactionStopTimestamp();
                               1765                 :     }
 3062 heikki.linnakangas       1766 ECB             : 
 2947 andres                   1767 CBC        4780 :     XactLogAbortRecord(xact_time,
                               1768                 :                        nchildren, children,
                               1769                 :                        nrels, rels,
  368 andres                   1770 ECB             :                        ndroppedstats, droppedstats,
                               1771                 :                        MyXactFlags, InvalidTransactionId,
                               1772                 :                        NULL);
 8062 tgl                      1773                 : 
   90 akapila                  1774 GNC        4780 :     if (replorigin)
                               1775                 :         /* Move LSNs forward for this replication origin */
                               1776              32 :         replorigin_session_advance(replorigin_session_origin_lsn,
                               1777                 :                                    XactLastRecEnd);
                               1778                 : 
                               1779                 :     /*
                               1780                 :      * Report the latest async abort LSN, so that the WAL writer knows to
                               1781                 :      * flush this abort. There's nothing to be gained by delaying this, since
                               1782                 :      * WALWriter may as well do this when it can. This is important with
                               1783                 :      * streaming replication because if we don't flush WAL regularly we will
                               1784                 :      * find that large aborts leave us with a long backlog for when commits
 4660 bruce                    1785 ECB             :      * occur after the abort, increasing our window of data loss should
                               1786                 :      * problems occur at that point.
 4714 simon                    1787                 :      */
 4714 simon                    1788 GIC        4780 :     if (!isSubXact)
 4637                          1789            4170 :         XLogSetAsyncXactLSN(XactLastRecEnd);
                               1790                 : 
                               1791                 :     /*
                               1792                 :      * Mark the transaction aborted in clog.  This is not absolutely necessary
                               1793                 :      * but we may as well do it while we are here; also, in the subxact case
                               1794                 :      * it is helpful because XactLockTableWait makes use of it to avoid
                               1795                 :      * waiting for already-aborted subtransactions.  It is OK to do it without
                               1796                 :      * having flushed the ABORT record to disk, because in event of a crash
                               1797                 :      * we'd be assumed to have aborted anyway.
                               1798                 :      */
 5284 alvherre                 1799 CBC        4780 :     TransactionIdAbortTree(xid, nchildren, children);
 8206 vadim4o                  1800 ECB             : 
 5695 tgl                      1801 GIC        4780 :     END_CRIT_SECTION();
                               1802                 : 
                               1803                 :     /* Compute latestXid while we have the child XIDs handy */
 5692                          1804            4780 :     latestXid = TransactionIdLatest(xid, nchildren, children);
                               1805                 : 
                               1806                 :     /*
                               1807                 :      * If we're aborting a subtransaction, we can immediately remove failed
                               1808                 :      * XIDs from PGPROC's cache of running child XIDs.  We do that here for
                               1809                 :      * subxacts, because we already have the child XID array at hand.  For
 5695 tgl                      1810 ECB             :      * main xacts, the equivalent happens just after this function returns.
                               1811                 :      */
 5695 tgl                      1812 CBC        4780 :     if (isSubXact)
 5692 tgl                      1813 GIC         610 :         XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
                               1814                 : 
 5695 tgl                      1815 ECB             :     /* Reset XactLastRecEnd until the next transaction writes something */
 5695 tgl                      1816 GIC        4780 :     if (!isSubXact)
 3941 heikki.linnakangas       1817            4170 :         XactLastRecEnd = 0;
                               1818                 : 
                               1819                 :     /* And clean up local data */
 6505 tgl                      1820            4780 :     if (rels)
                               1821             693 :         pfree(rels);
  368 andres                   1822            4780 :     if (ndroppedstats)
  368 andres                   1823 CBC         967 :         pfree(droppedstats);
 5692 tgl                      1824 ECB             : 
 5692 tgl                      1825 GIC        4780 :     return latestXid;
                               1826                 : }
 9770 scrappy                  1827 ECB             : 
 7331 bruce                    1828                 : /*
                               1829                 :  *  AtAbort_Memory
                               1830                 :  */
 9364                          1831                 : static void
 8202 tgl                      1832 CBC       31856 : AtAbort_Memory(void)
 9770 scrappy                  1833 ECB             : {
 8053 bruce                    1834                 :     /*
                               1835                 :      * Switch into TransactionAbortContext, which should have some free space
 5624                          1836                 :      * even if nothing else does.  We'll work in this context until we've
                               1837                 :      * finished cleaning up.
                               1838                 :      *
                               1839                 :      * It is barely possible to get here when we've not been able to create
                               1840                 :      * TransactionAbortContext yet; if so use TopMemoryContext.
                               1841                 :      */
 5981 tgl                      1842 GIC       31856 :     if (TransactionAbortContext != NULL)
 5981 tgl                      1843 CBC       31856 :         MemoryContextSwitchTo(TransactionAbortContext);
                               1844                 :     else
 8316 tgl                      1845 UIC           0 :         MemoryContextSwitchTo(TopMemoryContext);
 8320 tgl                      1846 GIC       31856 : }
                               1847                 : 
                               1848                 : /*
                               1849                 :  * AtSubAbort_Memory
                               1850                 :  */
                               1851                 : static void
 6856                          1852            4468 : AtSubAbort_Memory(void)
 6856 tgl                      1853 ECB             : {
 5981 tgl                      1854 CBC        4468 :     Assert(TransactionAbortContext != NULL);
                               1855                 : 
 5981 tgl                      1856 GBC        4468 :     MemoryContextSwitchTo(TransactionAbortContext);
 6856 tgl                      1857 CBC        4468 : }
                               1858                 : 
                               1859                 : 
                               1860                 : /*
                               1861                 :  *  AtAbort_ResourceOwner
                               1862                 :  */
 6761 tgl                      1863 ECB             : static void
 6761 tgl                      1864 GIC       20098 : AtAbort_ResourceOwner(void)
 6761 tgl                      1865 ECB             : {
                               1866                 :     /*
 6385 bruce                    1867                 :      * Make sure we have a valid ResourceOwner, if possible (else it will be
                               1868                 :      * NULL, which is OK)
                               1869                 :      */
 6761 tgl                      1870 GIC       20098 :     CurrentResourceOwner = TopTransactionResourceOwner;
                               1871           20098 : }
                               1872                 : 
                               1873                 : /*
                               1874                 :  * AtSubAbort_ResourceOwner
 6761 tgl                      1875 ECB             :  */
                               1876                 : static void
 6761 tgl                      1877 GIC        4468 : AtSubAbort_ResourceOwner(void)
                               1878                 : {
                               1879            4468 :     TransactionState s = CurrentTransactionState;
                               1880                 : 
 6761 tgl                      1881 ECB             :     /* Make sure we have a valid ResourceOwner */
 6761 tgl                      1882 CBC        4468 :     CurrentResourceOwner = s->curTransactionOwner;
 6761 tgl                      1883 GIC        4468 : }
                               1884                 : 
                               1885                 : 
                               1886                 : /*
                               1887                 :  * AtSubAbort_childXids
 6779 tgl                      1888 ECB             :  */
                               1889                 : static void
 6779 tgl                      1890 CBC         610 : AtSubAbort_childXids(void)
                               1891                 : {
 6779 tgl                      1892 GIC         610 :     TransactionState s = CurrentTransactionState;
 6779 tgl                      1893 ECB             : 
                               1894                 :     /*
                               1895                 :      * We keep the child-XID arrays in TopTransactionContext (see
                               1896                 :      * AtSubCommit_childXids).  This means we'd better free the array
                               1897                 :      * explicitly at abort to avoid leakage.
                               1898                 :      */
 5501 tgl                      1899 GIC         610 :     if (s->childXids != NULL)
                               1900              25 :         pfree(s->childXids);
 5501 tgl                      1901 CBC         610 :     s->childXids = NULL;
 5501 tgl                      1902 GIC         610 :     s->nChildXids = 0;
 5501 tgl                      1903 CBC         610 :     s->maxChildXids = 0;
                               1904                 : 
                               1905                 :     /*
                               1906                 :      * We could prune the unreportedXids array here. But we don't bother. That
                               1907                 :      * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
                               1908                 :      * would likely introduce more CPU time into the more common paths, so we
                               1909                 :      * choose not to do that.
 4859 simon                    1910 ECB             :      */
 6779 tgl                      1911 CBC         610 : }
 6779 tgl                      1912 ECB             : 
 8320                          1913                 : /* ----------------------------------------------------------------
                               1914                 :  *                      CleanupTransaction stuff
                               1915                 :  * ----------------------------------------------------------------
                               1916                 :  */
                               1917                 : 
                               1918                 : /*
                               1919                 :  *  AtCleanup_Memory
                               1920                 :  */
                               1921                 : static void
 8202 tgl                      1922 CBC       31856 : AtCleanup_Memory(void)
                               1923                 : {
 5981 tgl                      1924 GIC       31856 :     Assert(CurrentTransactionState->parent == NULL);
                               1925                 : 
                               1926                 :     /*
                               1927                 :      * Now that we're "out" of a transaction, have the system allocate things
                               1928                 :      * in the top memory context instead of per-transaction contexts.
                               1929                 :      */
 9345 bruce                    1930           31856 :     MemoryContextSwitchTo(TopMemoryContext);
                               1931                 : 
                               1932                 :     /*
 5981 tgl                      1933 ECB             :      * Clear the special abort context for next time.
                               1934                 :      */
 5981 tgl                      1935 CBC       31856 :     if (TransactionAbortContext != NULL)
 5981 tgl                      1936 GIC       31856 :         MemoryContextResetAndDeleteChildren(TransactionAbortContext);
                               1937                 : 
                               1938                 :     /*
                               1939                 :      * Release all transaction-local memory.
                               1940                 :      */
 8316 tgl                      1941 CBC       31856 :     if (TopTransactionContext != NULL)
 8316 tgl                      1942 GIC       20098 :         MemoryContextDelete(TopTransactionContext);
 8320                          1943           31856 :     TopTransactionContext = NULL;
 6856                          1944           31856 :     CurTransactionContext = NULL;
                               1945           31856 :     CurrentTransactionState->curTransactionContext = NULL;
 9770 scrappy                  1946 CBC       31856 : }
 9770 scrappy                  1947 ECB             : 
                               1948                 : 
                               1949                 : /* ----------------------------------------------------------------
                               1950                 :  *                      CleanupSubTransaction stuff
                               1951                 :  * ----------------------------------------------------------------
 6856 tgl                      1952                 :  */
                               1953                 : 
                               1954                 : /*
                               1955                 :  * AtSubCleanup_Memory
                               1956                 :  */
                               1957                 : static void
 6856 tgl                      1958 GIC        4468 : AtSubCleanup_Memory(void)
                               1959                 : {
                               1960            4468 :     TransactionState s = CurrentTransactionState;
                               1961                 : 
                               1962            4468 :     Assert(s->parent != NULL);
                               1963                 : 
                               1964                 :     /* Make sure we're not in an about-to-be-deleted context */
                               1965            4468 :     MemoryContextSwitchTo(s->parent->curTransactionContext);
                               1966            4468 :     CurTransactionContext = s->parent->curTransactionContext;
                               1967                 : 
                               1968                 :     /*
 5981 tgl                      1969 ECB             :      * Clear the special abort context for next time.
                               1970                 :      */
 5981 tgl                      1971 CBC        4468 :     if (TransactionAbortContext != NULL)
 5981 tgl                      1972 GIC        4468 :         MemoryContextResetAndDeleteChildren(TransactionAbortContext);
 5981 tgl                      1973 ECB             : 
                               1974                 :     /*
                               1975                 :      * Delete the subxact local memory contexts. Its CurTransactionContext can
 6385 bruce                    1976                 :      * go too (note this also kills CurTransactionContexts from any children
                               1977                 :      * of the subxact).
                               1978                 :      */
 6779 tgl                      1979 GIC        4468 :     if (s->curTransactionContext)
                               1980            4468 :         MemoryContextDelete(s->curTransactionContext);
                               1981            4468 :     s->curTransactionContext = NULL;
 6856 tgl                      1982 CBC        4468 : }
 6856 tgl                      1983 ECB             : 
                               1984                 : /* ----------------------------------------------------------------
                               1985                 :  *                      interface routines
                               1986                 :  * ----------------------------------------------------------------
                               1987                 :  */
                               1988                 : 
                               1989                 : /*
 7452 bruce                    1990                 :  *  StartTransaction
 9770 scrappy                  1991                 :  */
 9364 bruce                    1992                 : static void
 8202 tgl                      1993 CBC      485395 : StartTransaction(void)
                               1994                 : {
                               1995                 :     TransactionState s;
                               1996                 :     VirtualTransactionId vxid;
                               1997                 : 
                               1998                 :     /*
                               1999                 :      * Let's just make sure the state stack is empty
                               2000                 :      */
 6779 tgl                      2001 GIC      485395 :     s = &TopTransactionStateData;
                               2002          485395 :     CurrentTransactionState = s;
                               2003                 : 
 1473 tmunro                   2004 CBC      485395 :     Assert(!FullTransactionIdIsValid(XactTopFullTransactionId));
                               2005                 : 
                               2006                 :     /* check the current transaction state */
 1607 michael                  2007 GIC      485395 :     Assert(s->state == TRANS_DEFAULT);
                               2008                 : 
                               2009                 :     /*
                               2010                 :      * Set the current transaction state information appropriately during
                               2011                 :      * start processing.  Note that once the transaction status is switched
 1607 michael                  2012 ECB             :      * this process cannot fail until the user ID and the security context
                               2013                 :      * flags are fetched below.
                               2014                 :      */
 9345 bruce                    2015 CBC      485395 :     s->state = TRANS_START;
 1473 tmunro                   2016 GIC      485395 :     s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
                               2017                 : 
 1467 alvherre                 2018 ECB             :     /* Determine if statements are logged in this transaction */
 1467 alvherre                 2019 GIC      485395 :     xact_is_sampled = log_xact_sample_rate != 0 &&
 1467 alvherre                 2020 UIC           0 :         (log_xact_sample_rate == 1 ||
  497 tgl                      2021               0 :          pg_prng_double(&pg_global_prng_state) <= log_xact_sample_rate);
                               2022                 : 
                               2023                 :     /*
                               2024                 :      * initialize current transaction state fields
                               2025                 :      *
 1607 michael                  2026 ECB             :      * note: prevXactReadOnly is not used at the outermost level
                               2027                 :      */
 1607 michael                  2028 GIC      485395 :     s->nestingLevel = 1;
                               2029          485395 :     s->gucNestLevel = 1;
 1607 michael                  2030 CBC      485395 :     s->childXids = NULL;
 1607 michael                  2031 GBC      485395 :     s->nChildXids = 0;
                               2032          485395 :     s->maxChildXids = 0;
                               2033                 : 
                               2034                 :     /*
                               2035                 :      * Once the current user ID and the security context flags are fetched,
                               2036                 :      * both will be properly reset even if transaction startup fails.
                               2037                 :      */
 1607 michael                  2038 GIC      485395 :     GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
 1607 michael                  2039 ECB             : 
                               2040                 :     /* SecurityRestrictionContext should never be set outside a transaction */
 1607 michael                  2041 CBC      485395 :     Assert(s->prevSecContext == 0);
 1607 michael                  2042 ECB             : 
 7115 tgl                      2043                 :     /*
                               2044                 :      * Make sure we've reset xact state variables
                               2045                 :      *
                               2046                 :      * If recovery is still in progress, mark this transaction as read-only.
                               2047                 :      * We have lower level defences in XLogInsert and elsewhere to stop us
                               2048                 :      * from modifying data during recovery, but this gives the normal
 4859 simon                    2049                 :      * indication to the user that the transaction is read-only.
                               2050                 :      */
 4859 simon                    2051 GIC      485395 :     if (RecoveryInProgress())
 4859 simon                    2052 ECB             :     {
 4859 simon                    2053 GIC        1149 :         s->startedInRecovery = true;
                               2054            1149 :         XactReadOnly = true;
                               2055                 :     }
                               2056                 :     else
                               2057                 :     {
                               2058          484246 :         s->startedInRecovery = false;
                               2059          484246 :         XactReadOnly = DefaultXactReadOnly;
                               2060                 :     }
 4444 heikki.linnakangas       2061          485395 :     XactDeferrable = DefaultXactDeferrable;
 7115 tgl                      2062 CBC      485395 :     XactIsoLevel = DefaultXactIsoLevel;
 5730 tgl                      2063 GIC      485395 :     forceSyncCommit = false;
 2209 simon                    2064 CBC      485395 :     MyXactFlags = 0;
 7115 tgl                      2065 ECB             : 
                               2066                 :     /*
                               2067                 :      * reinitialize within-transaction counters
                               2068                 :      */
 6779 tgl                      2069 CBC      485395 :     s->subTransactionId = TopSubTransactionId;
                               2070          485395 :     currentSubTransactionId = TopSubTransactionId;
 6779 tgl                      2071 GIC      485395 :     currentCommandId = FirstCommandId;
 5609 tgl                      2072 CBC      485395 :     currentCommandIdUsed = false;
 6779 tgl                      2073 ECB             : 
 4859 simon                    2074                 :     /*
                               2075                 :      * initialize reported xid accounting
                               2076                 :      */
 4859 simon                    2077 GIC      485395 :     nUnreportedXids = 0;
 3407 rhaas                    2078          485395 :     s->didLogXid = false;
                               2079                 : 
 6840 tgl                      2080 ECB             :     /*
                               2081                 :      * must initialize resource-management stuff first
                               2082                 :      */
 6840 tgl                      2083 CBC      485395 :     AtStart_Memory();
 6840 tgl                      2084 GIC      485395 :     AtStart_ResourceOwner();
                               2085                 : 
                               2086                 :     /*
                               2087                 :      * Assign a new LocalTransactionId, and combine it with the backendId to
 5695 tgl                      2088 ECB             :      * form a virtual transaction id.
                               2089                 :      */
 5695 tgl                      2090 GIC      485395 :     vxid.backendId = MyBackendId;
                               2091          485395 :     vxid.localTransactionId = GetNextLocalTransactionId();
                               2092                 : 
                               2093                 :     /*
 5695 tgl                      2094 ECB             :      * Lock the virtual transaction id before we announce it in the proc array
 9345 bruce                    2095                 :      */
 5695 tgl                      2096 GIC      485395 :     VirtualXactLockTableInsert(vxid);
                               2097                 : 
                               2098                 :     /*
                               2099                 :      * Advertise it in the proc array.  We assume assignment of
                               2100                 :      * localTransactionId is atomic, and the backendId should be set already.
 5695 tgl                      2101 ECB             :      */
 5695 tgl                      2102 CBC      485395 :     Assert(MyProc->backendId == vxid.backendId);
 5695 tgl                      2103 GIC      485395 :     MyProc->lxid = vxid.localTransactionId;
                               2104                 : 
                               2105                 :     TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
                               2106                 : 
 6856 tgl                      2107 ECB             :     /*
                               2108                 :      * set transaction_timestamp() (a/k/a now()).  Normally, we want this to
                               2109                 :      * be the same as the first command's statement_timestamp(), so don't do a
                               2110                 :      * fresh GetCurrentTimestamp() call (which'd be expensive anyway).  But
                               2111                 :      * for transactions started inside procedures (i.e., nonatomic SPI
                               2112                 :      * contexts), we do need to advance the timestamp.  Also, in a parallel
 1644                          2113                 :      * worker, the timestamp should already have been provided by a call to
 1646                          2114                 :      * SetParallelStartTimestamps().
                               2115                 :      */
 1646 tgl                      2116 GIC      485395 :     if (!IsParallelWorker())
                               2117                 :     {
 1644                          2118          481501 :         if (!SPI_inside_nonatomic_context())
                               2119          479298 :             xactStartTimestamp = stmtStartTimestamp;
                               2120                 :         else
                               2121            2203 :             xactStartTimestamp = GetCurrentTimestamp();
                               2122                 :     }
                               2123                 :     else
 1646                          2124            3894 :         Assert(xactStartTimestamp != 0);
 5689                          2125          485395 :     pgstat_report_xact_timestamp(xactStartTimestamp);
                               2126                 :     /* Mark xactStopTimestamp as unset. */
 1644 tgl                      2127 CBC      485395 :     xactStopTimestamp = 0;
                               2128                 : 
 8053 bruce                    2129 ECB             :     /*
 6840 tgl                      2130                 :      * initialize other subsystems for new transaction
                               2131                 :      */
 5697 tgl                      2132 CBC      485395 :     AtStart_GUC();
 9345 bruce                    2133 GIC      485395 :     AtStart_Cache();
 6785 tgl                      2134          485395 :     AfterTriggerBeginXact();
 8593 JanWieck                 2135 ECB             : 
 8053 bruce                    2136                 :     /*
                               2137                 :      * done with start processing, set current transaction state to "in
                               2138                 :      * progress"
                               2139                 :      */
 9345 bruce                    2140 GIC      485395 :     s->state = TRANS_INPROGRESS;
                               2141                 : 
 6856 tgl                      2142          485395 :     ShowTransactionState("StartTransaction");
 9770 scrappy                  2143 CBC      485395 : }
 9770 scrappy                  2144 ECB             : 
 6505 tgl                      2145                 : 
                               2146                 : /*
                               2147                 :  *  CommitTransaction
                               2148                 :  *
                               2149                 :  * NB: if you change this routine, better look at PrepareTransaction too!
                               2150                 :  */
 9364 bruce                    2151                 : static void
 8202 tgl                      2152 GIC      465157 : CommitTransaction(void)
 9770 scrappy                  2153 ECB             : {
 9345 bruce                    2154 CBC      465157 :     TransactionState s = CurrentTransactionState;
                               2155                 :     TransactionId latestXid;
                               2156                 :     bool        is_parallel_worker;
                               2157                 : 
 2901 rhaas                    2158 GIC      465157 :     is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
                               2159                 : 
                               2160                 :     /* Enforce parallel mode restrictions during parallel worker commit. */
 2732                          2161          465157 :     if (is_parallel_worker)
                               2162            1295 :         EnterParallelMode();
 2732 rhaas                    2163 ECB             : 
 6856 tgl                      2164 GIC      465157 :     ShowTransactionState("CommitTransaction");
 6856 tgl                      2165 ECB             : 
                               2166                 :     /*
                               2167                 :      * check the current transaction state
                               2168                 :      */
 9345 bruce                    2169 CBC      465157 :     if (s->state != TRANS_INPROGRESS)
 6829 tgl                      2170 UIC           0 :         elog(WARNING, "CommitTransaction while in %s state",
                               2171                 :              TransStateAsString(s->state));
 6856 tgl                      2172 CBC      465157 :     Assert(s->parent == NULL);
 9345 bruce                    2173 ECB             : 
                               2174                 :     /*
 4424 tgl                      2175                 :      * Do pre-commit processing that involves calling user-defined code, such
                               2176                 :      * as triggers.  SECURITY_RESTRICTED_OPERATION contexts must not queue an
                               2177                 :      * action that would run here, because that would bypass the sandbox.
                               2178                 :      * Since closing cursors could queue trigger actions, triggers could open
                               2179                 :      * cursors, etc, we have to keep looping until there's nothing left to do.
 6736                          2180                 :      */
 6572 tgl                      2181 EUB             :     for (;;)
                               2182                 :     {
 6572 tgl                      2183 ECB             :         /*
                               2184                 :          * Fire all currently pending deferred triggers.
                               2185                 :          */
 6572 tgl                      2186 GIC      470958 :         AfterTriggerFireDeferred();
                               2187                 : 
                               2188                 :         /*
                               2189                 :          * Close open portals (converting holdable ones into static portals).
                               2190                 :          * If there weren't any, we are done ... otherwise loop back to check
                               2191                 :          * if they queued deferred triggers.  Lather, rinse, repeat.
                               2192                 :          */
 4424                          2193          470902 :         if (!PreCommit_Portals(false))
 6572                          2194          465101 :             break;
                               2195                 :     }
                               2196                 : 
 4424 tgl                      2197 ECB             :     /*
                               2198                 :      * The remaining actions cannot call any user-defined code, so it's safe
                               2199                 :      * to start shutting down within-transaction services.  But note that most
                               2200                 :      * of this stuff could still throw an error, which would switch us into
                               2201                 :      * the transaction-abort path.
                               2202                 :      */
                               2203                 : 
  881 noah                     2204 CBC      465101 :     CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT
  881 noah                     2205 ECB             :                       : XACT_EVENT_PRE_COMMIT);
                               2206                 : 
                               2207                 :     /* If we might have parallel workers, clean them up now. */
 2901 rhaas                    2208 GIC      465101 :     if (IsInParallelMode())
                               2209            1295 :         AtEOXact_Parallel(true);
                               2210                 : 
                               2211                 :     /* Shut down the deferred-trigger manager */
 4424 tgl                      2212          465101 :     AfterTriggerEndXact(true);
                               2213                 : 
                               2214                 :     /*
 6736 tgl                      2215 ECB             :      * Let ON COMMIT management do its thing (must happen after closing
                               2216                 :      * cursors, to avoid dangling-reference problems)
                               2217                 :      */
 6736 tgl                      2218 GIC      465101 :     PreCommit_on_commit_actions();
 7475 tgl                      2219 ECB             : 
 1100 noah                     2220                 :     /*
                               2221                 :      * Synchronize files that are created and not WAL-logged during this
                               2222                 :      * transaction. This must happen before AtEOXact_RelationMap(), so that we
                               2223                 :      * don't see committed-but-broken files after a crash.
                               2224                 :      */
 1100 noah                     2225 GIC      465098 :     smgrDoPendingSyncs(true, is_parallel_worker);
                               2226                 : 
                               2227                 :     /* close large objects before lower-level cleanup */
 6829 tgl                      2228          465098 :     AtEOXact_LargeObject(true);
 9028 bruce                    2229 ECB             : 
                               2230                 :     /*
                               2231                 :      * Insert notifications sent by NOTIFY commands into the queue.  This
                               2232                 :      * should be late in the pre-commit sequence to minimize time spent
                               2233                 :      * holding the notify-insertion lock.  However, this could result in
                               2234                 :      * creating a snapshot, so we must do it before serializable cleanup.
                               2235                 :      */
 1232 tgl                      2236 CBC      465098 :     PreCommit_Notify();
                               2237                 : 
                               2238                 :     /*
 4444 heikki.linnakangas       2239 ECB             :      * Mark serializable transaction as complete for predicate locking
                               2240                 :      * purposes.  This should be done as late as we can put it and still allow
                               2241                 :      * errors to be raised for failure patterns found at commit.  This is not
                               2242                 :      * appropriate in a parallel worker however, because we aren't committing
                               2243                 :      * the leader's transaction and its serializable state will live on.
                               2244                 :      */
 1486 tmunro                   2245 GIC      465098 :     if (!is_parallel_worker)
                               2246          463803 :         PreCommit_CheckForSerializationFailure();
 4444 heikki.linnakangas       2247 ECB             : 
                               2248                 :     /* Prevent cancel/die interrupt while cleaning up */
 6736 tgl                      2249 GIC      464943 :     HOLD_INTERRUPTS();
                               2250                 : 
                               2251                 :     /* Commit updates to the relation map --- do this as late as possible */
 1703 pg                       2252          464943 :     AtEOXact_RelationMap(true, is_parallel_worker);
                               2253                 : 
                               2254                 :     /*
                               2255                 :      * set the current transaction state information appropriately during
 6479 tgl                      2256 ECB             :      * commit processing
 6736                          2257                 :      */
 6736 tgl                      2258 GIC      464943 :     s->state = TRANS_COMMIT;
 2732 rhaas                    2259          464943 :     s->parallelModeLevel = 0;
 6736 tgl                      2260 ECB             : 
 2901 rhaas                    2261 GIC      464943 :     if (!is_parallel_worker)
                               2262                 :     {
 2901 rhaas                    2263 ECB             :         /*
                               2264                 :          * We need to mark our XIDs as committed in pg_xact.  This is where we
                               2265                 :          * durably commit.
                               2266                 :          */
 2901 rhaas                    2267 GIC      463648 :         latestXid = RecordTransactionCommit();
                               2268                 :     }
 2901 rhaas                    2269 ECB             :     else
                               2270                 :     {
                               2271                 :         /*
 1029 andres                   2272                 :          * We must not mark our XID committed; the parallel leader is
                               2273                 :          * responsible for that.
                               2274                 :          */
 2901 rhaas                    2275 GIC        1295 :         latestXid = InvalidTransactionId;
                               2276                 : 
                               2277                 :         /*
 1029 andres                   2278 ECB             :          * Make sure the leader will know about any WAL we wrote before it
                               2279                 :          * commits.
                               2280                 :          */
 2901 rhaas                    2281 GIC        1295 :         ParallelWorkerReportLastRecEnd(XactLastRecEnd);
                               2282                 :     }
                               2283                 : 
                               2284                 :     TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
                               2285                 : 
 5693 tgl                      2286 ECB             :     /*
                               2287                 :      * Let others know about no transaction in progress by me. Note that this
                               2288                 :      * must be done _before_ releasing locks we hold and _after_
                               2289                 :      * RecordTransactionCommit.
                               2290                 :      */
 5692 tgl                      2291 GIC      464943 :     ProcArrayEndTransaction(MyProc, latestXid);
 8711 vadim4o                  2292 ECB             : 
                               2293                 :     /*
                               2294                 :      * This is all post-commit cleanup.  Note that if an error is raised here,
                               2295                 :      * it's too late to abort the transaction.  This should be just
                               2296                 :      * noncritical resource releasing.
                               2297                 :      *
                               2298                 :      * The ordering of operations is not entirely random.  The idea is:
                               2299                 :      * release resources visible to other backends (eg, files, buffer pins);
                               2300                 :      * then release locks; then release backend-local resources. We want to
                               2301                 :      * release locks at the point where any backend waiting for us will see
 6347 bruce                    2302                 :      * our transaction as being fully cleaned up.
                               2303                 :      *
                               2304                 :      * Resources that can be associated with individual queries are handled by
                               2305                 :      * the ResourceOwner mechanism.  The other calls here are for backend-wide
                               2306                 :      * state.
                               2307                 :      */
                               2308                 : 
 2901 rhaas                    2309 GIC      464943 :     CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_COMMIT
                               2310                 :                       : XACT_EVENT_COMMIT);
                               2311                 : 
 6840 tgl                      2312          464943 :     ResourceOwnerRelease(TopTransactionResourceOwner,
                               2313                 :                          RESOURCE_RELEASE_BEFORE_LOCKS,
                               2314                 :                          true, true);
                               2315                 : 
                               2316                 :     /* Check we've released all buffer pins */
 6749                          2317          464943 :     AtEOXact_Buffers(true);
                               2318                 : 
                               2319                 :     /* Clean up the relation cache */
 6453 tgl                      2320 CBC      464943 :     AtEOXact_RelationCache(true);
                               2321                 : 
                               2322                 :     /*
 6385 bruce                    2323 ECB             :      * Make catalog changes visible to all backends.  This has to happen after
                               2324                 :      * relcache references are dropped (see comments for
                               2325                 :      * AtEOXact_RelationCache), but before locks are released (if anyone is
                               2326                 :      * waiting for lock on a relation we've modified, we want them to know
                               2327                 :      * about the catalog change before they start using the relation).
 6840 tgl                      2328                 :      */
 6840 tgl                      2329 GIC      464943 :     AtEOXact_Inval(true);
                               2330                 : 
 6555 tgl                      2331 CBC      464943 :     AtEOXact_MultiXact();
                               2332                 : 
 6840 tgl                      2333 GIC      464943 :     ResourceOwnerRelease(TopTransactionResourceOwner,
                               2334                 :                          RESOURCE_RELEASE_LOCKS,
                               2335                 :                          true, true);
                               2336          464943 :     ResourceOwnerRelease(TopTransactionResourceOwner,
                               2337                 :                          RESOURCE_RELEASE_AFTER_LOCKS,
                               2338                 :                          true, true);
                               2339                 : 
 3951 rhaas                    2340 ECB             :     /*
                               2341                 :      * Likewise, dropping of files deleted during the transaction is best done
                               2342                 :      * after releasing relcache and buffer pins.  (This is not strictly
                               2343                 :      * necessary during commit, since such pins should have been released
                               2344                 :      * already, but this ordering is definitely critical during abort.)  Since
                               2345                 :      * this may take many seconds, also delay until after releasing locks.
                               2346                 :      * Other backends will observe the attendant catalog changes and not
                               2347                 :      * attempt to access affected files.
                               2348                 :      */
 3951 rhaas                    2349 GIC      464943 :     smgrDoPendingDeletes(true);
                               2350                 : 
                               2351                 :     /*
                               2352                 :      * Send out notification signals to other backends (and do other
                               2353                 :      * post-commit NOTIFY cleanup).  This must not happen until after our
                               2354                 :      * transaction is fully done from the viewpoint of other backends.
                               2355                 :      */
 4800 tgl                      2356          464943 :     AtCommit_Notify();
                               2357                 : 
                               2358                 :     /*
                               2359                 :      * Everything after this should be purely internal-to-this-backend
  572 tgl                      2360 ECB             :      * cleanup.
                               2361                 :      */
 5697 tgl                      2362 GIC      464943 :     AtEOXact_GUC(true, 1);
 7068 mail                     2363          464943 :     AtEOXact_SPI(true);
 1643 tmunro                   2364          464943 :     AtEOXact_Enum();
 6779 tgl                      2365          464943 :     AtEOXact_on_commit_actions(true);
 2901 rhaas                    2366          464943 :     AtEOXact_Namespace(true, is_parallel_worker);
 3826 tgl                      2367 CBC      464943 :     AtEOXact_SMgr();
 1807 tgl                      2368 GIC      464943 :     AtEOXact_Files(true);
 5903                          2369          464943 :     AtEOXact_ComboCid();
 5827                          2370          464943 :     AtEOXact_HashTables(true);
 1460 akapila                  2371          464943 :     AtEOXact_PgStat(true, is_parallel_worker);
 2194 simon                    2372          464943 :     AtEOXact_Snapshot(true, false);
 2169 peter_e                  2373 CBC      464943 :     AtEOXact_ApplyLauncher(true);
   93 tgl                      2374 GNC      464943 :     AtEOXact_LogicalRepWorkers(true);
 5689 tgl                      2375 CBC      464943 :     pgstat_report_xact_timestamp(0);
 6840 tgl                      2376 ECB             : 
 6840 tgl                      2377 CBC      464943 :     CurrentResourceOwner = NULL;
                               2378          464943 :     ResourceOwnerDelete(TopTransactionResourceOwner);
                               2379          464943 :     s->curTransactionOwner = NULL;
                               2380          464943 :     CurTransactionResourceOwner = NULL;
                               2381          464943 :     TopTransactionResourceOwner = NULL;
 6840 tgl                      2382 ECB             : 
 7474 tgl                      2383 CBC      464943 :     AtCommit_Memory();
 7961 JanWieck                 2384 ECB             : 
 1473 tmunro                   2385 CBC      464943 :     s->fullTransactionId = InvalidFullTransactionId;
 6779 tgl                      2386          464943 :     s->subTransactionId = InvalidSubTransactionId;
 6856                          2387          464943 :     s->nestingLevel = 0;
 5697 tgl                      2388 GIC      464943 :     s->gucNestLevel = 0;
 5501 tgl                      2389 CBC      464943 :     s->childXids = NULL;
                               2390          464943 :     s->nChildXids = 0;
                               2391          464943 :     s->maxChildXids = 0;
 6856 tgl                      2392 ECB             : 
 1473 tmunro                   2393 CBC      464943 :     XactTopFullTransactionId = InvalidFullTransactionId;
 2901 rhaas                    2394 GIC      464943 :     nParallelCurrentXids = 0;
 2901 rhaas                    2395 ECB             : 
                               2396                 :     /*
 8053 bruce                    2397                 :      * done with commit processing, set current transaction state back to
                               2398                 :      * default
 9770 scrappy                  2399                 :      */
 9345 bruce                    2400 CBC      464943 :     s->state = TRANS_DEFAULT;
 8120 tgl                      2401 ECB             : 
 8115 tgl                      2402 CBC      464943 :     RESUME_INTERRUPTS();
 9770 scrappy                  2403          464943 : }
                               2404                 : 
 6505 tgl                      2405 ECB             : 
                               2406                 : /*
                               2407                 :  *  PrepareTransaction
                               2408                 :  *
                               2409                 :  * NB: if you change this routine, better look at CommitTransaction too!
                               2410                 :  */
                               2411                 : static void
 6505 tgl                      2412 CBC         402 : PrepareTransaction(void)
                               2413                 : {
 6385 bruce                    2414             402 :     TransactionState s = CurrentTransactionState;
                               2415             402 :     TransactionId xid = GetCurrentTransactionId();
                               2416                 :     GlobalTransaction gxact;
                               2417                 :     TimestampTz prepared_at;
                               2418                 : 
 2901 rhaas                    2419 GIC         402 :     Assert(!IsInParallelMode());
                               2420                 : 
 6505 tgl                      2421             402 :     ShowTransactionState("PrepareTransaction");
                               2422                 : 
                               2423                 :     /*
 6505 tgl                      2424 ECB             :      * check the current transaction state
                               2425                 :      */
 6505 tgl                      2426 CBC         402 :     if (s->state != TRANS_INPROGRESS)
 6505 tgl                      2427 LBC           0 :         elog(WARNING, "PrepareTransaction while in %s state",
                               2428                 :              TransStateAsString(s->state));
 6505 tgl                      2429 GIC         402 :     Assert(s->parent == NULL);
                               2430                 : 
 6505 tgl                      2431 ECB             :     /*
                               2432                 :      * Do pre-commit processing that involves calling user-defined code, such
 4424                          2433                 :      * as triggers.  Since closing cursors could queue trigger actions,
                               2434                 :      * triggers could open cursors, etc, we have to keep looping until there's
                               2435                 :      * nothing left to do.
                               2436                 :      */
                               2437                 :     for (;;)
 6505                          2438                 :     {
 6505 tgl                      2439 EUB             :         /*
                               2440                 :          * Fire all currently pending deferred triggers.
 6505 tgl                      2441 ECB             :          */
 6505 tgl                      2442 GIC         405 :         AfterTriggerFireDeferred();
                               2443                 : 
                               2444                 :         /*
                               2445                 :          * Close open portals (converting holdable ones into static portals).
                               2446                 :          * If there weren't any, we are done ... otherwise loop back to check
                               2447                 :          * if they queued deferred triggers.  Lather, rinse, repeat.
                               2448                 :          */
 4424                          2449             405 :         if (!PreCommit_Portals(true))
 6505                          2450             402 :             break;
                               2451                 :     }
                               2452                 : 
 3706                          2453             402 :     CallXactCallbacks(XACT_EVENT_PRE_PREPARE);
 3706 tgl                      2454 ECB             : 
                               2455                 :     /*
                               2456                 :      * The remaining actions cannot call any user-defined code, so it's safe
                               2457                 :      * to start shutting down within-transaction services.  But note that most
                               2458                 :      * of this stuff could still throw an error, which would switch us into
                               2459                 :      * the transaction-abort path.
                               2460                 :      */
 6505                          2461                 : 
 4424                          2462                 :     /* Shut down the deferred-trigger manager */
 4424 tgl                      2463 GIC         401 :     AfterTriggerEndXact(true);
                               2464                 : 
 6505 tgl                      2465 ECB             :     /*
                               2466                 :      * Let ON COMMIT management do its thing (must happen after closing
                               2467                 :      * cursors, to avoid dangling-reference problems)
                               2468                 :      */
 6505 tgl                      2469 GIC         401 :     PreCommit_on_commit_actions();
                               2470                 : 
                               2471                 :     /*
                               2472                 :      * Synchronize files that are created and not WAL-logged during this
                               2473                 :      * transaction. This must happen before EndPrepare(), so that we don't see
                               2474                 :      * committed-but-broken files after a crash and COMMIT PREPARED.
 1100 noah                     2475 ECB             :      */
 1100 noah                     2476 GIC         401 :     smgrDoPendingSyncs(true, false);
                               2477                 : 
                               2478                 :     /* close large objects before lower-level cleanup */
 6505 tgl                      2479             401 :     AtEOXact_LargeObject(true);
                               2480                 : 
 1232 tgl                      2481 ECB             :     /* NOTIFY requires no work at this point */
                               2482                 : 
                               2483                 :     /*
                               2484                 :      * Mark serializable transaction as complete for predicate locking
                               2485                 :      * purposes.  This should be done as late as we can put it and still allow
                               2486                 :      * errors to be raised for failure patterns found at commit.
                               2487                 :      */
 4444 heikki.linnakangas       2488 CBC         401 :     PreCommit_CheckForSerializationFailure();
                               2489                 : 
                               2490                 :     /*
 5050 bruce                    2491 ECB             :      * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
                               2492                 :      * this transaction.  Having the prepared xact hold locks on another
                               2493                 :      * backend's temp table seems a bad idea --- for instance it would prevent
                               2494                 :      * the backend from exiting.  There are other problems too, such as how to
                               2495                 :      * clean up the source backend's local buffers and ON COMMIT state if the
                               2496                 :      * prepared xact includes a DROP of a temp table.
                               2497                 :      *
                               2498                 :      * Other objects types, like functions, operators or extensions, share the
                               2499                 :      * same restriction as they should not be created, locked or dropped as
 1534 michael                  2500                 :      * this can mess up with this session or even a follow-up session trying
                               2501                 :      * to use the same temporary namespace.
                               2502                 :      *
                               2503                 :      * We must check this after executing any ON COMMIT actions, because they
                               2504                 :      * might still access a temp relation.
                               2505                 :      *
                               2506                 :      * XXX In principle this could be relaxed to allow some useful special
                               2507                 :      * cases, such as a temp table created and dropped all within the
                               2508                 :      * transaction.  That seems to require much more bookkeeping though.
                               2509                 :      */
 1542 michael                  2510 GIC         401 :     if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE))
                               2511              34 :         ereport(ERROR,
                               2512                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                               2513                 :                  errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
                               2514                 : 
                               2515                 :     /*
                               2516                 :      * Likewise, don't allow PREPARE after pg_export_snapshot.  This could be
                               2517                 :      * supported if we added cleanup logic to twophase.c, but for now it
                               2518                 :      * doesn't seem worth the trouble.
                               2519                 :      */
 4187 tgl                      2520             367 :     if (XactHasExportedSnapshots())
 4187 tgl                      2521 UIC           0 :         ereport(ERROR,
 4187 tgl                      2522 ECB             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 2118                          2523                 :                  errmsg("cannot PREPARE a transaction that has exported snapshots")));
                               2524                 : 
                               2525                 :     /* Prevent cancel/die interrupt while cleaning up */
 6505 tgl                      2526 GIC         367 :     HOLD_INTERRUPTS();
                               2527                 : 
                               2528                 :     /*
                               2529                 :      * set the current transaction state information appropriately during
                               2530                 :      * prepare processing
                               2531                 :      */
 6505 tgl                      2532 CBC         367 :     s->state = TRANS_PREPARE;
 6505 tgl                      2533 EUB             : 
 6493 tgl                      2534 GIC         367 :     prepared_at = GetCurrentTimestamp();
                               2535                 : 
                               2536                 :     /*
                               2537                 :      * Reserve the GID for this transaction. This could fail if the requested
                               2538                 :      * GID is invalid or already in use.
                               2539                 :      */
 6504                          2540             367 :     gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
 6504 tgl                      2541 ECB             :                             GetUserId(), MyDatabaseId);
 6505 tgl                      2542 GIC         356 :     prepareGID = NULL;
 6505 tgl                      2543 ECB             : 
                               2544                 :     /*
                               2545                 :      * Collect data for the 2PC state file.  Note that in general, no actual
                               2546                 :      * state change should happen in the called modules during this step,
                               2547                 :      * since it's still possible to fail before commit, and in that case we
                               2548                 :      * want transaction abort to be able to clean up.  (In particular, the
                               2549                 :      * AtPrepare routines may error out if they find cases they cannot
                               2550                 :      * handle.)  State cleanup should happen in the PostPrepare routines
 6385 bruce                    2551                 :      * below.  However, some modules can go ahead and clear state here because
                               2552                 :      * they wouldn't do anything with it during abort anyway.
                               2553                 :      *
                               2554                 :      * Note: because the 2PC state file records will be replayed in the same
                               2555                 :      * order they are made, the order of these calls has to match the order in
                               2556                 :      * which we want things to happen during COMMIT PREPARED or ROLLBACK
                               2557                 :      * PREPARED; in particular, pay attention to whether things should happen
                               2558                 :      * before or after releasing the transaction's locks.
                               2559                 :      */
 6505 tgl                      2560 GIC         356 :     StartPrepare(gxact);
                               2561                 : 
                               2562             356 :     AtPrepare_Notify();
                               2563             356 :     AtPrepare_Locks();
 4444 heikki.linnakangas       2564             354 :     AtPrepare_PredicateLocks();
 5796 tgl                      2565             354 :     AtPrepare_PgStat();
 4885 heikki.linnakangas       2566             354 :     AtPrepare_MultiXact();
 4809 tgl                      2567             354 :     AtPrepare_RelationMap();
                               2568                 : 
 6505 tgl                      2569 ECB             :     /*
                               2570                 :      * Here is where we really truly prepare.
                               2571                 :      *
 6347 bruce                    2572                 :      * We have to record transaction prepares even if we didn't make any
                               2573                 :      * updates, because the transaction manager might get confused if we lose
                               2574                 :      * a global transaction.
 6505 tgl                      2575                 :      */
 6505 tgl                      2576 CBC         354 :     EndPrepare(gxact);
                               2577                 : 
                               2578                 :     /*
                               2579                 :      * Now we clean up backend-internal state and release internal resources.
                               2580                 :      */
                               2581                 : 
                               2582                 :     /* Reset XactLastRecEnd until the next transaction writes something */
 3941 heikki.linnakangas       2583 GIC         354 :     XactLastRecEnd = 0;
                               2584                 : 
  533 noah                     2585 ECB             :     /*
                               2586                 :      * Transfer our locks to a dummy PGPROC.  This has to be done before
                               2587                 :      * ProcArrayClearTransaction().  Otherwise, a GetLockConflicts() would
                               2588                 :      * conclude "xact already committed or aborted" for our locks.
                               2589                 :      */
  533 noah                     2590 GIC         354 :     PostPrepare_Locks(xid);
                               2591                 : 
 6505 tgl                      2592 ECB             :     /*
                               2593                 :      * Let others know about no transaction in progress by me.  This has to be
                               2594                 :      * done *after* the prepared transaction has been marked valid, else
                               2595                 :      * someone may think it is unlocked and recyclable.
                               2596                 :      */
 5692 tgl                      2597 GIC         354 :     ProcArrayClearTransaction(MyProc);
                               2598                 : 
 6505 tgl                      2599 ECB             :     /*
                               2600                 :      * In normal commit-processing, this is all non-critical post-transaction
                               2601                 :      * cleanup.  When the transaction is prepared, however, it's important
                               2602                 :      * that the locks and other per-backend resources are transferred to the
                               2603                 :      * prepared transaction's PGPROC entry.  Note that if an error is raised
                               2604                 :      * here, it's too late to abort the transaction. XXX: This probably should
                               2605                 :      * be in a critical section, to force a PANIC if any of this fails, but
 3251 heikki.linnakangas       2606                 :      * that cure could be worse than the disease.
                               2607                 :      */
                               2608                 : 
 6505 tgl                      2609 GIC         354 :     CallXactCallbacks(XACT_EVENT_PREPARE);
                               2610                 : 
                               2611             354 :     ResourceOwnerRelease(TopTransactionResourceOwner,
                               2612                 :                          RESOURCE_RELEASE_BEFORE_LOCKS,
                               2613                 :                          true, true);
                               2614                 : 
                               2615                 :     /* Check we've released all buffer pins */
                               2616             354 :     AtEOXact_Buffers(true);
                               2617                 : 
 6453 tgl                      2618 ECB             :     /* Clean up the relation cache */
 6453 tgl                      2619 GIC         354 :     AtEOXact_RelationCache(true);
 6453 tgl                      2620 ECB             : 
                               2621                 :     /* notify doesn't need a postprepare call */
                               2622                 : 
 5796 tgl                      2623 GIC         354 :     PostPrepare_PgStat();
                               2624                 : 
 6505 tgl                      2625 CBC         354 :     PostPrepare_Inval();
                               2626                 : 
 6505 tgl                      2627 GIC         354 :     PostPrepare_smgr();
 6505 tgl                      2628 ECB             : 
 4885 heikki.linnakangas       2629 GIC         354 :     PostPrepare_MultiXact(xid);
                               2630                 : 
 4444                          2631             354 :     PostPrepare_PredicateLocks(xid);
 6505 tgl                      2632 ECB             : 
 6505 tgl                      2633 GIC         354 :     ResourceOwnerRelease(TopTransactionResourceOwner,
 6505 tgl                      2634 ECB             :                          RESOURCE_RELEASE_LOCKS,
                               2635                 :                          true, true);
 6505 tgl                      2636 CBC         354 :     ResourceOwnerRelease(TopTransactionResourceOwner,
                               2637                 :                          RESOURCE_RELEASE_AFTER_LOCKS,
 6505 tgl                      2638 ECB             :                          true, true);
                               2639                 : 
 3251 heikki.linnakangas       2640                 :     /*
                               2641                 :      * Allow another backend to finish the transaction.  After
 2878 bruce                    2642                 :      * PostPrepare_Twophase(), the transaction is completely detached from our
                               2643                 :      * backend.  The rest is just non-critical cleanup of backend-local state.
                               2644                 :      */
 3251 heikki.linnakangas       2645 CBC         354 :     PostPrepare_Twophase();
                               2646                 : 
                               2647                 :     /* PREPARE acts the same as COMMIT as far as GUC is concerned */
 5697 tgl                      2648 GIC         354 :     AtEOXact_GUC(true, 1);
 6505                          2649             354 :     AtEOXact_SPI(true);
 1643 tmunro                   2650             354 :     AtEOXact_Enum();
 6505 tgl                      2651             354 :     AtEOXact_on_commit_actions(true);
 2901 rhaas                    2652             354 :     AtEOXact_Namespace(true, false);
 3826 tgl                      2653             354 :     AtEOXact_SMgr();
 1807 tgl                      2654 CBC         354 :     AtEOXact_Files(true);
 5903 tgl                      2655 GIC         354 :     AtEOXact_ComboCid();
 5827                          2656             354 :     AtEOXact_HashTables(true);
 3272 tgl                      2657 ECB             :     /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
 2194 simon                    2658 CBC         354 :     AtEOXact_Snapshot(true, true);
                               2659                 :     /* we treat PREPARE as ROLLBACK so far as waking workers goes */
   93 tgl                      2660 GNC         354 :     AtEOXact_ApplyLauncher(false);
                               2661             354 :     AtEOXact_LogicalRepWorkers(false);
 3272 tgl                      2662 CBC         354 :     pgstat_report_xact_timestamp(0);
 6505 tgl                      2663 ECB             : 
 6505 tgl                      2664 CBC         354 :     CurrentResourceOwner = NULL;
                               2665             354 :     ResourceOwnerDelete(TopTransactionResourceOwner);
                               2666             354 :     s->curTransactionOwner = NULL;
                               2667             354 :     CurTransactionResourceOwner = NULL;
                               2668             354 :     TopTransactionResourceOwner = NULL;
                               2669                 : 
                               2670             354 :     AtCommit_Memory();
                               2671                 : 
 1473 tmunro                   2672             354 :     s->fullTransactionId = InvalidFullTransactionId;
 6505 tgl                      2673             354 :     s->subTransactionId = InvalidSubTransactionId;
                               2674             354 :     s->nestingLevel = 0;
 5697 tgl                      2675 GIC         354 :     s->gucNestLevel = 0;
 5501 tgl                      2676 CBC         354 :     s->childXids = NULL;
                               2677             354 :     s->nChildXids = 0;
                               2678             354 :     s->maxChildXids = 0;
 6505 tgl                      2679 ECB             : 
 1473 tmunro                   2680 CBC         354 :     XactTopFullTransactionId = InvalidFullTransactionId;
 2901 rhaas                    2681 GIC         354 :     nParallelCurrentXids = 0;
 2901 rhaas                    2682 ECB             : 
                               2683                 :     /*
 6385 bruce                    2684                 :      * done with 1st phase commit processing, set current transaction state
                               2685                 :      * back to default
 6505 tgl                      2686                 :      */
 6505 tgl                      2687 CBC         354 :     s->state = TRANS_DEFAULT;
 6505 tgl                      2688 ECB             : 
 6505 tgl                      2689 CBC         354 :     RESUME_INTERRUPTS();
                               2690             354 : }
                               2691                 : 
 6505 tgl                      2692 ECB             : 
 7331 bruce                    2693                 : /*
                               2694                 :  *  AbortTransaction
                               2695                 :  */
                               2696                 : static void
 8202 tgl                      2697 GIC       20098 : AbortTransaction(void)
                               2698                 : {
 9345 bruce                    2699 CBC       20098 :     TransactionState s = CurrentTransactionState;
                               2700                 :     TransactionId latestXid;
 2878 bruce                    2701 ECB             :     bool        is_parallel_worker;
 9345                          2702                 : 
                               2703                 :     /* Prevent cancel/die interrupt while cleaning up */
 8115 tgl                      2704 GIC       20098 :     HOLD_INTERRUPTS();
                               2705                 : 
                               2706                 :     /* Make sure we have a valid memory context and resource owner */
 5981                          2707           20098 :     AtAbort_Memory();
                               2708           20098 :     AtAbort_ResourceOwner();
 5981 tgl                      2709 ECB             : 
                               2710                 :     /*
 7862                          2711                 :      * Release any LW locks we might be holding as quickly as possible.
                               2712                 :      * (Regular locks, however, must be held till we finish aborting.)
                               2713                 :      * Releasing LW locks is critical since we might try to grab them again
                               2714                 :      * while cleaning up!
                               2715                 :      */
 7862 tgl                      2716 CBC       20098 :     LWLockReleaseAll();
                               2717                 : 
                               2718                 :     /* Clear wait information and command progress indicator */
 2586 rhaas                    2719           20098 :     pgstat_report_wait_end();
                               2720           20098 :     pgstat_progress_end_command();
                               2721                 : 
                               2722                 :     /* Clean up buffer context locks, too */
 8147 tgl                      2723 GIC       20098 :     UnlockBuffers();
                               2724                 : 
                               2725                 :     /* Reset WAL record construction state */
 3062 heikki.linnakangas       2726           20098 :     XLogResetInsertion();
 3062 heikki.linnakangas       2727 ECB             : 
                               2728                 :     /* Cancel condition variable sleep */
 2329 rhaas                    2729 GIC       20098 :     ConditionVariableCancelSleep();
 2329 rhaas                    2730 ECB             : 
 8120 tgl                      2731                 :     /*
                               2732                 :      * Also clean up any open wait for lock, since the lock manager will choke
                               2733                 :      * if we try to wait for another lock before doing this.
                               2734                 :      */
 4008 rhaas                    2735 GIC       20098 :     LockErrorCleanup();
                               2736                 : 
 3418 tgl                      2737 ECB             :     /*
                               2738                 :      * If any timeout events are still active, make sure the timeout interrupt
                               2739                 :      * is scheduled.  This covers possible loss of a timeout interrupt due to
                               2740                 :      * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
                               2741                 :      * We delay this till after LockErrorCleanup so that we don't uselessly
                               2742                 :      * reschedule lock or deadlock check timeouts.
                               2743                 :      */
 3418 tgl                      2744 GIC       20098 :     reschedule_timeouts();
                               2745                 : 
 3418 tgl                      2746 ECB             :     /*
                               2747                 :      * Re-enable signals, in case we got here by longjmp'ing out of a signal
                               2748                 :      * handler.  We do this fairly early in the sequence so that the timeout
                               2749                 :      * infrastructure will be functional if needed while aborting.
                               2750                 :      */
   65 tmunro                   2751 GNC       20098 :     sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
                               2752                 : 
                               2753                 :     /*
                               2754                 :      * check the current transaction state
 9770 scrappy                  2755 ECB             :      */
 2901 rhaas                    2756 GIC       20098 :     is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
 6505 tgl                      2757           20098 :     if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
 6829 tgl                      2758 UIC           0 :         elog(WARNING, "AbortTransaction while in %s state",
                               2759                 :              TransStateAsString(s->state));
 6856 tgl                      2760 GIC       20098 :     Assert(s->parent == NULL);
                               2761                 : 
 8053 bruce                    2762 ECB             :     /*
                               2763                 :      * set the current transaction state information appropriately during the
                               2764                 :      * abort processing
                               2765                 :      */
 9345 bruce                    2766 GIC       20098 :     s->state = TRANS_ABORT;
 9345 bruce                    2767 ECB             : 
 8147 tgl                      2768                 :     /*
 5575 tgl                      2769 EUB             :      * Reset user ID which might have been changed transiently.  We need this
                               2770                 :      * to clean up in case control escaped out of a SECURITY DEFINER function
 5050 bruce                    2771 ECB             :      * or other local change of CurrentUserId; therefore, the prior value of
                               2772                 :      * SecurityRestrictionContext also needs to be restored.
                               2773                 :      *
                               2774                 :      * (Note: it is not necessary to restore session authorization or role
                               2775                 :      * settings here because those can only be changed via GUC, and GUC will
                               2776                 :      * take care of rolling them back if need be.)
 8147 tgl                      2777                 :      */
 4869 tgl                      2778 GIC       20098 :     SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
                               2779                 : 
                               2780                 :     /* Forget about any active REINDEX. */
 1083                          2781           20098 :     ResetReindexState(s->nestingLevel);
                               2782                 : 
                               2783                 :     /* Reset logical streaming state. */
  974 akapila                  2784           20098 :     ResetLogicalStreamingState();
                               2785                 : 
                               2786                 :     /* Reset snapshot export state. */
  538 michael                  2787           20098 :     SnapBuildResetExportedSnapshotState();
                               2788                 : 
 2901 rhaas                    2789 ECB             :     /* If in parallel mode, clean up workers and exit parallel mode. */
 2901 rhaas                    2790 GIC       20098 :     if (IsInParallelMode())
                               2791                 :     {
 2901 rhaas                    2792 CBC           3 :         AtEOXact_Parallel(false);
 2901 rhaas                    2793 GIC           3 :         s->parallelModeLevel = 0;
                               2794                 :     }
 2901 rhaas                    2795 ECB             : 
                               2796                 :     /*
                               2797                 :      * do abort processing
 9770 scrappy                  2798                 :      */
 4790 bruce                    2799 GIC       20098 :     AfterTriggerEndXact(false); /* 'false' means it's abort */
 7282 tgl                      2800           20098 :     AtAbort_Portals();
 1100 noah                     2801 CBC       20098 :     smgrDoPendingSyncs(false, is_parallel_worker);
 4809 tgl                      2802 GIC       20098 :     AtEOXact_LargeObject(false);
 8951 tgl                      2803 CBC       20098 :     AtAbort_Notify();
 1703 pg                       2804           20098 :     AtEOXact_RelationMap(false, is_parallel_worker);
 3251 heikki.linnakangas       2805 GIC       20098 :     AtAbort_Twophase();
                               2806                 : 
                               2807                 :     /*
                               2808                 :      * Advertise the fact that we aborted in pg_xact (assuming that we got as
                               2809                 :      * far as assigning an XID to advertise).  But if we're inside a parallel
 2901 rhaas                    2810 ECB             :      * worker, skip this; the user backend must be the one to write the abort
                               2811                 :      * record.
 6622 tgl                      2812                 :      */
 2901 rhaas                    2813 CBC       20098 :     if (!is_parallel_worker)
                               2814           20095 :         latestXid = RecordTransactionAbort(false);
 2901 rhaas                    2815 ECB             :     else
                               2816                 :     {
 2901 rhaas                    2817 GIC           3 :         latestXid = InvalidTransactionId;
                               2818                 : 
                               2819                 :         /*
                               2820                 :          * Since the parallel leader won't get our value of XactLastRecEnd in
                               2821                 :          * this case, we nudge WAL-writer ourselves in this case.  See related
                               2822                 :          * comments in RecordTransactionAbort for why this matters.
                               2823                 :          */
 2901 rhaas                    2824 CBC           3 :         XLogSetAsyncXactLSN(XactLastRecEnd);
 2901 rhaas                    2825 ECB             :     }
                               2826                 : 
                               2827                 :     TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
 5693 tgl                      2828                 : 
                               2829                 :     /*
                               2830                 :      * Let others know about no transaction in progress by me. Note that this
                               2831                 :      * must be done _before_ releasing locks we hold and _after_
                               2832                 :      * RecordTransactionAbort.
                               2833                 :      */
 5692 tgl                      2834 GIC       20098 :     ProcArrayEndTransaction(MyProc, latestXid);
 7961 JanWieck                 2835 ECB             : 
                               2836                 :     /*
                               2837                 :      * Post-abort cleanup.  See notes in CommitTransaction() concerning
                               2838                 :      * ordering.  We can skip all of it if the transaction failed before
                               2839                 :      * creating a resource owner.
                               2840                 :      */
 4823 tgl                      2841 GIC       20098 :     if (TopTransactionResourceOwner != NULL)
                               2842                 :     {
 2901 rhaas                    2843           20098 :         if (is_parallel_worker)
                               2844               3 :             CallXactCallbacks(XACT_EVENT_PARALLEL_ABORT);
 2901 rhaas                    2845 ECB             :         else
 2901 rhaas                    2846 GIC       20095 :             CallXactCallbacks(XACT_EVENT_ABORT);
                               2847                 : 
 4823 tgl                      2848           20098 :         ResourceOwnerRelease(TopTransactionResourceOwner,
                               2849                 :                              RESOURCE_RELEASE_BEFORE_LOCKS,
                               2850                 :                              false, true);
                               2851           20098 :         AtEOXact_Buffers(false);
 4823 tgl                      2852 CBC       20098 :         AtEOXact_RelationCache(false);
 4823 tgl                      2853 GIC       20098 :         AtEOXact_Inval(false);
 4823 tgl                      2854 CBC       20098 :         AtEOXact_MultiXact();
                               2855           20098 :         ResourceOwnerRelease(TopTransactionResourceOwner,
                               2856                 :                              RESOURCE_RELEASE_LOCKS,
 4823 tgl                      2857 ECB             :                              false, true);
 4823 tgl                      2858 GIC       20098 :         ResourceOwnerRelease(TopTransactionResourceOwner,
 4823 tgl                      2859 ECB             :                              RESOURCE_RELEASE_AFTER_LOCKS,
                               2860                 :                              false, true);
 3951 rhaas                    2861 GIC       20098 :         smgrDoPendingDeletes(false);
 4823 tgl                      2862 ECB             : 
 4823 tgl                      2863 CBC       20098 :         AtEOXact_GUC(false, 1);
                               2864           20098 :         AtEOXact_SPI(false);
 1643 tmunro                   2865           20098 :         AtEOXact_Enum();
 4823 tgl                      2866           20098 :         AtEOXact_on_commit_actions(false);
 2901 rhaas                    2867 GIC       20098 :         AtEOXact_Namespace(false, is_parallel_worker);
 3826 tgl                      2868           20098 :         AtEOXact_SMgr();
 1807 tgl                      2869 CBC       20098 :         AtEOXact_Files(false);
 4823 tgl                      2870 GIC       20098 :         AtEOXact_ComboCid();
                               2871           20098 :         AtEOXact_HashTables(false);
 1460 akapila                  2872 CBC       20098 :         AtEOXact_PgStat(false, is_parallel_worker);
 2169 peter_e                  2873 GIC       20098 :         AtEOXact_ApplyLauncher(false);
   93 tgl                      2874 GNC       20098 :         AtEOXact_LogicalRepWorkers(false);
 4823 tgl                      2875 CBC       20098 :         pgstat_report_xact_timestamp(0);
 4823 tgl                      2876 ECB             :     }
 7937                          2877                 : 
 8053 bruce                    2878                 :     /*
                               2879                 :      * State remains TRANS_ABORT until CleanupTransaction().
 8320 tgl                      2880                 :      */
 8115 tgl                      2881 CBC       20098 :     RESUME_INTERRUPTS();
 8320                          2882           20098 : }
 8320 tgl                      2883 ECB             : 
 7331 bruce                    2884                 : /*
 7452                          2885                 :  *  CleanupTransaction
 8320 tgl                      2886                 :  */
                               2887                 : static void
 8202 tgl                      2888 GIC       20098 : CleanupTransaction(void)
                               2889                 : {
 8320                          2890           20098 :     TransactionState s = CurrentTransactionState;
                               2891                 : 
                               2892                 :     /*
 8053 bruce                    2893 ECB             :      * State should still be TRANS_ABORT from AbortTransaction().
 8320 tgl                      2894                 :      */
 8320 tgl                      2895 GIC       20098 :     if (s->state != TRANS_ABORT)
 6826 tgl                      2896 UIC           0 :         elog(FATAL, "CleanupTransaction: unexpected state %s",
                               2897                 :              TransStateAsString(s->state));
                               2898                 : 
                               2899                 :     /*
 8053 bruce                    2900 ECB             :      * do abort cleanup processing
                               2901                 :      */
 7282 tgl                      2902 CBC       20098 :     AtCleanup_Portals();        /* now safe to release portal memory */
 2118 tgl                      2903 GIC       20098 :     AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
                               2904                 : 
 6797 bruce                    2905           20098 :     CurrentResourceOwner = NULL;    /* and resource owner */
 6779 tgl                      2906           20098 :     if (TopTransactionResourceOwner)
 6779 tgl                      2907 CBC       20098 :         ResourceOwnerDelete(TopTransactionResourceOwner);
 6840 tgl                      2908 GBC       20098 :     s->curTransactionOwner = NULL;
 6840 tgl                      2909 GIC       20098 :     CurTransactionResourceOwner = NULL;
                               2910           20098 :     TopTransactionResourceOwner = NULL;
                               2911                 : 
 7282                          2912           20098 :     AtCleanup_Memory();         /* and transaction memory */
                               2913                 : 
 1473 tmunro                   2914 CBC       20098 :     s->fullTransactionId = InvalidFullTransactionId;
 6779 tgl                      2915           20098 :     s->subTransactionId = InvalidSubTransactionId;
 6856 tgl                      2916 GIC       20098 :     s->nestingLevel = 0;
 5697 tgl                      2917 CBC       20098 :     s->gucNestLevel = 0;
 5501                          2918           20098 :     s->childXids = NULL;
                               2919           20098 :     s->nChildXids = 0;
                               2920           20098 :     s->maxChildXids = 0;
 2901 rhaas                    2921           20098 :     s->parallelModeLevel = 0;
 2901 rhaas                    2922 ECB             : 
 1473 tmunro                   2923 GIC       20098 :     XactTopFullTransactionId = InvalidFullTransactionId;
 2901 rhaas                    2924 CBC       20098 :     nParallelCurrentXids = 0;
                               2925                 : 
 8053 bruce                    2926 ECB             :     /*
                               2927                 :      * done with abort processing, set current transaction state back to
                               2928                 :      * default
 9770 scrappy                  2929                 :      */
 9345 bruce                    2930 CBC       20098 :     s->state = TRANS_DEFAULT;
                               2931           20098 : }
 9345 bruce                    2932 ECB             : 
 7331                          2933                 : /*
                               2934                 :  *  StartTransactionCommand
 9345                          2935                 :  */
                               2936                 : void
 7270 tgl                      2937 GIC      548107 : StartTransactionCommand(void)
                               2938                 : {
 9345 bruce                    2939          548107 :     TransactionState s = CurrentTransactionState;
                               2940                 : 
                               2941          548107 :     switch (s->blockState)
 9345 bruce                    2942 ECB             :     {
 8053                          2943                 :             /*
                               2944                 :              * if we aren't in a transaction block, we just do our usual start
                               2945                 :              * transaction.
                               2946                 :              */
 9344 bruce                    2947 GIC      484070 :         case TBLOCK_DEFAULT:
                               2948          484070 :             StartTransaction();
 6943 bruce                    2949 CBC      484070 :             s->blockState = TBLOCK_STARTED;
 6943 bruce                    2950 GIC      484070 :             break;
 6943 bruce                    2951 ECB             : 
                               2952                 :             /*
 6385                          2953                 :              * We are somewhere in a transaction block or subtransaction and
                               2954                 :              * about to start a new command.  For now we do nothing, but
                               2955                 :              * someday we may do command-local resource initialization. (Note
                               2956                 :              * that any needed CommandCounterIncrement was done by the
                               2957                 :              * previous CommitTransactionCommand.)
                               2958                 :              */
 9344 bruce                    2959 CBC       63238 :         case TBLOCK_INPROGRESS:
 2040 tgl                      2960 ECB             :         case TBLOCK_IMPLICIT_INPROGRESS:
 6856                          2961                 :         case TBLOCK_SUBINPROGRESS:
 9344 bruce                    2962 CBC       63238 :             break;
                               2963                 : 
                               2964                 :             /*
                               2965                 :              * Here we are in a failed transaction block (one of the commands
                               2966                 :              * caused an abort) so we do nothing but remain in the abort
                               2967                 :              * state.  Eventually we will get a ROLLBACK command which will
                               2968                 :              * get us out of this state.  (It is up to other code to ensure
                               2969                 :              * that no commands other than ROLLBACK will be processed in these
                               2970                 :              * states.)
 9344 bruce                    2971 ECB             :              */
 9344 bruce                    2972 GIC         799 :         case TBLOCK_ABORT:
                               2973                 :         case TBLOCK_SUBABORT:
 9344 bruce                    2974 CBC         799 :             break;
                               2975                 : 
                               2976                 :             /* These cases are invalid. */
 6856 tgl                      2977 UIC           0 :         case TBLOCK_STARTED:
                               2978                 :         case TBLOCK_BEGIN:
                               2979                 :         case TBLOCK_PARALLEL_INPROGRESS:
                               2980                 :         case TBLOCK_SUBBEGIN:
                               2981                 :         case TBLOCK_END:
                               2982                 :         case TBLOCK_SUBRELEASE:
                               2983                 :         case TBLOCK_SUBCOMMIT:
 6779 tgl                      2984 ECB             :         case TBLOCK_ABORT_END:
                               2985                 :         case TBLOCK_SUBABORT_END:
                               2986                 :         case TBLOCK_ABORT_PENDING:
                               2987                 :         case TBLOCK_SUBABORT_PENDING:
                               2988                 :         case TBLOCK_SUBRESTART:
 6779 tgl                      2989 EUB             :         case TBLOCK_SUBABORT_RESTART:
                               2990                 :         case TBLOCK_PREPARE:
 6779 tgl                      2991 UIC           0 :             elog(ERROR, "StartTransactionCommand: unexpected state %s",
                               2992                 :                  BlockStateAsString(s->blockState));
                               2993                 :             break;
                               2994                 :     }
                               2995                 : 
                               2996                 :     /*
                               2997                 :      * We must switch to CurTransactionContext before returning. This is
                               2998                 :      * already done if we called StartTransaction, otherwise not.
                               2999                 :      */
 6856 tgl                      3000 GIC      548107 :     Assert(CurTransactionContext != NULL);
                               3001          548107 :     MemoryContextSwitchTo(CurTransactionContext);
 9345 bruce                    3002          548107 : }
 9345 bruce                    3003 EUB             : 
                               3004                 : 
                               3005                 : /*
                               3006                 :  * Simple system for saving and restoring transaction characteristics
                               3007                 :  * (isolation level, read only, deferrable).  We need this for transaction
                               3008                 :  * chaining, so that we can set the characteristics of the new transaction to
                               3009                 :  * be the same as the previous one.  (We need something like this because the
                               3010                 :  * GUC system resets the characteristics at transaction end, so for example
                               3011                 :  * just skipping the reset in StartTransaction() won't work.)
 1477 peter                    3012 ECB             :  */
                               3013                 : void
  405 tgl                      3014 CBC      529446 : SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
                               3015                 : {
  405 tgl                      3016 GIC      529446 :     s->save_XactIsoLevel = XactIsoLevel;
                               3017          529446 :     s->save_XactReadOnly = XactReadOnly;
                               3018          529446 :     s->save_XactDeferrable = XactDeferrable;
 1477 peter                    3019          529446 : }
                               3020                 : 
                               3021                 : void
  405 tgl                      3022              31 : RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
                               3023                 : {
                               3024              31 :     XactIsoLevel = s->save_XactIsoLevel;
                               3025              31 :     XactReadOnly = s->save_XactReadOnly;
  405 tgl                      3026 CBC          31 :     XactDeferrable = s->save_XactDeferrable;
 1477 peter                    3027 GIC          31 : }
 1477 peter                    3028 ECB             : 
                               3029                 : 
 7331 bruce                    3030                 : /*
 7452                          3031                 :  *  CommitTransactionCommand
                               3032                 :  */
                               3033                 : void
 7270 tgl                      3034 CBC      529442 : CommitTransactionCommand(void)
                               3035                 : {
 9345 bruce                    3036          529442 :     TransactionState s = CurrentTransactionState;
  405 tgl                      3037 ECB             :     SavedTransactionCharacteristics savetc;
 9345 bruce                    3038                 : 
  405 tgl                      3039 CBC      529442 :     SaveTransactionCharacteristics(&savetc);
                               3040                 : 
 9345 bruce                    3041 GIC      529442 :     switch (s->blockState)
                               3042                 :     {
                               3043                 :             /*
                               3044                 :              * These shouldn't happen.  TBLOCK_DEFAULT means the previous
                               3045                 :              * StartTransactionCommand didn't set the STARTED state
 2901 rhaas                    3046 ECB             :              * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
                               3047                 :              * by EndParallelWorkerTransaction(), not this function.
 6943 bruce                    3048                 :              */
 6943 bruce                    3049 UIC           0 :         case TBLOCK_DEFAULT:
                               3050                 :         case TBLOCK_PARALLEL_INPROGRESS:
 6830 tgl                      3051 LBC           0 :             elog(FATAL, "CommitTransactionCommand: unexpected state %s",
                               3052                 :                  BlockStateAsString(s->blockState));
 6943 bruce                    3053 ECB             :             break;
                               3054                 : 
                               3055                 :             /*
                               3056                 :              * If we aren't in a transaction block, just do our usual
                               3057                 :              * transaction commit, and return to the idle state.
                               3058                 :              */
 6943 bruce                    3059 GIC      458478 :         case TBLOCK_STARTED:
 7270 tgl                      3060          458478 :             CommitTransaction();
 6943 bruce                    3061 GBC      458468 :             s->blockState = TBLOCK_DEFAULT;
 9344 bruce                    3062 GIC      458468 :             break;
 9344 bruce                    3063 EUB             : 
                               3064                 :             /*
                               3065                 :              * We are completing a "BEGIN TRANSACTION" command, so we change
                               3066                 :              * to the "transaction block in progress" state and return.  (We
                               3067                 :              * assume the BEGIN did nothing to the database, so we need no
                               3068                 :              * CommandCounterIncrement.)
                               3069                 :              */
 9344 bruce                    3070 GIC        7436 :         case TBLOCK_BEGIN:
 9344 bruce                    3071 CBC        7436 :             s->blockState = TBLOCK_INPROGRESS;
                               3072            7436 :             break;
 9344 bruce                    3073 ECB             : 
 8053                          3074                 :             /*
                               3075                 :              * This is the case when we have finished executing a command
                               3076                 :              * someplace within a transaction block.  We increment the command
                               3077                 :              * counter and return.
                               3078                 :              */
 9344 bruce                    3079 GIC       47103 :         case TBLOCK_INPROGRESS:
                               3080                 :         case TBLOCK_IMPLICIT_INPROGRESS:
                               3081                 :         case TBLOCK_SUBINPROGRESS:
 9344 bruce                    3082 CBC       47103 :             CommandCounterIncrement();
                               3083           47103 :             break;
 9344 bruce                    3084 ECB             : 
                               3085                 :             /*
                               3086                 :              * We are completing a "COMMIT" command.  Do it and return to the
                               3087                 :              * idle state.
                               3088                 :              */
 9344 bruce                    3089 GIC        5027 :         case TBLOCK_END:
                               3090            5027 :             CommitTransaction();
 8320 tgl                      3091 CBC        4836 :             s->blockState = TBLOCK_DEFAULT;
 1477 peter                    3092 GIC        4836 :             if (s->chain)
                               3093                 :             {
 1477 peter                    3094 CBC           6 :                 StartTransaction();
                               3095               6 :                 s->blockState = TBLOCK_INPROGRESS;
 1477 peter                    3096 GIC           6 :                 s->chain = false;
  405 tgl                      3097               6 :                 RestoreTransactionCharacteristics(&savetc);
                               3098                 :             }
 9344 bruce                    3099            4836 :             break;
                               3100                 : 
 8053 bruce                    3101 ECB             :             /*
 6385                          3102                 :              * Here we are in the middle of a transaction block but one of the
                               3103                 :              * commands caused an abort so we do nothing but remain in the
 2884 magnus                   3104                 :              * abort state.  Eventually we will get a ROLLBACK command.
                               3105                 :              */
 9344 bruce                    3106 LBC           0 :         case TBLOCK_ABORT:
 6779 tgl                      3107 ECB             :         case TBLOCK_SUBABORT:
 9344 bruce                    3108 LBC           0 :             break;
 9344 bruce                    3109 ECB             : 
                               3110                 :             /*
 6385                          3111                 :              * Here we were in an aborted transaction block and we just got
                               3112                 :              * the ROLLBACK command from the user, so clean up the
                               3113                 :              * already-aborted transaction and return to the idle state.
                               3114                 :              */
 6779 tgl                      3115 GIC         612 :         case TBLOCK_ABORT_END:
 8320                          3116             612 :             CleanupTransaction();
 9344 bruce                    3117             612 :             s->blockState = TBLOCK_DEFAULT;
 1477 peter                    3118 GBC         612 :             if (s->chain)
                               3119                 :             {
                               3120               6 :                 StartTransaction();
 1477 peter                    3121 GIC           6 :                 s->blockState = TBLOCK_INPROGRESS;
                               3122               6 :                 s->chain = false;
  405 tgl                      3123               6 :                 RestoreTransactionCharacteristics(&savetc);
                               3124                 :             }
 9344 bruce                    3125             612 :             break;
                               3126                 : 
 6856 tgl                      3127 ECB             :             /*
 6385 bruce                    3128                 :              * Here we were in a perfectly good transaction block but the user
 3260                          3129                 :              * told us to ROLLBACK anyway.  We have to abort the transaction
 6385                          3130                 :              * and then clean up.
                               3131                 :              */
 6779 tgl                      3132 CBC         901 :         case TBLOCK_ABORT_PENDING:
                               3133             901 :             AbortTransaction();
                               3134             901 :             CleanupTransaction();
                               3135             901 :             s->blockState = TBLOCK_DEFAULT;
 1477 peter                    3136 GIC         901 :             if (s->chain)
 1477 peter                    3137 ECB             :             {
 1477 peter                    3138 GIC           9 :                 StartTransaction();
                               3139               9 :                 s->blockState = TBLOCK_INPROGRESS;
                               3140               9 :                 s->chain = false;
  405 tgl                      3141               9 :                 RestoreTransactionCharacteristics(&savetc);
                               3142                 :             }
 6830                          3143             901 :             break;
 6830 tgl                      3144 ECB             : 
 6505                          3145                 :             /*
                               3146                 :              * We are completing a "PREPARE TRANSACTION" command.  Do it and
                               3147                 :              * return to the idle state.
                               3148                 :              */
 6505 tgl                      3149 GIC         256 :         case TBLOCK_PREPARE:
 6505 tgl                      3150 CBC         256 :             PrepareTransaction();
                               3151             209 :             s->blockState = TBLOCK_DEFAULT;
                               3152             209 :             break;
 6505 tgl                      3153 ECB             : 
                               3154                 :             /*
                               3155                 :              * The user issued a SAVEPOINT inside a transaction block.
                               3156                 :              * Start a subtransaction.  (DefineSavepoint already did
                               3157                 :              * PushTransaction, so as to have someplace to put the SUBBEGIN
                               3158                 :              * state.)
                               3159                 :              */
 6856 tgl                      3160 GIC        8435 :         case TBLOCK_SUBBEGIN:
 6856 tgl                      3161 CBC        8435 :             StartSubTransaction();
                               3162            8435 :             s->blockState = TBLOCK_SUBINPROGRESS;
                               3163            8435 :             break;
 9345 bruce                    3164 ECB             : 
                               3165                 :             /*
                               3166                 :              * The user issued a RELEASE command, so we end the current
                               3167                 :              * subtransaction and return to the parent transaction. The parent
                               3168                 :              * might be ended too, so repeat till we find an INPROGRESS
                               3169                 :              * transaction or subtransaction.
                               3170                 :              */
 4282 simon                    3171 GIC         221 :         case TBLOCK_SUBRELEASE:
 6797 bruce                    3172 ECB             :             do
                               3173                 :             {
 4232 simon                    3174 CBC         221 :                 CommitSubTransaction();
 6797 bruce                    3175             221 :                 s = CurrentTransactionState;    /* changed by pop */
 4282 simon                    3176 GIC         221 :             } while (s->blockState == TBLOCK_SUBRELEASE);
                               3177                 : 
                               3178             135 :             Assert(s->blockState == TBLOCK_INPROGRESS ||
                               3179                 :                    s->blockState == TBLOCK_SUBINPROGRESS);
                               3180             135 :             break;
                               3181                 : 
                               3182                 :             /*
                               3183                 :              * The user issued a COMMIT, so we end the current subtransaction
                               3184                 :              * hierarchy and perform final commit. We do this by rolling up
                               3185                 :              * any subtransactions into their parent, which leads to O(N^2)
 4232 simon                    3186 ECB             :              * operations with respect to resource owners - this isn't that
 3955 bruce                    3187                 :              * bad until we approach a thousands of savepoints but is
                               3188                 :              * necessary for correctness should after triggers create new
                               3189                 :              * resource owners.
 4282 simon                    3190                 :              */
 4282 simon                    3191 GIC         570 :         case TBLOCK_SUBCOMMIT:
 4282 simon                    3192 ECB             :             do
                               3193                 :             {
 4232 simon                    3194 GIC         570 :                 CommitSubTransaction();
 4282                          3195             570 :                 s = CurrentTransactionState;    /* changed by pop */
                               3196             570 :             } while (s->blockState == TBLOCK_SUBCOMMIT);
                               3197                 :             /* If we had a COMMIT command, finish off the main xact too */
 6785 tgl                      3198             503 :             if (s->blockState == TBLOCK_END)
                               3199                 :             {
                               3200             357 :                 Assert(s->parent == NULL);
                               3201             357 :                 CommitTransaction();
                               3202             344 :                 s->blockState = TBLOCK_DEFAULT;
  779 fujii                    3203 CBC         344 :                 if (s->chain)
                               3204                 :                 {
  779 fujii                    3205 GIC           6 :                     StartTransaction();
  779 fujii                    3206 CBC           6 :                     s->blockState = TBLOCK_INPROGRESS;
                               3207               6 :                     s->chain = false;
  405 tgl                      3208               6 :                     RestoreTransactionCharacteristics(&savetc);
                               3209                 :                 }
 6785 tgl                      3210 ECB             :             }
 6505 tgl                      3211 GIC         146 :             else if (s->blockState == TBLOCK_PREPARE)
 6505 tgl                      3212 ECB             :             {
 6505 tgl                      3213 CBC         146 :                 Assert(s->parent == NULL);
                               3214             146 :                 PrepareTransaction();
                               3215             145 :                 s->blockState = TBLOCK_DEFAULT;
                               3216                 :             }
 6779 tgl                      3217 ECB             :             else
 4282 simon                    3218 LBC           0 :                 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
 4282 simon                    3219 ECB             :                      BlockStateAsString(s->blockState));
 6856 tgl                      3220 CBC         489 :             break;
                               3221                 : 
                               3222                 :             /*
 6779 tgl                      3223 ECB             :              * The current already-failed subtransaction is ending due to a
                               3224                 :              * ROLLBACK or ROLLBACK TO command, so pop it and recursively
                               3225                 :              * examine the parent (which could be in any of several states).
 6856                          3226                 :              */
 6779 tgl                      3227 CBC          40 :         case TBLOCK_SUBABORT_END:
 6779 tgl                      3228 GIC          40 :             CleanupSubTransaction();
                               3229              40 :             CommitTransactionCommand();
 6856 tgl                      3230 GBC          40 :             break;
                               3231                 : 
 6856 tgl                      3232 ECB             :             /*
                               3233                 :              * As above, but it's not dead yet, so abort first.
                               3234                 :              */
 6779 tgl                      3235 GIC         168 :         case TBLOCK_SUBABORT_PENDING:
                               3236             168 :             AbortSubTransaction();
                               3237             168 :             CleanupSubTransaction();
                               3238             168 :             CommitTransactionCommand();
 6856 tgl                      3239 CBC         168 :             break;
 6856 tgl                      3240 ECB             : 
                               3241                 :             /*
 6779                          3242                 :              * The current subtransaction is the target of a ROLLBACK TO
                               3243                 :              * command.  Abort and pop it, then start a new subtransaction
                               3244                 :              * with the same name.
                               3245                 :              */
 6779 tgl                      3246 GIC         252 :         case TBLOCK_SUBRESTART:
 6830 tgl                      3247 ECB             :             {
 6779                          3248                 :                 char       *name;
                               3249                 :                 int         savepointLevel;
                               3250                 : 
                               3251                 :                 /* save name and keep Cleanup from freeing it */
 6779 tgl                      3252 GIC         252 :                 name = s->name;
                               3253             252 :                 s->name = NULL;
                               3254             252 :                 savepointLevel = s->savepointLevel;
                               3255                 : 
                               3256             252 :                 AbortSubTransaction();
                               3257             252 :                 CleanupSubTransaction();
 6830 tgl                      3258 ECB             : 
 6779 tgl                      3259 GIC         252 :                 DefineSavepoint(NULL);
                               3260             252 :                 s = CurrentTransactionState;    /* changed by push */
                               3261             252 :                 s->name = name;
                               3262             252 :                 s->savepointLevel = savepointLevel;
                               3263                 : 
 6830 tgl                      3264 ECB             :                 /* This is the same as TBLOCK_SUBBEGIN case */
  163 peter                    3265 GNC         252 :                 Assert(s->blockState == TBLOCK_SUBBEGIN);
 6830 tgl                      3266 CBC         252 :                 StartSubTransaction();
 6830 tgl                      3267 GIC         252 :                 s->blockState = TBLOCK_SUBINPROGRESS;
 6830 tgl                      3268 ECB             :             }
 6856 tgl                      3269 CBC         252 :             break;
                               3270                 : 
 6779 tgl                      3271 ECB             :             /*
 6385 bruce                    3272                 :              * Same as above, but the subtransaction had already failed, so we
                               3273                 :              * don't need AbortSubTransaction.
 6779 tgl                      3274                 :              */
 6779 tgl                      3275 GIC          96 :         case TBLOCK_SUBABORT_RESTART:
                               3276                 :             {
 6779 tgl                      3277 ECB             :                 char       *name;
                               3278                 :                 int         savepointLevel;
 6797 bruce                    3279                 : 
                               3280                 :                 /* save name and keep Cleanup from freeing it */
 6779 tgl                      3281 CBC          96 :                 name = s->name;
 6779 tgl                      3282 GIC          96 :                 s->name = NULL;
                               3283              96 :                 savepointLevel = s->savepointLevel;
                               3284                 : 
                               3285              96 :                 CleanupSubTransaction();
                               3286                 : 
 6779 tgl                      3287 CBC          96 :                 DefineSavepoint(NULL);
 6779 tgl                      3288 GIC          96 :                 s = CurrentTransactionState;    /* changed by push */
                               3289              96 :                 s->name = name;
                               3290              96 :                 s->savepointLevel = savepointLevel;
                               3291                 : 
                               3292                 :                 /* This is the same as TBLOCK_SUBBEGIN case */
  163 peter                    3293 GNC          96 :                 Assert(s->blockState == TBLOCK_SUBBEGIN);
 6779 tgl                      3294 CBC          96 :                 StartSubTransaction();
                               3295              96 :                 s->blockState = TBLOCK_SUBINPROGRESS;
                               3296                 :             }
                               3297              96 :             break;
                               3298                 :     }
 6830                          3299          529180 : }
 6830 tgl                      3300 ECB             : 
 6856                          3301                 : /*
                               3302                 :  *  AbortCurrentTransaction
                               3303                 :  */
                               3304                 : void
 6856 tgl                      3305 CBC       19890 : AbortCurrentTransaction(void)
 6856 tgl                      3306 ECB             : {
 6856 tgl                      3307 CBC       19890 :     TransactionState s = CurrentTransactionState;
                               3308                 : 
                               3309           19890 :     switch (s->blockState)
                               3310                 :     {
 6943 bruce                    3311              43 :         case TBLOCK_DEFAULT:
 6622 tgl                      3312 GIC          43 :             if (s->state == TRANS_DEFAULT)
                               3313                 :             {
                               3314                 :                 /* we are idle, so nothing to do */
                               3315                 :             }
                               3316                 :             else
 6622 tgl                      3317 ECB             :             {
                               3318                 :                 /*
                               3319                 :                  * We can get here after an error during transaction start
                               3320                 :                  * (state will be TRANS_START).  Need to clean up the
                               3321                 :                  * incompletely started transaction.  First, adjust the
                               3322                 :                  * low-level state to suppress warning message from
                               3323                 :                  * AbortTransaction.
                               3324                 :                  */
 6622 tgl                      3325 UIC           0 :                 if (s->state == TRANS_START)
                               3326               0 :                     s->state = TRANS_INPROGRESS;
                               3327               0 :                 AbortTransaction();
                               3328               0 :                 CleanupTransaction();
                               3329                 :             }
 6943 bruce                    3330 GIC          43 :             break;
                               3331                 : 
                               3332                 :             /*
                               3333                 :              * If we aren't in a transaction block, we just do the basic abort
                               3334                 :              * & cleanup transaction.  For this purpose, we treat an implicit
                               3335                 :              * transaction block as if it were a simple statement.
                               3336                 :              */
 6943 bruce                    3337 GBC       17967 :         case TBLOCK_STARTED:
 2040 tgl                      3338 EUB             :         case TBLOCK_IMPLICIT_INPROGRESS:
 9344 bruce                    3339 GBC       17967 :             AbortTransaction();
 7270 tgl                      3340           17967 :             CleanupTransaction();
 6943 bruce                    3341 GIC       17967 :             s->blockState = TBLOCK_DEFAULT;
 9344 bruce                    3342 CBC       17967 :             break;
                               3343                 : 
                               3344                 :             /*
                               3345                 :              * If we are in TBLOCK_BEGIN it means something screwed up right
                               3346                 :              * after reading "BEGIN TRANSACTION".  We assume that the user
                               3347                 :              * will interpret the error as meaning the BEGIN failed to get him
                               3348                 :              * into a transaction block, so we should abort and return to idle
 6385 bruce                    3349 ECB             :              * state.
                               3350                 :              */
 9344 bruce                    3351 LBC           0 :         case TBLOCK_BEGIN:
                               3352               0 :             AbortTransaction();
 6779 tgl                      3353               0 :             CleanupTransaction();
                               3354               0 :             s->blockState = TBLOCK_DEFAULT;
 9344 bruce                    3355 UIC           0 :             break;
                               3356                 : 
                               3357                 :             /*
                               3358                 :              * We are somewhere in a transaction block and we've gotten a
                               3359                 :              * failure, so we abort the transaction and set up the persistent
                               3360                 :              * ABORT state.  We will stay in ABORT until we get a ROLLBACK.
                               3361                 :              */
 9344 bruce                    3362 GIC         622 :         case TBLOCK_INPROGRESS:
 2901 rhaas                    3363 EUB             :         case TBLOCK_PARALLEL_INPROGRESS:
 9344 bruce                    3364 GBC         622 :             AbortTransaction();
 6943                          3365             622 :             s->blockState = TBLOCK_ABORT;
 6779 tgl                      3366 EUB             :             /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
 9344 bruce                    3367 GBC         622 :             break;
                               3368                 : 
                               3369                 :             /*
                               3370                 :              * Here, we failed while trying to COMMIT.  Clean up the
                               3371                 :              * transaction and return to idle state (we do not want to stay in
                               3372                 :              * the transaction).
                               3373                 :              */
 9344 bruce                    3374 CBC         204 :         case TBLOCK_END:
 9344 bruce                    3375 GIC         204 :             AbortTransaction();
 8320 tgl                      3376 CBC         204 :             CleanupTransaction();
 6943 bruce                    3377             204 :             s->blockState = TBLOCK_DEFAULT;
 9344 bruce                    3378 GIC         204 :             break;
 9344 bruce                    3379 ECB             : 
                               3380                 :             /*
                               3381                 :              * Here, we are already in an aborted transaction state and are
                               3382                 :              * waiting for a ROLLBACK, but for some reason we failed again! So
                               3383                 :              * we just remain in the abort state.
                               3384                 :              */
 9344 bruce                    3385 GIC          52 :         case TBLOCK_ABORT:
 6856 tgl                      3386 ECB             :         case TBLOCK_SUBABORT:
 9344 bruce                    3387 CBC          52 :             break;
 9344 bruce                    3388 ECB             : 
 8053                          3389                 :             /*
 6779 tgl                      3390                 :              * We are in a failed transaction and we got the ROLLBACK command.
                               3391                 :              * We have already aborted, we just need to cleanup and go to idle
                               3392                 :              * state.
                               3393                 :              */
 6779 tgl                      3394 UIC           0 :         case TBLOCK_ABORT_END:
 8320                          3395               0 :             CleanupTransaction();
 9344 bruce                    3396               0 :             s->blockState = TBLOCK_DEFAULT;
 9344 bruce                    3397 LBC           0 :             break;
                               3398                 : 
 6856 tgl                      3399 ECB             :             /*
                               3400                 :              * We are in a live transaction and we got a ROLLBACK command.
                               3401                 :              * Abort, cleanup, go to idle state.
                               3402                 :              */
 6779 tgl                      3403 UIC           0 :         case TBLOCK_ABORT_PENDING:
                               3404               0 :             AbortTransaction();
                               3405               0 :             CleanupTransaction();
 6779 tgl                      3406 UBC           0 :             s->blockState = TBLOCK_DEFAULT;
 6856                          3407               0 :             break;
 6856 tgl                      3408 EUB             : 
 6505                          3409                 :             /*
                               3410                 :              * Here, we failed while trying to PREPARE.  Clean up the
                               3411                 :              * transaction and return to idle state (we do not want to stay in
                               3412                 :              * the transaction).
                               3413                 :              */
 6505 tgl                      3414 GIC          48 :         case TBLOCK_PREPARE:
 6505 tgl                      3415 GBC          48 :             AbortTransaction();
                               3416              48 :             CleanupTransaction();
                               3417              48 :             s->blockState = TBLOCK_DEFAULT;
                               3418              48 :             break;
 6505 tgl                      3419 EUB             : 
                               3420                 :             /*
                               3421                 :              * We got an error inside a subtransaction.  Abort just the
                               3422                 :              * subtransaction, and go to the persistent SUBABORT state until
                               3423                 :              * we get ROLLBACK.
                               3424                 :              */
 6856 tgl                      3425 GIC         954 :         case TBLOCK_SUBINPROGRESS:
 6856 tgl                      3426 CBC         954 :             AbortSubTransaction();
                               3427             954 :             s->blockState = TBLOCK_SUBABORT;
                               3428             954 :             break;
 6856 tgl                      3429 ECB             : 
                               3430                 :             /*
                               3431                 :              * If we failed while trying to create a subtransaction, clean up
                               3432                 :              * the broken subtransaction and abort the parent.  The same
                               3433                 :              * applies if we get a failure while ending a subtransaction.
                               3434                 :              */
 6779 tgl                      3435 UIC           0 :         case TBLOCK_SUBBEGIN:
                               3436                 :         case TBLOCK_SUBRELEASE:
 4282 simon                    3437 ECB             :         case TBLOCK_SUBCOMMIT:
 6830 tgl                      3438                 :         case TBLOCK_SUBABORT_PENDING:
 6779                          3439                 :         case TBLOCK_SUBRESTART:
 6856 tgl                      3440 LBC           0 :             AbortSubTransaction();
 6856 tgl                      3441 UIC           0 :             CleanupSubTransaction();
                               3442               0 :             AbortCurrentTransaction();
                               3443               0 :             break;
                               3444                 : 
                               3445                 :             /*
                               3446                 :              * Same as above, except the Abort() was already done.
 6856 tgl                      3447 EUB             :              */
 6779 tgl                      3448 UIC           0 :         case TBLOCK_SUBABORT_END:
                               3449                 :         case TBLOCK_SUBABORT_RESTART:
 6856                          3450               0 :             CleanupSubTransaction();
                               3451               0 :             AbortCurrentTransaction();
 6856 tgl                      3452 UBC           0 :             break;
 9345 bruce                    3453 EUB             :     }
 9345 bruce                    3454 GBC       19890 : }
 9345 bruce                    3455 EUB             : 
                               3456                 : /*
                               3457                 :  *  PreventInTransactionBlock
                               3458                 :  *
                               3459                 :  *  This routine is to be called by statements that must not run inside
 7452                          3460                 :  *  a transaction block, typically because they have non-rollback-able
                               3461                 :  *  side effects or do internal commits.
 7475 tgl                      3462                 :  *
  151                          3463                 :  *  If this routine completes successfully, then the calling statement is
                               3464                 :  *  guaranteed that if it completes without error, its results will be
                               3465                 :  *  committed immediately.
  151 tgl                      3466 ECB             :  *
                               3467                 :  *  If we have already started a transaction block, issue an error; also issue
                               3468                 :  *  an error if we appear to be running inside a user-defined function (which
                               3469                 :  *  could issue more commands and possibly cause a failure after the statement
                               3470                 :  *  completes).  Subtransactions are verboten too.
                               3471                 :  *
                               3472                 :  *  We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
                               3473                 :  *  that postgres.c follows through by committing after the statement is done.
                               3474                 :  *
                               3475                 :  *  isTopLevel: passed down from ProcessUtility to determine whether we are
                               3476                 :  *  inside a function.  (We will always fail if this is false, but it's
                               3477                 :  *  convenient to centralize the check here instead of making callers do it.)
                               3478                 :  *  stmtType: statement type name, for error messages.
                               3479                 :  */
                               3480                 : void
 1878 peter_e                  3481 GIC        5265 : PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
                               3482                 : {
                               3483                 :     /*
                               3484                 :      * xact block already started?
                               3485                 :      */
 7475 tgl                      3486            5265 :     if (IsTransactionBlock())
 7202                          3487              48 :         ereport(ERROR,
                               3488                 :                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
                               3489                 :         /* translator: %s represents an SQL statement name */
                               3490                 :                  errmsg("%s cannot run inside a transaction block",
                               3491                 :                         stmtType)));
                               3492                 : 
 6856 tgl                      3493 ECB             :     /*
                               3494                 :      * subtransaction?
                               3495                 :      */
 6856 tgl                      3496 GIC        5217 :     if (IsSubTransaction())
 6856 tgl                      3497 UIC           0 :         ereport(ERROR,
 6856 tgl                      3498 ECB             :                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
                               3499                 :         /* translator: %s represents an SQL statement name */
                               3500                 :                  errmsg("%s cannot run inside a subtransaction",
                               3501                 :                         stmtType)));
                               3502                 : 
                               3503                 :     /*
                               3504                 :      * inside a pipeline that has started an implicit transaction?
                               3505                 :      */
  117 tgl                      3506 GIC        5217 :     if (MyXactFlags & XACT_FLAGS_PIPELINING)
  117 tgl                      3507 UIC           0 :         ereport(ERROR,
  117 tgl                      3508 ECB             :                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
  117 tgl                      3509 EUB             :         /* translator: %s represents an SQL statement name */
                               3510                 :                  errmsg("%s cannot be executed within a pipeline",
                               3511                 :                         stmtType)));
                               3512                 : 
                               3513                 :     /*
                               3514                 :      * inside a function call?
                               3515                 :      */
 5871 tgl                      3516 GIC        5217 :     if (!isTopLevel)
 7202                          3517               3 :         ereport(ERROR,
 7202 tgl                      3518 ECB             :                 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
 7188 bruce                    3519 EUB             :         /* translator: %s represents an SQL statement name */
                               3520                 :                  errmsg("%s cannot be executed from a function", stmtType)));
                               3521                 : 
                               3522                 :     /* If we got past IsTransactionBlock test, should be in default state */
 6943 bruce                    3523 GIC        5214 :     if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
 6896 tgl                      3524            4571 :         CurrentTransactionState->blockState != TBLOCK_STARTED)
 6856 tgl                      3525 UIC           0 :         elog(FATAL, "cannot prevent transaction chain");
                               3526                 : 
                               3527                 :     /* All okay.  Set the flag to make sure the right thing happens later. */
  257 tgl                      3528 CBC        5214 :     MyXactFlags |= XACT_FLAGS_NEEDIMMEDIATECOMMIT;
 7475                          3529            5214 : }
                               3530                 : 
                               3531                 : /*
                               3532                 :  *  WarnNoTransactionBlock
                               3533                 :  *  RequireTransactionBlock
                               3534                 :  *
 1878 peter_e                  3535 ECB             :  *  These two functions allow for warnings or errors if a command is executed
                               3536                 :  *  outside of a transaction block.  This is useful for commands that have no
 1878 peter_e                  3537 EUB             :  *  effects that persist past transaction end (and so calling them outside a
                               3538                 :  *  transaction block is presumably an error).  DECLARE CURSOR is an example.
                               3539                 :  *  While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
 1878 peter_e                  3540 ECB             :  *  that have no effect issue warnings, all other no-effect commands generate
                               3541                 :  *  errors.
                               3542                 :  *
                               3543                 :  *  If we appear to be running inside a user-defined function, we do not
                               3544                 :  *  issue anything, since the function could issue more commands that make
                               3545                 :  *  use of the current statement's results.  Likewise subtransactions.
                               3546                 :  *  Thus these are inverses for PreventInTransactionBlock.
                               3547                 :  *
                               3548                 :  *  isTopLevel: passed down from ProcessUtility to determine whether we are
                               3549                 :  *  inside a function.
                               3550                 :  *  stmtType: statement type name, for warning or error messages.
                               3551                 :  */
                               3552                 : void
 1878 peter_e                  3553 GIC         779 : WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
                               3554                 : {
                               3555             779 :     CheckTransactionBlock(isTopLevel, false, stmtType);
 3422 bruce                    3556             779 : }
                               3557                 : 
                               3558                 : void
 1878 peter_e                  3559            3296 : RequireTransactionBlock(bool isTopLevel, const char *stmtType)
                               3560                 : {
                               3561            3296 :     CheckTransactionBlock(isTopLevel, true, stmtType);
 3422 bruce                    3562            3286 : }
                               3563                 : 
                               3564                 : /*
 1878 peter_e                  3565 ECB             :  * This is the implementation of the above two.
                               3566                 :  */
 3422 bruce                    3567                 : static void
 1878 peter_e                  3568 CBC        4075 : CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
                               3569                 : {
                               3570                 :     /*
 7447 tgl                      3571 ECB             :      * xact block already started?
                               3572                 :      */
 7447 tgl                      3573 CBC        4075 :     if (IsTransactionBlock())
                               3574            4046 :         return;
                               3575                 : 
                               3576                 :     /*
                               3577                 :      * subtransaction?
                               3578                 :      */
 6856 tgl                      3579 GIC          29 :     if (IsSubTransaction())
 6856 tgl                      3580 LBC           0 :         return;
                               3581                 : 
                               3582                 :     /*
                               3583                 :      * inside a function call?
                               3584                 :      */
 5871 tgl                      3585 CBC          29 :     if (!isTopLevel)
 7447                          3586              13 :         return;
                               3587                 : 
 3422 bruce                    3588 GIC          16 :     ereport(throwError ? ERROR : WARNING,
                               3589                 :             (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
                               3590                 :     /* translator: %s represents an SQL statement name */
 5911 bruce                    3591 ECB             :              errmsg("%s can only be used in transaction blocks",
 7202 tgl                      3592 EUB             :                     stmtType)));
                               3593                 : }
                               3594                 : 
                               3595                 : /*
                               3596                 :  *  IsInTransactionBlock
 6896 tgl                      3597 ECB             :  *
                               3598                 :  *  This routine is for statements that need to behave differently inside
                               3599                 :  *  a transaction block than when running as single commands.  ANALYZE is
                               3600                 :  *  currently the only example.
                               3601                 :  *
                               3602                 :  *  If this routine returns "false", then the calling statement is allowed
                               3603                 :  *  to perform internal transaction-commit-and-start cycles; there is not a
                               3604                 :  *  risk of messing up any transaction already in progress.  (Note that this
                               3605                 :  *  is not the identical guarantee provided by PreventInTransactionBlock,
                               3606                 :  *  since we will not force a post-statement commit.)
                               3607                 :  *
                               3608                 :  *  isTopLevel: passed down from ProcessUtility to determine whether we are
                               3609                 :  *  inside a function.
                               3610                 :  */
                               3611                 : bool
 1878 peter_e                  3612 GIC        2525 : IsInTransactionBlock(bool isTopLevel)
                               3613                 : {
                               3614                 :     /*
                               3615                 :      * Return true on same conditions that would make
                               3616                 :      * PreventInTransactionBlock error out
                               3617                 :      */
 6896 tgl                      3618            2525 :     if (IsTransactionBlock())
                               3619              57 :         return true;
                               3620                 : 
 6856                          3621            2468 :     if (IsSubTransaction())
 6856 tgl                      3622 UIC           0 :         return true;
                               3623                 : 
  117 tgl                      3624 CBC        2468 :     if (MyXactFlags & XACT_FLAGS_PIPELINING)
  117 tgl                      3625 UIC           0 :         return true;
                               3626                 : 
 5871 tgl                      3627 GIC        2468 :     if (!isTopLevel)
 6896                          3628              53 :         return true;
                               3629                 : 
 6896 tgl                      3630 CBC        2415 :     if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
                               3631            2415 :         CurrentTransactionState->blockState != TBLOCK_STARTED)
 6896 tgl                      3632 UIC           0 :         return true;
 6896 tgl                      3633 ECB             : 
 6896 tgl                      3634 GBC        2415 :     return false;
                               3635                 : }
 6896 tgl                      3636 ECB             : 
 7475 tgl                      3637 EUB             : 
                               3638                 : /*
 6825 tgl                      3639 ECB             :  * Register or deregister callback functions for start- and end-of-xact
                               3640                 :  * operations.
                               3641                 :  *
 7133                          3642                 :  * These functions are intended for use by dynamically loaded modules.
                               3643                 :  * For built-in modules we generally just hardwire the appropriate calls
 7133 tgl                      3644 EUB             :  * (mainly because it's easier to control the order that way, where needed).
                               3645                 :  *
 6825 tgl                      3646 ECB             :  * At transaction end, the callback occurs post-commit or post-abort, so the
                               3647                 :  * callback functions can only do noncritical cleanup.
                               3648                 :  */
                               3649                 : void
 6825 tgl                      3650 GIC        1770 : RegisterXactCallback(XactCallback callback, void *arg)
                               3651                 : {
                               3652                 :     XactCallbackItem *item;
                               3653                 : 
                               3654                 :     item = (XactCallbackItem *)
                               3655            1770 :         MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
 7133                          3656            1770 :     item->callback = callback;
                               3657            1770 :     item->arg = arg;
 6825                          3658            1770 :     item->next = Xact_callbacks;
                               3659            1770 :     Xact_callbacks = item;
 7133                          3660            1770 : }
                               3661                 : 
 7133 tgl                      3662 ECB             : void
 6825 tgl                      3663 UIC           0 : UnregisterXactCallback(XactCallback callback, void *arg)
                               3664                 : {
                               3665                 :     XactCallbackItem *item;
                               3666                 :     XactCallbackItem *prev;
 7133 tgl                      3667 ECB             : 
 7133 tgl                      3668 LBC           0 :     prev = NULL;
 6825                          3669               0 :     for (item = Xact_callbacks; item; prev = item, item = item->next)
 7133 tgl                      3670 ECB             :     {
 7133 tgl                      3671 LBC           0 :         if (item->callback == callback && item->arg == arg)
 7133 tgl                      3672 ECB             :         {
 7133 tgl                      3673 UIC           0 :             if (prev)
                               3674               0 :                 prev->next = item->next;
 7133 tgl                      3675 EUB             :             else
 6825 tgl                      3676 UIC           0 :                 Xact_callbacks = item->next;
 7133                          3677               0 :             pfree(item);
                               3678               0 :             break;
                               3679                 :         }
 7133 tgl                      3680 EUB             :     }
 7133 tgl                      3681 UBC           0 : }
                               3682                 : 
 7133 tgl                      3683 EUB             : static void
 6779 tgl                      3684 GIC      950898 : CallXactCallbacks(XactEvent event)
 7133 tgl                      3685 EUB             : {
 6825                          3686                 :     XactCallbackItem *item;
                               3687                 :     XactCallbackItem *next;
                               3688                 : 
  193 tgl                      3689 GNC     1177686 :     for (item = Xact_callbacks; item; item = next)
                               3690                 :     {
                               3691                 :         /* allow callbacks to unregister themselves when called */
                               3692          226789 :         next = item->next;
 2040 peter_e                  3693 GBC      226789 :         item->callback(event, item->arg);
                               3694                 :     }
 6779 tgl                      3695          950897 : }
                               3696                 : 
                               3697                 : 
 6779 tgl                      3698 EUB             : /*
                               3699                 :  * Register or deregister callback functions for start- and end-of-subxact
                               3700                 :  * operations.
 6779 tgl                      3701 ECB             :  *
                               3702                 :  * Pretty much same as above, but for subtransaction events.
                               3703                 :  *
                               3704                 :  * At subtransaction end, the callback occurs post-subcommit or post-subabort,
                               3705                 :  * so the callback functions can only do noncritical cleanup.  At
                               3706                 :  * subtransaction start, the callback is called when the subtransaction has
                               3707                 :  * finished initializing.
                               3708                 :  */
                               3709                 : void
 6779 tgl                      3710 CBC        1770 : RegisterSubXactCallback(SubXactCallback callback, void *arg)
                               3711                 : {
 6779 tgl                      3712 ECB             :     SubXactCallbackItem *item;
                               3713                 : 
                               3714                 :     item = (SubXactCallbackItem *)
 6779 tgl                      3715 GIC        1770 :         MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
                               3716            1770 :     item->callback = callback;
                               3717            1770 :     item->arg = arg;
                               3718            1770 :     item->next = SubXact_callbacks;
                               3719            1770 :     SubXact_callbacks = item;
                               3720            1770 : }
                               3721                 : 
                               3722                 : void
 6779 tgl                      3723 UIC           0 : UnregisterSubXactCallback(SubXactCallback callback, void *arg)
                               3724                 : {
                               3725                 :     SubXactCallbackItem *item;
                               3726                 :     SubXactCallbackItem *prev;
 6779 tgl                      3727 ECB             : 
 6779 tgl                      3728 UIC           0 :     prev = NULL;
                               3729               0 :     for (item = SubXact_callbacks; item; prev = item, item = item->next)
                               3730                 :     {
                               3731               0 :         if (item->callback == callback && item->arg == arg)
 6779 tgl                      3732 ECB             :         {
 6779 tgl                      3733 LBC           0 :             if (prev)
                               3734               0 :                 prev->next = item->next;
 6779 tgl                      3735 ECB             :             else
 6779 tgl                      3736 LBC           0 :                 SubXact_callbacks = item->next;
                               3737               0 :             pfree(item);
 6779 tgl                      3738 UIC           0 :             break;
                               3739                 :         }
 6779 tgl                      3740 EUB             :     }
 6779 tgl                      3741 UIC           0 : }
                               3742                 : 
                               3743                 : static void
 6779 tgl                      3744 GIC       21881 : CallSubXactCallbacks(SubXactEvent event,
 6779 tgl                      3745 EUB             :                      SubTransactionId mySubid,
                               3746                 :                      SubTransactionId parentSubid)
                               3747                 : {
                               3748                 :     SubXactCallbackItem *item;
                               3749                 :     SubXactCallbackItem *next;
                               3750                 : 
  193 tgl                      3751 GNC       38344 :     for (item = SubXact_callbacks; item; item = next)
                               3752                 :     {
                               3753                 :         /* allow callbacks to unregister themselves when called */
                               3754           16463 :         next = item->next;
 2040 peter_e                  3755 GBC       16463 :         item->callback(event, mySubid, parentSubid, item->arg);
                               3756                 :     }
 7133 tgl                      3757 GIC       21881 : }
 7133 tgl                      3758 EUB             : 
                               3759                 : 
 9345 bruce                    3760                 : /* ----------------------------------------------------------------
                               3761                 :  *                     transaction block support
                               3762                 :  * ----------------------------------------------------------------
                               3763                 :  */
                               3764                 : 
                               3765                 : /*
 7452 bruce                    3766 ECB             :  *  BeginTransactionBlock
                               3767                 :  *      This executes a BEGIN command.
                               3768                 :  */
                               3769                 : void
 9345 bruce                    3770 GIC        7436 : BeginTransactionBlock(void)
                               3771                 : {
                               3772            7436 :     TransactionState s = CurrentTransactionState;
 9345 bruce                    3773 ECB             : 
 6830 tgl                      3774 GIC        7436 :     switch (s->blockState)
                               3775                 :     {
 6943 bruce                    3776 ECB             :             /*
 6385                          3777                 :              * We are not inside a transaction block, so allow one to begin.
                               3778                 :              */
 6943 bruce                    3779 CBC        6960 :         case TBLOCK_STARTED:
 6943 bruce                    3780 GIC        6960 :             s->blockState = TBLOCK_BEGIN;
                               3781            6960 :             break;
                               3782                 : 
                               3783                 :             /*
                               3784                 :              * BEGIN converts an implicit transaction block to a regular one.
                               3785                 :              * (Note that we allow this even if we've already done some
                               3786                 :              * commands, which is a bit odd but matches historical practice.)
                               3787                 :              */
 2040 tgl                      3788             476 :         case TBLOCK_IMPLICIT_INPROGRESS:
                               3789             476 :             s->blockState = TBLOCK_BEGIN;
                               3790             476 :             break;
                               3791                 : 
 6856 tgl                      3792 ECB             :             /*
                               3793                 :              * Already a transaction block in progress.
                               3794                 :              */
 6943 bruce                    3795 UIC           0 :         case TBLOCK_INPROGRESS:
 2901 rhaas                    3796 ECB             :         case TBLOCK_PARALLEL_INPROGRESS:
                               3797                 :         case TBLOCK_SUBINPROGRESS:
                               3798                 :         case TBLOCK_ABORT:
                               3799                 :         case TBLOCK_SUBABORT:
 6830 tgl                      3800 UIC           0 :             ereport(WARNING,
 6830 tgl                      3801 ECB             :                     (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
 6385 bruce                    3802                 :                      errmsg("there is already a transaction in progress")));
 6943 bruce                    3803 LBC           0 :             break;
                               3804                 : 
                               3805                 :             /* These cases are invalid. */
 6943 bruce                    3806 UIC           0 :         case TBLOCK_DEFAULT:
                               3807                 :         case TBLOCK_BEGIN:
                               3808                 :         case TBLOCK_SUBBEGIN:
                               3809                 :         case TBLOCK_END:
 4282 simon                    3810 ECB             :         case TBLOCK_SUBRELEASE:
                               3811                 :         case TBLOCK_SUBCOMMIT:
 6779 tgl                      3812                 :         case TBLOCK_ABORT_END:
                               3813                 :         case TBLOCK_SUBABORT_END:
                               3814                 :         case TBLOCK_ABORT_PENDING:
                               3815                 :         case TBLOCK_SUBABORT_PENDING:
                               3816                 :         case TBLOCK_SUBRESTART:
 6779 tgl                      3817 EUB             :         case TBLOCK_SUBABORT_RESTART:
                               3818                 :         case TBLOCK_PREPARE:
 6856 tgl                      3819 UIC           0 :             elog(FATAL, "BeginTransactionBlock: unexpected state %s",
                               3820                 :                  BlockStateAsString(s->blockState));
                               3821                 :             break;
 6943 bruce                    3822 EUB             :     }
 9770 scrappy                  3823 GIC        7436 : }
                               3824                 : 
 6505 tgl                      3825 EUB             : /*
                               3826                 :  *  PrepareTransactionBlock
                               3827                 :  *      This executes a PREPARE command.
                               3828                 :  *
                               3829                 :  * Since PREPARE may actually do a ROLLBACK, the result indicates what
                               3830                 :  * happened: true for PREPARE, false for ROLLBACK.
                               3831                 :  *
                               3832                 :  * Note that we don't actually do anything here except change blockState.
                               3833                 :  * The real work will be done in the upcoming PrepareTransaction().
                               3834                 :  * We do it this way because it's not convenient to change memory context,
                               3835                 :  * resource owner, etc while executing inside a Portal.
                               3836                 :  */
                               3837                 : bool
 1986 peter_e                  3838 GIC         404 : PrepareTransactionBlock(const char *gid)
                               3839                 : {
                               3840                 :     TransactionState s;
 6385 bruce                    3841 EUB             :     bool        result;
                               3842                 : 
                               3843                 :     /* Set up to commit the current transaction */
 1477 peter                    3844 GIC         404 :     result = EndTransactionBlock(false);
 6505 tgl                      3845 ECB             : 
                               3846                 :     /* If successful, change outer tblock state to PREPARE */
 6505 tgl                      3847 GIC         404 :     if (result)
                               3848                 :     {
                               3849             402 :         s = CurrentTransactionState;
                               3850                 : 
                               3851             555 :         while (s->parent != NULL)
                               3852             153 :             s = s->parent;
                               3853                 : 
                               3854             402 :         if (s->blockState == TBLOCK_END)
                               3855                 :         {
                               3856                 :             /* Save GID where PrepareTransaction can find it again */
                               3857             402 :             prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
                               3858                 : 
                               3859             402 :             s->blockState = TBLOCK_PREPARE;
 6505 tgl                      3860 ECB             :         }
                               3861                 :         else
                               3862                 :         {
                               3863                 :             /*
                               3864                 :              * ignore case where we are not in a transaction;
                               3865                 :              * EndTransactionBlock already issued a warning.
                               3866                 :              */
 2040 tgl                      3867 UIC           0 :             Assert(s->blockState == TBLOCK_STARTED ||
                               3868                 :                    s->blockState == TBLOCK_IMPLICIT_INPROGRESS);
 6505 tgl                      3869 ECB             :             /* Don't send back a PREPARE result tag... */
 6505 tgl                      3870 UIC           0 :             result = false;
 6505 tgl                      3871 ECB             :         }
                               3872                 :     }
                               3873                 : 
 6505 tgl                      3874 CBC         404 :     return result;
                               3875                 : }
 6505 tgl                      3876 ECB             : 
                               3877                 : /*
                               3878                 :  *  EndTransactionBlock
 6856                          3879                 :  *      This executes a COMMIT command.
                               3880                 :  *
 6830                          3881                 :  * Since COMMIT may actually do a ROLLBACK, the result indicates what
                               3882                 :  * happened: true for COMMIT, false for ROLLBACK.
                               3883                 :  *
                               3884                 :  * Note that we don't actually do anything here except change blockState.
                               3885                 :  * The real work will be done in the upcoming CommitTransactionCommand().
                               3886                 :  * We do it this way because it's not convenient to change memory context,
                               3887                 :  * resource owner, etc while executing inside a Portal.
                               3888                 :  */
 6830 tgl                      3889 EUB             : bool
 1477 peter                    3890 GIC        6178 : EndTransactionBlock(bool chain)
                               3891                 : {
 9345 bruce                    3892 GBC        6178 :     TransactionState s = CurrentTransactionState;
 6830 tgl                      3893 GIC        6178 :     bool        result = false;
                               3894                 : 
                               3895            6178 :     switch (s->blockState)
 6830 tgl                      3896 ECB             :     {
                               3897                 :             /*
                               3898                 :              * We are in a transaction block, so tell CommitTransactionCommand
                               3899                 :              * to COMMIT.
                               3900                 :              */
 6943 bruce                    3901 GIC        5271 :         case TBLOCK_INPROGRESS:
 6830 tgl                      3902            5271 :             s->blockState = TBLOCK_END;
                               3903            5271 :             result = true;
 6856                          3904            5271 :             break;
                               3905                 : 
                               3906                 :             /*
                               3907                 :              * We are in an implicit transaction block.  If AND CHAIN was
                               3908                 :              * specified, error.  Otherwise commit, but issue a warning
                               3909                 :              * because there was no explicit BEGIN before this.
                               3910                 :              */
 2040                          3911              24 :         case TBLOCK_IMPLICIT_INPROGRESS:
 1309 peter                    3912 CBC          24 :             if (chain)
 1309 peter                    3913 GIC          12 :                 ereport(ERROR,
 1309 peter                    3914 ECB             :                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
 1060 tgl                      3915                 :                 /* translator: %s represents an SQL statement name */
                               3916                 :                          errmsg("%s can only be used in transaction blocks",
 1309 peter                    3917                 :                                 "COMMIT AND CHAIN")));
                               3918                 :             else
 1309 peter                    3919 GIC          12 :                 ereport(WARNING,
                               3920                 :                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
                               3921                 :                          errmsg("there is no transaction in progress")));
 2040 tgl                      3922              12 :             s->blockState = TBLOCK_END;
 2040 tgl                      3923 CBC          12 :             result = true;
                               3924              12 :             break;
 2040 tgl                      3925 ECB             : 
 6943 bruce                    3926                 :             /*
                               3927                 :              * We are in a failed transaction block.  Tell
                               3928                 :              * CommitTransactionCommand it's time to exit the block.
                               3929                 :              */
 6943 bruce                    3930 GIC         338 :         case TBLOCK_ABORT:
 6779 tgl                      3931             338 :             s->blockState = TBLOCK_ABORT_END;
 6943 bruce                    3932             338 :             break;
 9770 scrappy                  3933 ECB             : 
 6785 tgl                      3934                 :             /*
 6385 bruce                    3935                 :              * We are in a live subtransaction block.  Set up to subcommit all
                               3936                 :              * open subtransactions and then commit the main transaction.
                               3937                 :              */
 6785 tgl                      3938 GIC         503 :         case TBLOCK_SUBINPROGRESS:
                               3939            1073 :             while (s->parent != NULL)
                               3940                 :             {
 6779 tgl                      3941 CBC         570 :                 if (s->blockState == TBLOCK_SUBINPROGRESS)
 4282 simon                    3942 GIC         570 :                     s->blockState = TBLOCK_SUBCOMMIT;
                               3943                 :                 else
 6779 tgl                      3944 LBC           0 :                     elog(FATAL, "EndTransactionBlock: unexpected state %s",
 6779 tgl                      3945 ECB             :                          BlockStateAsString(s->blockState));
 6785 tgl                      3946 CBC         570 :                 s = s->parent;
                               3947                 :             }
 6779 tgl                      3948 GIC         503 :             if (s->blockState == TBLOCK_INPROGRESS)
                               3949             503 :                 s->blockState = TBLOCK_END;
                               3950                 :             else
 6779 tgl                      3951 UIC           0 :                 elog(FATAL, "EndTransactionBlock: unexpected state %s",
 6779 tgl                      3952 ECB             :                      BlockStateAsString(s->blockState));
 6785 tgl                      3953 CBC         503 :             result = true;
                               3954             503 :             break;
                               3955                 : 
                               3956                 :             /*
                               3957                 :              * Here we are inside an aborted subtransaction.  Treat the COMMIT
                               3958                 :              * as ROLLBACK: set up to abort everything and exit the main
                               3959                 :              * transaction.
 6856 tgl                      3960 ECB             :              */
 6856 tgl                      3961 CBC          30 :         case TBLOCK_SUBABORT:
 6779 tgl                      3962 GIC          60 :             while (s->parent != NULL)
 6779 tgl                      3963 ECB             :             {
 6779 tgl                      3964 CBC          30 :                 if (s->blockState == TBLOCK_SUBINPROGRESS)
 6779 tgl                      3965 UIC           0 :                     s->blockState = TBLOCK_SUBABORT_PENDING;
 6779 tgl                      3966 GBC          30 :                 else if (s->blockState == TBLOCK_SUBABORT)
 6779 tgl                      3967 GIC          30 :                     s->blockState = TBLOCK_SUBABORT_END;
 6779 tgl                      3968 ECB             :                 else
 6779 tgl                      3969 UIC           0 :                     elog(FATAL, "EndTransactionBlock: unexpected state %s",
 6779 tgl                      3970 ECB             :                          BlockStateAsString(s->blockState));
 6779 tgl                      3971 CBC          30 :                 s = s->parent;
                               3972                 :             }
 6779 tgl                      3973 GBC          30 :             if (s->blockState == TBLOCK_INPROGRESS)
 6779 tgl                      3974 GIC          30 :                 s->blockState = TBLOCK_ABORT_PENDING;
 6779 tgl                      3975 LBC           0 :             else if (s->blockState == TBLOCK_ABORT)
                               3976               0 :                 s->blockState = TBLOCK_ABORT_END;
                               3977                 :             else
 6779 tgl                      3978 UIC           0 :                 elog(FATAL, "EndTransactionBlock: unexpected state %s",
                               3979                 :                      BlockStateAsString(s->blockState));
 6856 tgl                      3980 GIC          30 :             break;
                               3981                 : 
                               3982                 :             /*
 1309 peter                    3983 ECB             :              * The user issued COMMIT when not inside a transaction.  For
                               3984                 :              * COMMIT without CHAIN, issue a WARNING, staying in
                               3985                 :              * TBLOCK_STARTED state.  The upcoming call to
 6735 tgl                      3986                 :              * CommitTransactionCommand() will then close the transaction and
 1309 peter                    3987 EUB             :              * put us back into the default state.  For COMMIT AND CHAIN,
 1309 peter                    3988 ECB             :              * error.
 6943 bruce                    3989                 :              */
 6779 tgl                      3990 GIC          12 :         case TBLOCK_STARTED:
 1309 peter                    3991 GBC          12 :             if (chain)
 1309 peter                    3992 GIC           3 :                 ereport(ERROR,
 1309 peter                    3993 ECB             :                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
                               3994                 :                 /* translator: %s represents an SQL statement name */
                               3995                 :                          errmsg("%s can only be used in transaction blocks",
                               3996                 :                                 "COMMIT AND CHAIN")));
 1309 peter                    3997 EUB             :             else
 1309 peter                    3998 GBC           9 :                 ereport(WARNING,
                               3999                 :                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
 1309 peter                    4000 EUB             :                          errmsg("there is no transaction in progress")));
 6735 tgl                      4001 GIC           9 :             result = true;
 6943 bruce                    4002 CBC           9 :             break;
                               4003                 : 
                               4004                 :             /*
                               4005                 :              * The user issued a COMMIT that somehow ran inside a parallel
                               4006                 :              * worker.  We can't cope with that.
                               4007                 :              */
 2901 rhaas                    4008 UIC           0 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4009               0 :             ereport(FATAL,
                               4010                 :                     (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
                               4011                 :                      errmsg("cannot commit during a parallel operation")));
 2901 rhaas                    4012 ECB             :             break;
                               4013                 : 
 6779 tgl                      4014                 :             /* These cases are invalid. */
 6943 bruce                    4015 UIC           0 :         case TBLOCK_DEFAULT:
                               4016                 :         case TBLOCK_BEGIN:
                               4017                 :         case TBLOCK_SUBBEGIN:
                               4018                 :         case TBLOCK_END:
                               4019                 :         case TBLOCK_SUBRELEASE:
 4282 simon                    4020 ECB             :         case TBLOCK_SUBCOMMIT:
                               4021                 :         case TBLOCK_ABORT_END:
                               4022                 :         case TBLOCK_SUBABORT_END:
 6779 tgl                      4023                 :         case TBLOCK_ABORT_PENDING:
 6830                          4024                 :         case TBLOCK_SUBABORT_PENDING:
                               4025                 :         case TBLOCK_SUBRESTART:
                               4026                 :         case TBLOCK_SUBABORT_RESTART:
                               4027                 :         case TBLOCK_PREPARE:
 6856 tgl                      4028 UIC           0 :             elog(FATAL, "EndTransactionBlock: unexpected state %s",
                               4029                 :                  BlockStateAsString(s->blockState));
 6943 bruce                    4030 EUB             :             break;
 9345                          4031                 :     }
                               4032                 : 
 1477 peter                    4033 GIC        6163 :     Assert(s->blockState == TBLOCK_STARTED ||
                               4034                 :            s->blockState == TBLOCK_END ||
                               4035                 :            s->blockState == TBLOCK_ABORT_END ||
                               4036                 :            s->blockState == TBLOCK_ABORT_PENDING);
 1477 peter                    4037 EUB             : 
 1477 peter                    4038 GIC        6163 :     s->chain = chain;
                               4039                 : 
 6830 tgl                      4040            6163 :     return result;
                               4041                 : }
                               4042                 : 
                               4043                 : /*
                               4044                 :  *  UserAbortTransactionBlock
                               4045                 :  *      This executes a ROLLBACK command.
                               4046                 :  *
                               4047                 :  * As above, we don't actually do anything here except change blockState.
                               4048                 :  */
                               4049                 : void
 1477 peter                    4050 GBC        1160 : UserAbortTransactionBlock(bool chain)
                               4051                 : {
 9345 bruce                    4052 GIC        1160 :     TransactionState s = CurrentTransactionState;
                               4053                 : 
 6830 tgl                      4054            1160 :     switch (s->blockState)
 6830 tgl                      4055 ECB             :     {
                               4056                 :             /*
                               4057                 :              * We are inside a transaction block and we got a ROLLBACK command
                               4058                 :              * from the user, so tell CommitTransactionCommand to abort and
                               4059                 :              * exit the transaction block.
                               4060                 :              */
 6779 tgl                      4061 GIC         797 :         case TBLOCK_INPROGRESS:
 6779 tgl                      4062 CBC         797 :             s->blockState = TBLOCK_ABORT_PENDING;
 6856 tgl                      4063 GIC         797 :             break;
                               4064                 : 
                               4065                 :             /*
                               4066                 :              * We are inside a failed transaction block and we got a ROLLBACK
                               4067                 :              * command from the user.  Abort processing is already done, so
                               4068                 :              * CommitTransactionCommand just has to cleanup and go back to
                               4069                 :              * idle state.
                               4070                 :              */
 6779                          4071             274 :         case TBLOCK_ABORT:
 6779 tgl                      4072 CBC         274 :             s->blockState = TBLOCK_ABORT_END;
 6856 tgl                      4073 GIC         274 :             break;
 6856 tgl                      4074 ECB             : 
                               4075                 :             /*
 3260 bruce                    4076                 :              * We are inside a subtransaction.  Mark everything up to top
                               4077                 :              * level as exitable.
                               4078                 :              */
 6856 tgl                      4079 GIC          50 :         case TBLOCK_SUBINPROGRESS:
                               4080                 :         case TBLOCK_SUBABORT:
 6779                          4081             203 :             while (s->parent != NULL)
                               4082                 :             {
 6779 tgl                      4083 CBC         153 :                 if (s->blockState == TBLOCK_SUBINPROGRESS)
                               4084             143 :                     s->blockState = TBLOCK_SUBABORT_PENDING;
                               4085              10 :                 else if (s->blockState == TBLOCK_SUBABORT)
 6779 tgl                      4086 GIC          10 :                     s->blockState = TBLOCK_SUBABORT_END;
                               4087                 :                 else
 6779 tgl                      4088 UIC           0 :                     elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
                               4089                 :                          BlockStateAsString(s->blockState));
 6779 tgl                      4090 GIC         153 :                 s = s->parent;
                               4091                 :             }
                               4092              50 :             if (s->blockState == TBLOCK_INPROGRESS)
 6779 tgl                      4093 CBC          50 :                 s->blockState = TBLOCK_ABORT_PENDING;
 6779 tgl                      4094 LBC           0 :             else if (s->blockState == TBLOCK_ABORT)
                               4095               0 :                 s->blockState = TBLOCK_ABORT_END;
                               4096                 :             else
 6779 tgl                      4097 UIC           0 :                 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
                               4098                 :                      BlockStateAsString(s->blockState));
 6856 tgl                      4099 GIC          50 :             break;
                               4100                 : 
 6856 tgl                      4101 ECB             :             /*
                               4102                 :              * The user issued ABORT when not inside a transaction.  For
 1309 peter                    4103                 :              * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
                               4104                 :              * The upcoming call to CommitTransactionCommand() will then put
                               4105                 :              * us back into the default state.  For ROLLBACK AND CHAIN, error.
 2040 tgl                      4106                 :              *
                               4107                 :              * We do the same thing with ABORT inside an implicit transaction,
                               4108                 :              * although in this case we might be rolling back actual database
                               4109                 :              * state changes.  (It's debatable whether we should issue a
 2040 tgl                      4110 EUB             :              * WARNING in this case, but we have done so historically.)
                               4111                 :              */
 6856 tgl                      4112 CBC          39 :         case TBLOCK_STARTED:
                               4113                 :         case TBLOCK_IMPLICIT_INPROGRESS:
 1309 peter                    4114              39 :             if (chain)
                               4115              15 :                 ereport(ERROR,
 1309 peter                    4116 EUB             :                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
 1060 tgl                      4117                 :                 /* translator: %s represents an SQL statement name */
                               4118                 :                          errmsg("%s can only be used in transaction blocks",
 1309 peter                    4119                 :                                 "ROLLBACK AND CHAIN")));
                               4120                 :             else
 1309 peter                    4121 CBC          24 :                 ereport(WARNING,
                               4122                 :                         (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
                               4123                 :                          errmsg("there is no transaction in progress")));
 6779 tgl                      4124 GIC          24 :             s->blockState = TBLOCK_ABORT_PENDING;
 6856                          4125              24 :             break;
                               4126                 : 
                               4127                 :             /*
                               4128                 :              * The user issued an ABORT that somehow ran inside a parallel
                               4129                 :              * worker.  We can't cope with that.
                               4130                 :              */
 2901 rhaas                    4131 UIC           0 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4132               0 :             ereport(FATAL,
                               4133                 :                     (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
 2901 rhaas                    4134 ECB             :                      errmsg("cannot abort during a parallel operation")));
                               4135                 :             break;
                               4136                 : 
 6830 tgl                      4137                 :             /* These cases are invalid. */
 6856 tgl                      4138 UIC           0 :         case TBLOCK_DEFAULT:
                               4139                 :         case TBLOCK_BEGIN:
                               4140                 :         case TBLOCK_SUBBEGIN:
                               4141                 :         case TBLOCK_END:
                               4142                 :         case TBLOCK_SUBRELEASE:
 4282 simon                    4143 ECB             :         case TBLOCK_SUBCOMMIT:
                               4144                 :         case TBLOCK_ABORT_END:
                               4145                 :         case TBLOCK_SUBABORT_END:
 6779 tgl                      4146                 :         case TBLOCK_ABORT_PENDING:
 6830                          4147                 :         case TBLOCK_SUBABORT_PENDING:
                               4148                 :         case TBLOCK_SUBRESTART:
                               4149                 :         case TBLOCK_SUBABORT_RESTART:
                               4150                 :         case TBLOCK_PREPARE:
 6856 tgl                      4151 UIC           0 :             elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
                               4152                 :                  BlockStateAsString(s->blockState));
 6856 tgl                      4153 EUB             :             break;
 9345 bruce                    4154                 :     }
                               4155                 : 
 1477 peter                    4156 GIC        1145 :     Assert(s->blockState == TBLOCK_ABORT_END ||
                               4157                 :            s->blockState == TBLOCK_ABORT_PENDING);
                               4158                 : 
                               4159            1145 :     s->chain = chain;
 6830 tgl                      4160 GBC        1145 : }
                               4161                 : 
                               4162                 : /*
                               4163                 :  * BeginImplicitTransactionBlock
                               4164                 :  *      Start an implicit transaction block if we're not already in one.
                               4165                 :  *
                               4166                 :  * Unlike BeginTransactionBlock, this is called directly from the main loop
                               4167                 :  * in postgres.c, not within a Portal.  So we can just change blockState
                               4168                 :  * without a lot of ceremony.  We do not expect caller to do
                               4169                 :  * CommitTransactionCommand/StartTransactionCommand.
                               4170                 :  */
                               4171                 : void
 2040 tgl                      4172 GIC       58453 : BeginImplicitTransactionBlock(void)
 2040 tgl                      4173 EUB             : {
 2040 tgl                      4174 GIC       58453 :     TransactionState s = CurrentTransactionState;
                               4175                 : 
                               4176                 :     /*
                               4177                 :      * If we are in STARTED state (that is, no transaction block is open),
 2040 tgl                      4178 ECB             :      * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
                               4179                 :      * block.
                               4180                 :      *
                               4181                 :      * For caller convenience, we consider all other transaction states as
                               4182                 :      * legal here; otherwise the caller would need its own state check, which
                               4183                 :      * seems rather pointless.
                               4184                 :      */
 2040 tgl                      4185 GIC       58453 :     if (s->blockState == TBLOCK_STARTED)
                               4186           16191 :         s->blockState = TBLOCK_IMPLICIT_INPROGRESS;
                               4187           58453 : }
                               4188                 : 
                               4189                 : /*
                               4190                 :  * EndImplicitTransactionBlock
                               4191                 :  *      End an implicit transaction block, if we're in one.
                               4192                 :  *
                               4193                 :  * Like EndTransactionBlock, we just make any needed blockState change here.
 2040 tgl                      4194 ECB             :  * The real work will be done in the upcoming CommitTransactionCommand().
                               4195                 :  */
                               4196                 : void
 2040 tgl                      4197 GIC       16170 : EndImplicitTransactionBlock(void)
                               4198                 : {
                               4199           16170 :     TransactionState s = CurrentTransactionState;
                               4200                 : 
                               4201                 :     /*
                               4202                 :      * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
                               4203                 :      * allowing CommitTransactionCommand to commit whatever happened during
                               4204                 :      * the implicit transaction block as though it were a single statement.
                               4205                 :      *
                               4206                 :      * For caller convenience, we consider all other transaction states as
 2040 tgl                      4207 ECB             :      * legal here; otherwise the caller would need its own state check, which
                               4208                 :      * seems rather pointless.
                               4209                 :      */
 2040 tgl                      4210 GIC       16170 :     if (s->blockState == TBLOCK_IMPLICIT_INPROGRESS)
                               4211           15642 :         s->blockState = TBLOCK_STARTED;
                               4212           16170 : }
                               4213                 : 
                               4214                 : /*
                               4215                 :  * DefineSavepoint
                               4216                 :  *      This executes a SAVEPOINT command.
                               4217                 :  */
                               4218                 : void
 1986 peter_e                  4219 CBC        1353 : DefineSavepoint(const char *name)
                               4220                 : {
 6797 bruce                    4221            1353 :     TransactionState s = CurrentTransactionState;
                               4222                 : 
                               4223                 :     /*
                               4224                 :      * Workers synchronize transaction state at the beginning of each parallel
                               4225                 :      * operation, so we can't account for new subtransactions after that
                               4226                 :      * point.  (Note that this check will certainly error out if s->blockState
                               4227                 :      * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
                               4228                 :      * below.)
                               4229                 :      */
 2901 rhaas                    4230 GIC        1353 :     if (IsInParallelMode())
 2901 rhaas                    4231 UIC           0 :         ereport(ERROR,
 2901 rhaas                    4232 ECB             :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
 2118 tgl                      4233                 :                  errmsg("cannot define savepoints during a parallel operation")));
 2901 rhaas                    4234                 : 
 6830 tgl                      4235 GIC        1353 :     switch (s->blockState)
                               4236                 :     {
                               4237            1347 :         case TBLOCK_INPROGRESS:
                               4238                 :         case TBLOCK_SUBINPROGRESS:
                               4239                 :             /* Normal subtransaction start */
                               4240            1347 :             PushTransaction();
 2118 tgl                      4241 CBC        1347 :             s = CurrentTransactionState;    /* changed by push */
                               4242                 : 
 6830 tgl                      4243 ECB             :             /*
                               4244                 :              * Savepoint names, like the TransactionState block itself, live
                               4245                 :              * in TopTransactionContext.
                               4246                 :              */
 6779 tgl                      4247 GIC        1347 :             if (name)
                               4248             999 :                 s->name = MemoryContextStrdup(TopTransactionContext, name);
 6830                          4249            1347 :             break;
                               4250                 : 
                               4251                 :             /*
 2040 tgl                      4252 ECB             :              * We disallow savepoint commands in implicit transaction blocks.
 2040 tgl                      4253 EUB             :              * There would be no great difficulty in allowing them so far as
                               4254                 :              * this module is concerned, but a savepoint seems inconsistent
                               4255                 :              * with exec_simple_query's behavior of abandoning the whole query
                               4256                 :              * string upon error.  Also, the point of an implicit transaction
 2040 tgl                      4257 ECB             :              * block (as opposed to a regular one) is to automatically close
                               4258                 :              * after an error, so it's hard to see how a savepoint would fit
                               4259                 :              * into that.
                               4260                 :              *
                               4261                 :              * The error messages for this are phrased as if there were no
                               4262                 :              * active transaction block at all, which is historical but
                               4263                 :              * perhaps could be improved.
                               4264                 :              */
 2040 tgl                      4265 GIC           6 :         case TBLOCK_IMPLICIT_INPROGRESS:
                               4266               6 :             ereport(ERROR,
                               4267                 :                     (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
                               4268                 :             /* translator: %s represents an SQL statement name */
 2040 tgl                      4269 ECB             :                      errmsg("%s can only be used in transaction blocks",
                               4270                 :                             "SAVEPOINT")));
                               4271                 :             break;
                               4272                 : 
                               4273                 :             /* These cases are invalid. */
 6830 tgl                      4274 UIC           0 :         case TBLOCK_DEFAULT:
                               4275                 :         case TBLOCK_STARTED:
                               4276                 :         case TBLOCK_BEGIN:
                               4277                 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4278                 :         case TBLOCK_SUBBEGIN:
                               4279                 :         case TBLOCK_END:
                               4280                 :         case TBLOCK_SUBRELEASE:
                               4281                 :         case TBLOCK_SUBCOMMIT:
                               4282                 :         case TBLOCK_ABORT:
                               4283                 :         case TBLOCK_SUBABORT:
                               4284                 :         case TBLOCK_ABORT_END:
                               4285                 :         case TBLOCK_SUBABORT_END:
                               4286                 :         case TBLOCK_ABORT_PENDING:
 6830 tgl                      4287 ECB             :         case TBLOCK_SUBABORT_PENDING:
 6779                          4288                 :         case TBLOCK_SUBRESTART:
                               4289                 :         case TBLOCK_SUBABORT_RESTART:
                               4290                 :         case TBLOCK_PREPARE:
 6826 tgl                      4291 UIC           0 :             elog(FATAL, "DefineSavepoint: unexpected state %s",
                               4292                 :                  BlockStateAsString(s->blockState));
                               4293                 :             break;
                               4294                 :     }
 6830 tgl                      4295 GIC        1347 : }
 6830 tgl                      4296 EUB             : 
                               4297                 : /*
                               4298                 :  * ReleaseSavepoint
                               4299                 :  *      This executes a RELEASE command.
                               4300                 :  *
                               4301                 :  * As above, we don't actually do anything here except change blockState.
                               4302                 :  */
                               4303                 : void
 1878 peter_e                  4304 GIC         138 : ReleaseSavepoint(const char *name)
                               4305                 : {
 6797 bruce                    4306             138 :     TransactionState s = CurrentTransactionState;
                               4307                 :     TransactionState target,
                               4308                 :                 xact;
                               4309                 : 
                               4310                 :     /*
                               4311                 :      * Workers synchronize transaction state at the beginning of each parallel
                               4312                 :      * operation, so we can't account for transaction state change after that
 2901 rhaas                    4313 EUB             :      * point.  (Note that this check will certainly error out if s->blockState
                               4314                 :      * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
                               4315                 :      * below.)
                               4316                 :      */
 2901 rhaas                    4317 CBC         138 :     if (IsInParallelMode())
 2901 rhaas                    4318 UIC           0 :         ereport(ERROR,
                               4319                 :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
                               4320                 :                  errmsg("cannot release savepoints during a parallel operation")));
                               4321                 : 
 6830 tgl                      4322 GIC         138 :     switch (s->blockState)
                               4323                 :     {
                               4324                 :             /*
                               4325                 :              * We can't release a savepoint if there is no savepoint defined.
 6779 tgl                      4326 ECB             :              */
 6830 tgl                      4327 UIC           0 :         case TBLOCK_INPROGRESS:
 6830 tgl                      4328 LBC           0 :             ereport(ERROR,
                               4329                 :                     (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
                               4330                 :                      errmsg("savepoint \"%s\" does not exist", name)));
                               4331                 :             break;
                               4332                 : 
 2040 tgl                      4333 GIC           3 :         case TBLOCK_IMPLICIT_INPROGRESS:
                               4334                 :             /* See comment about implicit transactions in DefineSavepoint */
                               4335               3 :             ereport(ERROR,
                               4336                 :                     (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
                               4337                 :             /* translator: %s represents an SQL statement name */
                               4338                 :                      errmsg("%s can only be used in transaction blocks",
 2040 tgl                      4339 ECB             :                             "RELEASE SAVEPOINT")));
 2040 tgl                      4340 EUB             :             break;
                               4341                 : 
                               4342                 :             /*
                               4343                 :              * We are in a non-aborted subtransaction.  This is the only valid
 6385 bruce                    4344 ECB             :              * case.
                               4345                 :              */
 6830 tgl                      4346 GIC         135 :         case TBLOCK_SUBINPROGRESS:
                               4347             135 :             break;
                               4348                 : 
 6779 tgl                      4349 EUB             :             /* These cases are invalid. */
 6830 tgl                      4350 UBC           0 :         case TBLOCK_DEFAULT:
                               4351                 :         case TBLOCK_STARTED:
                               4352                 :         case TBLOCK_BEGIN:
                               4353                 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4354                 :         case TBLOCK_SUBBEGIN:
 6779 tgl                      4355 ECB             :         case TBLOCK_END:
                               4356                 :         case TBLOCK_SUBRELEASE:
 4282 simon                    4357                 :         case TBLOCK_SUBCOMMIT:
                               4358                 :         case TBLOCK_ABORT:
                               4359                 :         case TBLOCK_SUBABORT:
                               4360                 :         case TBLOCK_ABORT_END:
                               4361                 :         case TBLOCK_SUBABORT_END:
                               4362                 :         case TBLOCK_ABORT_PENDING:
                               4363                 :         case TBLOCK_SUBABORT_PENDING:
                               4364                 :         case TBLOCK_SUBRESTART:
                               4365                 :         case TBLOCK_SUBABORT_RESTART:
                               4366                 :         case TBLOCK_PREPARE:
 6830 tgl                      4367 UIC           0 :             elog(FATAL, "ReleaseSavepoint: unexpected state %s",
 6830 tgl                      4368 ECB             :                  BlockStateAsString(s->blockState));
                               4369                 :             break;
                               4370                 :     }
                               4371                 : 
 6801 tgl                      4372 GBC         221 :     for (target = s; PointerIsValid(target); target = target->parent)
                               4373                 :     {
 6830 tgl                      4374 GIC         221 :         if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
                               4375             135 :             break;
                               4376                 :     }
                               4377                 : 
                               4378             135 :     if (!PointerIsValid(target))
 6830 tgl                      4379 UIC           0 :         ereport(ERROR,
                               4380                 :                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
                               4381                 :                  errmsg("savepoint \"%s\" does not exist", name)));
                               4382                 : 
                               4383                 :     /* disallow crossing savepoint level boundaries */
 6801 tgl                      4384 GIC         135 :     if (target->savepointLevel != s->savepointLevel)
 6801 tgl                      4385 UIC           0 :         ereport(ERROR,
                               4386                 :                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
                               4387                 :                  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
                               4388                 : 
 6801 tgl                      4389 EUB             :     /*
                               4390                 :      * Mark "commit pending" all subtransactions up to the target
                               4391                 :      * subtransaction.  The actual commits will happen when control gets to
                               4392                 :      * CommitTransactionCommand.
                               4393                 :      */
 6801 tgl                      4394 CBC         135 :     xact = CurrentTransactionState;
                               4395                 :     for (;;)
 6801 tgl                      4396 ECB             :     {
 6801 tgl                      4397 CBC         221 :         Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
 4282 simon                    4398 GIC         221 :         xact->blockState = TBLOCK_SUBRELEASE;
 6801 tgl                      4399             221 :         if (xact == target)
 6801 tgl                      4400 CBC         135 :             break;
 6801 tgl                      4401 GBC          86 :         xact = xact->parent;
 6801 tgl                      4402 GIC          86 :         Assert(PointerIsValid(xact));
                               4403                 :     }
 6830                          4404             135 : }
                               4405                 : 
 6830 tgl                      4406 ECB             : /*
 6830 tgl                      4407 EUB             :  * RollbackToSavepoint
                               4408                 :  *      This executes a ROLLBACK TO <savepoint> command.
                               4409                 :  *
                               4410                 :  * As above, we don't actually do anything here except change blockState.
                               4411                 :  */
                               4412                 : void
 1878 peter_e                  4413 GIC         354 : RollbackToSavepoint(const char *name)
                               4414                 : {
 6830 tgl                      4415             354 :     TransactionState s = CurrentTransactionState;
 6830 tgl                      4416 ECB             :     TransactionState target,
                               4417                 :                 xact;
                               4418                 : 
 2901 rhaas                    4419                 :     /*
                               4420                 :      * Workers synchronize transaction state at the beginning of each parallel
                               4421                 :      * operation, so we can't account for transaction state change after that
                               4422                 :      * point.  (Note that this check will certainly error out if s->blockState
                               4423                 :      * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
                               4424                 :      * below.)
                               4425                 :      */
 2901 rhaas                    4426 CBC         354 :     if (IsInParallelMode())
 2901 rhaas                    4427 UIC           0 :         ereport(ERROR,
                               4428                 :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
                               4429                 :                  errmsg("cannot rollback to savepoints during a parallel operation")));
                               4430                 : 
 6830 tgl                      4431 GIC         354 :     switch (s->blockState)
                               4432                 :     {
                               4433                 :             /*
                               4434                 :              * We can't rollback to a savepoint if there is no savepoint
 6797 bruce                    4435 ECB             :              * defined.
                               4436                 :              */
 6830 tgl                      4437 CBC           3 :         case TBLOCK_INPROGRESS:
                               4438                 :         case TBLOCK_ABORT:
 6830 tgl                      4439 GIC           3 :             ereport(ERROR,
                               4440                 :                     (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
                               4441                 :                      errmsg("savepoint \"%s\" does not exist", name)));
                               4442                 :             break;
                               4443                 : 
 2040                          4444               3 :         case TBLOCK_IMPLICIT_INPROGRESS:
                               4445                 :             /* See comment about implicit transactions in DefineSavepoint */
                               4446               3 :             ereport(ERROR,
                               4447                 :                     (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
 2040 tgl                      4448 ECB             :             /* translator: %s represents an SQL statement name */
 2040 tgl                      4449 EUB             :                      errmsg("%s can only be used in transaction blocks",
                               4450                 :                             "ROLLBACK TO SAVEPOINT")));
                               4451                 :             break;
                               4452                 : 
 6830 tgl                      4453 ECB             :             /*
                               4454                 :              * There is at least one savepoint, so proceed.
                               4455                 :              */
 6830 tgl                      4456 GIC         348 :         case TBLOCK_SUBINPROGRESS:
                               4457                 :         case TBLOCK_SUBABORT:
                               4458             348 :             break;
 6830 tgl                      4459 ECB             : 
                               4460                 :             /* These cases are invalid. */
 6830 tgl                      4461 LBC           0 :         case TBLOCK_DEFAULT:
                               4462                 :         case TBLOCK_STARTED:
                               4463                 :         case TBLOCK_BEGIN:
                               4464                 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4465                 :         case TBLOCK_SUBBEGIN:
 6830 tgl                      4466 ECB             :         case TBLOCK_END:
                               4467                 :         case TBLOCK_SUBRELEASE:
 4282 simon                    4468                 :         case TBLOCK_SUBCOMMIT:
                               4469                 :         case TBLOCK_ABORT_END:
                               4470                 :         case TBLOCK_SUBABORT_END:
                               4471                 :         case TBLOCK_ABORT_PENDING:
                               4472                 :         case TBLOCK_SUBABORT_PENDING:
                               4473                 :         case TBLOCK_SUBRESTART:
                               4474                 :         case TBLOCK_SUBABORT_RESTART:
                               4475                 :         case TBLOCK_PREPARE:
 6830 tgl                      4476 UIC           0 :             elog(FATAL, "RollbackToSavepoint: unexpected state %s",
                               4477                 :                  BlockStateAsString(s->blockState));
 6830 tgl                      4478 ECB             :             break;
                               4479                 :     }
                               4480                 : 
 6823 tgl                      4481 GIC         373 :     for (target = s; PointerIsValid(target); target = target->parent)
                               4482                 :     {
 6830 tgl                      4483 GBC         373 :         if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
 6830 tgl                      4484 GIC         348 :             break;
                               4485                 :     }
                               4486                 : 
                               4487             348 :     if (!PointerIsValid(target))
 6830 tgl                      4488 UIC           0 :         ereport(ERROR,
                               4489                 :                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
                               4490                 :                  errmsg("savepoint \"%s\" does not exist", name)));
                               4491                 : 
                               4492                 :     /* disallow crossing savepoint level boundaries */
 6823 tgl                      4493 GIC         348 :     if (target->savepointLevel != s->savepointLevel)
 6823 tgl                      4494 UIC           0 :         ereport(ERROR,
                               4495                 :                 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
                               4496                 :                  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
                               4497                 : 
 6830 tgl                      4498 EUB             :     /*
                               4499                 :      * Mark "abort pending" all subtransactions up to the target
                               4500                 :      * subtransaction.  The actual aborts will happen when control gets to
                               4501                 :      * CommitTransactionCommand.
                               4502                 :      */
 6830 tgl                      4503 CBC         348 :     xact = CurrentTransactionState;
                               4504                 :     for (;;)
 6830 tgl                      4505 ECB             :     {
 6779 tgl                      4506 CBC         373 :         if (xact == target)
 6779 tgl                      4507 GIC         348 :             break;
                               4508              25 :         if (xact->blockState == TBLOCK_SUBINPROGRESS)
 6779 tgl                      4509 CBC          25 :             xact->blockState = TBLOCK_SUBABORT_PENDING;
 6779 tgl                      4510 UBC           0 :         else if (xact->blockState == TBLOCK_SUBABORT)
 6779 tgl                      4511 UIC           0 :             xact->blockState = TBLOCK_SUBABORT_END;
                               4512                 :         else
                               4513               0 :             elog(FATAL, "RollbackToSavepoint: unexpected state %s",
                               4514                 :                  BlockStateAsString(xact->blockState));
 6830 tgl                      4515 CBC          25 :         xact = xact->parent;
 6830 tgl                      4516 GBC          25 :         Assert(PointerIsValid(xact));
                               4517                 :     }
                               4518                 : 
                               4519                 :     /* And mark the target as "restart pending" */
 6779 tgl                      4520 GIC         348 :     if (xact->blockState == TBLOCK_SUBINPROGRESS)
                               4521             252 :         xact->blockState = TBLOCK_SUBRESTART;
                               4522              96 :     else if (xact->blockState == TBLOCK_SUBABORT)
                               4523              96 :         xact->blockState = TBLOCK_SUBABORT_RESTART;
                               4524                 :     else
 6779 tgl                      4525 LBC           0 :         elog(FATAL, "RollbackToSavepoint: unexpected state %s",
                               4526                 :              BlockStateAsString(xact->blockState));
 6830 tgl                      4527 GIC         348 : }
 6830 tgl                      4528 ECB             : 
                               4529                 : /*
 6826                          4530                 :  * BeginInternalSubTransaction
 5793                          4531                 :  *      This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
 2040 tgl                      4532 EUB             :  *      TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_END, and TBLOCK_PREPARE states,
                               4533                 :  *      and therefore it can safely be used in functions that might be called
                               4534                 :  *      when not inside a BEGIN block or when running deferred triggers at
                               4535                 :  *      COMMIT/PREPARE time.  Also, it automatically does
                               4536                 :  *      CommitTransactionCommand/StartTransactionCommand instead of expecting
 2040 tgl                      4537 ECB             :  *      the caller to do it.
 6826                          4538                 :  */
                               4539                 : void
 1986 peter_e                  4540 GIC        7436 : BeginInternalSubTransaction(const char *name)
                               4541                 : {
 6797 bruce                    4542 CBC        7436 :     TransactionState s = CurrentTransactionState;
 6826 tgl                      4543 ECB             : 
 2901 rhaas                    4544                 :     /*
                               4545                 :      * Workers synchronize transaction state at the beginning of each parallel
                               4546                 :      * operation, so we can't account for new subtransactions after that
 2878 bruce                    4547 EUB             :      * point. We might be able to make an exception for the type of
                               4548                 :      * subtransaction established by this function, which is typically used in
 2878 bruce                    4549 ECB             :      * contexts where we're going to release or roll back the subtransaction
                               4550                 :      * before proceeding further, so that no enduring change to the
                               4551                 :      * transaction state occurs. For now, however, we prohibit this case along
                               4552                 :      * with all the others.
                               4553                 :      */
 2901 rhaas                    4554 GIC        7436 :     if (IsInParallelMode())
 2901 rhaas                    4555 UIC           0 :         ereport(ERROR,
                               4556                 :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
                               4557                 :                  errmsg("cannot start subtransactions during a parallel operation")));
                               4558                 : 
 6826 tgl                      4559 GIC        7436 :     switch (s->blockState)
                               4560                 :     {
                               4561            7436 :         case TBLOCK_STARTED:
 6826 tgl                      4562 ECB             :         case TBLOCK_INPROGRESS:
                               4563                 :         case TBLOCK_IMPLICIT_INPROGRESS:
 5793                          4564                 :         case TBLOCK_END:
                               4565                 :         case TBLOCK_PREPARE:
                               4566                 :         case TBLOCK_SUBINPROGRESS:
                               4567                 :             /* Normal subtransaction start */
 6826 tgl                      4568 GIC        7436 :             PushTransaction();
 2118                          4569            7436 :             s = CurrentTransactionState;    /* changed by push */
                               4570                 : 
                               4571                 :             /*
                               4572                 :              * Savepoint names, like the TransactionState block itself, live
                               4573                 :              * in TopTransactionContext.
                               4574                 :              */
 6826                          4575            7436 :             if (name)
 6779 tgl                      4576 CBC         818 :                 s->name = MemoryContextStrdup(TopTransactionContext, name);
 6826 tgl                      4577 GBC        7436 :             break;
                               4578                 : 
                               4579                 :             /* These cases are invalid. */
 6826 tgl                      4580 UIC           0 :         case TBLOCK_DEFAULT:
 6826 tgl                      4581 ECB             :         case TBLOCK_BEGIN:
                               4582                 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4583                 :         case TBLOCK_SUBBEGIN:
                               4584                 :         case TBLOCK_SUBRELEASE:
                               4585                 :         case TBLOCK_SUBCOMMIT:
                               4586                 :         case TBLOCK_ABORT:
                               4587                 :         case TBLOCK_SUBABORT:
                               4588                 :         case TBLOCK_ABORT_END:
                               4589                 :         case TBLOCK_SUBABORT_END:
 6779                          4590                 :         case TBLOCK_ABORT_PENDING:
 6826                          4591                 :         case TBLOCK_SUBABORT_PENDING:
                               4592                 :         case TBLOCK_SUBRESTART:
                               4593                 :         case TBLOCK_SUBABORT_RESTART:
 6826 tgl                      4594 UIC           0 :             elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
                               4595                 :                  BlockStateAsString(s->blockState));
                               4596                 :             break;
 6826 tgl                      4597 ECB             :     }
                               4598                 : 
 6826 tgl                      4599 CBC        7436 :     CommitTransactionCommand();
 6826 tgl                      4600 GIC        7436 :     StartTransactionCommand();
                               4601            7436 : }
 6826 tgl                      4602 EUB             : 
                               4603                 : /*
                               4604                 :  * ReleaseCurrentSubTransaction
                               4605                 :  *
                               4606                 :  * RELEASE (ie, commit) the innermost subtransaction, regardless of its
                               4607                 :  * savepoint name (if any).
                               4608                 :  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
                               4609                 :  */
                               4610                 : void
 6826 tgl                      4611 GIC        3524 : ReleaseCurrentSubTransaction(void)
                               4612                 : {
                               4613            3524 :     TransactionState s = CurrentTransactionState;
                               4614                 : 
                               4615                 :     /*
 2901 rhaas                    4616 EUB             :      * Workers synchronize transaction state at the beginning of each parallel
                               4617                 :      * operation, so we can't account for commit of subtransactions after that
                               4618                 :      * point.  This should not happen anyway.  Code calling this would
                               4619                 :      * typically have called BeginInternalSubTransaction() first, failing
                               4620                 :      * there.
 2901 rhaas                    4621 ECB             :      */
 2901 rhaas                    4622 CBC        3524 :     if (IsInParallelMode())
 2901 rhaas                    4623 LBC           0 :         ereport(ERROR,
                               4624                 :                 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
                               4625                 :                  errmsg("cannot commit subtransactions during a parallel operation")));
                               4626                 : 
 6826 tgl                      4627 GIC        3524 :     if (s->blockState != TBLOCK_SUBINPROGRESS)
 6826 tgl                      4628 UIC           0 :         elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
                               4629                 :              BlockStateAsString(s->blockState));
 6785 tgl                      4630 GIC        3524 :     Assert(s->state == TRANS_INPROGRESS);
 6826                          4631            3524 :     MemoryContextSwitchTo(CurTransactionContext);
 4232 simon                    4632            3524 :     CommitSubTransaction();
 6385 bruce                    4633 CBC        3524 :     s = CurrentTransactionState;    /* changed by pop */
 6785 tgl                      4634 GIC        3524 :     Assert(s->state == TRANS_INPROGRESS);
 6826 tgl                      4635 CBC        3524 : }
                               4636                 : 
                               4637                 : /*
                               4638                 :  * RollbackAndReleaseCurrentSubTransaction
                               4639                 :  *
                               4640                 :  * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
                               4641                 :  * of its savepoint name (if any).
                               4642                 :  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
                               4643                 :  */
 6830 tgl                      4644 ECB             : void
 6826 tgl                      4645 GBC        3912 : RollbackAndReleaseCurrentSubTransaction(void)
                               4646                 : {
 6826 tgl                      4647 GIC        3912 :     TransactionState s = CurrentTransactionState;
                               4648                 : 
 2901 rhaas                    4649 ECB             :     /*
 2901 rhaas                    4650 EUB             :      * Unlike ReleaseCurrentSubTransaction(), this is nominally permitted
                               4651                 :      * during parallel operations.  That's because we may be in the leader,
 2901 rhaas                    4652 ECB             :      * recovering from an error thrown while we were in parallel mode.  We
                               4653                 :      * won't reach here in a worker, because BeginInternalSubTransaction()
                               4654                 :      * will have failed.
                               4655                 :      */
                               4656                 : 
 6826 tgl                      4657 CBC        3912 :     switch (s->blockState)
                               4658                 :     {
                               4659                 :             /* Must be in a subtransaction */
 6826 tgl                      4660 GIC        3912 :         case TBLOCK_SUBINPROGRESS:
                               4661                 :         case TBLOCK_SUBABORT:
                               4662            3912 :             break;
                               4663                 : 
                               4664                 :             /* These cases are invalid. */
 6826 tgl                      4665 UIC           0 :         case TBLOCK_DEFAULT:
                               4666                 :         case TBLOCK_STARTED:
 6826 tgl                      4667 ECB             :         case TBLOCK_BEGIN:
                               4668                 :         case TBLOCK_IMPLICIT_INPROGRESS:
 2901 rhaas                    4669                 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4670                 :         case TBLOCK_SUBBEGIN:
                               4671                 :         case TBLOCK_INPROGRESS:
                               4672                 :         case TBLOCK_END:
                               4673                 :         case TBLOCK_SUBRELEASE:
                               4674                 :         case TBLOCK_SUBCOMMIT:
                               4675                 :         case TBLOCK_ABORT:
                               4676                 :         case TBLOCK_ABORT_END:
                               4677                 :         case TBLOCK_SUBABORT_END:
                               4678                 :         case TBLOCK_ABORT_PENDING:
 6826 tgl                      4679                 :         case TBLOCK_SUBABORT_PENDING:
                               4680                 :         case TBLOCK_SUBRESTART:
                               4681                 :         case TBLOCK_SUBABORT_RESTART:
 6505                          4682                 :         case TBLOCK_PREPARE:
 6826 tgl                      4683 UIC           0 :             elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
 6826 tgl                      4684 ECB             :                  BlockStateAsString(s->blockState));
                               4685                 :             break;
                               4686                 :     }
 6826 tgl                      4687 EUB             : 
                               4688                 :     /*
                               4689                 :      * Abort the current subtransaction, if needed.
                               4690                 :      */
 6826 tgl                      4691 GIC        3912 :     if (s->blockState == TBLOCK_SUBINPROGRESS)
                               4692            3094 :         AbortSubTransaction();
                               4693                 : 
                               4694                 :     /* And clean it up, too */
 6779                          4695            3912 :     CleanupSubTransaction();
                               4696                 : 
                               4697            3912 :     s = CurrentTransactionState;    /* changed by pop */
  163 peter                    4698 GNC        3912 :     Assert(s->blockState == TBLOCK_SUBINPROGRESS ||
                               4699                 :                 s->blockState == TBLOCK_INPROGRESS ||
                               4700                 :                 s->blockState == TBLOCK_IMPLICIT_INPROGRESS ||
                               4701                 :                 s->blockState == TBLOCK_STARTED);
 9770 scrappy                  4702 GIC        3912 : }
                               4703                 : 
                               4704                 : /*
 7452 bruce                    4705 EUB             :  *  AbortOutOfAnyTransaction
                               4706                 :  *
                               4707                 :  *  This routine is provided for error recovery purposes.  It aborts any
                               4708                 :  *  active transaction or transaction block, leaving the system in a known
                               4709                 :  *  idle state.
                               4710                 :  */
                               4711                 : void
 8202 tgl                      4712 GIC       11758 : AbortOutOfAnyTransaction(void)
 8951 tgl                      4713 ECB             : {
 8951 tgl                      4714 CBC       11758 :     TransactionState s = CurrentTransactionState;
                               4715                 : 
                               4716                 :     /* Ensure we're not running in a doomed memory context */
 2064                          4717           11758 :     AtAbort_Memory();
                               4718                 : 
 8951 tgl                      4719 ECB             :     /*
 6856                          4720                 :      * Get out of any transaction or nested transaction
                               4721                 :      */
                               4722                 :     do
                               4723                 :     {
 6856 tgl                      4724 CBC       11758 :         switch (s->blockState)
                               4725                 :         {
 6856 tgl                      4726 GIC       11392 :             case TBLOCK_DEFAULT:
 3968                          4727           11392 :                 if (s->state == TRANS_DEFAULT)
                               4728                 :                 {
                               4729                 :                     /* Not in a transaction, do nothing */
                               4730                 :                 }
                               4731                 :                 else
                               4732                 :                 {
                               4733                 :                     /*
 3968 tgl                      4734 ECB             :                      * We can get here after an error during transaction start
                               4735                 :                      * (state will be TRANS_START).  Need to clean up the
                               4736                 :                      * incompletely started transaction.  First, adjust the
                               4737                 :                      * low-level state to suppress warning message from
                               4738                 :                      * AbortTransaction.
                               4739                 :                      */
 3968 tgl                      4740 UIC           0 :                     if (s->state == TRANS_START)
                               4741               0 :                         s->state = TRANS_INPROGRESS;
                               4742               0 :                     AbortTransaction();
                               4743               0 :                     CleanupTransaction();
                               4744                 :                 }
 6856 tgl                      4745 GIC       11392 :                 break;
 6856 tgl                      4746 CBC         356 :             case TBLOCK_STARTED:
                               4747                 :             case TBLOCK_BEGIN:
 6856 tgl                      4748 ECB             :             case TBLOCK_INPROGRESS:
 2040                          4749                 :             case TBLOCK_IMPLICIT_INPROGRESS:
                               4750                 :             case TBLOCK_PARALLEL_INPROGRESS:
                               4751                 :             case TBLOCK_END:
                               4752                 :             case TBLOCK_ABORT_PENDING:
                               4753                 :             case TBLOCK_PREPARE:
                               4754                 :                 /* In a transaction, so clean up */
 6856 tgl                      4755 GIC         356 :                 AbortTransaction();
                               4756             356 :                 CleanupTransaction();
                               4757             356 :                 s->blockState = TBLOCK_DEFAULT;
                               4758             356 :                 break;
                               4759              10 :             case TBLOCK_ABORT:
                               4760                 :             case TBLOCK_ABORT_END:
                               4761                 : 
 2064 tgl                      4762 EUB             :                 /*
                               4763                 :                  * AbortTransaction is already done, still need Cleanup.
                               4764                 :                  * However, if we failed partway through running ROLLBACK,
                               4765                 :                  * there will be an active portal running that command, which
                               4766                 :                  * we need to shut down before doing CleanupTransaction.
 2064 tgl                      4767 ECB             :                  */
 2064 tgl                      4768 CBC          10 :                 AtAbort_Portals();
 6856 tgl                      4769 GIC          10 :                 CleanupTransaction();
                               4770              10 :                 s->blockState = TBLOCK_DEFAULT;
                               4771              10 :                 break;
                               4772                 : 
                               4773                 :                 /*
                               4774                 :                  * In a subtransaction, so clean it up and abort parent too
                               4775                 :                  */
 6779 tgl                      4776 UIC           0 :             case TBLOCK_SUBBEGIN:
 6856 tgl                      4777 ECB             :             case TBLOCK_SUBINPROGRESS:
 4282 simon                    4778                 :             case TBLOCK_SUBRELEASE:
                               4779                 :             case TBLOCK_SUBCOMMIT:
 6830 tgl                      4780                 :             case TBLOCK_SUBABORT_PENDING:
 6779                          4781                 :             case TBLOCK_SUBRESTART:
 6856 tgl                      4782 UIC           0 :                 AbortSubTransaction();
                               4783               0 :                 CleanupSubTransaction();
 6797 bruce                    4784               0 :                 s = CurrentTransactionState;    /* changed by pop */
 6856 tgl                      4785               0 :                 break;
                               4786                 : 
                               4787               0 :             case TBLOCK_SUBABORT:
                               4788                 :             case TBLOCK_SUBABORT_END:
                               4789                 :             case TBLOCK_SUBABORT_RESTART:
 6856 tgl                      4790 ECB             :                 /* As above, but AbortSubTransaction already done */
 2064 tgl                      4791 LBC           0 :                 if (s->curTransactionOwner)
 2064 tgl                      4792 ECB             :                 {
                               4793                 :                     /* As in TBLOCK_ABORT, might have a live portal to zap */
 2064 tgl                      4794 UIC           0 :                     AtSubAbort_Portals(s->subTransactionId,
                               4795               0 :                                        s->parent->subTransactionId,
                               4796                 :                                        s->curTransactionOwner,
                               4797               0 :                                        s->parent->curTransactionOwner);
 2064 tgl                      4798 EUB             :                 }
 6856 tgl                      4799 UIC           0 :                 CleanupSubTransaction();
 6797 bruce                    4800               0 :                 s = CurrentTransactionState;    /* changed by pop */
 6856 tgl                      4801               0 :                 break;
                               4802                 :         }
 6856 tgl                      4803 GIC       11758 :     } while (s->blockState != TBLOCK_DEFAULT);
 8720 bruce                    4804 EUB             : 
 6856 tgl                      4805                 :     /* Should be out of all subxacts now */
 6856 tgl                      4806 GBC       11758 :     Assert(s->parent == NULL);
 2064 tgl                      4807 EUB             : 
                               4808                 :     /* If we didn't actually have anything to do, revert to TopMemoryContext */
 2064 tgl                      4809 GBC       11758 :     AtCleanup_Memory();
 8951 tgl                      4810 GIC       11758 : }
                               4811                 : 
                               4812                 : /*
 7288 tgl                      4813 EUB             :  * IsTransactionBlock --- are we within a transaction block?
                               4814                 :  */
                               4815                 : bool
 8202 tgl                      4816 GBC      346442 : IsTransactionBlock(void)
 9770 scrappy                  4817 EUB             : {
 9345 bruce                    4818 GIC      346442 :     TransactionState s = CurrentTransactionState;
 9345 bruce                    4819 EUB             : 
 6943 bruce                    4820 GIC      346442 :     if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
 7288 tgl                      4821 GBC      279465 :         return false;
 9345 bruce                    4822 EUB             : 
 7288 tgl                      4823 GBC       66977 :     return true;
                               4824                 : }
 7288 tgl                      4825 ECB             : 
                               4826                 : /*
                               4827                 :  * IsTransactionOrTransactionBlock --- are we within either a transaction
 6797 bruce                    4828                 :  * or a transaction block?  (The backend is only really "idle" when this
                               4829                 :  * returns false.)
                               4830                 :  *
 7115 tgl                      4831                 :  * This should match up with IsTransactionBlock and IsTransactionState.
                               4832                 :  */
                               4833                 : bool
 7115 tgl                      4834 GIC      888573 : IsTransactionOrTransactionBlock(void)
                               4835                 : {
                               4836          888573 :     TransactionState s = CurrentTransactionState;
                               4837                 : 
 6943 bruce                    4838 CBC      888573 :     if (s->blockState == TBLOCK_DEFAULT)
 7115 tgl                      4839 GIC      831389 :         return false;
 7115 tgl                      4840 ECB             : 
 7115 tgl                      4841 GIC       57184 :     return true;
 7115 tgl                      4842 ECB             : }
                               4843                 : 
                               4844                 : /*
 7288                          4845                 :  * TransactionBlockStatusCode - return status code to send in ReadyForQuery
                               4846                 :  */
                               4847                 : char
 7288 tgl                      4848 GIC      250115 : TransactionBlockStatusCode(void)
                               4849                 : {
                               4850          250115 :     TransactionState s = CurrentTransactionState;
                               4851                 : 
                               4852          250115 :     switch (s->blockState)
                               4853                 :     {
                               4854          193701 :         case TBLOCK_DEFAULT:
                               4855                 :         case TBLOCK_STARTED:
 7288 tgl                      4856 CBC      193701 :             return 'I';         /* idle --- not in transaction */
 7288 tgl                      4857 GIC       55606 :         case TBLOCK_BEGIN:
 6779 tgl                      4858 ECB             :         case TBLOCK_SUBBEGIN:
                               4859                 :         case TBLOCK_INPROGRESS:
 2040                          4860                 :         case TBLOCK_IMPLICIT_INPROGRESS:
 2901 rhaas                    4861                 :         case TBLOCK_PARALLEL_INPROGRESS:
                               4862                 :         case TBLOCK_SUBINPROGRESS:
 6779 tgl                      4863                 :         case TBLOCK_END:
                               4864                 :         case TBLOCK_SUBRELEASE:
                               4865                 :         case TBLOCK_SUBCOMMIT:
                               4866                 :         case TBLOCK_PREPARE:
 7288 tgl                      4867 GIC       55606 :             return 'T';         /* in transaction */
                               4868             808 :         case TBLOCK_ABORT:
                               4869                 :         case TBLOCK_SUBABORT:
 6779 tgl                      4870 ECB             :         case TBLOCK_ABORT_END:
                               4871                 :         case TBLOCK_SUBABORT_END:
                               4872                 :         case TBLOCK_ABORT_PENDING:
                               4873                 :         case TBLOCK_SUBABORT_PENDING:
                               4874                 :         case TBLOCK_SUBRESTART:
                               4875                 :         case TBLOCK_SUBABORT_RESTART:
 7288 tgl                      4876 CBC         808 :             return 'E';         /* in failed transaction */
                               4877                 :     }
 7288 tgl                      4878 ECB             : 
                               4879                 :     /* should never get here */
 6856 tgl                      4880 UIC           0 :     elog(FATAL, "invalid transaction block state: %s",
                               4881                 :          BlockStateAsString(s->blockState));
                               4882                 :     return 0;                   /* keep compiler quiet */
                               4883                 : }
                               4884                 : 
                               4885                 : /*
                               4886                 :  * IsSubTransaction
                               4887                 :  */
                               4888                 : bool
 6856 tgl                      4889 CBC      824995 : IsSubTransaction(void)
 6856 tgl                      4890 ECB             : {
 6856 tgl                      4891 GIC      824995 :     TransactionState s = CurrentTransactionState;
                               4892                 : 
 6825                          4893          824995 :     if (s->nestingLevel >= 2)
                               4894             489 :         return true;
                               4895                 : 
                               4896          824506 :     return false;
                               4897                 : }
 6856 tgl                      4898 ECB             : 
                               4899                 : /*
                               4900                 :  * StartSubTransaction
                               4901                 :  *
 6779 tgl                      4902 EUB             :  * If you're wondering why this is separate from PushTransaction: it's because
                               4903                 :  * we can't conveniently do this stuff right inside DefineSavepoint.  The
                               4904                 :  * SAVEPOINT utility command will be executed inside a Portal, and if we
                               4905                 :  * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
                               4906                 :  * the Portal will undo those settings.  So we make DefineSavepoint just
                               4907                 :  * push a dummy transaction block, and when control returns to the main
                               4908                 :  * idle loop, CommitTransactionCommand will be called, and we'll come here
                               4909                 :  * to finish starting the subtransaction.
                               4910                 :  */
 6856 tgl                      4911 ECB             : static void
 6856 tgl                      4912 GIC        8783 : StartSubTransaction(void)
 6856 tgl                      4913 ECB             : {
 6856 tgl                      4914 GIC        8783 :     TransactionState s = CurrentTransactionState;
 6856 tgl                      4915 ECB             : 
 6856 tgl                      4916 CBC        8783 :     if (s->state != TRANS_DEFAULT)
 6829 tgl                      4917 UIC           0 :         elog(WARNING, "StartSubTransaction while in %s state",
 6829 tgl                      4918 ECB             :              TransStateAsString(s->state));
                               4919                 : 
 6856 tgl                      4920 GIC        8783 :     s->state = TRANS_START;
                               4921                 : 
                               4922                 :     /*
                               4923                 :      * Initialize subsystems for new subtransaction
                               4924                 :      *
                               4925                 :      * must initialize resource-management stuff first
                               4926                 :      */
 6840                          4927            8783 :     AtSubStart_Memory();
                               4928            8783 :     AtSubStart_ResourceOwner();
 6785                          4929            8783 :     AfterTriggerBeginSubXact();
                               4930                 : 
 6856                          4931            8783 :     s->state = TRANS_INPROGRESS;
                               4932                 : 
                               4933                 :     /*
 6797 bruce                    4934 ECB             :      * Call start-of-subxact callbacks
                               4935                 :      */
 6779 tgl                      4936 CBC        8783 :     CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
 6779 tgl                      4937 GIC        8783 :                          s->parent->subTransactionId);
 6825 tgl                      4938 ECB             : 
 6856 tgl                      4939 GBC        8783 :     ShowTransactionState("StartSubTransaction");
 6856 tgl                      4940 GIC        8783 : }
                               4941                 : 
 6856 tgl                      4942 ECB             : /*
                               4943                 :  * CommitSubTransaction
                               4944                 :  *
                               4945                 :  *  The caller has to make sure to always reassign CurrentTransactionState
                               4946                 :  *  if it has a local pointer to it after calling this function.
                               4947                 :  */
                               4948                 : static void
 4232 simon                    4949 CBC        4315 : CommitSubTransaction(void)
 6856 tgl                      4950 ECB             : {
 6856 tgl                      4951 CBC        4315 :     TransactionState s = CurrentTransactionState;
                               4952                 : 
                               4953            4315 :     ShowTransactionState("CommitSubTransaction");
                               4954                 : 
 6856 tgl                      4955 GIC        4315 :     if (s->state != TRANS_INPROGRESS)
 6829 tgl                      4956 UIC           0 :         elog(WARNING, "CommitSubTransaction while in %s state",
                               4957                 :              TransStateAsString(s->state));
 6856 tgl                      4958 ECB             : 
 3706                          4959                 :     /* Pre-commit processing goes here */
                               4960                 : 
 3706 tgl                      4961 CBC        4315 :     CallSubXactCallbacks(SUBXACT_EVENT_PRE_COMMIT_SUB, s->subTransactionId,
                               4962            4315 :                          s->parent->subTransactionId);
                               4963                 : 
                               4964                 :     /* If in parallel mode, clean up workers and exit parallel mode. */
 2901 rhaas                    4965 GIC        4315 :     if (IsInParallelMode())
                               4966                 :     {
 2901 rhaas                    4967 UIC           0 :         AtEOSubXact_Parallel(true, s->subTransactionId);
                               4968               0 :         s->parallelModeLevel = 0;
                               4969                 :     }
                               4970                 : 
 3706 tgl                      4971 ECB             :     /* Do the actual "commit", such as it is */
 6856 tgl                      4972 GIC        4315 :     s->state = TRANS_COMMIT;
 6856 tgl                      4973 ECB             : 
                               4974                 :     /* Must CCI to ensure commands of subtransaction are seen as done */
 6856 tgl                      4975 CBC        4315 :     CommandCounterIncrement();
                               4976                 : 
 5050 bruce                    4977 ECB             :     /*
 3260 bruce                    4978 EUB             :      * Prior to 8.4 we marked subcommit in clog at this point.  We now only
                               4979                 :      * perform that step, if required, as part of the atomic update of the
                               4980                 :      * whole transaction tree at top level commit or abort.
                               4981                 :      */
                               4982                 : 
 6856 tgl                      4983 ECB             :     /* Post-commit cleanup */
 1473 tmunro                   4984 CBC        4315 :     if (FullTransactionIdIsValid(s->fullTransactionId))
 5695 tgl                      4985 GIC        2804 :         AtSubCommit_childXids();
 6785                          4986            4315 :     AfterTriggerEndSubXact(true);
 6779 tgl                      4987 CBC        4315 :     AtSubCommit_Portals(s->subTransactionId,
 6779 tgl                      4988 GIC        4315 :                         s->parent->subTransactionId,
  555 tgl                      4989 GBC        4315 :                         s->parent->nestingLevel,
 6825                          4990            4315 :                         s->parent->curTransactionOwner);
 6779 tgl                      4991 GIC        4315 :     AtEOSubXact_LargeObject(true, s->subTransactionId,
                               4992            4315 :                             s->parent->subTransactionId);
 6825                          4993            4315 :     AtSubCommit_Notify();
 6825 tgl                      4994 ECB             : 
 6779 tgl                      4995 GIC        4315 :     CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
                               4996            4315 :                          s->parent->subTransactionId);
 6829 tgl                      4997 ECB             : 
 6840 tgl                      4998 GIC        4315 :     ResourceOwnerRelease(s->curTransactionOwner,
                               4999                 :                          RESOURCE_RELEASE_BEFORE_LOCKS,
                               5000                 :                          true, false);
 6779                          5001            4315 :     AtEOSubXact_RelationCache(true, s->subTransactionId,
                               5002            4315 :                               s->parent->subTransactionId);
 6825                          5003            4315 :     AtEOSubXact_Inval(true);
 6789                          5004            4315 :     AtSubCommit_smgr();
                               5005                 : 
 6779 tgl                      5006 ECB             :     /*
                               5007                 :      * The only lock we actually release here is the subtransaction XID lock.
                               5008                 :      */
 6779 tgl                      5009 CBC        4315 :     CurrentResourceOwner = s->curTransactionOwner;
 1473 tmunro                   5010            4315 :     if (FullTransactionIdIsValid(s->fullTransactionId))
                               5011            2804 :         XactLockTableDelete(XidFromFullTransactionId(s->fullTransactionId));
 6779 tgl                      5012 ECB             : 
 4282 simon                    5013                 :     /*
                               5014                 :      * Other locks should get transferred to their parent resource owner.
                               5015                 :      */
 6801 tgl                      5016 GIC        4315 :     ResourceOwnerRelease(s->curTransactionOwner,
 6801 tgl                      5017 ECB             :                          RESOURCE_RELEASE_LOCKS,
 4232 simon                    5018                 :                          true, false);
 6840 tgl                      5019 GIC        4315 :     ResourceOwnerRelease(s->curTransactionOwner,
 6840 tgl                      5020 ECB             :                          RESOURCE_RELEASE_AFTER_LOCKS,
                               5021                 :                          true, false);
                               5022                 : 
 5697 tgl                      5023 CBC        4315 :     AtEOXact_GUC(true, s->gucNestLevel);
 6779                          5024            4315 :     AtEOSubXact_SPI(true, s->subTransactionId);
                               5025            4315 :     AtEOSubXact_on_commit_actions(true, s->subTransactionId,
                               5026            4315 :                                   s->parent->subTransactionId);
 6779 tgl                      5027 GIC        4315 :     AtEOSubXact_Namespace(true, s->subTransactionId,
                               5028            4315 :                           s->parent->subTransactionId);
                               5029            4315 :     AtEOSubXact_Files(true, s->subTransactionId,
                               5030            4315 :                       s->parent->subTransactionId);
 5827 tgl                      5031 CBC        4315 :     AtEOSubXact_HashTables(true, s->nestingLevel);
 5796                          5032            4315 :     AtEOSubXact_PgStat(true, s->nestingLevel);
 5445 alvherre                 5033            4315 :     AtSubCommit_Snapshot(s->nestingLevel);
                               5034                 : 
                               5035                 :     /*
                               5036                 :      * We need to restore the upper transaction's read-only state, in case the
                               5037                 :      * upper is read-write while the child is read-only; GUC will incorrectly
 6385 bruce                    5038 ECB             :      * think it should leave the child state in place.
                               5039                 :      */
 6829 tgl                      5040 GIC        4315 :     XactReadOnly = s->prevXactReadOnly;
 6829 tgl                      5041 ECB             : 
 6840 tgl                      5042 GIC        4315 :     CurrentResourceOwner = s->parent->curTransactionOwner;
                               5043            4315 :     CurTransactionResourceOwner = s->parent->curTransactionOwner;
 6801                          5044            4315 :     ResourceOwnerDelete(s->curTransactionOwner);
 6840 tgl                      5045 CBC        4315 :     s->curTransactionOwner = NULL;
 6840 tgl                      5046 ECB             : 
 6856 tgl                      5047 CBC        4315 :     AtSubCommit_Memory();
 6856 tgl                      5048 ECB             : 
 6856 tgl                      5049 CBC        4315 :     s->state = TRANS_DEFAULT;
 6779 tgl                      5050 ECB             : 
 6779 tgl                      5051 CBC        4315 :     PopTransaction();
 6856                          5052            4315 : }
 6856 tgl                      5053 ECB             : 
                               5054                 : /*
                               5055                 :  * AbortSubTransaction
                               5056                 :  */
                               5057                 : static void
 6856 tgl                      5058 GIC        4468 : AbortSubTransaction(void)
                               5059                 : {
                               5060            4468 :     TransactionState s = CurrentTransactionState;
                               5061                 : 
 5981 tgl                      5062 ECB             :     /* Prevent cancel/die interrupt while cleaning up */
 6856 tgl                      5063 GIC        4468 :     HOLD_INTERRUPTS();
 6856 tgl                      5064 ECB             : 
 5981                          5065                 :     /* Make sure we have a valid memory context and resource owner */
 5981 tgl                      5066 CBC        4468 :     AtSubAbort_Memory();
                               5067            4468 :     AtSubAbort_ResourceOwner();
                               5068                 : 
 6856 tgl                      5069 ECB             :     /*
                               5070                 :      * Release any LW locks we might be holding as quickly as possible.
                               5071                 :      * (Regular locks, however, must be held till we finish aborting.)
                               5072                 :      * Releasing LW locks is critical since we might try to grab them again
 6385 bruce                    5073                 :      * while cleaning up!
 6856 tgl                      5074                 :      *
                               5075                 :      * FIXME This may be incorrect --- Are there some locks we should keep?
                               5076                 :      * Buffer locks, for example?  I don't think so but I'm not sure.
                               5077                 :      */
 6856 tgl                      5078 GIC        4468 :     LWLockReleaseAll();
                               5079                 : 
 2586 rhaas                    5080 CBC        4468 :     pgstat_report_wait_end();
 2586 rhaas                    5081 GIC        4468 :     pgstat_progress_end_command();
 6856 tgl                      5082            4468 :     UnlockBuffers();
                               5083                 : 
 3062 heikki.linnakangas       5084 ECB             :     /* Reset WAL record construction state */
 3062 heikki.linnakangas       5085 GIC        4468 :     XLogResetInsertion();
                               5086                 : 
 1935 rhaas                    5087 ECB             :     /* Cancel condition variable sleep */
 1935 rhaas                    5088 CBC        4468 :     ConditionVariableCancelSleep();
                               5089                 : 
                               5090                 :     /*
                               5091                 :      * Also clean up any open wait for lock, since the lock manager will choke
                               5092                 :      * if we try to wait for another lock before doing this.
                               5093                 :      */
 4008 rhaas                    5094 GIC        4468 :     LockErrorCleanup();
                               5095                 : 
                               5096                 :     /*
                               5097                 :      * If any timeout events are still active, make sure the timeout interrupt
                               5098                 :      * is scheduled.  This covers possible loss of a timeout interrupt due to
 3418 tgl                      5099 ECB             :      * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
                               5100                 :      * We delay this till after LockErrorCleanup so that we don't uselessly
                               5101                 :      * reschedule lock or deadlock check timeouts.
                               5102                 :      */
 3418 tgl                      5103 CBC        4468 :     reschedule_timeouts();
                               5104                 : 
                               5105                 :     /*
 3418 tgl                      5106 ECB             :      * Re-enable signals, in case we got here by longjmp'ing out of a signal
                               5107                 :      * handler.  We do this fairly early in the sequence so that the timeout
                               5108                 :      * infrastructure will be functional if needed while aborting.
                               5109                 :      */
   65 tmunro                   5110 GNC        4468 :     sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
                               5111                 : 
                               5112                 :     /*
                               5113                 :      * check the current transaction state
                               5114                 :      */
 5981 tgl                      5115 CBC        4468 :     ShowTransactionState("AbortSubTransaction");
                               5116                 : 
 5981 tgl                      5117 GIC        4468 :     if (s->state != TRANS_INPROGRESS)
 5981 tgl                      5118 UIC           0 :         elog(WARNING, "AbortSubTransaction while in %s state",
                               5119                 :              TransStateAsString(s->state));
                               5120                 : 
 5981 tgl                      5121 GIC        4468 :     s->state = TRANS_ABORT;
                               5122                 : 
                               5123                 :     /*
 5050 bruce                    5124 ECB             :      * Reset user ID which might have been changed transiently.  (See notes in
                               5125                 :      * AbortTransaction.)
                               5126                 :      */
 4869 tgl                      5127 GIC        4468 :     SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
                               5128                 : 
                               5129                 :     /* Forget about any active REINDEX. */
 1083                          5130            4468 :     ResetReindexState(s->nestingLevel);
 1083 tgl                      5131 ECB             : 
                               5132                 :     /* Reset logical streaming state. */
  974 akapila                  5133 GIC        4468 :     ResetLogicalStreamingState();
                               5134                 : 
                               5135                 :     /*
  538 michael                  5136 ECB             :      * No need for SnapBuildResetExportedSnapshotState() here, snapshot
                               5137                 :      * exports are not supported in subtransactions.
                               5138                 :      */
  538 michael                  5139 EUB             : 
                               5140                 :     /* Exit from parallel mode, if necessary. */
 2901 rhaas                    5141 GIC        4468 :     if (IsInParallelMode())
 2901 rhaas                    5142 ECB             :     {
 2901 rhaas                    5143 GIC           3 :         AtEOSubXact_Parallel(false, s->subTransactionId);
                               5144               3 :         s->parallelModeLevel = 0;
                               5145                 :     }
                               5146                 : 
                               5147                 :     /*
 6385 bruce                    5148 ECB             :      * We can skip all this stuff if the subxact failed before creating a
                               5149                 :      * ResourceOwner...
                               5150                 :      */
 6779 tgl                      5151 CBC        4468 :     if (s->curTransactionOwner)
                               5152                 :     {
 6779 tgl                      5153 GIC        4468 :         AfterTriggerEndSubXact(false);
 6779 tgl                      5154 CBC        4468 :         AtSubAbort_Portals(s->subTransactionId,
 6779 tgl                      5155 GIC        4468 :                            s->parent->subTransactionId,
                               5156                 :                            s->curTransactionOwner,
                               5157            4468 :                            s->parent->curTransactionOwner);
                               5158            4468 :         AtEOSubXact_LargeObject(false, s->subTransactionId,
                               5159            4468 :                                 s->parent->subTransactionId);
                               5160            4468 :         AtSubAbort_Notify();
                               5161                 : 
 2214 rhaas                    5162 ECB             :         /* Advertise the fact that we aborted in pg_xact. */
 5692 tgl                      5163 GIC        4468 :         (void) RecordTransactionAbort(true);
 5695 tgl                      5164 ECB             : 
                               5165                 :         /* Post-abort cleanup */
 1473 tmunro                   5166 GIC        4468 :         if (FullTransactionIdIsValid(s->fullTransactionId))
 6779 tgl                      5167             610 :             AtSubAbort_childXids();
                               5168                 : 
                               5169            4468 :         CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
                               5170            4468 :                              s->parent->subTransactionId);
                               5171                 : 
 6779 tgl                      5172 CBC        4468 :         ResourceOwnerRelease(s->curTransactionOwner,
                               5173                 :                              RESOURCE_RELEASE_BEFORE_LOCKS,
 6779 tgl                      5174 ECB             :                              false, false);
 6779 tgl                      5175 CBC        4468 :         AtEOSubXact_RelationCache(false, s->subTransactionId,
                               5176            4468 :                                   s->parent->subTransactionId);
 6779 tgl                      5177 GIC        4468 :         AtEOSubXact_Inval(false);
 6779 tgl                      5178 CBC        4468 :         ResourceOwnerRelease(s->curTransactionOwner,
 6779 tgl                      5179 ECB             :                              RESOURCE_RELEASE_LOCKS,
                               5180                 :                              false, false);
 6779 tgl                      5181 CBC        4468 :         ResourceOwnerRelease(s->curTransactionOwner,
                               5182                 :                              RESOURCE_RELEASE_AFTER_LOCKS,
                               5183                 :                              false, false);
 3951 rhaas                    5184            4468 :         AtSubAbort_smgr();
                               5185                 : 
 5697 tgl                      5186 GIC        4468 :         AtEOXact_GUC(false, s->gucNestLevel);
 6779 tgl                      5187 CBC        4468 :         AtEOSubXact_SPI(false, s->subTransactionId);
                               5188            4468 :         AtEOSubXact_on_commit_actions(false, s->subTransactionId,
 6779 tgl                      5189 GIC        4468 :                                       s->parent->subTransactionId);
 6779 tgl                      5190 CBC        4468 :         AtEOSubXact_Namespace(false, s->subTransactionId,
                               5191            4468 :                               s->parent->subTransactionId);
 6779 tgl                      5192 GIC        4468 :         AtEOSubXact_Files(false, s->subTransactionId,
 6779 tgl                      5193 CBC        4468 :                           s->parent->subTransactionId);
 5827 tgl                      5194 GIC        4468 :         AtEOSubXact_HashTables(false, s->nestingLevel);
 5796                          5195            4468 :         AtEOSubXact_PgStat(false, s->nestingLevel);
 5445 alvherre                 5196 CBC        4468 :         AtSubAbort_Snapshot(s->nestingLevel);
 6779 tgl                      5197 ECB             :     }
 6856                          5198                 : 
 6829                          5199                 :     /*
                               5200                 :      * Restore the upper transaction's read-only state, too.  This should be
                               5201                 :      * redundant with GUC's cleanup but we may as well do it for consistency
 6385 bruce                    5202                 :      * with the commit case.
                               5203                 :      */
 6829 tgl                      5204 GIC        4468 :     XactReadOnly = s->prevXactReadOnly;
 6829 tgl                      5205 ECB             : 
 6856 tgl                      5206 GIC        4468 :     RESUME_INTERRUPTS();
 6856 tgl                      5207 CBC        4468 : }
 6856 tgl                      5208 ECB             : 
                               5209                 : /*
                               5210                 :  * CleanupSubTransaction
 6779                          5211                 :  *
                               5212                 :  *  The caller has to make sure to always reassign CurrentTransactionState
                               5213                 :  *  if it has a local pointer to it after calling this function.
 6856                          5214                 :  */
                               5215                 : static void
 6856 tgl                      5216 CBC        4468 : CleanupSubTransaction(void)
 6856 tgl                      5217 ECB             : {
 6856 tgl                      5218 GIC        4468 :     TransactionState s = CurrentTransactionState;
                               5219                 : 
                               5220            4468 :     ShowTransactionState("CleanupSubTransaction");
                               5221                 : 
                               5222            4468 :     if (s->state != TRANS_ABORT)
 6829 tgl                      5223 UIC           0 :         elog(WARNING, "CleanupSubTransaction while in %s state",
                               5224                 :              TransStateAsString(s->state));
 6856 tgl                      5225 ECB             : 
 6779 tgl                      5226 GIC        4468 :     AtSubCleanup_Portals(s->subTransactionId);
 6840 tgl                      5227 ECB             : 
 6840 tgl                      5228 CBC        4468 :     CurrentResourceOwner = s->parent->curTransactionOwner;
 6840 tgl                      5229 GIC        4468 :     CurTransactionResourceOwner = s->parent->curTransactionOwner;
 6779                          5230            4468 :     if (s->curTransactionOwner)
                               5231            4468 :         ResourceOwnerDelete(s->curTransactionOwner);
 6840                          5232            4468 :     s->curTransactionOwner = NULL;
                               5233                 : 
 6856                          5234            4468 :     AtSubCleanup_Memory();
                               5235                 : 
                               5236            4468 :     s->state = TRANS_DEFAULT;
 6856 tgl                      5237 ECB             : 
 6779 tgl                      5238 GIC        4468 :     PopTransaction();
 6856 tgl                      5239 CBC        4468 : }
                               5240                 : 
 6856 tgl                      5241 ECB             : /*
                               5242                 :  * PushTransaction
 6779                          5243                 :  *      Create transaction state stack entry for a subtransaction
 6830 tgl                      5244 EUB             :  *
                               5245                 :  *  The caller has to make sure to always reassign CurrentTransactionState
                               5246                 :  *  if it has a local pointer to it after calling this function.
 6856 tgl                      5247 ECB             :  */
                               5248                 : static void
 6856 tgl                      5249 CBC        8783 : PushTransaction(void)
 6856 tgl                      5250 ECB             : {
 6797 bruce                    5251 CBC        8783 :     TransactionState p = CurrentTransactionState;
 6797 bruce                    5252 ECB             :     TransactionState s;
 6856 tgl                      5253                 : 
                               5254                 :     /*
                               5255                 :      * We keep subtransaction state nodes in TopTransactionContext.
                               5256                 :      */
                               5257                 :     s = (TransactionState)
 6856 tgl                      5258 GIC        8783 :         MemoryContextAllocZero(TopTransactionContext,
 6856 tgl                      5259 ECB             :                                sizeof(TransactionStateData));
 6385 bruce                    5260                 : 
                               5261                 :     /*
                               5262                 :      * Assign a subtransaction ID, watching out for counter wraparound.
                               5263                 :      */
 6779 tgl                      5264 GIC        8783 :     currentSubTransactionId += 1;
                               5265            8783 :     if (currentSubTransactionId == InvalidSubTransactionId)
                               5266                 :     {
 6779 tgl                      5267 UIC           0 :         currentSubTransactionId -= 1;
                               5268               0 :         pfree(s);
                               5269               0 :         ereport(ERROR,
 6779 tgl                      5270 ECB             :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                               5271                 :                  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
                               5272                 :     }
                               5273                 : 
                               5274                 :     /*
                               5275                 :      * We can now stack a minimally valid subtransaction without fear of
                               5276                 :      * failure.
                               5277                 :      */
 1473 tmunro                   5278 GIC        8783 :     s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
 6779 tgl                      5279 CBC        8783 :     s->subTransactionId = currentSubTransactionId;
 6856 tgl                      5280 GIC        8783 :     s->parent = p;
                               5281            8783 :     s->nestingLevel = p->nestingLevel + 1;
 5697                          5282            8783 :     s->gucNestLevel = NewGUCNestLevel();
 6830                          5283            8783 :     s->savepointLevel = p->savepointLevel;
 6856                          5284            8783 :     s->state = TRANS_DEFAULT;
 6856 tgl                      5285 CBC        8783 :     s->blockState = TBLOCK_SUBBEGIN;
 4869                          5286            8783 :     GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
 6779 tgl                      5287 GIC        8783 :     s->prevXactReadOnly = XactReadOnly;
 2901 rhaas                    5288 GBC        8783 :     s->parallelModeLevel = 0;
  523 akapila                  5289            8783 :     s->topXidLogged = false;
 6856 tgl                      5290 EUB             : 
 6779 tgl                      5291 GIC        8783 :     CurrentTransactionState = s;
                               5292                 : 
                               5293                 :     /*
                               5294                 :      * AbortSubTransaction and CleanupSubTransaction have to be able to cope
                               5295                 :      * with the subtransaction from here on out; in particular they should not
                               5296                 :      * assume that it necessarily has a transaction context, resource owner,
                               5297                 :      * or XID.
                               5298                 :      */
 6856 tgl                      5299 CBC        8783 : }
 6856 tgl                      5300 ECB             : 
                               5301                 : /*
                               5302                 :  * PopTransaction
                               5303                 :  *      Pop back to parent transaction state
 6830                          5304                 :  *
                               5305                 :  *  The caller has to make sure to always reassign CurrentTransactionState
                               5306                 :  *  if it has a local pointer to it after calling this function.
 6856                          5307                 :  */
                               5308                 : static void
 6856 tgl                      5309 CBC        8783 : PopTransaction(void)
 6856 tgl                      5310 ECB             : {
 6856 tgl                      5311 GIC        8783 :     TransactionState s = CurrentTransactionState;
 6856 tgl                      5312 ECB             : 
 6856 tgl                      5313 GIC        8783 :     if (s->state != TRANS_DEFAULT)
 6829 tgl                      5314 UIC           0 :         elog(WARNING, "PopTransaction while in %s state",
                               5315                 :              TransStateAsString(s->state));
                               5316                 : 
 6856 tgl                      5317 GIC        8783 :     if (s->parent == NULL)
 6856 tgl                      5318 UIC           0 :         elog(FATAL, "PopTransaction with no parent");
                               5319                 : 
 6856 tgl                      5320 CBC        8783 :     CurrentTransactionState = s->parent;
                               5321                 : 
                               5322                 :     /* Let's just make sure CurTransactionContext is good */
 6856 tgl                      5323 GIC        8783 :     CurTransactionContext = s->parent->curTransactionContext;
                               5324            8783 :     MemoryContextSwitchTo(CurTransactionContext);
                               5325                 : 
                               5326                 :     /* Ditto for ResourceOwner links */
 6840                          5327            8783 :     CurTransactionResourceOwner = s->parent->curTransactionOwner;
                               5328            8783 :     CurrentResourceOwner = s->parent->curTransactionOwner;
                               5329                 : 
 6856 tgl                      5330 ECB             :     /* Free the old child structure */
 6830 tgl                      5331 GIC        8783 :     if (s->name)
 6830 tgl                      5332 CBC        1817 :         pfree(s->name);
 6856 tgl                      5333 GIC        8783 :     pfree(s);
 6856 tgl                      5334 CBC        8783 : }
 6856 tgl                      5335 EUB             : 
                               5336                 : /*
                               5337                 :  * EstimateTransactionStateSpace
 2901 rhaas                    5338 ECB             :  *      Estimate the amount of space that will be needed by
 2901 rhaas                    5339 EUB             :  *      SerializeTransactionState.  It would be OK to overestimate slightly,
                               5340                 :  *      but it's simple for us to work out the precise value, so we do.
 2901 rhaas                    5341 ECB             :  */
                               5342                 : Size
 2901 rhaas                    5343 GIC         403 : EstimateTransactionStateSpace(void)
 2901 rhaas                    5344 ECB             : {
                               5345                 :     TransactionState s;
 1473 tmunro                   5346 GIC         403 :     Size        nxids = 0;
                               5347             403 :     Size        size = SerializedTransactionStateHeaderSize;
 2901 rhaas                    5348 ECB             : 
 2901 rhaas                    5349 CBC        2000 :     for (s = CurrentTransactionState; s != NULL; s = s->parent)
                               5350                 :     {
 1473 tmunro                   5351 GIC        1597 :         if (FullTransactionIdIsValid(s->fullTransactionId))
 2901 rhaas                    5352 CBC         893 :             nxids = add_size(nxids, 1);
                               5353            1597 :         nxids = add_size(nxids, s->nChildXids);
 2901 rhaas                    5354 ECB             :     }
                               5355                 : 
 1458 tmunro                   5356 GIC         403 :     return add_size(size, mul_size(sizeof(TransactionId), nxids));
                               5357                 : }
                               5358                 : 
                               5359                 : /*
                               5360                 :  * SerializeTransactionState
                               5361                 :  *      Write out relevant details of our transaction state that will be
                               5362                 :  *      needed by a parallel worker.
                               5363                 :  *
 2901 rhaas                    5364 ECB             :  * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
                               5365                 :  * associated with this transaction.  These are serialized into a
                               5366                 :  * caller-supplied buffer big enough to hold the number of bytes reported by
 1473 tmunro                   5367                 :  * EstimateTransactionStateSpace().  We emit the XIDs in sorted order for the
                               5368                 :  * convenience of the receiving process.
                               5369                 :  */
 2901 rhaas                    5370                 : void
 2901 rhaas                    5371 GIC         403 : SerializeTransactionState(Size maxsize, char *start_address)
 2901 rhaas                    5372 ECB             : {
                               5373                 :     TransactionState s;
 2878 bruce                    5374 CBC         403 :     Size        nxids = 0;
 2878 bruce                    5375 GIC         403 :     Size        i = 0;
                               5376                 :     TransactionId *workspace;
 1473 tmunro                   5377 ECB             :     SerializedTransactionState *result;
                               5378                 : 
 1473 tmunro                   5379 GIC         403 :     result = (SerializedTransactionState *) start_address;
                               5380                 : 
                               5381             403 :     result->xactIsoLevel = XactIsoLevel;
                               5382             403 :     result->xactDeferrable = XactDeferrable;
                               5383             403 :     result->topFullTransactionId = XactTopFullTransactionId;
                               5384             403 :     result->currentFullTransactionId =
                               5385             403 :         CurrentTransactionState->fullTransactionId;
                               5386             403 :     result->currentCommandId = currentCommandId;
                               5387                 : 
                               5388                 :     /*
                               5389                 :      * If we're running in a parallel worker and launching a parallel worker
                               5390                 :      * of our own, we can just pass along the information that was passed to
                               5391                 :      * us.
 2901 rhaas                    5392 ECB             :      */
 2901 rhaas                    5393 GIC         403 :     if (nParallelCurrentXids > 0)
                               5394                 :     {
 1473 tmunro                   5395 LBC           0 :         result->nParallelCurrentXids = nParallelCurrentXids;
                               5396               0 :         memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
                               5397                 :                nParallelCurrentXids * sizeof(TransactionId));
 2901 rhaas                    5398 UIC           0 :         return;
                               5399                 :     }
 2901 rhaas                    5400 ECB             : 
                               5401                 :     /*
 2878 bruce                    5402                 :      * OK, we need to generate a sorted list of XIDs that our workers should
                               5403                 :      * view as current.  First, figure out how many there are.
 2901 rhaas                    5404                 :      */
 2901 rhaas                    5405 CBC        2000 :     for (s = CurrentTransactionState; s != NULL; s = s->parent)
 2901 rhaas                    5406 ECB             :     {
 1473 tmunro                   5407 CBC        1597 :         if (FullTransactionIdIsValid(s->fullTransactionId))
 2901 rhaas                    5408 GIC         893 :             nxids = add_size(nxids, 1);
                               5409            1597 :         nxids = add_size(nxids, s->nChildXids);
                               5410                 :     }
 1473 tmunro                   5411             403 :     Assert(SerializedTransactionStateHeaderSize + nxids * sizeof(TransactionId)
                               5412                 :            <= maxsize);
                               5413                 : 
 2901 rhaas                    5414 ECB             :     /* Copy them to our scratch space. */
 2901 rhaas                    5415 GIC         403 :     workspace = palloc(nxids * sizeof(TransactionId));
 2901 rhaas                    5416 GBC        2000 :     for (s = CurrentTransactionState; s != NULL; s = s->parent)
 2901 rhaas                    5417 EUB             :     {
 1473 tmunro                   5418 GIC        1597 :         if (FullTransactionIdIsValid(s->fullTransactionId))
 1473 tmunro                   5419 GBC         893 :             workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
  402 tgl                      5420 GIC        1597 :         if (s->nChildXids > 0)
  402 tgl                      5421 UIC           0 :             memcpy(&workspace[i], s->childXids,
                               5422               0 :                    s->nChildXids * sizeof(TransactionId));
 2901 rhaas                    5423 GIC        1597 :         i += s->nChildXids;
                               5424                 :     }
                               5425             403 :     Assert(i == nxids);
 2901 rhaas                    5426 ECB             : 
                               5427                 :     /* Sort them. */
 2901 rhaas                    5428 CBC         403 :     qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
 2901 rhaas                    5429 ECB             : 
                               5430                 :     /* Copy data into output area. */
 1473 tmunro                   5431 GIC         403 :     result->nParallelCurrentXids = nxids;
 1473 tmunro                   5432 CBC         403 :     memcpy(&result->parallelCurrentXids[0], workspace,
                               5433                 :            nxids * sizeof(TransactionId));
                               5434                 : }
                               5435                 : 
 2901 rhaas                    5436 ECB             : /*
                               5437                 :  * StartParallelWorkerTransaction
                               5438                 :  *      Start a parallel worker transaction, restoring the relevant
                               5439                 :  *      transaction state serialized by SerializeTransactionState.
                               5440                 :  */
                               5441                 : void
 2901 rhaas                    5442 GBC        1298 : StartParallelWorkerTransaction(char *tstatespace)
 2901 rhaas                    5443 EUB             : {
 1473 tmunro                   5444 ECB             :     SerializedTransactionState *tstate;
                               5445                 : 
 2901 rhaas                    5446 CBC        1298 :     Assert(CurrentTransactionState->blockState == TBLOCK_DEFAULT);
 2901 rhaas                    5447 GIC        1298 :     StartTransaction();
                               5448                 : 
 1473 tmunro                   5449 CBC        1298 :     tstate = (SerializedTransactionState *) tstatespace;
 1473 tmunro                   5450 GIC        1298 :     XactIsoLevel = tstate->xactIsoLevel;
                               5451            1298 :     XactDeferrable = tstate->xactDeferrable;
 1473 tmunro                   5452 CBC        1298 :     XactTopFullTransactionId = tstate->topFullTransactionId;
                               5453            1298 :     CurrentTransactionState->fullTransactionId =
                               5454                 :         tstate->currentFullTransactionId;
 1473 tmunro                   5455 GIC        1298 :     currentCommandId = tstate->currentCommandId;
                               5456            1298 :     nParallelCurrentXids = tstate->nParallelCurrentXids;
                               5457            1298 :     ParallelCurrentXids = &tstate->parallelCurrentXids[0];
                               5458                 : 
 2901 rhaas                    5459            1298 :     CurrentTransactionState->blockState = TBLOCK_PARALLEL_INPROGRESS;
                               5460            1298 : }
                               5461                 : 
                               5462                 : /*
 2901 rhaas                    5463 ECB             :  * EndParallelWorkerTransaction
                               5464                 :  *      End a parallel worker transaction.
                               5465                 :  */
                               5466                 : void
 2901 rhaas                    5467 CBC        1295 : EndParallelWorkerTransaction(void)
 2901 rhaas                    5468 ECB             : {
 2901 rhaas                    5469 GIC        1295 :     Assert(CurrentTransactionState->blockState == TBLOCK_PARALLEL_INPROGRESS);
 2901 rhaas                    5470 CBC        1295 :     CommitTransaction();
                               5471            1295 :     CurrentTransactionState->blockState = TBLOCK_DEFAULT;
                               5472            1295 : }
 2901 rhaas                    5473 ECB             : 
 6856 tgl                      5474                 : /*
                               5475                 :  * ShowTransactionState
                               5476                 :  *      Debug support
                               5477                 :  */
                               5478                 : static void
 6856 tgl                      5479 GIC      972988 : ShowTransactionState(const char *str)
 6856 tgl                      5480 ECB             : {
                               5481                 :     /* skip work if message will definitely not be printed */
  867 tgl                      5482 GIC      972988 :     if (message_level_is_interesting(DEBUG5))
 2334 rhaas                    5483 UIC           0 :         ShowTransactionStateRec(str, CurrentTransactionState);
 6856 tgl                      5484 GIC      972988 : }
                               5485                 : 
                               5486                 : /*
                               5487                 :  * ShowTransactionStateRec
 6856 tgl                      5488 ECB             :  *      Recursive subroutine for ShowTransactionState
                               5489                 :  */
                               5490                 : static void
 2334 rhaas                    5491 LBC           0 : ShowTransactionStateRec(const char *str, TransactionState s)
 6856 tgl                      5492 ECB             : {
 5501                          5493                 :     StringInfoData buf;
                               5494                 : 
 5501 tgl                      5495 UIC           0 :     initStringInfo(&buf);
                               5496                 : 
                               5497               0 :     if (s->nChildXids > 0)
                               5498                 :     {
                               5499                 :         int         i;
 5501 tgl                      5500 ECB             : 
 2334 rhaas                    5501 UIC           0 :         appendStringInfo(&buf, ", children: %u", s->childXids[0]);
 5501 tgl                      5502               0 :         for (i = 1; i < s->nChildXids; i++)
 5501 tgl                      5503 LBC           0 :             appendStringInfo(&buf, " %u", s->childXids[i]);
 5501 tgl                      5504 EUB             :     }
 5501 tgl                      5505 ECB             : 
 6856 tgl                      5506 UIC           0 :     if (s->parent)
 2334 rhaas                    5507               0 :         ShowTransactionStateRec(str, s->parent);
                               5508                 : 
                               5509               0 :     ereport(DEBUG5,
                               5510                 :             (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
                               5511                 :                              str, s->nestingLevel,
 6385 bruce                    5512 EUB             :                              PointerIsValid(s->name) ? s->name : "unnamed",
                               5513                 :                              BlockStateAsString(s->blockState),
                               5514                 :                              TransStateAsString(s->state),
                               5515                 :                              (unsigned int) XidFromFullTransactionId(s->fullTransactionId),
 6779 tgl                      5516                 :                              (unsigned int) s->subTransactionId,
                               5517                 :                              (unsigned int) currentCommandId,
 5609                          5518                 :                              currentCommandIdUsed ? " (used)" : "",
                               5519                 :                              buf.data)));
                               5520                 : 
 5501 tgl                      5521 UIC           0 :     pfree(buf.data);
 6856 tgl                      5522 UBC           0 : }
 6856 tgl                      5523 EUB             : 
                               5524                 : /*
                               5525                 :  * BlockStateAsString
                               5526                 :  *      Debug support
                               5527                 :  */
                               5528                 : static const char *
 6856 tgl                      5529 UIC           0 : BlockStateAsString(TBlockState blockState)
 6856 tgl                      5530 EUB             : {
 6830 tgl                      5531 UIC           0 :     switch (blockState)
                               5532                 :     {
 6856                          5533               0 :         case TBLOCK_DEFAULT:
                               5534               0 :             return "DEFAULT";
                               5535               0 :         case TBLOCK_STARTED:
                               5536               0 :             return "STARTED";
                               5537               0 :         case TBLOCK_BEGIN:
                               5538               0 :             return "BEGIN";
                               5539               0 :         case TBLOCK_INPROGRESS:
                               5540               0 :             return "INPROGRESS";
 2040                          5541               0 :         case TBLOCK_IMPLICIT_INPROGRESS:
 2040 tgl                      5542 UBC           0 :             return "IMPLICIT_INPROGRESS";
 2901 rhaas                    5543               0 :         case TBLOCK_PARALLEL_INPROGRESS:
 2901 rhaas                    5544 UIC           0 :             return "PARALLEL_INPROGRESS";
 6856 tgl                      5545               0 :         case TBLOCK_END:
                               5546               0 :             return "END";
                               5547               0 :         case TBLOCK_ABORT:
                               5548               0 :             return "ABORT";
 6779                          5549               0 :         case TBLOCK_ABORT_END:
 1877 peter_e                  5550 UBC           0 :             return "ABORT_END";
 6779 tgl                      5551 UIC           0 :         case TBLOCK_ABORT_PENDING:
 1877 peter_e                  5552 UBC           0 :             return "ABORT_PENDING";
 6505 tgl                      5553 UIC           0 :         case TBLOCK_PREPARE:
 6505 tgl                      5554 UBC           0 :             return "PREPARE";
 6856                          5555               0 :         case TBLOCK_SUBBEGIN:
 1877 peter_e                  5556               0 :             return "SUBBEGIN";
 6856 tgl                      5557               0 :         case TBLOCK_SUBINPROGRESS:
 1877 peter_e                  5558               0 :             return "SUBINPROGRESS";
 4282 simon                    5559               0 :         case TBLOCK_SUBRELEASE:
 1877 peter_e                  5560               0 :             return "SUBRELEASE";
 4282 simon                    5561               0 :         case TBLOCK_SUBCOMMIT:
 1877 peter_e                  5562               0 :             return "SUBCOMMIT";
 6856 tgl                      5563               0 :         case TBLOCK_SUBABORT:
 1877 peter_e                  5564               0 :             return "SUBABORT";
 6779 tgl                      5565               0 :         case TBLOCK_SUBABORT_END:
 1877 peter_e                  5566               0 :             return "SUBABORT_END";
 6830 tgl                      5567               0 :         case TBLOCK_SUBABORT_PENDING:
 1877 peter_e                  5568               0 :             return "SUBABORT_PENDING";
 6779 tgl                      5569               0 :         case TBLOCK_SUBRESTART:
 1877 peter_e                  5570               0 :             return "SUBRESTART";
 6779 tgl                      5571               0 :         case TBLOCK_SUBABORT_RESTART:
 1877 peter_e                  5572               0 :             return "SUBABORT_RESTART";
 6856 tgl                      5573 EUB             :     }
 6856 tgl                      5574 UBC           0 :     return "UNRECOGNIZED";
 6856 tgl                      5575 EUB             : }
                               5576                 : 
                               5577                 : /*
                               5578                 :  * TransStateAsString
                               5579                 :  *      Debug support
                               5580                 :  */
                               5581                 : static const char *
 6856 tgl                      5582 UBC           0 : TransStateAsString(TransState state)
 6856 tgl                      5583 EUB             : {
 6830 tgl                      5584 UBC           0 :     switch (state)
 6830 tgl                      5585 EUB             :     {
 6856 tgl                      5586 UBC           0 :         case TRANS_DEFAULT:
                               5587               0 :             return "DEFAULT";
                               5588               0 :         case TRANS_START:
                               5589               0 :             return "START";
 6505                          5590               0 :         case TRANS_INPROGRESS:
 1877 peter_e                  5591               0 :             return "INPROGRESS";
 6856 tgl                      5592               0 :         case TRANS_COMMIT:
                               5593               0 :             return "COMMIT";
 6856 tgl                      5594 UIC           0 :         case TRANS_ABORT:
 6856 tgl                      5595 UBC           0 :             return "ABORT";
 6505 tgl                      5596 UIC           0 :         case TRANS_PREPARE:
                               5597               0 :             return "PREPARE";
                               5598                 :     }
 6856                          5599               0 :     return "UNRECOGNIZED";
                               5600                 : }
                               5601                 : 
                               5602                 : /*
 6856 tgl                      5603 EUB             :  * xactGetCommittedChildren
                               5604                 :  *
 3260 bruce                    5605                 :  * Gets the list of committed children of the current transaction.  The return
                               5606                 :  * value is the number of child transactions.  *ptr is set to point to an
 5501 tgl                      5607                 :  * array of TransactionIds.  The array is allocated in TopTransactionContext;
                               5608                 :  * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
                               5609                 :  * If there are no subxacts, *ptr is set to NULL.
 6856                          5610                 :  */
                               5611                 : int
 6840 tgl                      5612 GBC      468793 : xactGetCommittedChildren(TransactionId **ptr)
 6856 tgl                      5613 EUB             : {
 6797 bruce                    5614 GBC      468793 :     TransactionState s = CurrentTransactionState;
 6856 tgl                      5615 EUB             : 
 5501 tgl                      5616 GBC      468793 :     if (s->nChildXids == 0)
 6856                          5617          468159 :         *ptr = NULL;
 5501 tgl                      5618 EUB             :     else
 5501 tgl                      5619 GIC         634 :         *ptr = s->childXids;
 6856 tgl                      5620 EUB             : 
 5501 tgl                      5621 GIC      468793 :     return s->nChildXids;
                               5622                 : }
                               5623                 : 
                               5624                 : /*
                               5625                 :  *  XLOG support routines
                               5626                 :  */
                               5627                 : 
                               5628                 : 
                               5629                 : /*
                               5630                 :  * Log the commit record for a plain or twophase transaction commit.
                               5631                 :  *
                               5632                 :  * A 2pc commit will be emitted when twophase_xid is valid, a plain one
 2947 andres                   5633 ECB             :  * otherwise.
                               5634                 :  */
                               5635                 : XLogRecPtr
 2947 andres                   5636 GIC      293823 : XactLogCommitRecord(TimestampTz commit_time,
 2878 bruce                    5637 ECB             :                     int nsubxacts, TransactionId *subxacts,
                               5638                 :                     int nrels, RelFileLocator *rels,
                               5639                 :                     int ndroppedstats, xl_xact_stats_item *droppedstats,
                               5640                 :                     int nmsgs, SharedInvalidationMessage *msgs,
                               5641                 :                     bool relcacheInval,
 1838 simon                    5642                 :                     int xactflags, TransactionId twophase_xid,
                               5643                 :                     const char *twophase_gid)
                               5644                 : {
                               5645                 :     xl_xact_commit xlrec;
                               5646                 :     xl_xact_xinfo xl_xinfo;
                               5647                 :     xl_xact_dbinfo xl_dbinfo;
                               5648                 :     xl_xact_subxacts xl_subxacts;
                               5649                 :     xl_xact_relfilelocators xl_relfilelocators;
                               5650                 :     xl_xact_stats_items xl_dropped_stats;
                               5651                 :     xl_xact_invals xl_invals;
                               5652                 :     xl_xact_twophase xl_twophase;
                               5653                 :     xl_xact_origin xl_origin;
                               5654                 :     uint8       info;
                               5655                 : 
 2947 andres                   5656 GIC      293823 :     Assert(CritSectionCount > 0);
 2947 andres                   5657 ECB             : 
 2947 andres                   5658 GIC      293823 :     xl_xinfo.xinfo = 0;
                               5659                 : 
                               5660                 :     /* decide between a plain and 2pc commit */
                               5661          293823 :     if (!TransactionIdIsValid(twophase_xid))
                               5662          293498 :         info = XLOG_XACT_COMMIT;
                               5663                 :     else
                               5664             325 :         info = XLOG_XACT_COMMIT_PREPARED;
                               5665                 : 
                               5666                 :     /* First figure out and collect all the information needed */
                               5667                 : 
                               5668          293823 :     xlrec.xact_time = commit_time;
                               5669                 : 
                               5670          293823 :     if (relcacheInval)
                               5671           21924 :         xl_xinfo.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
                               5672          293823 :     if (forceSyncCommit)
                               5673             878 :         xl_xinfo.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
 2209 simon                    5674          293823 :     if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
                               5675          100012 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
                               5676                 : 
 2567 rhaas                    5677 ECB             :     /*
                               5678                 :      * Check if the caller would like to ask standbys for immediate feedback
                               5679                 :      * once this commit is applied.
                               5680                 :      */
 2567 rhaas                    5681 GIC      293823 :     if (synchronous_commit >= SYNCHRONOUS_COMMIT_REMOTE_APPLY)
 2567 rhaas                    5682 LBC           0 :         xl_xinfo.xinfo |= XACT_COMPLETION_APPLY_FEEDBACK;
 2567 rhaas                    5683 ECB             : 
                               5684                 :     /*
 2947 andres                   5685                 :      * Relcache invalidations requires information about the current database
                               5686                 :      * and so does logical decoding.
                               5687                 :      */
 2947 andres                   5688 GIC      293823 :     if (nmsgs > 0 || XLogLogicalInfoActive())
 2947 andres                   5689 ECB             :     {
 2947 andres                   5690 GIC      252963 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
 2947 andres                   5691 CBC      252963 :         xl_dbinfo.dbId = MyDatabaseId;
                               5692          252963 :         xl_dbinfo.tsId = MyDatabaseTableSpace;
 2947 andres                   5693 ECB             :     }
                               5694                 : 
 2947 andres                   5695 CBC      293823 :     if (nsubxacts > 0)
 2947 andres                   5696 ECB             :     {
 2947 andres                   5697 GIC         540 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
                               5698             540 :         xl_subxacts.nsubxacts = nsubxacts;
                               5699                 :     }
                               5700                 : 
                               5701          293823 :     if (nrels > 0)
 2947 andres                   5702 ECB             :     {
  277 rhaas                    5703 GNC        7396 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILELOCATORS;
                               5704            7396 :         xl_relfilelocators.nrels = nrels;
  965 heikki.linnakangas       5705 GIC        7396 :         info |= XLR_SPECIAL_REL_UPDATE;
                               5706                 :     }
                               5707                 : 
  368 andres                   5708          293823 :     if (ndroppedstats > 0)
  368 andres                   5709 ECB             :     {
  368 andres                   5710 GIC        8939 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
  368 andres                   5711 CBC        8939 :         xl_dropped_stats.nitems = ndroppedstats;
  368 andres                   5712 ECB             :     }
                               5713                 : 
 2947 andres                   5714 GIC      293823 :     if (nmsgs > 0)
                               5715                 :     {
 2947 andres                   5716 CBC      251876 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
 2947 andres                   5717 GIC      251876 :         xl_invals.nmsgs = nmsgs;
 2947 andres                   5718 ECB             :     }
                               5719                 : 
 2947 andres                   5720 GIC      293823 :     if (TransactionIdIsValid(twophase_xid))
                               5721                 :     {
 2947 andres                   5722 CBC         325 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
 2947 andres                   5723 GIC         325 :         xl_twophase.xid = twophase_xid;
 1838 simon                    5724 CBC         325 :         Assert(twophase_gid != NULL);
 1838 simon                    5725 ECB             : 
 1838 simon                    5726 CBC         325 :         if (XLogLogicalInfoActive())
 1838 simon                    5727 GIC          49 :             xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
                               5728                 :     }
 2947 andres                   5729 ECB             : 
                               5730                 :     /* dump transaction origin information */
 2750 alvherre                 5731 CBC      293823 :     if (replorigin_session_origin != InvalidRepOriginId)
 2902 andres                   5732 ECB             :     {
 2902 andres                   5733 GIC         851 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
                               5734                 : 
 2750 alvherre                 5735 CBC         851 :         xl_origin.origin_lsn = replorigin_session_origin_lsn;
 2750 alvherre                 5736 GIC         851 :         xl_origin.origin_timestamp = replorigin_session_origin_timestamp;
 2902 andres                   5737 ECB             :     }
                               5738                 : 
 2947 andres                   5739 GIC      293823 :     if (xl_xinfo.xinfo != 0)
                               5740          256562 :         info |= XLOG_XACT_HAS_INFO;
 2947 andres                   5741 ECB             : 
                               5742                 :     /* Then include all the collected data into the commit record. */
                               5743                 : 
 2947 andres                   5744 CBC      293823 :     XLogBeginInsert();
 2947 andres                   5745 ECB             : 
 2947 andres                   5746 GIC      293823 :     XLogRegisterData((char *) (&xlrec), sizeof(xl_xact_commit));
 2947 andres                   5747 ECB             : 
 2947 andres                   5748 CBC      293823 :     if (xl_xinfo.xinfo != 0)
 2947 andres                   5749 GIC      256562 :         XLogRegisterData((char *) (&xl_xinfo.xinfo), sizeof(xl_xinfo.xinfo));
                               5750                 : 
                               5751          293823 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
 2947 andres                   5752 CBC      252963 :         XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
                               5753                 : 
                               5754          293823 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
                               5755                 :     {
                               5756             540 :         XLogRegisterData((char *) (&xl_subxacts),
 2947 andres                   5757 ECB             :                          MinSizeOfXactSubxacts);
 2947 andres                   5758 GIC         540 :         XLogRegisterData((char *) subxacts,
                               5759                 :                          nsubxacts * sizeof(TransactionId));
 2947 andres                   5760 ECB             :     }
                               5761                 : 
  277 rhaas                    5762 GNC      293823 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
                               5763                 :     {
                               5764            7396 :         XLogRegisterData((char *) (&xl_relfilelocators),
                               5765                 :                          MinSizeOfXactRelfileLocators);
 2947 andres                   5766 GIC        7396 :         XLogRegisterData((char *) rels,
                               5767                 :                          nrels * sizeof(RelFileLocator));
                               5768                 :     }
 2947 andres                   5769 ECB             : 
  368 andres                   5770 CBC      293823 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
                               5771                 :     {
                               5772            8939 :         XLogRegisterData((char *) (&xl_dropped_stats),
  368 andres                   5773 ECB             :                          MinSizeOfXactStatsItems);
  368 andres                   5774 GIC        8939 :         XLogRegisterData((char *) droppedstats,
  368 andres                   5775 ECB             :                          ndroppedstats * sizeof(xl_xact_stats_item));
                               5776                 :     }
                               5777                 : 
 2947 andres                   5778 GIC      293823 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
 2947 andres                   5779 ECB             :     {
 2947 andres                   5780 GIC      251876 :         XLogRegisterData((char *) (&xl_invals), MinSizeOfXactInvals);
                               5781          251876 :         XLogRegisterData((char *) msgs,
                               5782                 :                          nmsgs * sizeof(SharedInvalidationMessage));
 2947 andres                   5783 ECB             :     }
                               5784                 : 
 2947 andres                   5785 CBC      293823 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
                               5786                 :     {
                               5787             325 :         XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
 1838 simon                    5788 GIC         325 :         if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
 1531 peter                    5789              49 :             XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
                               5790                 :     }
 2947 andres                   5791 ECB             : 
 2902 andres                   5792 GIC      293823 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
 2902 andres                   5793 CBC         851 :         XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
                               5794                 : 
 2902 andres                   5795 ECB             :     /* we allow filtering by xacts */
 2299 andres                   5796 GIC      293823 :     XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
                               5797                 : 
 2947                          5798          293823 :     return XLogInsert(RM_XACT_ID, info);
 2947 andres                   5799 ECB             : }
                               5800                 : 
                               5801                 : /*
                               5802                 :  * Log the commit record for a plain or twophase transaction abort.
                               5803                 :  *
                               5804                 :  * A 2pc abort will be emitted when twophase_xid is valid, a plain one
                               5805                 :  * otherwise.
                               5806                 :  */
                               5807                 : XLogRecPtr
 2947 andres                   5808 CBC        4818 : XactLogAbortRecord(TimestampTz abort_time,
 2878 bruce                    5809 ECB             :                    int nsubxacts, TransactionId *subxacts,
                               5810                 :                    int nrels, RelFileLocator *rels,
                               5811                 :                    int ndroppedstats, xl_xact_stats_item *droppedstats,
                               5812                 :                    int xactflags, TransactionId twophase_xid,
 1838 simon                    5813                 :                    const char *twophase_gid)
 2947 andres                   5814                 : {
                               5815                 :     xl_xact_abort xlrec;
                               5816                 :     xl_xact_xinfo xl_xinfo;
 2878 bruce                    5817                 :     xl_xact_subxacts xl_subxacts;
                               5818                 :     xl_xact_relfilelocators xl_relfilelocators;
  368 andres                   5819                 :     xl_xact_stats_items xl_dropped_stats;
                               5820                 :     xl_xact_twophase xl_twophase;
                               5821                 :     xl_xact_dbinfo xl_dbinfo;
                               5822                 :     xl_xact_origin xl_origin;
                               5823                 : 
                               5824                 :     uint8       info;
                               5825                 : 
 2947 andres                   5826 GIC        4818 :     Assert(CritSectionCount > 0);
                               5827                 : 
                               5828            4818 :     xl_xinfo.xinfo = 0;
 2947 andres                   5829 ECB             : 
                               5830                 :     /* decide between a plain and 2pc abort */
 2947 andres                   5831 GIC        4818 :     if (!TransactionIdIsValid(twophase_xid))
                               5832            4780 :         info = XLOG_XACT_ABORT;
                               5833                 :     else
                               5834              38 :         info = XLOG_XACT_ABORT_PREPARED;
                               5835                 : 
                               5836                 : 
                               5837                 :     /* First figure out and collect all the information needed */
                               5838                 : 
                               5839            4818 :     xlrec.xact_time = abort_time;
                               5840                 : 
 2209 simon                    5841            4818 :     if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
                               5842            1905 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
                               5843                 : 
 2947 andres                   5844            4818 :     if (nsubxacts > 0)
                               5845                 :     {
                               5846             100 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
 2947 andres                   5847 CBC         100 :         xl_subxacts.nsubxacts = nsubxacts;
                               5848                 :     }
 2947 andres                   5849 ECB             : 
 2947 andres                   5850 GIC        4818 :     if (nrels > 0)
                               5851                 :     {
  277 rhaas                    5852 GNC         697 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILELOCATORS;
                               5853             697 :         xl_relfilelocators.nrels = nrels;
  965 heikki.linnakangas       5854 GIC         697 :         info |= XLR_SPECIAL_REL_UPDATE;
 2947 andres                   5855 ECB             :     }
                               5856                 : 
  368 andres                   5857 GIC        4818 :     if (ndroppedstats > 0)
                               5858                 :     {
                               5859             969 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
  368 andres                   5860 CBC         969 :         xl_dropped_stats.nitems = ndroppedstats;
                               5861                 :     }
  368 andres                   5862 ECB             : 
 2947 andres                   5863 CBC        4818 :     if (TransactionIdIsValid(twophase_xid))
                               5864                 :     {
                               5865              38 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
 2947 andres                   5866 GIC          38 :         xl_twophase.xid = twophase_xid;
 1838 simon                    5867 CBC          38 :         Assert(twophase_gid != NULL);
 1838 simon                    5868 ECB             : 
 1838 simon                    5869 GIC          38 :         if (XLogLogicalInfoActive())
                               5870              16 :             xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
 1838 simon                    5871 ECB             :     }
                               5872                 : 
 1838 simon                    5873 CBC        4818 :     if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
 1838 simon                    5874 ECB             :     {
 1838 simon                    5875 CBC          16 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
 1838 simon                    5876 GIC          16 :         xl_dbinfo.dbId = MyDatabaseId;
                               5877              16 :         xl_dbinfo.tsId = MyDatabaseTableSpace;
 1838 simon                    5878 ECB             :     }
                               5879                 : 
  762 akapila                  5880                 :     /*
                               5881                 :      * Dump transaction origin information. We need this during recovery to
                               5882                 :      * update the replication origin progress.
                               5883                 :      */
   90 akapila                  5884 GNC        4818 :     if (replorigin_session_origin != InvalidRepOriginId)
 1838 simon                    5885 ECB             :     {
 1838 simon                    5886 CBC          38 :         xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
 1838 simon                    5887 ECB             : 
 1838 simon                    5888 GIC          38 :         xl_origin.origin_lsn = replorigin_session_origin_lsn;
 1838 simon                    5889 CBC          38 :         xl_origin.origin_timestamp = replorigin_session_origin_timestamp;
 2947 andres                   5890 ECB             :     }
                               5891                 : 
 2947 andres                   5892 GIC        4818 :     if (xl_xinfo.xinfo != 0)
 2947 andres                   5893 CBC        2386 :         info |= XLOG_XACT_HAS_INFO;
                               5894                 : 
 2947 andres                   5895 ECB             :     /* Then include all the collected data into the abort record. */
                               5896                 : 
 2947 andres                   5897 CBC        4818 :     XLogBeginInsert();
                               5898                 : 
 2947 andres                   5899 GIC        4818 :     XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
                               5900                 : 
                               5901            4818 :     if (xl_xinfo.xinfo != 0)
                               5902            2386 :         XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
                               5903                 : 
 1838 simon                    5904 CBC        4818 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
 1838 simon                    5905 GIC          16 :         XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
 1838 simon                    5906 ECB             : 
 2947 andres                   5907 GIC        4818 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
 2947 andres                   5908 ECB             :     {
 2947 andres                   5909 CBC         100 :         XLogRegisterData((char *) (&xl_subxacts),
                               5910                 :                          MinSizeOfXactSubxacts);
 2947 andres                   5911 GIC         100 :         XLogRegisterData((char *) subxacts,
 2947 andres                   5912 ECB             :                          nsubxacts * sizeof(TransactionId));
                               5913                 :     }
                               5914                 : 
  277 rhaas                    5915 GNC        4818 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
                               5916                 :     {
                               5917             697 :         XLogRegisterData((char *) (&xl_relfilelocators),
                               5918                 :                          MinSizeOfXactRelfileLocators);
 2947 andres                   5919 CBC         697 :         XLogRegisterData((char *) rels,
                               5920                 :                          nrels * sizeof(RelFileLocator));
 2947 andres                   5921 ECB             :     }
                               5922                 : 
  368 andres                   5923 GIC        4818 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
  368 andres                   5924 ECB             :     {
  368 andres                   5925 CBC         969 :         XLogRegisterData((char *) (&xl_dropped_stats),
                               5926                 :                          MinSizeOfXactStatsItems);
                               5927             969 :         XLogRegisterData((char *) droppedstats,
                               5928                 :                          ndroppedstats * sizeof(xl_xact_stats_item));
  368 andres                   5929 ECB             :     }
                               5930                 : 
 2947 andres                   5931 CBC        4818 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
                               5932                 :     {
 2947 andres                   5933 GIC          38 :         XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
 1838 simon                    5934              38 :         if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
 1531 peter                    5935 CBC          16 :             XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
                               5936                 :     }
 1838 simon                    5937 ECB             : 
 1838 simon                    5938 GIC        4818 :     if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
 1838 simon                    5939 CBC          38 :         XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
                               5940                 : 
                               5941                 :     /* Include the replication origin */
   90 akapila                  5942 GNC        4818 :     XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
 2947 andres                   5943 ECB             : 
 2947 andres                   5944 GIC        4818 :     return XLogInsert(RM_XACT_ID, info);
 2947 andres                   5945 ECB             : }
                               5946                 : 
 4859 simon                    5947                 : /*
                               5948                 :  * Before 9.0 this was a fairly short function, but now it performs many
                               5949                 :  * actions for which the order of execution is critical.
                               5950                 :  */
 6505 tgl                      5951                 : static void
 2947 andres                   5952 GIC       18923 : xact_redo_commit(xl_xact_parsed_commit *parsed,
 2947 andres                   5953 ECB             :                  TransactionId xid,
 2902                          5954                 :                  XLogRecPtr lsn,
                               5955                 :                  RepOriginId origin_id)
                               5956                 : {
                               5957                 :     TransactionId max_xid;
 2878 bruce                    5958                 :     TimestampTz commit_time;
 6505 tgl                      5959                 : 
 2125 alvherre                 5960 GIC       18923 :     Assert(TransactionIdIsValid(xid));
                               5961                 : 
 2947 andres                   5962 CBC       18923 :     max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
                               5963                 : 
  971 andres                   5964 ECB             :     /* Make sure nextXid is beyond any XID mentioned in the record. */
 1473 tmunro                   5965 GIC       18923 :     AdvanceNextFullTransactionIdPastXid(max_xid);
                               5966                 : 
 2569 andres                   5967           18923 :     Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
                               5968                 :            (origin_id == InvalidRepOriginId));
                               5969                 : 
 2902                          5970           18923 :     if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
                               5971              24 :         commit_time = parsed->origin_timestamp;
 2902 andres                   5972 ECB             :     else
 2902 andres                   5973 GIC       18899 :         commit_time = parsed->xact_time;
                               5974                 : 
                               5975                 :     /* Set the transaction commit timestamp and metadata */
 2947                          5976           18923 :     TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
                               5977                 :                                    commit_time, origin_id);
                               5978                 : 
 4714 simon                    5979           18923 :     if (standbyState == STANDBY_DISABLED)
 4859 simon                    5980 ECB             :     {
                               5981                 :         /*
 2214 rhaas                    5982                 :          * Mark the transaction committed in pg_xact.
                               5983                 :          */
 2947 andres                   5984 GIC        2153 :         TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
 4859 simon                    5985 ECB             :     }
                               5986                 :     else
                               5987                 :     {
                               5988                 :         /*
                               5989                 :          * If a transaction completion record arrives that has as-yet
 4808 tgl                      5990                 :          * unobserved subtransactions then this will not have been fully
                               5991                 :          * handled by the call to RecordKnownAssignedTransactionIds() in the
                               5992                 :          * main recovery loop in xlog.c. So we need to do bookkeeping again to
                               5993                 :          * cover that case. This is confusing and it is easy to think this
                               5994                 :          * call is irrelevant, which has happened three times in development
                               5995                 :          * already. Leave it in.
 4859 simon                    5996                 :          */
 4859 simon                    5997 GIC       16770 :         RecordKnownAssignedTransactionIds(max_xid);
                               5998                 : 
 4859 simon                    5999 ECB             :         /*
                               6000                 :          * Mark the transaction committed in pg_xact. We use async commit
                               6001                 :          * protocol during recovery to provide information on database
                               6002                 :          * consistency for when users try to set hint bits. It is important
                               6003                 :          * that we do not set hint bits until the minRecoveryPoint is past
 4790 bruce                    6004                 :          * this commit record. This ensures that if we crash we don't see hint
                               6005                 :          * bits set on changes made by transactions that haven't yet
                               6006                 :          * recovered. It's unlikely but it's good to be safe.
                               6007                 :          */
 1165 alvherre                 6008 GIC       16770 :         TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
                               6009                 : 
                               6010                 :         /*
                               6011                 :          * We must mark clog before we update the ProcArray.
                               6012                 :          */
                               6013           16770 :         ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
                               6014                 : 
                               6015                 :         /*
                               6016                 :          * Send any cache invalidations attached to the commit. We must
 4790 bruce                    6017 ECB             :          * maintain the same order of invalidation then release locks as
                               6018                 :          * occurs in CommitTransaction().
                               6019                 :          */
 1165 alvherre                 6020 GIC       16770 :         ProcessCommittedInvalidationMessages(parsed->msgs, parsed->nmsgs,
 2118 tgl                      6021           16770 :                                              XactCompletionRelcacheInitFileInval(parsed->xinfo),
                               6022                 :                                              parsed->dbId, parsed->tsId);
                               6023                 : 
                               6024                 :         /*
                               6025                 :          * Release locks, if any. We do this for both two phase and normal one
                               6026                 :          * phase transactions. In effect we are ignoring the prepare phase and
                               6027                 :          * just going straight to lock release.
 4859 simon                    6028 ECB             :          */
 2209 simon                    6029 GIC       16770 :         if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
 1758                          6030            8063 :             StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
                               6031                 :     }
                               6032                 : 
 2902 andres                   6033 CBC       18923 :     if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
                               6034                 :     {
                               6035                 :         /* recover apply progress */
 2902 andres                   6036 GIC          24 :         replorigin_advance(origin_id, parsed->origin_lsn, lsn,
                               6037                 :                            false /* backward */ , false /* WAL */ );
                               6038                 :     }
                               6039                 : 
 6505 tgl                      6040 ECB             :     /* Make sure files supposed to be dropped are dropped */
 2947 andres                   6041 CBC       18923 :     if (parsed->nrels > 0)
                               6042                 :     {
                               6043                 :         /*
                               6044                 :          * First update minimum recovery point to cover this WAL record. Once
                               6045                 :          * a relation is deleted, there's no going back. The buffer manager
                               6046                 :          * enforces the WAL-first rule for normal updates to relation files,
                               6047                 :          * so that the minimum recovery point is always updated before the
                               6048                 :          * corresponding change in the data file is flushed to disk, but we
 3772 heikki.linnakangas       6049 ECB             :          * have to do the same here since we're bypassing the buffer manager.
                               6050                 :          *
                               6051                 :          * Doing this before deleting the files means that if a deletion fails
                               6052                 :          * for some reason, you cannot start up the system even after restart,
                               6053                 :          * until you fix the underlying situation so that the deletion will
                               6054                 :          * succeed. Alternatively, we could update the minimum recovery point
                               6055                 :          * after deletion, but that would leave a small window where the
                               6056                 :          * WAL-first rule would be violated.
                               6057                 :          */
 3772 heikki.linnakangas       6058 GIC        1629 :         XLogFlush(lsn);
                               6059                 : 
                               6060                 :         /* Make sure files supposed to be dropped are dropped */
  277 rhaas                    6061 GNC        1629 :         DropRelationFiles(parsed->xlocators, parsed->nrels, true);
                               6062                 :     }
                               6063                 : 
  368 andres                   6064 GIC       18923 :     if (parsed->nstats > 0)
                               6065                 :     {
                               6066                 :         /* see equivalent call for relations above */
                               6067            2192 :         XLogFlush(lsn);
                               6068                 : 
                               6069            2192 :         pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
                               6070                 :     }
                               6071                 : 
                               6072                 :     /*
                               6073                 :      * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
                               6074                 :      * in normal operation. For example, in CREATE DATABASE, we copy all files
                               6075                 :      * from the template database, and then commit the transaction. If we
                               6076                 :      * crash after all the files have been copied but before the commit, you
                               6077                 :      * have files in the data directory without an entry in pg_database. To
 3602 bruce                    6078 ECB             :      * minimize the window for that, we use ForceSyncCommit() to rush the
                               6079                 :      * commit record to disk as quick as possible. We have the same window
                               6080                 :      * during recovery, and forcing an XLogFlush() (which updates
                               6081                 :      * minRecoveryPoint during recovery) helps to reduce that problem window,
                               6082                 :      * for any user that requested ForceSyncCommit().
                               6083                 :      */
 2947 andres                   6084 CBC       18923 :     if (XactCompletionForceSyncCommit(parsed->xinfo))
 4859 simon                    6085 GIC          39 :         XLogFlush(lsn);
                               6086                 : 
 2567 rhaas                    6087 ECB             :     /*
                               6088                 :      * If asked by the primary (because someone is waiting for a synchronous
 2495                          6089                 :      * commit = remote_apply), we will need to ask walreceiver to send a reply
                               6090                 :      * immediately.
                               6091                 :      */
 2567 rhaas                    6092 GIC       18923 :     if (XactCompletionApplyFeedback(parsed->xinfo))
 2567 rhaas                    6093 UIC           0 :         XLogRequestWalReceiverReply();
 4303 simon                    6094 GIC       18923 : }
                               6095                 : 
                               6096                 : /*
                               6097                 :  * Be careful with the order of execution, as with xact_redo_commit().
                               6098                 :  * The two functions are similar but differ in key places.
                               6099                 :  *
                               6100                 :  * Note also that an abort can be for a subtransaction and its children,
                               6101                 :  * not just for a top level abort. That means we have to consider
                               6102                 :  * topxid != xid, whereas in commit we would find topxid == xid always
                               6103                 :  * because subtransaction commit is never WAL logged.
 4859 simon                    6104 ECB             :  */
 6505 tgl                      6105                 : static void
  762 akapila                  6106 GIC        1429 : xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid,
                               6107                 :                 XLogRecPtr lsn, RepOriginId origin_id)
                               6108                 : {
                               6109                 :     TransactionId max_xid;
                               6110                 : 
 2125 alvherre                 6111            1429 :     Assert(TransactionIdIsValid(xid));
 2125 alvherre                 6112 ECB             : 
  971 andres                   6113 EUB             :     /* Make sure nextXid is beyond any XID mentioned in the record. */
 2947 andres                   6114 CBC        1429 :     max_xid = TransactionIdLatest(xid,
                               6115                 :                                   parsed->nsubxacts,
 2947 andres                   6116 GIC        1429 :                                   parsed->subxacts);
 1473 tmunro                   6117            1429 :     AdvanceNextFullTransactionIdPastXid(max_xid);
                               6118                 : 
 4714 simon                    6119            1429 :     if (standbyState == STANDBY_DISABLED)
                               6120                 :     {
                               6121                 :         /* Mark the transaction aborted in pg_xact, no need for async stuff */
 2947 andres                   6122              20 :         TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
                               6123                 :     }
                               6124                 :     else
                               6125                 :     {
 4859 simon                    6126 ECB             :         /*
                               6127                 :          * If a transaction completion record arrives that has as-yet
                               6128                 :          * unobserved subtransactions then this will not have been fully
                               6129                 :          * handled by the call to RecordKnownAssignedTransactionIds() in the
                               6130                 :          * main recovery loop in xlog.c. So we need to do bookkeeping again to
 4790 bruce                    6131                 :          * cover that case. This is confusing and it is easy to think this
                               6132                 :          * call is irrelevant, which has happened three times in development
                               6133                 :          * already. Leave it in.
 4859 simon                    6134                 :          */
 4859 simon                    6135 GIC        1409 :         RecordKnownAssignedTransactionIds(max_xid);
 4859 simon                    6136 ECB             : 
 2214 rhaas                    6137                 :         /* Mark the transaction aborted in pg_xact, no need for async stuff */
 2947 andres                   6138 GIC        1409 :         TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
 4859 simon                    6139 ECB             : 
                               6140                 :         /*
                               6141                 :          * We must update the ProcArray after we have marked clog.
                               6142                 :          */
 1165 alvherre                 6143 GIC        1409 :         ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
                               6144                 : 
                               6145                 :         /*
                               6146                 :          * There are no invalidation messages to send or undo.
                               6147                 :          */
                               6148                 : 
                               6149                 :         /*
                               6150                 :          * Release locks, if any. There are no invalidations to send.
                               6151                 :          */
 2209 simon                    6152            1409 :         if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
                               6153             863 :             StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
                               6154                 :     }
 6505 tgl                      6155 ECB             : 
  762 akapila                  6156 GIC        1429 :     if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
                               6157                 :     {
  762 akapila                  6158 ECB             :         /* recover apply progress */
  762 akapila                  6159 GIC           5 :         replorigin_advance(origin_id, parsed->origin_lsn, lsn,
                               6160                 :                            false /* backward */ , false /* WAL */ );
                               6161                 :     }
                               6162                 : 
 6505 tgl                      6163 ECB             :     /* Make sure files supposed to be dropped are dropped */
  619 fujii                    6164 GIC        1429 :     if (parsed->nrels > 0)
                               6165                 :     {
                               6166                 :         /*
                               6167                 :          * See comments about update of minimum recovery point on truncation,
                               6168                 :          * in xact_redo_commit().
                               6169                 :          */
                               6170             221 :         XLogFlush(lsn);
                               6171                 : 
  277 rhaas                    6172 GNC         221 :         DropRelationFiles(parsed->xlocators, parsed->nrels, true);
  619 fujii                    6173 ECB             :     }
                               6174                 : 
  368 andres                   6175 GIC        1429 :     if (parsed->nstats > 0)
  368 andres                   6176 ECB             :     {
                               6177                 :         /* see equivalent call for relations above */
  368 andres                   6178 GIC         295 :         XLogFlush(lsn);
  368 andres                   6179 ECB             : 
  368 andres                   6180 GIC         295 :         pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
                               6181                 :     }
 6505 tgl                      6182            1429 : }
                               6183                 : 
 8206 vadim4o                  6184 ECB             : void
 3062 heikki.linnakangas       6185 GIC       20638 : xact_redo(XLogReaderState *record)
                               6186                 : {
 2947 andres                   6187           20638 :     uint8       info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
                               6188                 : 
                               6189                 :     /* Backup blocks are not used in xact records */
 3062 heikki.linnakangas       6190 CBC       20638 :     Assert(!XLogRecHasAnyBlockRefs(record));
                               6191                 : 
 2125 alvherre                 6192           20638 :     if (info == XLOG_XACT_COMMIT)
                               6193                 :     {
 6997 tgl                      6194 GIC       18884 :         xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
 2947 andres                   6195 ECB             :         xl_xact_parsed_commit parsed;
                               6196                 : 
 2125 alvherre                 6197 GIC       18884 :         ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
 2125 alvherre                 6198 CBC       18884 :         xact_redo_commit(&parsed, XLogRecGetXid(record),
 2125 alvherre                 6199 GIC       18884 :                          record->EndRecPtr, XLogRecGetOrigin(record));
 2125 alvherre                 6200 ECB             :     }
 2125 alvherre                 6201 GIC        1754 :     else if (info == XLOG_XACT_COMMIT_PREPARED)
 2125 alvherre                 6202 ECB             :     {
 2125 alvherre                 6203 GIC          39 :         xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
                               6204                 :         xl_xact_parsed_commit parsed;
 6997 tgl                      6205 ECB             : 
 2125 alvherre                 6206 GIC          39 :         ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
 2125 alvherre                 6207 CBC          39 :         xact_redo_commit(&parsed, parsed.twophase_xid,
 2125 alvherre                 6208 GIC          39 :                          record->EndRecPtr, XLogRecGetOrigin(record));
                               6209                 : 
 2125 alvherre                 6210 ECB             :         /* Delete TwoPhaseState gxact entry and/or 2PC file. */
 2125 alvherre                 6211 GIC          39 :         LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
 2125 alvherre                 6212 CBC          39 :         PrepareRedoRemove(parsed.twophase_xid, false);
 2125 alvherre                 6213 GIC          39 :         LWLockRelease(TwoPhaseStateLock);
 6505 tgl                      6214 ECB             :     }
 2125 alvherre                 6215 GIC        1715 :     else if (info == XLOG_XACT_ABORT)
                               6216                 :     {
 6505 tgl                      6217 CBC        1410 :         xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
 2947 andres                   6218 ECB             :         xl_xact_parsed_abort parsed;
                               6219                 : 
 2125 alvherre                 6220 GIC        1410 :         ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
  762 akapila                  6221 CBC        1410 :         xact_redo_abort(&parsed, XLogRecGetXid(record),
  762 akapila                  6222 GIC        1410 :                         record->EndRecPtr, XLogRecGetOrigin(record));
 2125 alvherre                 6223 ECB             :     }
 2125 alvherre                 6224 GIC         305 :     else if (info == XLOG_XACT_ABORT_PREPARED)
                               6225                 :     {
 2125 alvherre                 6226 CBC          19 :         xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
 2125 alvherre                 6227 ECB             :         xl_xact_parsed_abort parsed;
 6796 tgl                      6228                 : 
 2125 alvherre                 6229 GIC          19 :         ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
  762 akapila                  6230              19 :         xact_redo_abort(&parsed, parsed.twophase_xid,
  762 akapila                  6231 CBC          19 :                         record->EndRecPtr, XLogRecGetOrigin(record));
 2196 simon                    6232 ECB             : 
 2125 alvherre                 6233                 :         /* Delete TwoPhaseState gxact entry and/or 2PC file. */
 2125 alvherre                 6234 GIC          19 :         LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
 2125 alvherre                 6235 CBC          19 :         PrepareRedoRemove(parsed.twophase_xid, false);
 2125 alvherre                 6236 GIC          19 :         LWLockRelease(TwoPhaseStateLock);
 6505 tgl                      6237 ECB             :     }
 6505 tgl                      6238 GIC         286 :     else if (info == XLOG_XACT_PREPARE)
                               6239                 :     {
 2196 simon                    6240 ECB             :         /*
 2153 bruce                    6241                 :          * Store xid and start/end pointers of the WAL record in TwoPhaseState
                               6242                 :          * gxact entry.
                               6243                 :          */
 2125 alvherre                 6244 CBC          69 :         LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
 2196 simon                    6245 GIC          69 :         PrepareRedoAdd(XLogRecGetData(record),
 2196 simon                    6246 ECB             :                        record->ReadRecPtr,
                               6247                 :                        record->EndRecPtr,
 1838 simon                    6248 GIC          69 :                        XLogRecGetOrigin(record));
 2125 alvherre                 6249 CBC          69 :         LWLockRelease(TwoPhaseStateLock);
 6505 tgl                      6250 ECB             :     }
 4859 simon                    6251 CBC         217 :     else if (info == XLOG_XACT_ASSIGNMENT)
                               6252                 :     {
 4859 simon                    6253 GIC          21 :         xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
 4859 simon                    6254 ECB             : 
 4714 simon                    6255 CBC          21 :         if (standbyState >= STANDBY_INITIALIZED)
 4859                          6256              21 :             ProcArrayApplyXidAssignment(xlrec->xtop,
 4859 simon                    6257 GIC          21 :                                         xlrec->nsubxacts, xlrec->xsub);
 4859 simon                    6258 ECB             :     }
  990 akapila                  6259 GIC         196 :     else if (info == XLOG_XACT_INVALIDATIONS)
                               6260                 :     {
                               6261                 :         /*
                               6262                 :          * XXX we do ignore this for now, what matters are invalidations
                               6263                 :          * written into the commit record.
  990 akapila                  6264 ECB             :          */
                               6265                 :     }
                               6266                 :     else
 6505 tgl                      6267 UIC           0 :         elog(PANIC, "xact_redo: unknown op code %u", info);
 6505 tgl                      6268 CBC       20638 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a