Index: src/backend/access/transam/xact.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql-server/src/backend/access/transam/xact.c,v
retrieving revision 1.164
diff -c -r1.164 xact.c
*** src/backend/access/transam/xact.c	11 Feb 2004 22:55:24 -0000	1.164
--- src/backend/access/transam/xact.c	27 Mar 2004 02:53:00 -0000
***************
*** 197,203 ****
  	FirstCommandId,				/* command id */
  	0,							/* scan command id */
  	0x0,						/* start time */
- 	TRANS_DEFAULT,				/* transaction state */
  	TBLOCK_DEFAULT				/* transaction block state from the client
  								 * perspective */
  };
--- 197,202 ----
***************
*** 239,305 ****
   * ----------------------------------------------------------------
   */
  
- #ifdef NOT_USED
- 
- /* --------------------------------
-  *	TransactionFlushEnabled()
-  *	SetTransactionFlushEnabled()
-  *
-  *	These are used to test and set the "TransactionFlushState"
-  *	variable.  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;
- 
- int
- TransactionFlushEnabled(void)
- {
- 	return TransactionFlushState;
- }
- 
- void
- SetTransactionFlushEnabled(bool state)
- {
- 	TransactionFlushState = (state == true);
- }
- #endif
- 
- 
- /*
-  *	IsTransactionState
-  *
-  *	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;
- 	}
- 
- 	/*
- 	 * Shouldn't get here, but lint is not happy with this...
- 	 */
- 	return false;
- }
- 
  /*
   *	IsAbortedTransactionBlockState
   *
--- 238,243 ----
***************
*** 850,867 ****
  	TransactionState s = CurrentTransactionState;
  
  	/*
- 	 * check the current transaction state
- 	 */
- 	if (s->state != TRANS_DEFAULT)
- 		elog(WARNING, "StartTransaction and not in default state");
- 
- 	/*
- 	 * set the current transaction state information appropriately during
- 	 * start processing
- 	 */
- 	s->state = TRANS_START;
- 
- 	/*
  	 * Make sure we've freed any old snapshot, and reset xact state variables
  	 */
  	FreeXactSnapshot();
--- 788,793 ----
***************
*** 893,904 ****
  	 */
  	DeferredTriggerBeginXact();
  
- 	/*
- 	 * done with start processing, set current transaction state to "in
- 	 * progress"
- 	 */
- 	s->state = TRANS_INPROGRESS;
- 
  }
  
  /*
--- 819,824 ----
***************
*** 907,920 ****
  static void
  CommitTransaction(void)
  {
- 	TransactionState s = CurrentTransactionState;
- 
- 	/*
- 	 * check the current transaction state
- 	 */
- 	if (s->state != TRANS_INPROGRESS)
- 		elog(WARNING, "CommitTransaction and not in in-progress state");
- 
  	/*
  	 * Tell the trigger manager that this transaction is about to be
  	 * committed. He'll invoke all trigger deferred until XACT before we
--- 827,832 ----
***************
*** 932,943 ****
  	HOLD_INTERRUPTS();
  
  	/*
- 	 * set the current transaction state information appropriately during
- 	 * the abort processing
- 	 */
- 	s->state = TRANS_COMMIT;
- 
- 	/*
  	 * Do pre-commit processing (most of this stuff requires database
  	 * access, and in fact could still cause an error...)
  	 */
--- 844,849 ----
***************
*** 1012,1023 ****
  	pgstat_count_xact_commit();
  	AtCommit_Memory();
  
- 	/*
- 	 * done with commit processing, set current transaction state back to
- 	 * default
- 	 */
- 	s->state = TRANS_DEFAULT;
- 
  	RESUME_INTERRUPTS();
  }
  
