From d015dcbe4eeaebe6084983945ef68a642c38e0e1 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 9 Oct 2002 04:59:38 +0000 Subject: [PATCH] Have SET not start transaction when autocommit off, with doc updates. --- doc/src/sgml/ref/reset.sgml | 8 +++++++- doc/src/sgml/ref/set.sgml | 8 +++++++- doc/src/sgml/runtime.sgml | 38 ++++++++++++++++++++++++++----------- src/backend/tcop/postgres.c | 31 +++++++++++++++++++++--------- 4 files changed, 63 insertions(+), 22 deletions(-) diff --git a/doc/src/sgml/ref/reset.sgml b/doc/src/sgml/ref/reset.sgml index 1af55703cd..a21aa0239f 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 bc3688a565..1c9bd31e1e 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 a7215c89ce..2936e9b4c7 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 f3bd34fde2..1b60326609 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; /* -- GitLab