Hackers,
This is a cleanup patch for access/transam/xact.c. It is a trimmed down
version of the previous patch, with the controversial part removed. It
only removes some #ifdef NOT_USED code, and adds a new TBLOCK state
which signals the fact that StartTransaction() has been executed.
Please review and apply if OK.
--
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"El sabio habla porque tiene algo que decir;
el tonto, porque tiene que decir algo" (Platon).
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 30 Mar 2004 20:44:15 -0000
***************
*** 239,274 ****
* ----------------------------------------------------------------
*/
- #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
*
--- 239,244 ----
***************
*** 1171,1176 ****
--- 1141,1155 ----
*/
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;
/*
***************
*** 1202,1210 ****
*/
case TBLOCK_END:
elog(WARNING, "StartTransactionCommand: unexpected
TBLOCK_END");
- s->blockState = TBLOCK_DEFAULT;
CommitTransaction();
StartTransaction();
break;
/*
--- 1181,1189 ----
*/
case TBLOCK_END:
elog(WARNING, "StartTransactionCommand: unexpected
TBLOCK_END");
CommitTransaction();
StartTransaction();
+ s->blockState = TBLOCK_DEFAULT;
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;
/*
--- 1226,1246 ----
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,1326 ****
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;
/*
--- 1303,1322 ----
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:
AbortTransaction();
CleanupTransaction();
+ s->blockState = TBLOCK_DEFAULT;
break;
/*
***************
*** 1330,1338 ****
* things.
*/
case TBLOCK_BEGIN:
- s->blockState = TBLOCK_ABORT;
AbortTransaction();
! /* CleanupTransaction happens when we exit TBLOCK_ABORT */
break;
/*
--- 1326,1334 ----
* things.
*/
case TBLOCK_BEGIN:
AbortTransaction();
! s->blockState = TBLOCK_ABORT;
! /* CleanupTransaction happens when we exit TBLOCK_ENDABORT */
break;
/*
***************
*** 1342,1350 ****
* restore us to a normal state.
*/
case TBLOCK_INPROGRESS:
- s->blockState = TBLOCK_ABORT;
AbortTransaction();
! /* CleanupTransaction happens when we exit TBLOCK_ABORT */
break;
/*
--- 1338,1346 ----
* restore us to a normal state.
*/
case TBLOCK_INPROGRESS:
AbortTransaction();
! s->blockState = TBLOCK_ABORT;
! /* CleanupTransaction happens when we exit TBLOCK_ENDABORT */
break;
/*
***************
*** 1353,1361 ****
* and put us back into the default state.
*/
case TBLOCK_END:
- s->blockState = TBLOCK_DEFAULT;
AbortTransaction();
CleanupTransaction();
break;
/*
--- 1349,1357 ----
* and put us back into the default state.
*/
case TBLOCK_END:
AbortTransaction();
CleanupTransaction();
+ s->blockState = TBLOCK_DEFAULT;
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 */
}
--- 1416,1423 ----
/* 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 */
}
***************
*** 1534,1561 ****
{
TransactionState s = CurrentTransactionState;
! /*
! * 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")));
! /*
! * set the current transaction block state information appropriately
! * during begin processing
! */
! s->blockState = TBLOCK_BEGIN;
! /*
! * do begin processing here. Nothing to do at present.
! */
! /*
! * done with begin processing, set block state to inprogress
! */
! s->blockState = TBLOCK_INPROGRESS;
}
/*
--- 1531,1567 ----
{
TransactionState s = CurrentTransactionState;
! switch (s->blockState) {
! /*
! * We are inside a transaction, so allow a transaction block
! * to begin.
! */
! case TBLOCK_STARTED:
! s->blockState = TBLOCK_BEGIN;
! break;
! /* Already a transaction block in progress. */
! case TBLOCK_INPROGRESS:
! ereport(WARNING,
! (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
! errmsg("there is already a transaction in
progress")));
! /*
! * This shouldn't happen, because a transaction in aborted
state
! * will not be allowed to call BeginTransactionBlock.
! */
! case TBLOCK_ABORT:
! elog(WARNING, "BeginTransactionBlock: unexpected
TBLOCK_ABORT");
! break;
! /* These cases are invalid. Reject them altogether. */
! case TBLOCK_DEFAULT:
! case TBLOCK_BEGIN:
! case TBLOCK_ENDABORT:
! case TBLOCK_END:
! elog(FATAL, "BeginTransactionBlock: not in a user-allowed
state!");
! break;
! }
}
/*
***************
*** 1566,1650 ****
{
TransactionState s = CurrentTransactionState;
! /*
! * check the current transaction state
! */
! 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, the user issued COMMIT 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;
! }
! /*
! * 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
--- 1572,1622 ----
{
TransactionState s = CurrentTransactionState;
! switch (s->blockState) {
/*
* 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
*/
! case TBLOCK_INPROGRESS:
! s->blockState = TBLOCK_END;
! break;
! /*
! * 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.
! */
! case TBLOCK_ABORT:
! s->blockState = TBLOCK_ENDABORT;
! break;
! case TBLOCK_STARTED:
! /*
! * here, the user issued COMMIT 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;
! break;
! /* These cases are invalid. Reject them altogether. */
! case TBLOCK_DEFAULT:
! case TBLOCK_BEGIN:
! case TBLOCK_ENDABORT:
! case TBLOCK_END:
! elog(FATAL, "EndTransactionBlock and not in a user-allowed
state");
! break;
}
}
/*
* UserAbortTransactionBlock
***************
*** 1669,1678 ****
{
/*
* 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();
--- 1641,1649 ----
{
/*
* 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().
*/
s->blockState = TBLOCK_ABORT;
AbortTransaction();
***************
*** 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;
}
--- 1677,1706 ----
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;
--- 1713,1719 ----
{
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;
--- 1731,1737 ----
{
TransactionState s = CurrentTransactionState;
! if (s->blockState == TBLOCK_DEFAULT)
return false;
return true;
***************
*** 1775,1780 ****
--- 1748,1754 ----
switch (s->blockState)
{
case TBLOCK_DEFAULT:
+ case TBLOCK_STARTED:
return 'I'; /* idle --- not in transaction
*/
case TBLOCK_BEGIN:
case TBLOCK_INPROGRESS:
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 30 Mar 2004 20:45:17 -0000
***************
*** 58,63 ****
--- 58,64 ----
typedef enum TBlockState
{
TBLOCK_DEFAULT,
+ TBLOCK_STARTED,
TBLOCK_BEGIN,
TBLOCK_INPROGRESS,
TBLOCK_END,
---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend