aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xact.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xact.c')
-rw-r--r--src/backend/access/transam/xact.c2014
1 files changed, 1022 insertions, 992 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 5ac4a42c7c7..da32570d87b 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -1,138 +1,138 @@
/*-------------------------------------------------------------------------
*
* xact.c--
- * top level transaction system support routines
+ * top level transaction system support routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.13 1997/08/29 09:02:11 vadim Exp $
- *
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.14 1997/09/07 04:39:38 momjian Exp $
+ *
* NOTES
- * Transaction aborts can now occur two ways:
+ * Transaction aborts can now occur two ways:
*
- * 1) system dies from some internal cause (Assert, etc..)
- * 2) user types abort
+ * 1) system dies from some internal cause (Assert, etc..)
+ * 2) user types abort
*
- * These two cases used to be treated identically, but now
- * we need to distinguish them. Why? consider the following
- * two situatuons:
+ * These two cases used to be treated identically, but now
+ * we need to distinguish them. Why? consider the following
+ * two situatuons:
*
- * case 1 case 2
- * ------ ------
- * 1) user types BEGIN 1) user types BEGIN
- * 2) user does something 2) user does something
- * 3) user does not like what 3) system aborts for some reason
- * she shes and types ABORT
+ * case 1 case 2
+ * ------ ------
+ * 1) user types BEGIN 1) user types BEGIN
+ * 2) user does something 2) user does something
+ * 3) user does not like what 3) system aborts for some reason
+ * she shes and types ABORT
*
- * In case 1, we want to abort the transaction and return to the
- * default state. In case 2, there may be more commands coming
- * our way which are part of the same transaction block and we have
- * to ignore these commands until we see an END transaction.
- * (or an ABORT! --djm)
+ * In case 1, we want to abort the transaction and return to the
+ * default state. In case 2, there may be more commands coming
+ * our way which are part of the same transaction block and we have
+ * to ignore these commands until we see an END transaction.
+ * (or an ABORT! --djm)
*
- * Internal aborts are now handled by AbortTransactionBlock(), just as
- * they always have been, and user aborts are now handled by
- * UserAbortTransactionBlock(). Both of them rely on AbortTransaction()
- * to do all the real work. The only difference is what state we
- * enter after AbortTransaction() does it's work:
- *
- * * AbortTransactionBlock() leaves us in TBLOCK_ABORT and
- * * UserAbortTransactionBlock() leaves us in TBLOCK_ENDABORT
- *
- * NOTES
- * This file is an attempt at a redesign of the upper layer
- * of the V1 transaction system which was too poorly thought
- * out to describe. This new system hopes to be both simpler
- * in design, simpler to extend and needs to contain added
- * functionality to solve problems beyond the scope of the V1
- * system. (In particuler, communication of transaction
- * information between parallel backends has to be supported)
+ * Internal aborts are now handled by AbortTransactionBlock(), just as
+ * they always have been, and user aborts are now handled by
+ * UserAbortTransactionBlock(). Both of them rely on AbortTransaction()
+ * to do all the real work. The only difference is what state we
+ * enter after AbortTransaction() does it's work:
*
- * The essential aspects of the transaction system are:
+ * * AbortTransactionBlock() leaves us in TBLOCK_ABORT and
+ * * UserAbortTransactionBlock() leaves us in TBLOCK_ENDABORT
*
- * o transaction id generation
- * o transaction log updating
- * o memory cleanup
- * o cache invalidation
- * o lock cleanup
+ * NOTES
+ * This file is an attempt at a redesign of the upper layer
+ * of the V1 transaction system which was too poorly thought
+ * out to describe. This new system hopes to be both simpler
+ * in design, simpler to extend and needs to contain added
+ * functionality to solve problems beyond the scope of the V1
+ * system. (In particuler, communication of transaction
+ * information between parallel backends has to be supported)
*
- * Hence, the functional division of the transaction code is
- * based on what of the above things need to be done during
- * a start/commit/abort transaction. For instance, the
- * routine AtCommit_Memory() takes care of all the memory
- * cleanup stuff done at commit time.
+ * The essential aspects of the transaction system are:
*
- * The code is layered as follows:
+ * o transaction id generation
+ * o transaction log updating
+ * o memory cleanup
+ * o cache invalidation
+ * o lock cleanup
*
- * StartTransaction
- * CommitTransaction
- * AbortTransaction
- * UserAbortTransaction
+ * Hence, the functional division of the transaction code is
+ * based on what of the above things need to be done during
+ * a start/commit/abort transaction. For instance, the
+ * routine AtCommit_Memory() takes care of all the memory
+ * cleanup stuff done at commit time.
*
- * are provided to do the lower level work like recording
- * the transaction status in the log and doing memory cleanup.
- * above these routines are another set of functions:
+ * The code is layered as follows:
*
- * StartTransactionCommand
- * CommitTransactionCommand
- * AbortCurrentTransaction
+ * StartTransaction
+ * CommitTransaction
+ * AbortTransaction
+ * UserAbortTransaction
*
- * These are the routines used in the postgres main processing
- * loop. They are sensitive to the current transaction block state
- * and make calls to the lower level routines appropriately.
+ * are provided to do the lower level work like recording
+ * the transaction status in the log and doing memory cleanup.
+ * above these routines are another set of functions:
*
- * Support for transaction blocks is provided via the functions:
+ * StartTransactionCommand
+ * CommitTransactionCommand
+ * AbortCurrentTransaction
*
- * StartTransactionBlock
- * CommitTransactionBlock
- * AbortTransactionBlock
+ * These are the routines used in the postgres main processing
+ * loop. They are sensitive to the current transaction block state
+ * and make calls to the lower level routines appropriately.
+ *
+ * Support for transaction blocks is provided via the functions:
+ *
+ * StartTransactionBlock
+ * CommitTransactionBlock
+ * AbortTransactionBlock
*
- * These are invoked only in responce to a user "BEGIN", "END",
- * or "ABORT" command. The tricky part about these functions
- * is that they are called within the postgres main loop, in between
- * the StartTransactionCommand() and CommitTransactionCommand().
+ * These are invoked only in responce to a user "BEGIN", "END",
+ * or "ABORT" command. The tricky part about these functions
+ * is that they are called within the postgres main loop, in between
+ * the StartTransactionCommand() and CommitTransactionCommand().
*
- * For example, consider the following sequence of user commands:
+ * For example, consider the following sequence of user commands:
*
- * 1) begin
- * 2) retrieve (foo.all)
- * 3) append foo (bar = baz)
- * 4) end
+ * 1) begin
+ * 2) retrieve (foo.all)
+ * 3) append foo (bar = baz)
+ * 4) end
*
- * in the main processing loop, this results in the following
- * transaction sequence:
+ * in the main processing loop, this results in the following
+ * transaction sequence:
*
- * / StartTransactionCommand();
- * 1) / ProcessUtility(); << begin
- * \ StartTransactionBlock();
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 1) / ProcessUtility(); << begin
+ * \ StartTransactionBlock();
+ * \ CommitTransactionCommand();
*
- * / StartTransactionCommand();
- * 2) < ProcessQuery(); << retrieve (foo.all)
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 2) < ProcessQuery(); << retrieve (foo.all)
+ * \ CommitTransactionCommand();
*
- * / StartTransactionCommand();
- * 3) < ProcessQuery(); << append foo (bar = baz)
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 3) < ProcessQuery(); << append foo (bar = baz)
+ * \ CommitTransactionCommand();
*
- * / StartTransactionCommand();
- * 4) / ProcessUtility(); << end
- * \ CommitTransactionBlock();
- * \ CommitTransactionCommand();
+ * / StartTransactionCommand();
+ * 4) / ProcessUtility(); << end
+ * \ CommitTransactionBlock();
+ * \ CommitTransactionCommand();
*
- * The point of this example is to demonstrate the need for
- * StartTransactionCommand() and CommitTransactionCommand() to
- * be state smart -- they should do nothing in between the calls
- * to StartTransactionBlock() and EndTransactionBlock() and
- * outside these calls they need to do normal start/commit
- * processing.
+ * The point of this example is to demonstrate the need for
+ * StartTransactionCommand() and CommitTransactionCommand() to
+ * be state smart -- they should do nothing in between the calls
+ * to StartTransactionBlock() and EndTransactionBlock() and
+ * outside these calls they need to do normal start/commit
+ * processing.
*
- * Furthermore, suppose the "retrieve (foo.all)" caused an abort
- * condition. We would then want to abort the transaction and
- * ignore all subsequent commands up to the "end".
- * -cim 3/23/90
+ * Furthermore, suppose the "retrieve (foo.all)" caused an abort
+ * condition. We would then want to abort the transaction and
+ * ignore all subsequent commands up to the "end".
+ * -cim 3/23/90
*
*-------------------------------------------------------------------------
*/
@@ -142,7 +142,7 @@
#include <access/xact.h>
#include <utils/inval.h>
#include <utils/portal.h>
-#include <access/transam.h>
+#include <access/transam.h>
#include <storage/proc.h>
#include <utils/mcxt.h>
#include <catalog/heap.h>
@@ -151,683 +151,700 @@
#include <commands/async.h>
#include <commands/sequence.h>
-static void AbortTransaction(void);
-static void AtAbort_Cache(void);
-static void AtAbort_Locks(void);
-static void AtAbort_Memory(void);
-static void AtCommit_Cache(void);
-static void AtCommit_Locks(void);
-static void AtCommit_Memory(void);
-static void AtStart_Cache(void);
-static void AtStart_Locks(void);
-static void AtStart_Memory(void);
-static void CommitTransaction(void);
-static void RecordTransactionAbort(void);
-static void RecordTransactionCommit(void);
-static void StartTransaction(void);
+static void AbortTransaction(void);
+static void AtAbort_Cache(void);
+static void AtAbort_Locks(void);
+static void AtAbort_Memory(void);
+static void AtCommit_Cache(void);
+static void AtCommit_Locks(void);
+static void AtCommit_Memory(void);
+static void AtStart_Cache(void);
+static void AtStart_Locks(void);
+static void AtStart_Memory(void);
+static void CommitTransaction(void);
+static void RecordTransactionAbort(void);
+static void RecordTransactionCommit(void);
+static void StartTransaction(void);
/* ----------------
- * global variables holding the current transaction state.
+ * global variables holding the current transaction state.
*
- * Note: when we are running several slave processes, the
- * current transaction state data is copied into shared memory
- * and the CurrentTransactionState pointer changed to
- * point to the shared copy. All this occurrs in slaves.c
+ * Note: when we are running several slave processes, the
+ * current transaction state data is copied into shared memory
+ * and the CurrentTransactionState pointer changed to
+ * point to the shared copy. All this occurrs in slaves.c
* ----------------
*/
TransactionStateData CurrentTransactionStateData = {
- 0, /* transaction id */
- FirstCommandId, /* command id */
- 0x0, /* start time */
- TRANS_DEFAULT, /* transaction state */
- TBLOCK_DEFAULT /* transaction block state */
- };
+ 0, /* transaction id */
+ FirstCommandId, /* command id */
+ 0x0, /* start time */
+ TRANS_DEFAULT, /* transaction state */
+ TBLOCK_DEFAULT /* transaction block state */
+};
TransactionState CurrentTransactionState =
- &CurrentTransactionStateData;
+&CurrentTransactionStateData;
/* ----------------
- * info returned when the system is disabled
+ * info returned when the system is disabled
*
* Apparently a lot of this code is inherited from other prototype systems.
* For DisabledStartTime, use a symbolic value to make the relationships clearer.
* The old value of 1073741823 corresponds to a date in y2004, which is coming closer
- * every day. It appears that if we return a value guaranteed larger than
- * any real time associated with a transaction then comparisons in other
- * modules will still be correct. Let's use BIG_ABSTIME for this. tgl 2/14/97
+ * every day. It appears that if we return a value guaranteed larger than
+ * any real time associated with a transaction then comparisons in other
+ * modules will still be correct. Let's use BIG_ABSTIME for this. tgl 2/14/97
*
- * Note: I have no idea what the significance of the
- * 1073741823 in DisabledStartTime.. I just carried
- * this over when converting things from the old
- * V1 transaction system. -cim 3/18/90
+ * Note: I have no idea what the significance of the
+ * 1073741823 in DisabledStartTime.. I just carried
+ * this over when converting things from the old
+ * V1 transaction system. -cim 3/18/90
* ----------------
*/
-TransactionId DisabledTransactionId = (TransactionId)-1;
-
-CommandId DisabledCommandId = (CommandId) -1;
-
-AbsoluteTime DisabledStartTime = (AbsoluteTime) BIG_ABSTIME; /* 1073741823; */
-
+TransactionId DisabledTransactionId = (TransactionId) - 1;
+
+CommandId DisabledCommandId = (CommandId) - 1;
+
+AbsoluteTime DisabledStartTime = (AbsoluteTime) BIG_ABSTIME; /* 1073741823; */
+
/* ----------------
- * overflow flag
+ * overflow flag
* ----------------
*/
-bool CommandIdCounterOverflowFlag;
-
+bool CommandIdCounterOverflowFlag;
+
/* ----------------
- * catalog creation transaction bootstrapping flag.
- * This should be eliminated and added to the transaction
- * state stuff. -cim 3/19/90
+ * catalog creation transaction bootstrapping flag.
+ * This should be eliminated and added to the transaction
+ * state stuff. -cim 3/19/90
* ----------------
*/
-bool AMI_OVERRIDE = false;
-
+bool AMI_OVERRIDE = false;
+
/* ----------------------------------------------------------------
- * transaction state accessors
+ * transaction state accessors
* ----------------------------------------------------------------
*/
-
+
/* --------------------------------
- * TranactionFlushEnabled()
- * SetTranactionFlushEnabled()
+ * TranactionFlushEnabled()
+ * SetTranactionFlushEnabled()
*
- * These are used to test and set the "TransactionFlushState"
- * varable. If this variable is true (the default), then
- * the system will flush all dirty buffers to disk at the end
- * of each transaction. If false then we are assuming the
- * buffer pool resides in stable main memory, in which case we
- * only do writes as necessary.
+ * These are used to test and set the "TransactionFlushState"
+ * varable. If this variable is true (the default), then
+ * the system will flush all dirty buffers to disk at the end
+ * of each transaction. If false then we are assuming the
+ * buffer pool resides in stable main memory, in which case we
+ * only do writes as necessary.
* --------------------------------
*/
-static int TransactionFlushState = 1;
+static int TransactionFlushState = 1;
int
TransactionFlushEnabled(void)
-{
- return TransactionFlushState;
+{
+ return TransactionFlushState;
}
#ifdef NOT_USED
void
SetTransactionFlushEnabled(bool state)
-{
- TransactionFlushState = (state == true);
+{
+ TransactionFlushState = (state == true);
}
+
#endif
/* --------------------------------
- * IsTransactionState
+ * IsTransactionState
*
- * This returns true if we are currently running a query
- * within an executing transaction.
+ * This returns true if we are currently running a query
+ * within an executing transaction.
* --------------------------------
*/
bool
IsTransactionState(void)
{
- TransactionState s = CurrentTransactionState;
-
- switch (s->state) {
- case TRANS_DEFAULT: return false;
- case TRANS_START: return true;
- case TRANS_INPROGRESS: return true;
- case TRANS_COMMIT: return true;
- case TRANS_ABORT: return true;
- case TRANS_DISABLED: return false;
- }
- /*
- * Shouldn't get here, but lint is not happy with this...
- */
- return(false);
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->state)
+ {
+ case TRANS_DEFAULT:
+ return false;
+ case TRANS_START:
+ return true;
+ case TRANS_INPROGRESS:
+ return true;
+ case TRANS_COMMIT:
+ return true;
+ case TRANS_ABORT:
+ return true;
+ case TRANS_DISABLED:
+ return false;
+ }
+
+ /*
+ * Shouldn't get here, but lint is not happy with this...
+ */
+ return (false);
}
/* --------------------------------
- * IsAbortedTransactionBlockState
+ * IsAbortedTransactionBlockState
*
- * This returns true if we are currently running a query
- * within an aborted transaction block.
+ * This returns true if we are currently running a query
+ * within an aborted transaction block.
* --------------------------------
*/
bool
IsAbortedTransactionBlockState()
{
- TransactionState s = CurrentTransactionState;
-
- if (s->blockState == TBLOCK_ABORT)
- return true;
-
- return false;
+ TransactionState s = CurrentTransactionState;
+
+ if (s->blockState == TBLOCK_ABORT)
+ return true;
+
+ return false;
}
/* --------------------------------
- * OverrideTransactionSystem
+ * OverrideTransactionSystem
*
- * This is used to temporarily disable the transaction
- * processing system in order to do initialization of
- * the transaction system data structures and relations
- * themselves.
+ * This is used to temporarily disable the transaction
+ * processing system in order to do initialization of
+ * the transaction system data structures and relations
+ * themselves.
* --------------------------------
*/
-int SavedTransactionState;
+int SavedTransactionState;
void
OverrideTransactionSystem(bool flag)
{
- TransactionState s = CurrentTransactionState;
-
- if (flag == true) {
- if (s->state == TRANS_DISABLED)
- return;
-
- SavedTransactionState = s->state;
- s->state = TRANS_DISABLED;
- } else {
- if (s->state != TRANS_DISABLED)
- return;
-
- s->state = SavedTransactionState;
- }
+ TransactionState s = CurrentTransactionState;
+
+ if (flag == true)
+ {
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ SavedTransactionState = s->state;
+ s->state = TRANS_DISABLED;
+ }
+ else
+ {
+ if (s->state != TRANS_DISABLED)
+ return;
+
+ s->state = SavedTransactionState;
+ }
}
/* --------------------------------
- * GetCurrentTransactionId
+ * GetCurrentTransactionId
*
- * This returns the id of the current transaction, or
- * the id of the "disabled" transaction.
+ * This returns the id of the current transaction, or
+ * the id of the "disabled" transaction.
* --------------------------------
*/
TransactionId
GetCurrentTransactionId()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" transaction id.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (TransactionId) DisabledTransactionId;
-
- /* ----------------
- * otherwise return the current transaction id.
- * ----------------
- */
- return (TransactionId) s->transactionIdData;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" transaction id.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (TransactionId) DisabledTransactionId;
+
+ /* ----------------
+ * otherwise return the current transaction id.
+ * ----------------
+ */
+ return (TransactionId) s->transactionIdData;
}
/* --------------------------------
- * GetCurrentCommandId
+ * GetCurrentCommandId
* --------------------------------
*/
CommandId
GetCurrentCommandId()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" command id.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (CommandId) DisabledCommandId;
-
- return s->commandId;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" command id.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (CommandId) DisabledCommandId;
+
+ return s->commandId;
}
CommandId
GetScanCommandId()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" command id.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (CommandId) DisabledCommandId;
-
- return s->scanCommandId;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" command id.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (CommandId) DisabledCommandId;
+
+ return s->scanCommandId;
}
/* --------------------------------
- * GetCurrentTransactionStartTime
+ * GetCurrentTransactionStartTime
* --------------------------------
*/
AbsoluteTime
GetCurrentTransactionStartTime()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * if the transaction system is disabled, we return
- * the special "disabled" starting time.
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return (AbsoluteTime) DisabledStartTime;
-
- return s->startTime;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * if the transaction system is disabled, we return
+ * the special "disabled" starting time.
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED)
+ return (AbsoluteTime) DisabledStartTime;
+
+ return s->startTime;
}
/* --------------------------------
- * TransactionIdIsCurrentTransactionId
+ * TransactionIdIsCurrentTransactionId
* --------------------------------
*/
bool
TransactionIdIsCurrentTransactionId(TransactionId xid)
{
- TransactionState s = CurrentTransactionState;
-
- if (AMI_OVERRIDE)
- return false;
-
- return (bool)
- TransactionIdEquals(xid, s->transactionIdData);
+ TransactionState s = CurrentTransactionState;
+
+ if (AMI_OVERRIDE)
+ return false;
+
+ return (bool)
+ TransactionIdEquals(xid, s->transactionIdData);
}
/* --------------------------------
- * CommandIdIsCurrentCommandId
+ * CommandIdIsCurrentCommandId
* --------------------------------
*/
bool
CommandIdIsCurrentCommandId(CommandId cid)
{
- TransactionState s = CurrentTransactionState;
-
- if (AMI_OVERRIDE)
- return false;
-
- return
- (cid == s->commandId) ? true : false;
+ TransactionState s = CurrentTransactionState;
+
+ if (AMI_OVERRIDE)
+ return false;
+
+ return
+ (cid == s->commandId) ? true : false;
}
bool
CommandIdGEScanCommandId(CommandId cid)
{
- TransactionState s = CurrentTransactionState;
-
- if (AMI_OVERRIDE)
- return false;
-
- return
- (cid >= s->scanCommandId) ? true : false;
+ TransactionState s = CurrentTransactionState;
+
+ if (AMI_OVERRIDE)
+ return false;
+
+ return
+ (cid >= s->scanCommandId) ? true : false;
}
/* --------------------------------
- * ClearCommandIdCounterOverflowFlag
+ * ClearCommandIdCounterOverflowFlag
* --------------------------------
*/
#ifdef NOT_USED
void
ClearCommandIdCounterOverflowFlag()
{
- CommandIdCounterOverflowFlag = false;
+ CommandIdCounterOverflowFlag = false;
}
+
#endif
/* --------------------------------
- * CommandCounterIncrement
+ * CommandCounterIncrement
* --------------------------------
*/
void
CommandCounterIncrement()
{
- CurrentTransactionStateData.commandId += 1;
- if (CurrentTransactionStateData.commandId == FirstCommandId) {
- CommandIdCounterOverflowFlag = true;
- elog(WARN, "You may only have 65535 commands per transaction");
- }
-
- CurrentTransactionStateData.scanCommandId =
- CurrentTransactionStateData.commandId;
-
- /* make cache changes visible to me */
- AtCommit_Cache();
- AtStart_Cache();
+ CurrentTransactionStateData.commandId += 1;
+ if (CurrentTransactionStateData.commandId == FirstCommandId)
+ {
+ CommandIdCounterOverflowFlag = true;
+ elog(WARN, "You may only have 65535 commands per transaction");
+ }
+
+ CurrentTransactionStateData.scanCommandId =
+ CurrentTransactionStateData.commandId;
+
+ /* make cache changes visible to me */
+ AtCommit_Cache();
+ AtStart_Cache();
}
-void
-SetScanCommandId (CommandId savedId)
+void
+SetScanCommandId(CommandId savedId)
{
- CurrentTransactionStateData.scanCommandId = savedId;
-
+ CurrentTransactionStateData.scanCommandId = savedId;
+
}
/* ----------------------------------------------------------------
- * initialization stuff
+ * initialization stuff
* ----------------------------------------------------------------
*/
void
InitializeTransactionSystem()
{
- InitializeTransactionLog();
+ InitializeTransactionLog();
}
/* ----------------------------------------------------------------
- * StartTransaction stuff
+ * StartTransaction stuff
* ----------------------------------------------------------------
*/
/* --------------------------------
- * AtStart_Cache
+ * AtStart_Cache
* --------------------------------
*/
static void
-AtStart_Cache()
+AtStart_Cache()
{
- DiscardInvalid();
+ DiscardInvalid();
}
/* --------------------------------
- * AtStart_Locks
+ * AtStart_Locks
* --------------------------------
*/
static void
-AtStart_Locks()
+AtStart_Locks()
{
- /*
- * at present, it is unknown to me what belongs here -cim 3/18/90
- *
- * There isn't anything to do at the start of a xact for locks.
- * -mer 5/24/92
- */
+
+ /*
+ * at present, it is unknown to me what belongs here -cim 3/18/90
+ *
+ * There isn't anything to do at the start of a xact for locks. -mer
+ * 5/24/92
+ */
}
/* --------------------------------
- * AtStart_Memory
+ * AtStart_Memory
* --------------------------------
*/
static void
-AtStart_Memory()
+AtStart_Memory()
{
- Portal portal;
- MemoryContext portalContext;
-
- /* ----------------
- * get the blank portal and its memory context
- * ----------------
- */
- portal = GetPortalByName(NULL);
- portalContext = (MemoryContext) PortalGetHeapMemory(portal);
-
- /* ----------------
- * tell system to allocate in the blank portal context
- * ----------------
- */
- MemoryContextSwitchTo(portalContext);
- StartPortalAllocMode(DefaultAllocMode, 0);
+ Portal portal;
+ MemoryContext portalContext;
+
+ /* ----------------
+ * get the blank portal and its memory context
+ * ----------------
+ */
+ portal = GetPortalByName(NULL);
+ portalContext = (MemoryContext) PortalGetHeapMemory(portal);
+
+ /* ----------------
+ * tell system to allocate in the blank portal context
+ * ----------------
+ */
+ MemoryContextSwitchTo(portalContext);
+ StartPortalAllocMode(DefaultAllocMode, 0);
}
/* ----------------------------------------------------------------
- * CommitTransaction stuff
+ * CommitTransaction stuff
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RecordTransactionCommit
+ * RecordTransactionCommit
*
- * Note: the two calls to BufferManagerFlush() exist to ensure
- * that data pages are written before log pages. These
- * explicit calls should be replaced by a more efficient
- * ordered page write scheme in the buffer manager
- * -cim 3/18/90
+ * Note: the two calls to BufferManagerFlush() exist to ensure
+ * that data pages are written before log pages. These
+ * explicit calls should be replaced by a more efficient
+ * ordered page write scheme in the buffer manager
+ * -cim 3/18/90
* --------------------------------
*/
static void
-RecordTransactionCommit()
+RecordTransactionCommit()
{
- TransactionId xid;
- int leak;
-
- /* ----------------
- * get the current transaction id
- * ----------------
- */
- xid = GetCurrentTransactionId();
-
- /* ----------------
- * flush the buffer manager pages. Note: if we have stable
- * main memory, dirty shared buffers are not flushed
- * plai 8/7/90
- * ----------------
- */
- leak = BufferPoolCheckLeak();
- FlushBufferPool(!TransactionFlushEnabled());
- if (leak) ResetBufferPool();
-
- /* ----------------
- * have the transaction access methods record the status
- * of this transaction id in the pg_log / pg_time relations.
- * ----------------
- */
- TransactionIdCommit(xid);
-
- /* ----------------
- * Now write the log/time info to the disk too.
- * ----------------
- */
- leak = BufferPoolCheckLeak();
- FlushBufferPool(!TransactionFlushEnabled());
- if (leak) ResetBufferPool();
+ TransactionId xid;
+ int leak;
+
+ /* ----------------
+ * get the current transaction id
+ * ----------------
+ */
+ xid = GetCurrentTransactionId();
+
+ /* ----------------
+ * flush the buffer manager pages. Note: if we have stable
+ * main memory, dirty shared buffers are not flushed
+ * plai 8/7/90
+ * ----------------
+ */
+ leak = BufferPoolCheckLeak();
+ FlushBufferPool(!TransactionFlushEnabled());
+ if (leak)
+ ResetBufferPool();
+
+ /* ----------------
+ * have the transaction access methods record the status
+ * of this transaction id in the pg_log / pg_time relations.
+ * ----------------
+ */
+ TransactionIdCommit(xid);
+
+ /* ----------------
+ * Now write the log/time info to the disk too.
+ * ----------------
+ */
+ leak = BufferPoolCheckLeak();
+ FlushBufferPool(!TransactionFlushEnabled());
+ if (leak)
+ ResetBufferPool();
}
/* --------------------------------
- * AtCommit_Cache
+ * AtCommit_Cache
* --------------------------------
*/
static void
AtCommit_Cache()
{
- /* ----------------
- * Make catalog changes visible to me for the next command.
- * Other backends will not process my invalidation messages until
- * after I commit and free my locks--though they will do
- * unnecessary work if I abort.
- * ----------------
- */
- RegisterInvalid(true);
+ /* ----------------
+ * Make catalog changes visible to me for the next command.
+ * Other backends will not process my invalidation messages until
+ * after I commit and free my locks--though they will do
+ * unnecessary work if I abort.
+ * ----------------
+ */
+ RegisterInvalid(true);
}
/* --------------------------------
- * AtCommit_Locks
+ * AtCommit_Locks
* --------------------------------
*/
static void
-AtCommit_Locks()
+AtCommit_Locks()
{
- /* ----------------
- * XXX What if ProcReleaseLocks fails? (race condition?)
- *
- * Then you're up a creek! -mer 5/24/92
- * ----------------
- */
- ProcReleaseLocks();
+ /* ----------------
+ * XXX What if ProcReleaseLocks fails? (race condition?)
+ *
+ * Then you're up a creek! -mer 5/24/92
+ * ----------------
+ */
+ ProcReleaseLocks();
}
/* --------------------------------
- * AtCommit_Memory
+ * AtCommit_Memory
* --------------------------------
*/
static void
-AtCommit_Memory()
+AtCommit_Memory()
{
- /* ----------------
- * now that we're "out" of a transaction, have the
- * system allocate things in the top memory context instead
- * of the blank portal memory context.
- * ----------------
- */
- EndPortalAllocMode();
- MemoryContextSwitchTo(TopMemoryContext);
+ /* ----------------
+ * now that we're "out" of a transaction, have the
+ * system allocate things in the top memory context instead
+ * of the blank portal memory context.
+ * ----------------
+ */
+ EndPortalAllocMode();
+ MemoryContextSwitchTo(TopMemoryContext);
}
/* ----------------------------------------------------------------
- * AbortTransaction stuff
+ * AbortTransaction stuff
* ----------------------------------------------------------------
*/
/* --------------------------------
- * RecordTransactionAbort
+ * RecordTransactionAbort
* --------------------------------
*/
static void
-RecordTransactionAbort()
+RecordTransactionAbort()
{
- TransactionId xid;
-
- /* ----------------
- * get the current transaction id
- * ----------------
- */
- xid = GetCurrentTransactionId();
-
- /* ----------------
- * have the transaction access methods record the status
- * of this transaction id in the pg_log / pg_time relations.
- * ----------------
- */
- TransactionIdAbort(xid);
-
- /* ----------------
- * flush the buffer manager pages. Note: if we have stable
- * main memory, dirty shared buffers are not flushed
- * plai 8/7/90
- * ----------------
- */
- ResetBufferPool();
+ TransactionId xid;
+
+ /* ----------------
+ * get the current transaction id
+ * ----------------
+ */
+ xid = GetCurrentTransactionId();
+
+ /* ----------------
+ * have the transaction access methods record the status
+ * of this transaction id in the pg_log / pg_time relations.
+ * ----------------
+ */
+ TransactionIdAbort(xid);
+
+ /* ----------------
+ * flush the buffer manager pages. Note: if we have stable
+ * main memory, dirty shared buffers are not flushed
+ * plai 8/7/90
+ * ----------------
+ */
+ ResetBufferPool();
}
/* --------------------------------
- * AtAbort_Cache
+ * AtAbort_Cache
* --------------------------------
*/
static void
-AtAbort_Cache()
+AtAbort_Cache()
{
- RegisterInvalid(false);
+ RegisterInvalid(false);
}
/* --------------------------------
- * AtAbort_Locks
+ * AtAbort_Locks
* --------------------------------
*/
static void
-AtAbort_Locks()
+AtAbort_Locks()
{
- /* ----------------
- * XXX What if ProcReleaseLocks() fails? (race condition?)
- *
- * Then you're up a creek without a paddle! -mer
- * ----------------
- */
- ProcReleaseLocks();
+ /* ----------------
+ * XXX What if ProcReleaseLocks() fails? (race condition?)
+ *
+ * Then you're up a creek without a paddle! -mer
+ * ----------------
+ */
+ ProcReleaseLocks();
}
/* --------------------------------
- * AtAbort_Memory
+ * AtAbort_Memory
* --------------------------------
*/
static void
-AtAbort_Memory()
+AtAbort_Memory()
{
- /* ----------------
- * after doing an abort transaction, make certain the
- * system uses the top memory context rather then the
- * portal memory context (until the next transaction).
- * ----------------
- */
- MemoryContextSwitchTo(TopMemoryContext);
+ /* ----------------
+ * after doing an abort transaction, make certain the
+ * system uses the top memory context rather then the
+ * portal memory context (until the next transaction).
+ * ----------------
+ */
+ MemoryContextSwitchTo(TopMemoryContext);
}
/* ----------------------------------------------------------------
- * interface routines
+ * interface routines
* ----------------------------------------------------------------
*/
/* --------------------------------
- * StartTransaction
+ * StartTransaction
*
* --------------------------------
*/
static void
StartTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * Check the current transaction state. If the transaction system
- * is switched off, or if we're already in a transaction, do nothing.
- * We're already in a transaction when the monitor sends a null
- * command to the backend to flush the comm channel. This is a
- * hacky fix to a communications problem, and we keep having to
- * deal with it here. We should fix the comm channel code. mao 080891
- * ----------------
- */
- if (s->state == TRANS_DISABLED || s->state == TRANS_INPROGRESS)
- return;
-
- /* ----------------
- * set the current transaction state information
- * appropriately during start processing
- * ----------------
- */
- s->state = TRANS_START;
-
- /* ----------------
- * generate a new transaction id
- * ----------------
- */
- GetNewTransactionId(&(s->transactionIdData));
-
- /* ----------------
- * initialize current transaction state fields
- * ----------------
- */
- s->commandId = FirstCommandId;
- s->scanCommandId = FirstCommandId;
- s->startTime = GetCurrentAbsoluteTime();
-
- /* ----------------
- * initialize the various transaction subsystems
- * ----------------
- */
- AtStart_Cache();
- AtStart_Locks();
- AtStart_Memory();
-
- /* --------------
- initialize temporary relations list
- the tempRelList is a list of temporary relations that
- are created in the course of the transactions
- they need to be destroyed properly at the end of the transactions
- */
- InitTempRelList();
-
- /* ----------------
- * done with start processing, set current transaction
- * state to "in progress"
- * ----------------
- */
- s->state = TRANS_INPROGRESS;
-
- /*
- * Let others to know about current transaction is in progress
- * - vadim 11/26/96
- */
- if ( MyProc != (PROC*) NULL )
- MyProc->xid = s->transactionIdData;
+ TransactionState s = CurrentTransactionState;
+
+ /* ----------------
+ * Check the current transaction state. If the transaction system
+ * is switched off, or if we're already in a transaction, do nothing.
+ * We're already in a transaction when the monitor sends a null
+ * command to the backend to flush the comm channel. This is a
+ * hacky fix to a communications problem, and we keep having to
+ * deal with it here. We should fix the comm channel code. mao 080891
+ * ----------------
+ */
+ if (s->state == TRANS_DISABLED || s->state == TRANS_INPROGRESS)
+ return;
+
+ /* ----------------
+ * set the current transaction state information
+ * appropriately during start processing
+ * ----------------
+ */
+ s->state = TRANS_START;
+
+ /* ----------------
+ * generate a new transaction id
+ * ----------------
+ */
+ GetNewTransactionId(&(s->transactionIdData));
+
+ /* ----------------
+ * initialize current transaction state fields
+ * ----------------
+ */
+ s->commandId = FirstCommandId;
+ s->scanCommandId = FirstCommandId;
+ s->startTime = GetCurrentAbsoluteTime();
+
+ /* ----------------
+ * initialize the various transaction subsystems
+ * ----------------
+ */
+ AtStart_Cache();
+ AtStart_Locks();
+ AtStart_Memory();
+
+ /* --------------
+ initialize temporary relations list
+ the tempRelList is a list of temporary relations that
+ are created in the course of the transactions
+ they need to be destroyed properly at the end of the transactions
+ */
+ InitTempRelList();
+
+ /* ----------------
+ * done with start processing, set current transaction
+ * state to "in progress"
+ * ----------------
+ */
+ s->state = TRANS_INPROGRESS;
+
+ /*
+ * Let others to know about current transaction is in progress - vadim
+ * 11/26/96
+ */
+ if (MyProc != (PROC *) NULL)
+ MyProc->xid = s->transactionIdData;
}
@@ -838,591 +855,604 @@ StartTransaction()
bool
CurrentXactInProgress()
{
- return (CurrentTransactionState->state == TRANS_INPROGRESS);
+ return (CurrentTransactionState->state == TRANS_INPROGRESS);
}
/* --------------------------------
- * CommitTransaction
+ * CommitTransaction
*
* --------------------------------
*/
static void
CommitTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->state != TRANS_INPROGRESS)
- elog(NOTICE, "CommitTransaction and not in in-progress state ");
-
- /* ----------------
- * set the current transaction state information
- * appropriately during the abort processing
- * ----------------
- */
- s->state = TRANS_COMMIT;
-
- /* ----------------
- * do commit processing
- * ----------------
- */
- CloseSequences ();
- DestroyTempRels();
- AtEOXact_portals();
- RecordTransactionCommit();
- RelationPurgeLocalRelation(true);
- AtCommit_Cache();
- AtCommit_Locks();
- AtCommit_Memory();
-
- /* ----------------
- * done with commit processing, set current transaction
- * state back to default
- * ----------------
- */
- s->state = TRANS_DEFAULT;
- { /* want this after commit */
- if (IsNormalProcessingMode())
- Async_NotifyAtCommit();
- }
-
- /*
- * Let others to know about no transaction in progress
- * - vadim 11/26/96
- */
- if ( MyProc != (PROC*) NULL )
- MyProc->xid = InvalidTransactionId;
-}
+ TransactionState s = CurrentTransactionState;
-/* --------------------------------
- * AbortTransaction
- *
- * --------------------------------
- */
-static void
-AbortTransaction()
-{
- TransactionState s = CurrentTransactionState;
-
- /*
- * Let others to know about no transaction in progress
- * - vadim 11/26/96
- */
- if ( MyProc != (PROC*) NULL )
- MyProc->xid = InvalidTransactionId;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->state != TRANS_INPROGRESS)
- elog(NOTICE, "AbortTransaction and not in in-progress state ");
-
- /* ----------------
- * set the current transaction state information
- * appropriately during the abort processing
- * ----------------
- */
- s->state = TRANS_ABORT;
-
- /* ----------------
- * do abort processing
- * ----------------
- */
- CloseSequences ();
- AtEOXact_portals();
- RecordTransactionAbort();
- RelationPurgeLocalRelation(false);
- DestroyTempRels();
- AtAbort_Cache();
- AtAbort_Locks();
- AtAbort_Memory();
-
- /* ----------------
- * done with abort processing, set current transaction
- * state back to default
- * ----------------
- */
- s->state = TRANS_DEFAULT;
- {
- /* We need to do this in case another process notified us while
- we are in the middle of an aborted transaction. We need to
- notify our frontend after we finish the current transaction.
- -- jw, 1/3/94
- */
- if (IsNormalProcessingMode())
- Async_NotifyAtAbort();
- }
-}
-
-/* --------------------------------
- * StartTransactionCommand
- * --------------------------------
- */
-void
-StartTransactionCommand()
-{
- TransactionState s = CurrentTransactionState;
-
- switch(s->blockState) {
/* ----------------
- * if we aren't in a transaction block, we
- * just do our usual start transaction.
+ * check the current transaction state
* ----------------
*/
- case TBLOCK_DEFAULT:
- StartTransaction();
- break;
-
- /* ----------------
- * We should never experience this -- if we do it
- * means the BEGIN state was not changed in the previous
- * CommitTransactionCommand(). If we get it, we print
- * a warning and change to the in-progress state.
- * ----------------
- */
- case TBLOCK_BEGIN:
- elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_BEGIN");
- s->blockState = TBLOCK_INPROGRESS;
- break;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->state != TRANS_INPROGRESS)
+ elog(NOTICE, "CommitTransaction and not in in-progress state ");
+
/* ----------------
- * This is the case when are somewhere in a transaction
- * block and about to start a new command. For now we
- * do nothing but someday we may do command-local resource
- * initialization.
+ * set the current transaction state information
+ * appropriately during the abort processing
* ----------------
*/
- case TBLOCK_INPROGRESS:
- break;
-
+ s->state = TRANS_COMMIT;
+
/* ----------------
- * As with BEGIN, we should never experience this --
- * if we do it means the END state was not changed in the
- * previous CommitTransactionCommand(). If we get it, we
- * print a warning, commit the transaction, start a new
- * transaction and change to the default state.
+ * do commit processing
* ----------------
*/
- case TBLOCK_END:
- elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_END");
- s->blockState = TBLOCK_DEFAULT;
- CommitTransaction();
- StartTransaction();
- break;
-
+ CloseSequences();
+ DestroyTempRels();
+ AtEOXact_portals();
+ RecordTransactionCommit();
+ RelationPurgeLocalRelation(true);
+ AtCommit_Cache();
+ AtCommit_Locks();
+ AtCommit_Memory();
+
/* ----------------
- * Here we are in the middle of a transaction block but
- * one of the commands caused an abort so we do nothing
- * but remain in the abort state. Eventually we will get
- * to the "END TRANSACTION" which will set things straight.
+ * done with commit processing, set current transaction
+ * state back to default
* ----------------
*/
- case TBLOCK_ABORT:
- break;
-
- /* ----------------
- * This means we somehow aborted and the last call to
- * CommitTransactionCommand() didn't clear the state so
- * we remain in the ENDABORT state and mabey next time
- * we get to CommitTransactionCommand() the state will
- * get reset to default.
- * ----------------
+ s->state = TRANS_DEFAULT;
+ { /* want this after commit */
+ if (IsNormalProcessingMode())
+ Async_NotifyAtCommit();
+ }
+
+ /*
+ * Let others to know about no transaction in progress - vadim
+ * 11/26/96
*/
- case TBLOCK_ENDABORT:
- elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_ENDABORT");
- break;
- }
+ if (MyProc != (PROC *) NULL)
+ MyProc->xid = InvalidTransactionId;
}
+
/* --------------------------------
- * CommitTransactionCommand
+ * AbortTransaction
+ *
* --------------------------------
*/
-void
-CommitTransactionCommand()
+static void
+AbortTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- switch(s->blockState) {
- /* ----------------
- * if we aren't in a transaction block, we
- * just do our usual transaction commit
- * ----------------
- */
- case TBLOCK_DEFAULT:
- CommitTransaction();
- break;
-
- /* ----------------
- * This is the case right after we get a "BEGIN TRANSACTION"
- * command, but the user hasn't done anything else yet, so
- * we change to the "transaction block in progress" state
- * and return.
- * ----------------
+ TransactionState s = CurrentTransactionState;
+
+ /*
+ * Let others to know about no transaction in progress - vadim
+ * 11/26/96
*/
- case TBLOCK_BEGIN:
- s->blockState = TBLOCK_INPROGRESS;
- break;
-
+ if (MyProc != (PROC *) NULL)
+ MyProc->xid = InvalidTransactionId;
+
/* ----------------
- * This is the case when we have finished executing a command
- * someplace within a transaction block. We increment the
- * command counter and return. Someday we may free resources
- * local to the command.
- *
- * That someday is today, at least for memory allocated by
- * command in the BlankPortal' HeapMemory context.
- * - vadim 03/25/97
+ * check the current transaction state
* ----------------
*/
- case TBLOCK_INPROGRESS:
- CommandCounterIncrement();
-#ifdef TBL_FREE_CMD_MEMORY
- EndPortalAllocMode ();
- StartPortalAllocMode (DefaultAllocMode, 0);
-#endif
- break;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->state != TRANS_INPROGRESS)
+ elog(NOTICE, "AbortTransaction and not in in-progress state ");
+
/* ----------------
- * This is the case when we just got the "END TRANSACTION"
- * statement, so we go back to the default state and
- * commit the transaction.
+ * set the current transaction state information
+ * appropriately during the abort processing
* ----------------
*/
- case TBLOCK_END:
- s->blockState = TBLOCK_DEFAULT;
- CommitTransaction();
- break;
-
+ s->state = TRANS_ABORT;
+
/* ----------------
- * Here we are in the middle of a transaction block but
- * one of the commands caused an abort so we do nothing
- * but remain in the abort state. Eventually we will get
- * to the "END TRANSACTION" which will set things straight.
+ * do abort processing
* ----------------
*/
- case TBLOCK_ABORT:
- break;
-
+ CloseSequences();
+ AtEOXact_portals();
+ RecordTransactionAbort();
+ RelationPurgeLocalRelation(false);
+ DestroyTempRels();
+ AtAbort_Cache();
+ AtAbort_Locks();
+ AtAbort_Memory();
+
/* ----------------
- * Here we were in an aborted transaction block which
- * just processed the "END TRANSACTION" command from the
- * user, so now we return the to default state.
+ * done with abort processing, set current transaction
+ * state back to default
* ----------------
*/
- case TBLOCK_ENDABORT:
- s->blockState = TBLOCK_DEFAULT;
- break;
- }
+ s->state = TRANS_DEFAULT;
+ {
+
+ /*
+ * We need to do this in case another process notified us while we
+ * are in the middle of an aborted transaction. We need to notify
+ * our frontend after we finish the current transaction. -- jw,
+ * 1/3/94
+ */
+ if (IsNormalProcessingMode())
+ Async_NotifyAtAbort();
+ }
+}
+
+/* --------------------------------
+ * StartTransactionCommand
+ * --------------------------------
+ */
+void
+StartTransactionCommand()
+{
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->blockState)
+ {
+ /* ----------------
+ * if we aren't in a transaction block, we
+ * just do our usual start transaction.
+ * ----------------
+ */
+ case TBLOCK_DEFAULT:
+ StartTransaction();
+ break;
+
+ /* ----------------
+ * We should never experience this -- if we do it
+ * means the BEGIN state was not changed in the previous
+ * CommitTransactionCommand(). If we get it, we print
+ * a warning and change to the in-progress state.
+ * ----------------
+ */
+ case TBLOCK_BEGIN:
+ elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_BEGIN");
+ s->blockState = TBLOCK_INPROGRESS;
+ break;
+
+ /* ----------------
+ * This is the case when are somewhere in a transaction
+ * block and about to start a new command. For now we
+ * do nothing but someday we may do command-local resource
+ * initialization.
+ * ----------------
+ */
+ case TBLOCK_INPROGRESS:
+ break;
+
+ /* ----------------
+ * As with BEGIN, we should never experience this --
+ * if we do it means the END state was not changed in the
+ * previous CommitTransactionCommand(). If we get it, we
+ * print a warning, commit the transaction, start a new
+ * transaction and change to the default state.
+ * ----------------
+ */
+ case TBLOCK_END:
+ elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_END");
+ s->blockState = TBLOCK_DEFAULT;
+ CommitTransaction();
+ StartTransaction();
+ break;
+
+ /* ----------------
+ * Here we are in the middle of a transaction block but
+ * one of the commands caused an abort so we do nothing
+ * but remain in the abort state. Eventually we will get
+ * to the "END TRANSACTION" which will set things straight.
+ * ----------------
+ */
+ case TBLOCK_ABORT:
+ break;
+
+ /* ----------------
+ * This means we somehow aborted and the last call to
+ * CommitTransactionCommand() didn't clear the state so
+ * we remain in the ENDABORT state and mabey next time
+ * we get to CommitTransactionCommand() the state will
+ * get reset to default.
+ * ----------------
+ */
+ case TBLOCK_ENDABORT:
+ elog(NOTICE, "StartTransactionCommand: unexpected TBLOCK_ENDABORT");
+ break;
+ }
+}
+
+/* --------------------------------
+ * CommitTransactionCommand
+ * --------------------------------
+ */
+void
+CommitTransactionCommand()
+{
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->blockState)
+ {
+ /* ----------------
+ * if we aren't in a transaction block, we
+ * just do our usual transaction commit
+ * ----------------
+ */
+ case TBLOCK_DEFAULT:
+ CommitTransaction();
+ break;
+
+ /* ----------------
+ * This is the case right after we get a "BEGIN TRANSACTION"
+ * command, but the user hasn't done anything else yet, so
+ * we change to the "transaction block in progress" state
+ * and return.
+ * ----------------
+ */
+ case TBLOCK_BEGIN:
+ s->blockState = TBLOCK_INPROGRESS;
+ break;
+
+ /* ----------------
+ * This is the case when we have finished executing a command
+ * someplace within a transaction block. We increment the
+ * command counter and return. Someday we may free resources
+ * local to the command.
+ *
+ * That someday is today, at least for memory allocated by
+ * command in the BlankPortal' HeapMemory context.
+ * - vadim 03/25/97
+ * ----------------
+ */
+ case TBLOCK_INPROGRESS:
+ CommandCounterIncrement();
+#ifdef TBL_FREE_CMD_MEMORY
+ EndPortalAllocMode();
+ StartPortalAllocMode(DefaultAllocMode, 0);
+#endif
+ break;
+
+ /* ----------------
+ * This is the case when we just got the "END TRANSACTION"
+ * statement, so we go back to the default state and
+ * commit the transaction.
+ * ----------------
+ */
+ case TBLOCK_END:
+ s->blockState = TBLOCK_DEFAULT;
+ CommitTransaction();
+ break;
+
+ /* ----------------
+ * Here we are in the middle of a transaction block but
+ * one of the commands caused an abort so we do nothing
+ * but remain in the abort state. Eventually we will get
+ * to the "END TRANSACTION" which will set things straight.
+ * ----------------
+ */
+ case TBLOCK_ABORT:
+ break;
+
+ /* ----------------
+ * Here we were in an aborted transaction block which
+ * just processed the "END TRANSACTION" command from the
+ * user, so now we return the to default state.
+ * ----------------
+ */
+ case TBLOCK_ENDABORT:
+ s->blockState = TBLOCK_DEFAULT;
+ break;
+ }
}
/* --------------------------------
- * AbortCurrentTransaction
+ * AbortCurrentTransaction
* --------------------------------
*/
void
AbortCurrentTransaction()
{
- TransactionState s = CurrentTransactionState;
-
- switch(s->blockState) {
- /* ----------------
- * if we aren't in a transaction block, we
- * just do our usual abort transaction.
- * ----------------
- */
- case TBLOCK_DEFAULT:
- AbortTransaction();
- break;
-
- /* ----------------
- * If we are in the TBLOCK_BEGIN it means something
- * screwed up right after reading "BEGIN TRANSACTION"
- * so we enter the abort state. Eventually an "END
- * TRANSACTION" will fix things.
- * ----------------
- */
- case TBLOCK_BEGIN:
- s->blockState = TBLOCK_ABORT;
- AbortTransaction();
- break;
-
+ TransactionState s = CurrentTransactionState;
+
+ switch (s->blockState)
+ {
+ /* ----------------
+ * if we aren't in a transaction block, we
+ * just do our usual abort transaction.
+ * ----------------
+ */
+ case TBLOCK_DEFAULT:
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * If we are in the TBLOCK_BEGIN it means something
+ * screwed up right after reading "BEGIN TRANSACTION"
+ * so we enter the abort state. Eventually an "END
+ * TRANSACTION" will fix things.
+ * ----------------
+ */
+ case TBLOCK_BEGIN:
+ s->blockState = TBLOCK_ABORT;
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * This is the case when are somewhere in a transaction
+ * block which aborted so we abort the transaction and
+ * set the ABORT state. Eventually an "END TRANSACTION"
+ * will fix things and restore us to a normal state.
+ * ----------------
+ */
+ case TBLOCK_INPROGRESS:
+ s->blockState = TBLOCK_ABORT;
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * Here, the system was fouled up just after the
+ * user wanted to end the transaction block so we
+ * abort the transaction and put us back into the
+ * default state.
+ * ----------------
+ */
+ case TBLOCK_END:
+ s->blockState = TBLOCK_DEFAULT;
+ AbortTransaction();
+ break;
+
+ /* ----------------
+ * Here, we are already in an aborted transaction
+ * state and are waiting for an "END TRANSACTION" to
+ * come along and lo and behold, we abort again!
+ * So we just remain in the abort state.
+ * ----------------
+ */
+ case TBLOCK_ABORT:
+ break;
+
+ /* ----------------
+ * Here we were in an aborted transaction block which
+ * just processed the "END TRANSACTION" command but somehow
+ * aborted again.. since we must have done the abort
+ * processing, we return to the default state.
+ * ----------------
+ */
+ case TBLOCK_ENDABORT:
+ s->blockState = TBLOCK_DEFAULT;
+ break;
+ }
+}
+
+/* ----------------------------------------------------------------
+ * transaction block support
+ * ----------------------------------------------------------------
+ */
+/* --------------------------------
+ * BeginTransactionBlock
+ * --------------------------------
+ */
+void
+BeginTransactionBlock(void)
+{
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * This is the case when are somewhere in a transaction
- * block which aborted so we abort the transaction and
- * set the ABORT state. Eventually an "END TRANSACTION"
- * will fix things and restore us to a normal state.
+ * check the current transaction state
* ----------------
*/
- case TBLOCK_INPROGRESS:
- s->blockState = TBLOCK_ABORT;
- AbortTransaction();
- break;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->blockState != TBLOCK_DEFAULT)
+ elog(NOTICE, "BeginTransactionBlock and not in default state ");
+
/* ----------------
- * Here, the system was fouled up just after the
- * user wanted to end the transaction block so we
- * abort the transaction and put us back into the
- * default state.
+ * set the current transaction block state information
+ * appropriately during begin processing
* ----------------
*/
- case TBLOCK_END:
- s->blockState = TBLOCK_DEFAULT;
- AbortTransaction();
- break;
-
+ s->blockState = TBLOCK_BEGIN;
+
/* ----------------
- * Here, we are already in an aborted transaction
- * state and are waiting for an "END TRANSACTION" to
- * come along and lo and behold, we abort again!
- * So we just remain in the abort state.
+ * do begin processing
* ----------------
*/
- case TBLOCK_ABORT:
- break;
-
+
/* ----------------
- * Here we were in an aborted transaction block which
- * just processed the "END TRANSACTION" command but somehow
- * aborted again.. since we must have done the abort
- * processing, we return to the default state.
+ * done with begin processing, set block state to inprogress
* ----------------
*/
- case TBLOCK_ENDABORT:
- s->blockState = TBLOCK_DEFAULT;
- break;
- }
-}
-
-/* ----------------------------------------------------------------
- * transaction block support
- * ----------------------------------------------------------------
- */
-/* --------------------------------
- * BeginTransactionBlock
- * --------------------------------
- */
-void
-BeginTransactionBlock(void)
-{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->blockState != TBLOCK_DEFAULT)
- elog(NOTICE, "BeginTransactionBlock and not in default state ");
-
- /* ----------------
- * set the current transaction block state information
- * appropriately during begin processing
- * ----------------
- */
- s->blockState = TBLOCK_BEGIN;
-
- /* ----------------
- * do begin processing
- * ----------------
- */
-
- /* ----------------
- * done with begin processing, set block state to inprogress
- * ----------------
- */
- s->blockState = TBLOCK_INPROGRESS;
+ s->blockState = TBLOCK_INPROGRESS;
}
/* --------------------------------
- * EndTransactionBlock
+ * EndTransactionBlock
* --------------------------------
*/
void
EndTransactionBlock(void)
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->blockState == TBLOCK_INPROGRESS) {
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * here we are in a transaction block which should commit
- * when we get to the upcoming CommitTransactionCommand()
- * so we set the state to "END". CommitTransactionCommand()
- * will recognize this and commit the transaction and return
- * us to the default state
+ * check the current transaction state
* ----------------
*/
- s->blockState = TBLOCK_END;
- return;
- }
-
- if (s->blockState == TBLOCK_ABORT) {
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->blockState == TBLOCK_INPROGRESS)
+ {
+ /* ----------------
+ * here we are in a transaction block which should commit
+ * when we get to the upcoming CommitTransactionCommand()
+ * so we set the state to "END". CommitTransactionCommand()
+ * will recognize this and commit the transaction and return
+ * us to the default state
+ * ----------------
+ */
+ s->blockState = TBLOCK_END;
+ return;
+ }
+
+ if (s->blockState == TBLOCK_ABORT)
+ {
+ /* ----------------
+ * here, we are in a transaction block which aborted
+ * and since the AbortTransaction() was already done,
+ * we do whatever is needed and change to the special
+ * "END ABORT" state. The upcoming CommitTransactionCommand()
+ * will recognise this and then put us back in the default
+ * state.
+ * ----------------
+ */
+ s->blockState = TBLOCK_ENDABORT;
+ return;
+ }
+
/* ----------------
- * here, we are in a transaction block which aborted
- * and since the AbortTransaction() was already done,
- * we do whatever is needed and change to the special
- * "END ABORT" state. The upcoming CommitTransactionCommand()
- * will recognise this and then put us back in the default
- * state.
+ * We should not get here, but if we do, we go to the ENDABORT
+ * state after printing a warning. The upcoming call to
+ * CommitTransactionCommand() will then put us back into the
+ * default state.
* ----------------
*/
+ elog(NOTICE, "EndTransactionBlock and not inprogress/abort state ");
s->blockState = TBLOCK_ENDABORT;
- return;
- }
-
- /* ----------------
- * We should not get here, but if we do, we go to the ENDABORT
- * state after printing a warning. The upcoming call to
- * CommitTransactionCommand() will then put us back into the
- * default state.
- * ----------------
- */
- elog(NOTICE, "EndTransactionBlock and not inprogress/abort state ");
- s->blockState = TBLOCK_ENDABORT;
}
/* --------------------------------
- * AbortTransactionBlock
+ * AbortTransactionBlock
* --------------------------------
*/
#ifdef NOT_USED
static void
AbortTransactionBlock(void)
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- if (s->blockState == TBLOCK_INPROGRESS) {
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * here we were inside a transaction block something
- * screwed up inside the system so we enter the abort state,
- * do the abort processing and then return.
- * We remain in the abort state until we see the upcoming
- * END TRANSACTION command.
+ * check the current transaction state
* ----------------
*/
- s->blockState = TBLOCK_ABORT;
-
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ if (s->blockState == TBLOCK_INPROGRESS)
+ {
+ /* ----------------
+ * here we were inside a transaction block something
+ * screwed up inside the system so we enter the abort state,
+ * do the abort processing and then return.
+ * We remain in the abort state until we see the upcoming
+ * END TRANSACTION command.
+ * ----------------
+ */
+ s->blockState = TBLOCK_ABORT;
+
+ /* ----------------
+ * do abort processing and return
+ * ----------------
+ */
+ AbortTransaction();
+ return;
+ }
+
/* ----------------
- * do abort processing and return
+ * this case should not be possible, because it would mean
+ * the user entered an "abort" from outside a transaction block.
+ * So we print an error message, abort the transaction and
+ * enter the "ENDABORT" state so we will end up in the default
+ * state after the upcoming CommitTransactionCommand().
* ----------------
*/
+ elog(NOTICE, "AbortTransactionBlock and not in in-progress state");
AbortTransaction();
- return;
- }
-
- /* ----------------
- * this case should not be possible, because it would mean
- * the user entered an "abort" from outside a transaction block.
- * So we print an error message, abort the transaction and
- * enter the "ENDABORT" state so we will end up in the default
- * state after the upcoming CommitTransactionCommand().
- * ----------------
- */
- elog(NOTICE, "AbortTransactionBlock and not in in-progress state");
- AbortTransaction();
- s->blockState = TBLOCK_ENDABORT;
+ s->blockState = TBLOCK_ENDABORT;
}
+
#endif
/* --------------------------------
- * UserAbortTransactionBlock
+ * UserAbortTransactionBlock
* --------------------------------
*/
void
UserAbortTransactionBlock()
{
- TransactionState s = CurrentTransactionState;
-
- /* ----------------
- * check the current transaction state
- * ----------------
- */
- if (s->state == TRANS_DISABLED)
- return;
-
- /*
- * if the transaction has already been automatically aborted with an error,
- * and the user subsequently types 'abort', allow it. (the behavior is
- * the same as if they had typed 'end'.)
- */
- if (s->blockState == TBLOCK_ABORT) {
- s->blockState = TBLOCK_ENDABORT;
- return;
- }
-
- if (s->blockState == TBLOCK_INPROGRESS) {
+ TransactionState s = CurrentTransactionState;
+
/* ----------------
- * here we were inside a transaction block and we
- * got an abort command from the user, so we move to
- * the abort state, do the abort processing and
- * then change to the ENDABORT state so we will end up
- * in the default state after the upcoming
- * CommitTransactionCommand().
+ * check the current transaction state
* ----------------
*/
- s->blockState = TBLOCK_ABORT;
-
- /* ----------------
- * do abort processing
- * ----------------
+ if (s->state == TRANS_DISABLED)
+ return;
+
+ /*
+ * if the transaction has already been automatically aborted with an
+ * error, and the user subsequently types 'abort', allow it. (the
+ * behavior is the same as if they had typed 'end'.)
*/
- AbortTransaction();
-
+ if (s->blockState == TBLOCK_ABORT)
+ {
+ s->blockState = TBLOCK_ENDABORT;
+ return;
+ }
+
+ if (s->blockState == TBLOCK_INPROGRESS)
+ {
+ /* ----------------
+ * here we were inside a transaction block and we
+ * got an abort command from the user, so we move to
+ * the abort state, do the abort processing and
+ * then change to the ENDABORT state so we will end up
+ * in the default state after the upcoming
+ * CommitTransactionCommand().
+ * ----------------
+ */
+ s->blockState = TBLOCK_ABORT;
+
+ /* ----------------
+ * do abort processing
+ * ----------------
+ */
+ AbortTransaction();
+
+ /* ----------------
+ * change to the end abort state and return
+ * ----------------
+ */
+ s->blockState = TBLOCK_ENDABORT;
+ return;
+ }
+
/* ----------------
- * change to the end abort state and return
+ * this case should not be possible, because it would mean
+ * the user entered an "abort" from outside a transaction block.
+ * So we print an error message, abort the transaction and
+ * enter the "ENDABORT" state so we will end up in the default
+ * state after the upcoming CommitTransactionCommand().
* ----------------
*/
+ elog(NOTICE, "UserAbortTransactionBlock and not in in-progress state");
+ AbortTransaction();
s->blockState = TBLOCK_ENDABORT;
- return;
- }
-
- /* ----------------
- * this case should not be possible, because it would mean
- * the user entered an "abort" from outside a transaction block.
- * So we print an error message, abort the transaction and
- * enter the "ENDABORT" state so we will end up in the default
- * state after the upcoming CommitTransactionCommand().
- * ----------------
- */
- elog(NOTICE, "UserAbortTransactionBlock and not in in-progress state");
- AbortTransaction();
- s->blockState = TBLOCK_ENDABORT;
}
bool
IsTransactionBlock()
{
- TransactionState s = CurrentTransactionState;
-
- if (s->blockState == TBLOCK_INPROGRESS
- || s->blockState == TBLOCK_ENDABORT) {
- return (true);
- }
-
- return (false);
+ TransactionState s = CurrentTransactionState;
+
+ if (s->blockState == TBLOCK_INPROGRESS
+ || s->blockState == TBLOCK_ENDABORT)
+ {
+ return (true);
+ }
+
+ return (false);
}