AUTOCOMMIT mode is now an available backend GUC variable; setting it
authorTom Lane
Fri, 30 Aug 2002 22:18:07 +0000 (22:18 +0000)
committerTom Lane
Fri, 30 Aug 2002 22:18:07 +0000 (22:18 +0000)
to false provides more SQL-spec-compliant behavior than we had before.
I am not sure that setting it false is actually a good idea yet; there
is a lot of client-side code that will probably be broken by turning
autocommit off.  But it's a start.

Loosely based on a patch by David Van Wie.

15 files changed:
doc/src/sgml/release.sgml
doc/src/sgml/runtime.sgml
src/backend/access/transam/xact.c
src/backend/bootstrap/bootparse.y
src/backend/bootstrap/bootstrap.c
src/backend/catalog/namespace.c
src/backend/commands/async.c
src/backend/commands/indexcmds.c
src/backend/commands/vacuum.c
src/backend/tcop/postgres.c
src/backend/utils/init/postinit.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/bin/psql/tab-complete.c
src/include/access/xact.h

index 78606b68e94e3264e1faa9659370d517885c4769..3ba21bc1ab79f6a9bbfdeffe3d914046b4ceedfd 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
 worries about funny characters.
 -->
 
+No-autocommit mode is available (set autocommit to off)
 Substantial improvements in functionality for functions returning sets
 Client libraries older than 6.3 no longer supported (version 0 protocol removed)
 PREPARE statement allows caching query plans for interactive statements
index d97e368765da62ba396ad3e43715ec5b3b656070..fbbe6274dc091287864d57238fc2e5d9a929cd27 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -1135,6 +1135,29 @@ env PGOPTIONS='-c geqo=off' psql
 
    
     
+     
+      AUTOCOMMIT (bool)
+      autocommit
+      
+       
+        If set to true, PostgreSQL will
+   automatically do a COMMIT after each successful command
+   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.
+       
+      
+     
+
      
       AUSTRALIAN_TIMEZONES (bool)
       Australian time zones
index c9b60daef563cc764a6ef6429ad3d6fb92fd9325..1c1121e3e11a864edd417a2fcb035ae6aa1d8ade 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.130 2002/08/06 02:36:33 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.131 2002/08/30 22:18:05 tgl Exp $
  *
  * NOTES
  *     Transaction aborts can now occur two ways:
@@ -220,10 +220,15 @@ TransactionState CurrentTransactionState = &CurrentTransactionStateData;
 int            DefaultXactIsoLevel = XACT_READ_COMMITTED;
 int            XactIsoLevel;
 
+bool       autocommit = true;
+
 int            CommitDelay = 0;    /* precommit delay in microseconds */
 int            CommitSiblings = 5; /* number of concurrent xacts needed to
                                 * sleep */
 
+
+static bool suppressChain = false;
+
 static void (*_RollbackFunc) (void *) = NULL;
 static void *_RollbackData = NULL;
 
@@ -1149,13 +1154,24 @@ CleanupTransaction(void)
 
 /* --------------------------------
  *     StartTransactionCommand
+ *
+ * preventChain, if true, forces autocommit behavior at the next
+ * CommitTransactionCommand call.
  * --------------------------------
  */
 void
