Commit 90b22029 authored by Tom Lane's avatar Tom Lane

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.
parent 839cea88
......@@ -8,7 +8,7 @@
*
*
* 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
* Transaction aborts can now occur two ways:
......@@ -202,7 +202,7 @@ static TransactionStateData CurrentTransactionStateData = {
* perspective */
};
TransactionState CurrentTransactionState = &CurrentTransactionStateData;
static TransactionState CurrentTransactionState = &CurrentTransactionStateData;
/*
* User-tweakable parameters
......@@ -826,20 +826,11 @@ StartTransaction(void)
{
TransactionState s = CurrentTransactionState;
FreeXactSnapshot();
XactIsoLevel = DefaultXactIsoLevel;
XactReadOnly = DefaultXactReadOnly;
/*
* 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
* check the current transaction state
*/
if (s->state == TRANS_INPROGRESS)
return;
if (s->state != TRANS_DEFAULT)
elog(WARNING, "StartTransaction and not in default state");
/*
* set the current transaction state information appropriately during
......@@ -847,6 +838,13 @@ StartTransaction(void)
*/
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
*/
......@@ -1725,6 +1723,24 @@ IsTransactionBlock(void)
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
*/
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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"
/* stuff that we really ought not be touching directly :-( */
extern TransactionState CurrentTransactionState;
/*
* State for outbound notifies consists of a list of all relnames NOTIFYed
* in the current transaction. We do not actually perform a NOTIFY until
......@@ -717,7 +713,7 @@ Async_NotifyHandler(SIGNAL_ARGS)
void
EnableNotifyInterrupt(void)
{
if (CurrentTransactionState->blockState != TRANS_DEFAULT)
if (IsTransactionOrTransactionBlock())
return; /* not really idle */
/*
......
......@@ -8,7 +8,7 @@
*
*
* 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
* this is the "main" module of the postgres backend and
......@@ -2660,7 +2660,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster)
{
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();
if (IsTransactionBlock())
if (IsTransactionOrTransactionBlock())
{
set_ps_display("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) 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 EndTransactionBlock(void);
extern bool IsTransactionBlock(void);
extern bool IsTransactionOrTransactionBlock(void);
extern char TransactionBlockStatusCode(void);
extern void UserAbortTransactionBlock(void);
extern void AbortOutOfAnyTransaction(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment