LCOV - differential code coverage report
Current view: top level - src/backend/access/transam - xact.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: c38de3ae6098ccf1904109f2e550eb4777f66024 vs e352ac8c5c90ed6ce792f044c22145578542a330 Lines: 87.7 % 1921 1684 237 4 1680 4
Current Date: 2026-11-05 14:14:01 +0100 Functions: 93.6 % 110 103 7 4 99
Baseline: lcov-20261105-baseline Branches: 63.1 % 1094 690 404 690
Baseline Date: 2026-11-05 14:14:01 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(1,7] days: 100.0 % 2 2 2
(7,30] days: 100.0 % 2 2 2
(30,360] days: 97.1 % 35 34 1 2 32
(360..) days: 87.5 % 1882 1646 236 1646
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 93.6 % 109 102 7 4 98
Branch coverage date bins:
(30,360] days: 86.4 % 22 19 3 19
(360..) days: 62.6 % 1072 671 401 671

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

Generated by: LCOV version 2.0-1