Fix bad interaction between NOTIFY processing and V3 extended query

protocol, per report from Igor Shevchenko.  NOTIFY thought it could
do its thing if transaction blockState is TBLOCK_DEFAULT, but in
reality it had better check the low-level transaction state is
TRANS_DEFAULT as well.  Formerly it was not possible to wait for the
client in a state where the first is true and the second is not ...
but now we can have such a state.  Minor cleanup in StartTransaction()
as well.
This commit is contained in:
Tom Lane 2003-10-16 16:50:41 +00:00
parent 839cea8814
commit 90b2202975
4 changed files with 37 additions and 24 deletions
src
backend
access/transam
commands
tcop
include/access

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.155 2003/09/28 23:26:20 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.156 2003/10/16 16:50:41 tgl Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
@ -202,7 +202,7 @@ static TransactionStateData CurrentTransactionStateData = {
* perspective */ * perspective */
}; };
TransactionState CurrentTransactionState = &CurrentTransactionStateData; static TransactionState CurrentTransactionState = &CurrentTransactionStateData;
/* /*
* User-tweakable parameters * User-tweakable parameters
@ -826,20 +826,11 @@ StartTransaction(void)
{ {
TransactionState s = CurrentTransactionState; TransactionState s = CurrentTransactionState;
FreeXactSnapshot();
XactIsoLevel = DefaultXactIsoLevel;
XactReadOnly = DefaultXactReadOnly;
/* /*
* Check the current transaction state. If the transaction system is * check the current transaction state
* 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_INPROGRESS) if (s->state != TRANS_DEFAULT)
return; elog(WARNING, "StartTransaction and not in default state");
/* /*
* set the current transaction state information appropriately during * set the current transaction state information appropriately during
@ -847,6 +838,13 @@ StartTransaction(void)
*/ */
s->state = TRANS_START; s->state = TRANS_START;
/*
* Make sure we've freed any old snapshot, and reset xact state variables
*/
FreeXactSnapshot();
XactIsoLevel = DefaultXactIsoLevel;
XactReadOnly = DefaultXactReadOnly;
/* /*
* generate a new transaction id * generate a new transaction id
*/ */
@ -1725,6 +1723,24 @@ IsTransactionBlock(void)
return true; return true;
} }
/*
* IsTransactionOrTransactionBlock --- are we within either a transaction
* or a transaction block? (The backend is only really "idle" when this
* returns false.)
*
* This should match up with IsTransactionBlock and IsTransactionState.
*/
bool
IsTransactionOrTransactionBlock(void)
{
TransactionState s = CurrentTransactionState;
if (s->blockState == TBLOCK_DEFAULT && s->state == TRANS_DEFAULT)
return false;
return true;
}
/* /*
* TransactionBlockStatusCode - return status code to send in ReadyForQuery * TransactionBlockStatusCode - return status code to send in ReadyForQuery
*/ */

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.101 2003/10/01 21:30:52 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.102 2003/10/16 16:50:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -91,10 +91,6 @@
#include "utils/syscache.h" #include "utils/syscache.h"
/* stuff that we really ought not be touching directly :-( */
extern TransactionState CurrentTransactionState;
/* /*
* State for outbound notifies consists of a list of all relnames NOTIFYed * State for outbound notifies consists of a list of all relnames NOTIFYed
* in the current transaction. We do not actually perform a NOTIFY until * in the current transaction. We do not actually perform a NOTIFY until
@ -717,7 +713,7 @@ Async_NotifyHandler(SIGNAL_ARGS)
void void
EnableNotifyInterrupt(void) EnableNotifyInterrupt(void)
{ {
if (CurrentTransactionState->blockState != TRANS_DEFAULT) if (IsTransactionOrTransactionBlock())
return; /* not really idle */ return; /* not really idle */
/* /*

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.372 2003/10/09 02:40:18 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.373 2003/10/16 16:50:41 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
@ -2660,7 +2660,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.372 $ $Date: 2003/10/09 02:40:18 $\n"); puts("$Revision: 1.373 $ $Date: 2003/10/16 16:50:41 $\n");
} }
/* /*
@ -2796,7 +2796,7 @@ PostgresMain(int argc, char *argv[], const char *username)
{ {
pgstat_report_tabstat(); pgstat_report_tabstat();
if (IsTransactionBlock()) if (IsTransactionOrTransactionBlock())
{ {
set_ps_display("idle in transaction"); set_ps_display("idle in transaction");
pgstat_report_activity("<IDLE> in transaction"); pgstat_report_activity("<IDLE> in transaction");

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: xact.h,v 1.56 2003/09/28 23:26:20 tgl Exp $ * $Id: xact.h,v 1.57 2003/10/16 16:50:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -129,6 +129,7 @@ extern void AbortCurrentTransaction(void);
extern void BeginTransactionBlock(void); extern void BeginTransactionBlock(void);
extern void EndTransactionBlock(void); extern void EndTransactionBlock(void);
extern bool IsTransactionBlock(void); extern bool IsTransactionBlock(void);
extern bool IsTransactionOrTransactionBlock(void);
extern char TransactionBlockStatusCode(void); extern char TransactionBlockStatusCode(void);
extern void UserAbortTransactionBlock(void); extern void UserAbortTransactionBlock(void);
extern void AbortOutOfAnyTransaction(void); extern void AbortOutOfAnyTransaction(void);