diff --git a/doc/src/sgml/ref/reset.sgml b/doc/src/sgml/ref/reset.sgml
index 1af55703cd3..a21aa0239fb 100644
--- a/doc/src/sgml/ref/reset.sgml
+++ b/doc/src/sgml/ref/reset.sgml
@@ -1,5 +1,5 @@
@@ -66,6 +66,12 @@ SET variable TO DEFAULT
switches, or per-database or per-user default settings. See the
Administrator's Guide for details.
+
+
+ See the SHOW> manual page for details on the transaction
+ behavior of RESET>.
+
+
diff --git a/doc/src/sgml/ref/set.sgml b/doc/src/sgml/ref/set.sgml
index bc3688a5652..1c9bd31e1e9 100644
--- a/doc/src/sgml/ref/set.sgml
+++ b/doc/src/sgml/ref/set.sgml
@@ -1,5 +1,5 @@
@@ -108,6 +108,12 @@ SET [ SESSION | LOCAL ] TIME ZONE { timezoneSET value will take effect.
+
+ With autocommit> set to off>, SET>
+ does not start a new transaction block. See the
+ autocommit> section of the documentation for details.
+
+
Here are additional details about a few of the parameters that can be set:
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index a7215c89ce0..2936e9b4c70 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
@@ -1235,16 +1235,32 @@ env PGOPTIONS='-c geqo=off' psql
that is not inside an explicit transaction block (that is, unless a
BEGIN> with no matching COMMIT> has been
given).
- If set to false, PostgreSQL will commit
- the effects of commands only on receiving an explicit
- COMMIT> command. This mode can also be thought of as
- implicitly issuing BEGIN> whenever a command is received
- and PostgreSQL is not already inside
- a transaction block.
- The default is true, for compatibility with historical
- PostgreSQL behavior. But for maximum
- compatibility with the SQL specification, set it to false.
+ If set to false, PostgreSQL will
+ commit the commands only when receiving an explicit
+ COMMIT> command. This mode can also be thought of as
+ implicitly issuing BEGIN> whenever a command is
+ received that is not already inside a transaction block. The
+ default is true, for compatibility with historical
+ PostgreSQL behavior. However, for
+ maximum compatibility with the SQL specification, set it to
+ false.
+
+
+ With autocommit> set to false, SET>,
+ SHOW>, and RESET> do not start new
+ transaction blocks. They are run in their own transactions.
+ Once another command is issued, multi-statement transaction
+ behavior begins and any SET>, SHOW>, or
+ RESET> commands are considered to be part of the
+ transaction, i.e. they are committed or rolled back depending
+ on the completion status of the transaction. To have
+ SET>, SHOW>, and RESET>
+ commands at the start of a transaction, use BEGIN>
+ first.
+
+
+
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index f3bd34fde27..1b603266095 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.299 2002/10/08 17:17:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.300 2002/10/09 04:59:38 momjian Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -76,6 +76,7 @@ char *debug_query_string; /* for pgmonitor and
CommandDest whereToSendOutput = Debug;
extern int StatementTimeout;
+extern bool autocommit;
static bool dontExecute = false;
@@ -122,7 +123,7 @@ static int ReadCommand(StringInfo inBuf);
static List *pg_parse_query(StringInfo query_string, Oid *typev, int nargs);
static List *pg_analyze_and_rewrite(Node *parsetree);
static void start_xact_command(void);
-static void finish_xact_command(void);
+static void finish_xact_command(bool forceCommit);
static void SigHupHandler(SIGNAL_ARGS);
static void FloatExceptionHandler(SIGNAL_ARGS);
static const char *CreateCommandTag(Node *parsetree);
@@ -825,7 +826,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
*/
if (isTransactionStmt)
{
- finish_xact_command();
+ finish_xact_command(false);
xact_started = false;
}
} /* end loop over queries generated from a
@@ -843,7 +844,19 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
*/
if (lnext(parsetree_item) == NIL && xact_started)
{
- finish_xact_command();
+ /*
+ * Don't allow SET/SHOW/RESET to start a new transaction
+ * with autocommit off. We do this by forcing a COMMIT
+ * when these commands start a transaction.
+ */
+ if (autocommit ||
+ IsTransactionState() ||
+ (strcmp(commandTag, "SET") != 0 &&
+ strcmp(commandTag, "SHOW") != 0 &&
+ strcmp(commandTag, "RESET") != 0))
+ finish_xact_command(false);
+ else
+ finish_xact_command(true);
xact_started = false;
}
@@ -878,7 +891,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
* will only happen if the querystring was empty.)
*/
if (xact_started)
- finish_xact_command();
+ finish_xact_command(false);
if (save_Log_duration)
{
@@ -907,7 +920,7 @@ start_xact_command(void)
}
static void
-finish_xact_command(void)
+finish_xact_command(bool forceCommit)
{
/* Invoke IMMEDIATE constraint triggers */
DeferredTriggerEndQuery();
@@ -915,7 +928,7 @@ finish_xact_command(void)
/* Now commit the command */
elog(DEBUG1, "CommitTransactionCommand");
- CommitTransactionCommand(false);
+ CommitTransactionCommand(forceCommit);
#ifdef SHOW_MEMORY_STATS
/* Print mem stats at each commit for leak tracking */
@@ -1720,7 +1733,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
- puts("$Revision: 1.299 $ $Date: 2002/10/08 17:17:19 $\n");
+ puts("$Revision: 1.300 $ $Date: 2002/10/09 04:59:38 $\n");
}
/*
@@ -1923,7 +1936,7 @@ PostgresMain(int argc, char *argv[], const char *username)
}
/* commit the function-invocation transaction */
- finish_xact_command();
+ finish_xact_command(false);
break;
/*