-StartTransactionCommand(void)
+StartTransactionCommand(bool preventChain)
 {
    TransactionState s = CurrentTransactionState;
 
+   /*
+    * Remember if caller wants to prevent autocommit-off chaining.
+    * This is only allowed if not already in a transaction block.
+    */
+   suppressChain = preventChain;
+   if (preventChain && s->blockState != TBLOCK_DEFAULT)
+       elog(ERROR, "StartTransactionCommand: can't prevent chain");
+
    switch (s->blockState)
    {
            /*
@@ -1231,21 +1247,41 @@ StartTransactionCommand(void)
 
 /* --------------------------------
  *     CommitTransactionCommand
+ *
+ * forceCommit = true forces autocommit behavior even when autocommit is off.
  * --------------------------------
  */
 void
-CommitTransactionCommand(void)
+CommitTransactionCommand(bool forceCommit)
 {
    TransactionState s = CurrentTransactionState;
 
    switch (s->blockState)
    {
            /*
-            * if we aren't in a transaction block, we just do our usual
-            * transaction commit
+            * If we aren't in a transaction block, and we are doing
+            * autocommit, just do our usual transaction commit.  But
+            * if we aren't doing autocommit, start a transaction block
+            * automatically by switching to INPROGRESS state.  (We handle
+            * this choice here, and not earlier, so that an explicit BEGIN
+            * issued in autocommit-off mode won't issue strange warnings.)
+            *
+            * Autocommit mode is forced by either a true forceCommit parameter
+            * to me, or a true preventChain parameter to the preceding
+            * StartTransactionCommand call.  This is needed so that commands
+            * like VACUUM can ensure that the right things happen.
             */
        case TBLOCK_DEFAULT:
-           CommitTransaction();
+           if (autocommit || forceCommit || suppressChain)
+               CommitTransaction();
+           else
+           {
+               BeginTransactionBlock();
+               Assert(s->blockState == TBLOCK_INPROGRESS);
+               /* This code must match the TBLOCK_INPROGRESS case below: */
+               CommandCounterIncrement();
+               MemoryContextResetAndDeleteChildren(TransactionCommandContext);
+           }
            break;
 
            /*
@@ -1406,7 +1442,10 @@ BeginTransactionBlock(void)
    s->blockState = TBLOCK_BEGIN;
 
    /*
-    * do begin processing
+    * do begin processing.  NOTE: if you put anything here, check that
+    * it behaves properly in both autocommit-on and autocommit-off modes.
+    * In the latter case we will already have done some work in the new
+    * transaction.
     */
 
    /*
index f2d31356d9c73a9f9d25ca22d3ce6d944abbb5b5..a50e9ac88d25e5ff3ad866f078d531c082777c59 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.50 2002/07/20 05:16:56 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.51 2002/08/30 22:18:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -55,7 +55,7 @@
 static void
 do_start()
 {
-   StartTransactionCommand();
+   StartTransactionCommand(true);
    elog(DEBUG3, "start transaction");
 }
 
@@ -63,7 +63,7 @@ do_start()
 static void
 do_end()
 {
-   CommitTransactionCommand();
+   CommitTransactionCommand(true);
    elog(DEBUG3, "commit transaction");
    if (isatty(0))
    {
index ae4a86d1d4298d7496af783a549252de4f686c32..ef9ee498dbce4e60135aa2ae8006c5c7041a5de3 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.138 2002/08/17 15:12:06 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.139 2002/08/30 22:18:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -448,7 +448,7 @@ BootstrapMain(int argc, char *argv[])
    SetProcessingMode(BootstrapProcessing);
 
    /* clean up processing */
-   StartTransactionCommand();
+   StartTransactionCommand(true);
    cleanup();
 
    /* not reached, here to make compiler happy */
@@ -821,7 +821,7 @@ cleanup()
    }
    if (boot_reldesc != NULL)
        closerel(NULL);
-   CommitTransactionCommand();
+   CommitTransactionCommand(true);
    proc_exit(Warnings);
 }
 
index 33fc901e86717a5430eb704acadad34c492c98bc..f8a271f908201087bbb88c789857502b3481510b 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.32 2002/08/29 00:17:02 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.33 2002/08/30 22:18:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1610,11 +1610,11 @@ RemoveTempRelationsCallback(void)
    {
        /* Need to ensure we have a usable transaction. */
        AbortOutOfAnyTransaction();
-       StartTransactionCommand();
+       StartTransactionCommand(true);
 
        RemoveTempRelations(myTempNamespace);
 
-       CommitTransactionCommand();
+       CommitTransactionCommand(true);
    }
 }
 
index 4c7c5f211024609eec122ecfccf9edc8d2d30e36..97e1dc17ae29288a66d8a05c1bdf32c5dc0e5b37 100644 (file)
@@ -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.88 2002/08/05 03:29:16 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.89 2002/08/30 22:18:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -400,9 +400,9 @@ Async_UnlistenOnExit(void)
     */
    AbortOutOfAnyTransaction();
    /* Now we can do the unlisten */
-   StartTransactionCommand();
+   StartTransactionCommand(true);
    Async_UnlistenAll();
-   CommitTransactionCommand();
+   CommitTransactionCommand(true);
 }
 
 /*
@@ -749,7 +749,7 @@ ProcessIncomingNotify(void)
 
    notifyInterruptOccurred = 0;
 
-   StartTransactionCommand();
+   StartTransactionCommand(true);
 
    lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
    tdesc = RelationGetDescr(lRel);
@@ -803,7 +803,7 @@ ProcessIncomingNotify(void)
     */
    heap_close(lRel, NoLock);
 
-   CommitTransactionCommand();
+   CommitTransactionCommand(true);
 
    /*
     * Must flush the notify messages to ensure frontend gets them
index ec7e1482798a7242c8747ea3e47d6b9ebde55585..b951fccb98ca8bccabe8387e8d8fa045f1c1c028 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.85 2002/08/29 15:56:20 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.86 2002/08/30 22:18:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -735,15 +735,16 @@ ReindexDatabase(const char *dbname, bool force, bool all)
    heap_close(relationRelation, AccessShareLock);
 
    /* Now reindex each rel in a separate transaction */
-   CommitTransactionCommand();
+   CommitTransactionCommand(true);
    for (i = 0; i < relcnt; i++)
    {
-       StartTransactionCommand();
+       StartTransactionCommand(true);
        if (reindex_relation(relids[i], force))
            elog(NOTICE, "relation %u was reindexed", relids[i]);
-       CommitTransactionCommand();
+       CommitTransactionCommand(true);
    }
-   StartTransactionCommand();
+   /* Tell xact.c not to chain the upcoming commit */
+   StartTransactionCommand(true);
 
    MemoryContextDelete(private_context);
 }
index 4fc3b1d3d90b1da43c4f3eb46a159ac1a74a65c7..cda893fab75e007fdf010b8fe60e14fa49b217e2 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.234 2002/08/13 20:14:24 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.235 2002/08/30 22:18:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -273,7 +273,7 @@ vacuum(VacuumStmt *vacstmt)
        }
 
        /* matches the StartTransaction in PostgresMain() */
-       CommitTransactionCommand();
+       CommitTransactionCommand(true);
    }
 
    /*
@@ -296,14 +296,14 @@ vacuum(VacuumStmt *vacstmt)
             * return (else we leak memory while processing multiple tables).
             */
            if (vacstmt->vacuum)
-               StartTransactionCommand();
+               StartTransactionCommand(true);
            else
                old_context = MemoryContextSwitchTo(anl_context);
 
            analyze_rel(relid, vacstmt);
 
            if (vacstmt->vacuum)
