From ad4ce7aa5b7385a0481009d1b8d8774435b03b0d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 13 Oct 2002 16:55:05 +0000 Subject: [PATCH] Make SET really not start a transaction. --- doc/src/sgml/ref/reset.sgml | 4 ++-- doc/src/sgml/ref/set.sgml | 7 +++--- doc/src/sgml/ref/show.sgml | 9 +++++++- doc/src/sgml/runtime.sgml | 16 ++++++------- src/backend/tcop/postgres.c | 45 +++++++++++++++---------------------- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/doc/src/sgml/ref/reset.sgml b/doc/src/sgml/ref/reset.sgml index a21aa0239f..ed36d549c5 100644 --- a/doc/src/sgml/ref/reset.sgml +++ b/doc/src/sgml/ref/reset.sgml @@ -1,5 +1,5 @@ @@ -68,7 +68,7 @@ SET variable TO DEFAULT - See the SHOW manual page for details on the transaction + See the SET 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 4ee941be37..71e35b50a5 100644 --- a/doc/src/sgml/ref/set.sgml +++ b/doc/src/sgml/ref/set.sgml @@ -1,5 +1,5 @@ @@ -109,9 +109,10 @@ SET [ SESSION | LOCAL ] TIME ZONE { timezone - With autocommit set to off, SET + Even with autocommit set to off, SET does not start a new transaction block. See the - autocommit section of the documentation for details. + autocommit section of the Administrator's + Guide for details. diff --git a/doc/src/sgml/ref/show.sgml b/doc/src/sgml/ref/show.sgml index f42893ffb2..2f086ee8a2 100644 --- a/doc/src/sgml/ref/show.sgml +++ b/doc/src/sgml/ref/show.sgml @@ -1,5 +1,5 @@ @@ -60,6 +60,13 @@ SHOW ALL command-line flag when starting the postmaster. + + + Even with autocommit set to off, SHOW + does not start a new transaction block. See the + autocommit section of the Administrator's + Guide for details. + diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 2936e9b4c7..fc878e678c 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ @@ -1236,7 +1236,7 @@ env PGOPTIONS='-c geqo=off' psql BEGIN with no matching COMMIT has been given). If set to false, PostgreSQL will - commit the commands only when receiving an explicit + commit only upon 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 @@ -1247,16 +1247,16 @@ env PGOPTIONS='-c geqo=off' psql - With autocommit set to false, SET, + Even 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 + Once another command is issued, a transaction block + 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 + on the completion status of the transaction. To execute a + SET, SHOW, or RESET + command at the start of a transaction block, use BEGIN first. diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 1b60326609..1b636c18d7 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.300 2002/10/09 04:59:38 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.301 2002/10/13 16:55:05 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -76,7 +76,6 @@ char *debug_query_string; /* for pgmonitor and CommandDest whereToSendOutput = Debug; extern int StatementTimeout; -extern bool autocommit; static bool dontExecute = false; @@ -620,15 +619,11 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ foreach(parsetree_item, parsetree_list) { Node *parsetree = (Node *) lfirst(parsetree_item); - bool isTransactionStmt; const char *commandTag; char completionTag[COMPLETION_TAG_BUFSIZE]; List *querytree_list, *querytree_item; - /* Transaction control statements need some special handling */ - isTransactionStmt = IsA(parsetree, TransactionStmt); - /* * First we set the command-completion tag to the main query (as * opposed to each of the others that may be generated by analyze @@ -653,7 +648,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ { bool allowit = false; - if (isTransactionStmt) + if (IsA(parsetree, TransactionStmt)) { TransactionStmt *stmt = (TransactionStmt *) parsetree; @@ -698,6 +693,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ foreach(querytree_item, querytree_list) { Query *querytree = (Query *) lfirst(querytree_item); + bool endTransactionBlock = false; /* Make sure we are in a transaction command */ if (!xact_started) @@ -733,6 +729,13 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ IsA(utilityStmt, ReindexStmt)) SetQuerySnapshot(); + /* end transaction block if transaction or variable stmt */ + if (IsA(utilityStmt, TransactionStmt) || + IsA(utilityStmt, VariableSetStmt) || + IsA(utilityStmt, VariableShowStmt) || + IsA(utilityStmt, VariableResetStmt)) + endTransactionBlock = true; + if (querytree->originalQuery) { /* utility statement can override default tag string */ @@ -805,7 +808,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ * visible to subsequent ones. In particular we'd better do * so before checking constraints. */ - if (!isTransactionStmt) + if (!endTransactionBlock) CommandCounterIncrement(); /* @@ -820,13 +823,13 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ MemoryContextResetAndDeleteChildren(CurrentMemoryContext); /* - * If this was a transaction control statement, commit it and - * arrange to start a new xact command for the next command - * (if any). + * If this was a transaction control statement or a variable + * set/show/reset statement, commit it and arrange to start a + * new xact command for the next command (if any). */ - if (isTransactionStmt) + if (endTransactionBlock) { - finish_xact_command(false); + finish_xact_command(true); xact_started = false; } } /* end loop over queries generated from a @@ -844,19 +847,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */ */ if (lnext(parsetree_item) == NIL && xact_started) { - /* - * 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); + finish_xact_command(false); xact_started = false; } @@ -1733,7 +1724,7 @@ PostgresMain(int argc, char *argv[], const char *username) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.300 $ $Date: 2002/10/09 04:59:38 $\n"); + puts("$Revision: 1.301 $ $Date: 2002/10/13 16:55:05 $\n"); } /*