--- 918,923 ----
***************
*** 1027,1034 ****
  static void
  AbortTransaction(void)
  {
- 	TransactionState s = CurrentTransactionState;
- 
  	/* Prevent cancel/die interrupt while cleaning up */
  	HOLD_INTERRUPTS();
  
--- 927,932 ----
***************
*** 1050,1067 ****
  	 */
  	LockWaitCancel();
  
- 	/*
- 	 * check the current transaction state
- 	 */
- 	if (s->state != TRANS_INPROGRESS)
- 		elog(WARNING, "AbortTransaction and not in in-progress state");
- 
- 	/*
- 	 * set the current transaction state information appropriately during
- 	 * the abort processing
- 	 */
- 	s->state = TRANS_ABORT;
- 
  	/* Make sure we are in a valid memory context */
  	AtAbort_Memory();
  
--- 948,953 ----
***************
*** 1122,1130 ****
  	SetReindexProcessing(InvalidOid, InvalidOid);
  	pgstat_count_xact_rollback();
  
- 	/*
- 	 * State remains TRANS_ABORT until CleanupTransaction().
- 	 */
  	RESUME_INTERRUPTS();
  }
  
--- 1008,1013 ----
***************
*** 1134,1158 ****
  static void
  CleanupTransaction(void)
  {
- 	TransactionState s = CurrentTransactionState;
- 
- 	/*
- 	 * State should still be TRANS_ABORT from AbortTransaction().
- 	 */
- 	if (s->state != TRANS_ABORT)
- 		elog(FATAL, "CleanupTransaction and not in abort state");
- 
  	/*
  	 * do abort cleanup processing
  	 */
  	AtCleanup_Portals();		/* now safe to release portal memory */
  	AtCleanup_Memory();			/* and transaction memory */
  
- 	/*
- 	 * done with abort processing, set current transaction state back to
- 	 * default
- 	 */
- 	s->state = TRANS_DEFAULT;
  }
  
  /*
--- 1017,1028 ----
***************
*** 1171,1176 ****
--- 1041,1055 ----
  			 */
  		case TBLOCK_DEFAULT:
  			StartTransaction();
+ 			s->blockState = TBLOCK_STARTED;
+ 			break;
+ 
+ 			/*
+ 			 * We should never experience this -- it means the STARTED state
+ 			 * was not changed in the previous CommitTransactionCommand.
+ 			 */
+ 		case TBLOCK_STARTED:
+ 			elog(WARNING, "StartTransactionCommand: unexpected TBLOCK_STARTED");
  			break;
  
  			/*
***************
*** 1247,1257 ****
  	switch (s->blockState)
  	{
  			/*
  			 * If we aren't in a transaction block, just do our usual
  			 * transaction commit.
  			 */
! 		case TBLOCK_DEFAULT:
  			CommitTransaction();
  			break;
  
  			/*
--- 1126,1146 ----
  	switch (s->blockState)
  	{
  			/*
+ 			 * This shouldn't happen, because it means the previous
+ 			 * StartTransactionCommand didn't set the STARTED state
+ 			 * appropiately.
+ 			 */
+ 		case TBLOCK_DEFAULT:
+ 			elog(WARNING, "CommitTransactionCommand: unexpected TBLOCK_DEFAULT");
+ 			break;
+ 
+ 			/*
  			 * If we aren't in a transaction block, just do our usual
  			 * transaction commit.
  			 */
! 		case TBLOCK_STARTED:
  			CommitTransaction();
+ 			s->blockState = TBLOCK_DEFAULT;
  			break;
  
  			/*
***************
*** 1314,1324 ****
  
  	switch (s->blockState)
  	{
  			/*
  			 * if we aren't in a transaction block, we just do the basic
  			 * abort & cleanup transaction.
  			 */
! 		case TBLOCK_DEFAULT:
  			AbortTransaction();
  			CleanupTransaction();
  			break;
--- 1203,1220 ----
  
  	switch (s->blockState)
  	{
+ 		/*
+ 		 * we aren't in a transaction, so we do nothing.
+ 		 */
+ 		case TBLOCK_DEFAULT:
+ 			break;
+ 
  			/*
  			 * if we aren't in a transaction block, we just do the basic
  			 * abort & cleanup transaction.
  			 */
! 		case TBLOCK_STARTED:
! 			s->blockState = TBLOCK_DEFAULT;
  			AbortTransaction();
  			CleanupTransaction();
  			break;
***************
*** 1332,1338 ****
  		case TBLOCK_BEGIN:
  			s->blockState = TBLOCK_ABORT;
  			AbortTransaction();
! 			/* CleanupTransaction happens when we exit TBLOCK_ABORT */
  			break;
  
  			/*
--- 1228,1234 ----
  		case TBLOCK_BEGIN:
  			s->blockState = TBLOCK_ABORT;
  			AbortTransaction();
! 			/* CleanupTransaction happens when we exit TBLOCK_ENDABORT */
  			break;
  
  			/*
***************
*** 1344,1350 ****
  		case TBLOCK_INPROGRESS:
  			s->blockState = TBLOCK_ABORT;
  			AbortTransaction();
! 			/* CleanupTransaction happens when we exit TBLOCK_ABORT */
  			break;
  
  			/*
--- 1240,1246 ----
  		case TBLOCK_INPROGRESS:
  			s->blockState = TBLOCK_ABORT;
  			AbortTransaction();
! 			/* CleanupTransaction happens when we exit TBLOCK_ENDABORT */
  			break;
  
  			/*
***************
*** 1420,1426 ****
  		/* translator: %s represents an SQL statement name */
  			 errmsg("%s cannot be executed from a function", stmtType)));
  	/* If we got past IsTransactionBlock test, should be in default state */
! 	if (CurrentTransactionState->blockState != TBLOCK_DEFAULT)
  		elog(ERROR, "cannot prevent transaction chain");
  	/* all okay */
  }
--- 1316,1323 ----
  		/* translator: %s represents an SQL statement name */
  			 errmsg("%s cannot be executed from a function", stmtType)));
  	/* If we got past IsTransactionBlock test, should be in default state */
! 	if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
! 			CurrentTransactionState->blockState != TBLOCK_STARTED)
  		elog(ERROR, "cannot prevent transaction chain");
  	/* all okay */
  }
***************
*** 1537,1543 ****
  	/*
  	 * check the current transaction state
  	 */
! 	if (s->blockState != TBLOCK_DEFAULT)
  		ereport(WARNING,
  				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
  				 errmsg("there is already a transaction in progress")));
--- 1434,1440 ----
  	/*
  	 * check the current transaction state
  	 */
! 	if (s->blockState != TBLOCK_STARTED)
  		ereport(WARNING,
  				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
  				 errmsg("there is already a transaction in progress")));
***************
*** 1551,1561 ****
  	/*
  	 * do begin processing here.  Nothing to do at present.
  	 */
- 
- 	/*
- 	 * done with begin processing, set block state to inprogress
- 	 */
- 	s->blockState = TBLOCK_INPROGRESS;
  }
  
  /*
--- 1448,1453 ----
***************
*** 1608,1652 ****
  }
  
  /*
-  *	AbortTransactionBlock
-  */
- #ifdef NOT_USED
- static void
- AbortTransactionBlock(void)
- {
- 	TransactionState s = CurrentTransactionState;
- 
- 	/*
- 	 * check the current transaction state
- 	 */
- 	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 an END TRANSACTION command.
- 		 */
- 		s->blockState = TBLOCK_ABORT;
- 		AbortTransaction();
- 		return;
- 	}
- 
- 	/*
- 	 * here, the user issued ABORT when not inside a transaction. Issue a
- 	 * WARNING and go to abort state.  The upcoming call to
- 	 * CommitTransactionCommand() will then put us back into the default
- 	 * state.
- 	 */
- 	ereport(WARNING,
- 			(errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
- 			 errmsg("there is no transaction in progress")));
- 	AbortTransaction();
- 	s->blockState = TBLOCK_ENDABORT;
- }
- #endif
- 
- /*
   *	UserAbortTransactionBlock
   */
  void