-               CommitTransactionCommand();
+               CommitTransactionCommand(true);
            else
            {
                MemoryContextSwitchTo(old_context);
@@ -319,8 +319,12 @@ vacuum(VacuumStmt *vacstmt)
    {
        /* here, we are not in a transaction */
 
-       /* matches the CommitTransaction in PostgresMain() */
-       StartTransactionCommand();
+       /*
+        * This matches the CommitTransaction waiting for us in PostgresMain().
+        * We tell xact.c not to chain the upcoming commit, so that a VACUUM
+        * doesn't start a transaction block, even when autocommit is off.
+        */
+       StartTransactionCommand(true);
 
        /*
         * If we did a database-wide VACUUM, update the database's pg_database
@@ -703,7 +707,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
    Oid         toast_relid;
 
    /* Begin a transaction for vacuuming this relation */
-   StartTransactionCommand();
+   StartTransactionCommand(true);
 
    /*
     * Check for user-requested abort.  Note we want this to be inside a
@@ -719,7 +723,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
                              ObjectIdGetDatum(relid),
                              0, 0, 0))
    {
-       CommitTransactionCommand();
+       CommitTransactionCommand(true);
        return;
    }
 
@@ -750,7 +754,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
        elog(WARNING, "Skipping \"%s\" --- only table or database owner can VACUUM it",
             RelationGetRelationName(onerel));
        relation_close(onerel, lmode);
-       CommitTransactionCommand();
+       CommitTransactionCommand(true);
        return;
    }
 
@@ -763,7 +767,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
        elog(WARNING, "Skipping \"%s\" --- can not process indexes, views or special system tables",
             RelationGetRelationName(onerel));
        relation_close(onerel, lmode);
-       CommitTransactionCommand();
+       CommitTransactionCommand(true);
        return;
    }
 
@@ -799,7 +803,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
    /*
     * Complete the transaction and free all temporary memory used.
     */
-   CommitTransactionCommand();
+   CommitTransactionCommand(true);
 
    /*
     * If the relation has a secondary toast rel, vacuum that too while we
index 6988972e1d6e327ad59bf22bf88318fadaec0614..3947755a2e321ed0dd30d383e96b00d0c5b9e485 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.286 2002/08/29 23:39:05 inoue Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.287 2002/08/30 22:18:06 tgl Exp $
  *
  * NOTES
  *   this is the "main" module of the postgres backend and
@@ -860,7 +860,7 @@ static void
 start_xact_command(void)
 {
    elog(DEBUG1, "StartTransactionCommand");
-   StartTransactionCommand();
+   StartTransactionCommand(false);
 }
 
 static void
@@ -872,7 +872,7 @@ finish_xact_command(void)
    /* Now commit the command */
    elog(DEBUG1, "CommitTransactionCommand");
 
-   CommitTransactionCommand();
+   CommitTransactionCommand(false);
 
 #ifdef SHOW_MEMORY_STATS
    /* Print mem stats at each commit for leak tracking */
@@ -1664,7 +1664,7 @@ PostgresMain(int argc, char *argv[], const char *username)
    if (!IsUnderPostmaster)
    {
        puts("\nPOSTGRES backend interactive interface ");
-       puts("$Revision: 1.286 $ $Date: 2002/08/29 23:39:05 $\n");
+       puts("$Revision: 1.287 $ $Date: 2002/08/30 22:18:06 $\n");
    }
 
    /*
index b02e371a8182f6739d5645b103dcd29f5dcd36a5..82f4f632e58a4e23c56fb18c5f526c2e4d287a34 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.111 2002/08/29 21:02:12 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.112 2002/08/30 22:18:06 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -330,7 +330,7 @@ InitPostgres(const char *dbname, const char *username)
 
    /* start a new transaction here before access to db */
    if (!bootstrap)
-       StartTransactionCommand();
+       StartTransactionCommand(true);
 
    /*
     * It's now possible to do real access to the system catalogs.
@@ -394,7 +394,7 @@ InitPostgres(const char *dbname, const char *username)
 
    /* close the transaction we started above */
    if (!bootstrap)
-       CommitTransactionCommand();
+       CommitTransactionCommand(true);
 
    /*
     * Check a normal user hasn't connected to a superuser reserved slot.
index e394e2cd872a51fb87421429f13e193d6598dc7f..6000493a85357dc154005dc6cc69af98cfdf8bf5 100644 (file)
@@ -5,7 +5,7 @@
  * command, configuration file, and command line options.
  * See src/backend/utils/misc/README for more information.
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.88 2002/08/30 16:50:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.89 2002/08/30 22:18:07 tgl Exp $
  *
  * Copyright 2000 by PostgreSQL Global Development Group
  * Written by Peter Eisentraut .
@@ -58,6 +58,7 @@ extern int    PreAuthDelay;
 extern int AuthenticationTimeout;
 extern int StatementTimeout;
 extern int CheckPointTimeout;
+extern bool autocommit;
 extern int CommitDelay;
 extern int CommitSiblings;
 extern bool FixBTree;
@@ -487,6 +488,10 @@ static struct config_bool
        { "db_user_namespace", PGC_SIGHUP }, &Db_user_namespace,
        false, NULL, NULL
    },
+   {
+       { "autocommit", PGC_USERSET }, &autocommit, 
+       true, NULL, NULL
+   },
 
    {
        { NULL, 0 }, NULL, false, NULL, NULL
index 11e9caaabcf97e4059a52dece4322352e2c32d8b..1141e3c6042eb98ece730fc8f16ca283bf928c4b 100644 (file)
@@ -68,8 +68,6 @@
 #checkpoint_segments = 3   # in logfile segments, min 1, 16MB each
 #checkpoint_timeout = 300  # range 30-3600, in seconds
 #
-#wal_files = 0 # range 0-64
-#
 #commit_delay = 0      # range 0-100000, in microseconds
 #commit_siblings = 5       # range 1-1000
 #
 #
 #  Misc
 #
+#autocommit = true
 #dynamic_library_path = '$libdir'
 #search_path = '$user,public'
 #datestyle = 'iso, us'
index 98dfce1792687851d963a8f476bdd0f0a0bebb4a..0ff42b5ee3e86dfcdbadc2b28d9537a492918e5c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2000-2002 by PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.59 2002/08/30 18:15:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.60 2002/08/30 22:18:07 tgl Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -246,6 +246,7 @@ psql_completion(char *text, int start, int end)
        "australian_timezones",
        "password_encryption",
        "transform_null_equals",
+       "autocommit",
 
        "default_statistics_target",
        "geqo_threshold",
index 5448b68f72f4cbbb33ce73d81b1ee9d04da0630d..b74b9d4cdca2d2d5bd616add3a602b50b72e5f30 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: xact.h,v 1.44 2002/06/20 20:29:43 momjian Exp $
+ * $Id: xact.h,v 1.45 2002/08/30 22:18:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -105,8 +105,8 @@ extern AbsoluteTime GetCurrentTransactionStartTimeUsec(int *usec);
 extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
 extern bool CommandIdIsCurrentCommandId(CommandId cid);
 extern void CommandCounterIncrement(void);
-extern void StartTransactionCommand(void);
-extern void CommitTransactionCommand(void);
+extern void StartTransactionCommand(bool preventChain);
+extern void CommitTransactionCommand(bool forceCommit);
 extern void AbortCurrentTransaction(void);
 extern void BeginTransactionBlock(void);
 extern void EndTransactionBlock(void);