--- 1500,1505 ----
***************
*** 1669,1680 ****
  	{
  		/*
  		 * 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;
  		AbortTransaction();
  		s->blockState = TBLOCK_ENDABORT;
  		return;
--- 1522,1531 ----
  	{
  		/*
  		 * here we were inside a transaction block and we got an abort
! 		 * command from the user, so we move to the ENDABORT state and
! 		 * do abort processing so we will end up in the default state
! 		 * after the upcoming CommitTransactionCommand().
  		 */
  		AbortTransaction();
  		s->blockState = TBLOCK_ENDABORT;
  		return;
***************
*** 1706,1733 ****
  	TransactionState s = CurrentTransactionState;
  
  	/*
! 	 * Get out of any low-level transaction
  	 */
! 	switch (s->state)
  	{
! 		case TRANS_START:
! 		case TRANS_INPROGRESS:
! 		case TRANS_COMMIT:
  			/* In a transaction, so clean up */
  			AbortTransaction();
  			CleanupTransaction();
  			break;
! 		case TRANS_ABORT:
  			/* AbortTransaction already done, still need Cleanup */
  			CleanupTransaction();
  			break;
- 		case TRANS_DEFAULT:
- 			/* Not in a transaction, do nothing */
- 			break;
  	}
  
  	/*
! 	 * Now reset the high-level state
  	 */
  	s->blockState = TBLOCK_DEFAULT;
  }
--- 1557,1586 ----
  	TransactionState s = CurrentTransactionState;
  
  	/*
! 	 * Get out of any transaction
  	 */
! 	switch (s->blockState)
  	{
! 		case TBLOCK_DEFAULT:
! 			/* Not in a transaction, do nothing */
! 			break;
! 		case TBLOCK_STARTED:
! 		case TBLOCK_BEGIN:
! 		case TBLOCK_INPROGRESS:
! 		case TBLOCK_END:
  			/* In a transaction, so clean up */
  			AbortTransaction();
  			CleanupTransaction();
  			break;
! 		case TBLOCK_ABORT:
! 		case TBLOCK_ENDABORT:
  			/* AbortTransaction already done, still need Cleanup */
  			CleanupTransaction();
  			break;
  	}
  
  	/*
! 	 * Now reset the transaction state
  	 */
  	s->blockState = TBLOCK_DEFAULT;
  }
***************
*** 1740,1746 ****
  {
  	TransactionState s = CurrentTransactionState;
  
! 	if (s->blockState == TBLOCK_DEFAULT)
  		return false;
  
  	return true;
--- 1593,1599 ----
  {
  	TransactionState s = CurrentTransactionState;
  
! 	if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
  		return false;
  
  	return true;
***************
*** 1758,1764 ****
  {
  	TransactionState s = CurrentTransactionState;
  
! 	if (s->blockState == TBLOCK_DEFAULT && s->state == TRANS_DEFAULT)
  		return false;
  
  	return true;
--- 1611,1617 ----
  {
  	TransactionState s = CurrentTransactionState;
  
! 	if (s->blockState == TBLOCK_DEFAULT)
  		return false;
  
  	return true;
***************
*** 1775,1780 ****
--- 1628,1634 ----
  	switch (s->blockState)
  	{
  		case TBLOCK_DEFAULT:
+ 		case TBLOCK_STARTED:
  			return 'I';			/* idle --- not in transaction */
  		case TBLOCK_BEGIN:
  		case TBLOCK_INPROGRESS:
Index: src/backend/catalog/namespace.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql-server/src/backend/catalog/namespace.c,v
retrieving revision 1.63
diff -c -r1.63 namespace.c
*** src/backend/catalog/namespace.c	13 Feb 2004 01:08:20 -0000	1.63
--- src/backend/catalog/namespace.c	26 Mar 2004 22:52:42 -0000
***************
*** 1801,1807 ****
  	 * If we aren't inside a transaction, we cannot do database access so
  	 * cannot verify the individual names.	Must accept the list on faith.
  	 */
! 	if (source >= PGC_S_INTERACTIVE && IsTransactionState())
  	{
  		/*
  		 * Verify that all the names are either valid namespace names or
--- 1801,1807 ----
  	 * If we aren't inside a transaction, we cannot do database access so
  	 * cannot verify the individual names.	Must accept the list on faith.
  	 */
! 	if (source >= PGC_S_INTERACTIVE && IsTransactionOrTransactionBlock())
  	{
  		/*
  		 * Verify that all the names are either valid namespace names or
Index: src/backend/commands/variable.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql-server/src/backend/commands/variable.c,v
retrieving revision 1.93
diff -c -r1.93 variable.c
*** src/backend/commands/variable.c	19 Jan 2004 19:04:40 -0000	1.93
--- src/backend/commands/variable.c	26 Mar 2004 22:53:02 -0000
***************
*** 776,782 ****
  		/* not a saved ID, so look it up */
  		HeapTuple	userTup;
  
! 		if (!IsTransactionState())
  		{
  			/*
  			 * Can't do catalog lookups, so fail.  The upshot of this is
--- 776,782 ----
  		/* not a saved ID, so look it up */
  		HeapTuple	userTup;
  
! 		if (!IsTransactionOrTransactionBlock())
  		{
  			/*
  			 * Can't do catalog lookups, so fail.  The upshot of this is
Index: src/backend/utils/mb/mbutils.c
===================================================================
RCS file: /home/alvherre/cvs/pgsql-server/src/backend/utils/mb/mbutils.c,v
retrieving revision 1.46
diff -c -r1.46 mbutils.c
*** src/backend/utils/mb/mbutils.c	15 Mar 2004 10:41:25 -0000	1.46
--- src/backend/utils/mb/mbutils.c	26 Mar 2004 22:53:33 -0000
***************
*** 114,120 ****
  	 * postgresql.conf.  Which would probably be a stupid thing to do
  	 * anyway.
  	 */
! 	if (!IsTransactionState())
  		return -1;
  
  	/*
--- 114,120 ----
  	 * postgresql.conf.  Which would probably be a stupid thing to do
  	 * anyway.
  	 */
! 	if (!IsTransactionOrTransactionBlock())
  		return -1;
  
  	/*
***************
*** 232,238 ****
  	unsigned char *result;
  	Oid			proc;
  
! 	if (!IsTransactionState())
  		return src;
  
  	if (src_encoding == dest_encoding)
--- 232,238 ----
  	unsigned char *result;
  	Oid			proc;
  
! 	if (!IsTransactionOrTransactionBlock())
  		return src;
  
  	if (src_encoding == dest_encoding)
Index: src/include/access/xact.h
===================================================================
RCS file: /home/alvherre/cvs/pgsql-server/src/include/access/xact.h,v
retrieving revision 1.61
diff -c -r1.61 xact.h
*** src/include/access/xact.h	11 Feb 2004 22:55:25 -0000	1.61
--- src/include/access/xact.h	27 Mar 2004 02:52:30 -0000
***************
*** 41,63 ****
  extern bool XactReadOnly;
  
  /*
-  *	transaction states - transaction state from server perspective
-  */
- typedef enum TransState
- {
- 	TRANS_DEFAULT,
- 	TRANS_START,
- 	TRANS_INPROGRESS,
- 	TRANS_COMMIT,
- 	TRANS_ABORT
- } TransState;
- 
- /*
   *	transaction block states - transaction state of client queries
   */
  typedef enum TBlockState
  {
  	TBLOCK_DEFAULT,
  	TBLOCK_BEGIN,
  	TBLOCK_INPROGRESS,
  	TBLOCK_END,
--- 41,52 ----
  extern bool XactReadOnly;
  
  /*
   *	transaction block states - transaction state of client queries
   */
  typedef enum TBlockState
  {
  	TBLOCK_DEFAULT,
+ 	TBLOCK_STARTED,
  	TBLOCK_BEGIN,
  	TBLOCK_INPROGRESS,
  	TBLOCK_END,
***************
*** 79,85 ****
  	CommandId		commandId;
  	AbsoluteTime	startTime;
  	int				startTimeUsec;
- 	TransState		state;
  	TBlockState		blockState;
  } TransactionStateData;
  
--- 68,73 ----
***************
*** 123,129 ****
   *		extern definitions
   * ----------------
   */
- extern bool IsTransactionState(void);
  extern bool IsAbortedTransactionBlockState(void);
  extern TransactionId GetCurrentTransactionId(void);
  extern CommandId GetCurrentCommandId(void);
--- 111,116 ----
