]> granicus.if.org Git - postgresql/commitdiff
Implement isolation levels read uncommitted and repeatable read as acting
authorPeter Eisentraut <peter_e@gmx.net>
Thu, 6 Nov 2003 22:08:15 +0000 (22:08 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Thu, 6 Nov 2003 22:08:15 +0000 (22:08 +0000)
like the next higher one.

15 files changed:
doc/src/sgml/mvcc.sgml
doc/src/sgml/ref/set_transaction.sgml
doc/src/sgml/ref/start_transaction.sgml
doc/src/sgml/runtime.sgml
src/backend/catalog/sql_features.txt
src/backend/commands/trigger.c
src/backend/commands/variable.c
src/backend/executor/execMain.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/utils/adt/ri_triggers.c
src/backend/utils/misc/guc.c
src/backend/utils/time/tqual.c
src/bin/psql/tab-complete.c
src/include/access/xact.h

index e46c5928c78c5c19ecb64d847b6ee103b1969b65..a56d4a18a92ff1ce85005732b88d6fd4106750ad 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.40 2003/11/04 09:55:38 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.41 2003/11/06 22:08:14 petere Exp $
 -->
 
  <chapter id="mvcc">
@@ -206,8 +206,25 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.40 2003/11/04 09:55:38 petere
     </table>
 
    <para>
-    <productname>PostgreSQL</productname>
-    offers the Read Committed and Serializable isolation levels.
+    In <productname>PostgreSQL</productname>, you can use all four
+    possible transaction isolation levels.  Internally, there are only
+    two distinct isolation levels, which correspond to the levels Read
+    Committed and Serializable.  When you select the level Read
+    Uncommitted you really get Read Committed, and when you select
+    Repeatable Read you really get Serializable, so the actual
+    isolation level may be stricter than what you select.  This is
+    permitted by the SQL standard: the four isolation levels only
+    define which phenomena must not happen, they do not define which
+    phenomena must happen.  The reason that PostgreSQL only provides
+    two isolation levels is that this is the only sensible way to map
+    the isolation levels to the multiversion concurrency control
+    architecture.  The behavior of the available isolation levels is
+    detailed in the following subsections.
+   </para>
+
+   <para>
+    To set the transaction isolation level of a transaction, use the
+    command <xref linkend="sql-set-transaction">.
    </para>
 
   <sect2 id="xact-read-committed">
index cbe41d7175fa3beb1e7575df5a02132e94d84196..809b884d6ba626e780ac5ad3d5379f65ec43d168 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/set_transaction.sgml,v 1.17 2003/09/11 21:42:20 momjian Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/set_transaction.sgml,v 1.18 2003/11/06 22:08:14 petere Exp $ -->
 <refentry id="SQL-SET-TRANSACTION">
  <refmeta>
   <refentrytitle id="SQL-SET-TRANSACTION-TITLE">SET TRANSACTION</refentrytitle>
  <refsynopsisdiv>
 <synopsis>
 SET TRANSACTION
-    [ ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE } ] [ READ WRITE | READ ONLY ]
+    [ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
+    [ READ WRITE | READ ONLY ]
+
 SET SESSION CHARACTERISTICS AS TRANSACTION
-    [ ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE } ] [ READ WRITE | READ ONLY ]
+    [ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
+    [ READ WRITE | READ ONLY ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -76,8 +79,11 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
     </varlistentry>
    </variablelist>
 
-   The transaction isolation level cannot be set after the first query
-   or data-modification statement (<command>SELECT</command>,
+   The level <literal>READ UNCOMMITTED</literal> is mapped to
+   <literal>READ COMMITTED</literal>, the level <literal>REPEATABLE
+   READ</literal> is mapped to <literal>SERIALIZABLE</literal>, The
+   transaction isolation level cannot be set after the first query or
+   data-modification statement (<command>SELECT</command>,
    <command>INSERT</command>, <command>DELETE</command>,
    <command>UPDATE</command>, <command>FETCH</command>,
    <command>COPY</command>) of a transaction has been executed.  See
@@ -122,13 +128,12 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>'
   <para>
    Both commands are defined in the <acronym>SQL</acronym> standard.
    <literal>SERIALIZABLE</literal> is the default transaction
-   isolation level in the standard; in <productname>PostgreSQL</productname> the default is
-   ordinarily <literal>READ COMMITTED</literal>, but you can change it as
-   described above.  <productname>PostgreSQL</productname> does not
-   provide the isolation levels <literal>READ UNCOMMITTED</literal>
-   and <literal>REPEATABLE READ</literal>. Because of multiversion
-   concurrency control, the <literal>SERIALIZABLE</literal> level is
-   not truly serializable. See <xref linkend="mvcc"> for details.
+   isolation level in the standard; in
+   <productname>PostgreSQL</productname> the default is ordinarily
+   <literal>READ COMMITTED</literal>, but you can change it as
+   described above.  Because of multiversion concurrency control, the
+   <literal>SERIALIZABLE</literal> level is not truly
+   serializable. See <xref linkend="mvcc"> for details.
   </para>
 
   <para>
index 60089d71ee98123b07437f4acacc1d324e378370..7b1a2d583915bcb53f71e1e84344cef49404c197 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/start_transaction.sgml,v 1.7 2003/09/09 18:28:53 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/start_transaction.sgml,v 1.8 2003/11/06 22:08:14 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -20,7 +20,9 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-START TRANSACTION [ ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE } ] [ READ WRITE | READ ONLY ]
+START TRANSACTION
+    [ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
+    [ READ WRITE | READ ONLY ]
 </synopsis>
  </refsynopsisdiv>
 
index e6a9478cbb12ce6fcbd1bec0797c42a1ff55a69e..d23c78d0cc5f209cfa061ff98418538edcf6a898 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.216 2003/11/04 09:55:38 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.217 2003/11/06 22:08:14 petere Exp $
 -->
 
 <Chapter Id="runtime">
@@ -2043,10 +2043,12 @@ SET ENABLE_SEQSCAN TO OFF;
       <term><varname>default_transaction_isolation</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-        Each SQL transaction has an isolation level, which can be either
-        <quote>read committed</quote> or <quote>serializable</quote>.
-        This parameter controls the default isolation level of each new
-        transaction. The default is <quote>read committed</quote>.
+        Each SQL transaction has an isolation level, which can be
+        either <quote>read uncommitted</quote>, <quote>read
+        committed</quote>, <quote>repeatable read</quote>, or
+        <quote>serializable</quote>.  This parameter controls the
+        default isolation level of each new transaction. The default
+        is <quote>read committed</quote>.
        </para>
 
        <para>
index 4cd309dd65e4f59d71b254db43f34c7e7545f4c2..667bb93ba8c52a7baff6ec332a3ab96a48c5b51d 100644 (file)
@@ -156,10 +156,10 @@ F051      Basic date and time     07      LOCALTIME       YES
 F051   Basic date and time     08      LOCALTIMESTAMP  YES     
 F052   Intervals and datetime arithmetic                       YES     
 F081   UNION and EXCEPT in views                       YES     
-F111   Isolation levels other than SERIALIZABLE                        NO      
-F111   Isolation levels other than SERIALIZABLE        01      READ UNCOMMITTED isolation level        NO      
+F111   Isolation levels other than SERIALIZABLE                        YES     
+F111   Isolation levels other than SERIALIZABLE        01      READ UNCOMMITTED isolation level        YES     behaves like READ COMMITTED
 F111   Isolation levels other than SERIALIZABLE        02      READ COMMITTED isolation level  YES     
-F111   Isolation levels other than SERIALIZABLE        03      REPEATABLE READ isolation level NO      
+F111   Isolation levels other than SERIALIZABLE        03      REPEATABLE READ isolation level YES     behaves like SERIALIZABLE
 F121   Basic diagnostics management                    NO      
 F121   Basic diagnostics management    01      GET DIAGNOSTICS statement       NO      
 F121   Basic diagnostics management    02      SET TRANSACTION statement: DIAGNOSTICS SIZE clause      NO      
index d2cc87e43d5739a91f5c17b6113d270a2b315a08..9a603a6f0424ef09cd2842fdb77186fe42e63413 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.159 2003/10/02 06:34:03 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.160 2003/11/06 22:08:14 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1576,7 +1576,7 @@ ltrmark:;
 
                        case HeapTupleUpdated:
                                ReleaseBuffer(buffer);
-                               if (XactIsoLevel == XACT_SERIALIZABLE)
+                               if (IsXactIsoLevelSerializable)
                                        ereport(ERROR,
                                                        (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
                                                         errmsg("could not serialize access due to concurrent update")));
index 7c862a5b3ace2c98d8fda819c7299bb8c01a09c7..f763163957edd4fa64ef5883f9c6e6eb47d9593a 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.88 2003/09/25 06:57:59 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.89 2003/11/06 22:08:14 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -640,11 +640,21 @@ assign_XactIsoLevel(const char *value, bool doit, bool interactive)
                if (doit)
                        XactIsoLevel = XACT_SERIALIZABLE;
        }
+       else if (strcmp(value, "repeatable read") == 0)
+       {
+               if (doit)
+                       XactIsoLevel = XACT_REPEATABLE_READ;
+       }
        else if (strcmp(value, "read committed") == 0)
        {
                if (doit)
                        XactIsoLevel = XACT_READ_COMMITTED;
        }
+       else if (strcmp(value, "read uncommitted") == 0)
+       {
+               if (doit)
+                       XactIsoLevel = XACT_READ_UNCOMMITTED;
+       }
        else if (strcmp(value, "default") == 0)
        {
                if (doit)
@@ -659,10 +669,19 @@ assign_XactIsoLevel(const char *value, bool doit, bool interactive)
 const char *
 show_XactIsoLevel(void)
 {
-       if (XactIsoLevel == XACT_SERIALIZABLE)
-               return "serializable";
-       else
-               return "read committed";
+       switch (XactIsoLevel)
+       {
+               case XACT_READ_UNCOMMITTED:
+                       return "read uncommitted";
+               case XACT_READ_COMMITTED:
+                       return "read committed";
+               case XACT_REPEATABLE_READ:
+                       return "repeatable read";
+               case XACT_SERIALIZABLE:
+                       return "serializable";
+               default:
+                       return "bogus";
+       }
 }
 
 
index bfdc94c6d5169ddfaff7bbca8013686f949dc119..1e6c3ffe30c2f874767aa87571cdd0935bf8465c 100644 (file)
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.220 2003/10/01 21:30:52 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.221 2003/11/06 22:08:14 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1139,7 +1139,7 @@ lnext:    ;
                                                        break;
 
                                                case HeapTupleUpdated:
-                                                       if (XactIsoLevel == XACT_SERIALIZABLE)
+                                                       if (IsXactIsoLevelSerializable)
                                                                ereport(ERROR,
                                                                                (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
                                                                                 errmsg("could not serialize access due to concurrent update")));
@@ -1440,7 +1440,7 @@ ldelete:;
                        break;
 
                case HeapTupleUpdated:
-                       if (XactIsoLevel == XACT_SERIALIZABLE)
+                       if (IsXactIsoLevelSerializable)
                                ereport(ERROR,
                                                (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
                                                 errmsg("could not serialize access due to concurrent update")));
@@ -1576,7 +1576,7 @@ lreplace:;
                        break;
 
                case HeapTupleUpdated:
-                       if (XactIsoLevel == XACT_SERIALIZABLE)
+                       if (IsXactIsoLevelSerializable)
                                ereport(ERROR,
                                                (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
                                                 errmsg("could not serialize access due to concurrent update")));
index b73aa6f9eef5198aabb0d49ec822802ab6ddb82c..5f0b0f4e5da4034a0d5e7c145db6d567dd84e7fb 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.436 2003/10/02 06:34:04 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.437 2003/11/06 22:08:14 petere Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -342,7 +342,7 @@ static void doNegateFloat(Value *v);
 
        DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
        DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
-    DESC DISTINCT DO DOMAIN_P DOUBLE_P DROP
+       DESC DISTINCT DO DOMAIN_P DOUBLE_P DROP
 
        EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
        EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
@@ -380,7 +380,7 @@ static void doNegateFloat(Value *v);
        PRECISION PRESERVE PREPARE PRIMARY 
        PRIOR PRIVILEGES PROCEDURAL PROCEDURE
 
-       READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RENAME REPLACE
+       READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RENAME REPEATABLE REPLACE
        RESET RESTART RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS
        RULE
 
@@ -393,7 +393,7 @@ static void doNegateFloat(Value *v);
        TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
        TRUNCATE TRUSTED TYPE_P
 
-       UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
+       UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
        UPDATE USAGE USER USING
 
        VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
@@ -922,7 +922,9 @@ var_value:  opt_boolean
                                { $$ = makeAConst($1); }
                ;
 
-iso_level:     READ COMMITTED                                                  { $$ = "read committed"; }
+iso_level:     READ UNCOMMITTED                                                { $$ = "read uncommitted"; }
+                       | READ COMMITTED                                                { $$ = "read committed"; }
+                       | REPEATABLE READ                                               { $$ = "repeatable read"; }
                        | SERIALIZABLE                                                  { $$ = "serializable"; }
                ;
 
@@ -7407,6 +7409,7 @@ unreserved_keyword:
                        | REINDEX
                        | RELATIVE_P
                        | RENAME
+                       | REPEATABLE
                        | REPLACE
                        | RESET
                        | RESTART
@@ -7445,6 +7448,7 @@ unreserved_keyword:
                        | TRUNCATE
                        | TRUSTED
                        | TYPE_P
+                       | UNCOMMITTED
                        | UNENCRYPTED
                        | UNKNOWN
                        | UNLISTEN
index c4048b4c1d89d770f6e12c88540f0d620bf23c83..6d42a13ef87046153df0eb9acd4ec26fc52a904b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.141 2003/08/04 02:40:01 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.142 2003/11/06 22:08:15 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -251,6 +251,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"reindex", REINDEX},
        {"relative", RELATIVE_P},
        {"rename", RENAME},
+       {"repeatable", REPEATABLE},
        {"replace", REPLACE},
        {"reset", RESET},
        {"restart", RESTART},
@@ -307,6 +308,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"truncate", TRUNCATE},
        {"trusted", TRUSTED},
        {"type", TYPE_P},
+       {"uncommitted", UNCOMMITTED},
        {"unencrypted", UNENCRYPTED},
        {"union", UNION},
        {"unique", UNIQUE},
index d0e3e9c0817ac017414ce2a41d3bdab9f2ec63f6..7caca437449a9a941d4b0a02e470c8a55d3d522f 100644 (file)
@@ -17,7 +17,7 @@
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.63 2003/10/31 03:58:20 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.64 2003/11/06 22:08:15 petere Exp $
  *
  * ----------
  */
@@ -3073,7 +3073,7 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
         * rows under current snapshot that wouldn't be visible per the
         * transaction snapshot).
         */
-       if (XactIsoLevel == XACT_SERIALIZABLE)
+       if (IsXactIsoLevelSerializable)
        {
                useCurrentSnapshot = detectNewRows;
        }
index c3e9a0ec8180224df08c6d82c77e4b8f27995231..fd9def3e6cde4610ab8078dd6b8b06fcd6243c97 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.164 2003/10/18 22:59:09 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.165 2003/11/06 22:08:15 petere Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -1346,7 +1346,7 @@ static struct config_string ConfigureNamesString[] =
                {"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
                        gettext_noop("Sets the transaction isolation level of each new transaction."),
                        gettext_noop("Each SQL transaction has an isolation level, which "
-                                "can be either \"read committed\" or \"serializable\".")
+                                "can be either \"read uncommitted\", \"read committed\", \"repeatable read\", or \"serializable\".")
                },
                &default_iso_level_string,
                "read committed", assign_defaultxactisolevel, NULL
@@ -4238,11 +4238,21 @@ assign_defaultxactisolevel(const char *newval, bool doit, bool interactive)
                if (doit)
                        DefaultXactIsoLevel = XACT_SERIALIZABLE;
        }
+       else if (strcasecmp(newval, "repeatable read") == 0)
+       {
+               if (doit)
+                       DefaultXactIsoLevel = XACT_REPEATABLE_READ;
+       }
        else if (strcasecmp(newval, "read committed") == 0)
        {
                if (doit)
                        DefaultXactIsoLevel = XACT_READ_COMMITTED;
        }
+       else if (strcasecmp(newval, "read uncommitted") == 0)
+       {
+               if (doit)
+                       DefaultXactIsoLevel = XACT_READ_UNCOMMITTED;
+       }
        else
                return NULL;
        return newval;
index d7d22b77866878b6634347a30ed78ed855a0c117..fa59e0f17528d4075b80888babb7d3f7951e002b 100644 (file)
@@ -16,7 +16,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.70 2003/10/01 21:30:52 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.71 2003/11/06 22:08:15 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -984,7 +984,7 @@ SetQuerySnapshot(void)
                return;
        }
 
-       if (XactIsoLevel == XACT_SERIALIZABLE)
+       if (IsXactIsoLevelSerializable)
                QuerySnapshot = SerializableSnapshot;
        else
                QuerySnapshot = GetSnapshotData(&QuerySnapshotData, false);
index d4ceb9a3e9e9be6142043732bc0ebced66a4a0c4..5ac058e8deb1a3eb2342d51e9e7d84f03d6d4a82 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.91 2003/10/30 21:37:38 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.92 2003/11/06 22:08:15 petere Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -466,7 +466,7 @@ psql_completion(char *text, int start, int end)
                "ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT",
                "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE", "DROP", "EXECUTE",
                "EXPLAIN", "FETCH", "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY",
-               "PREPARE", "REINDEX", "RESET", "REVOKE", "ROLLBACK", "SELECT", "SET", "SHOW",
+               "PREPARE", "REINDEX", "RESET", "REVOKE", "ROLLBACK", "SELECT", "SET", "SHOW", "START",
                "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", NULL
        };
 
@@ -1101,30 +1101,36 @@ psql_completion(char *text, int start, int end)
                         strcasecmp(prev_wd, "SHOW") == 0)
                COMPLETE_WITH_LIST(pgsql_variables);
        /* Complete "SET TRANSACTION" */
-       else if ((strcasecmp(prev2_wd, "SET") == 0 &&
-                         strcasecmp(prev_wd, "TRANSACTION") == 0) ||
-                        (strcasecmp(prev4_wd, "SESSION") == 0 &&
-                         strcasecmp(prev3_wd, "CHARACTERISTICS") == 0 &&
-                         strcasecmp(prev2_wd, "AS") == 0 &&
-                         strcasecmp(prev_wd, "TRANSACTION") == 0))
+       else if ((strcasecmp(prev2_wd, "SET") == 0
+                         && strcasecmp(prev_wd, "TRANSACTION") == 0)
+                        || (strcasecmp(prev2_wd, "START") == 0
+                                && strcasecmp(prev_wd, "TRANSACTION") == 0)
+                        || (strcasecmp(prev4_wd, "SESSION") == 0
+                                && strcasecmp(prev3_wd, "CHARACTERISTICS") == 0
+                                && strcasecmp(prev2_wd, "AS") == 0
+                                && strcasecmp(prev_wd, "TRANSACTION") == 0))
        {
                static const char * const my_list[] =
                {"ISOLATION", "READ", NULL};
 
                COMPLETE_WITH_LIST(my_list);
        }
-       else if (strcasecmp(prev3_wd, "SET") == 0 &&
-                        strcasecmp(prev2_wd, "TRANSACTION") == 0 &&
-                        strcasecmp(prev_wd, "ISOLATION") == 0)
+       else if ((strcasecmp(prev3_wd, "SET") == 0
+                         || strcasecmp(prev3_wd, "START") == 0
+                         || (strcasecmp(prev4_wd, "CHARACTERISTICS") == 0
+                                 && strcasecmp(prev3_wd, "AS") == 0))
+                        && strcasecmp(prev2_wd, "TRANSACTION") == 0
+                        && strcasecmp(prev_wd, "ISOLATION") == 0)
                COMPLETE_WITH_CONST("LEVEL");
-       else if ((strcasecmp(prev4_wd, "SET") == 0 ||
-                         strcasecmp(prev4_wd, "AS") == 0) &&
-                        strcasecmp(prev3_wd, "TRANSACTION") == 0 &&
-                        strcasecmp(prev2_wd, "ISOLATION") == 0 &&
-                        strcasecmp(prev_wd, "LEVEL") == 0)
+       else if ((strcasecmp(prev4_wd, "SET") == 0
+                         || strcasecmp(prev4_wd, "START") == 0
+                         || strcasecmp(prev4_wd, "AS") == 0)
+                        && strcasecmp(prev3_wd, "TRANSACTION") == 0
+                        && strcasecmp(prev2_wd, "ISOLATION") == 0
+                        && strcasecmp(prev_wd, "LEVEL") == 0)
        {
                static const char * const my_list[] =
-               {"READ", "SERIALIZABLE", NULL};
+               {"READ", "REPEATABLE", "SERIALIZABLE", NULL};
 
                COMPLETE_WITH_LIST(my_list);
        }
@@ -1132,7 +1138,17 @@ psql_completion(char *text, int start, int end)
                         strcasecmp(prev3_wd, "ISOLATION") == 0 &&
                         strcasecmp(prev2_wd, "LEVEL") == 0 &&
                         strcasecmp(prev_wd, "READ") == 0)
-               COMPLETE_WITH_CONST("COMMITTED");
+       {
+               static const char * const my_list[] =
+               {"UNCOMMITTED", "COMMITTED", NULL};
+
+               COMPLETE_WITH_LIST(my_list);
+       }
+       else if (strcasecmp(prev4_wd, "TRANSACTION") == 0 &&
+                        strcasecmp(prev3_wd, "ISOLATION") == 0 &&
+                        strcasecmp(prev2_wd, "LEVEL") == 0 &&
+                        strcasecmp(prev_wd, "REPEATABLE") == 0)
+               COMPLETE_WITH_CONST("READ");
        else if ((strcasecmp(prev3_wd, "SET") == 0 ||
                          strcasecmp(prev3_wd, "AS") == 0) &&
                         strcasecmp(prev2_wd, "TRANSACTION") == 0 &&
@@ -1200,6 +1216,10 @@ psql_completion(char *text, int start, int end)
                }
        }
 
+/* START TRANSACTION */
+       else if (strcasecmp(prev_wd, "START") == 0)
+               COMPLETE_WITH_CONST("TRANSACTION");
+
 /* TRUNCATE */
        else if (strcasecmp(prev_wd, "TRUNCATE") == 0)
                COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
index d95c3df794586a1b20b87fd70c32c373846ca921..33a95bad997a9e31e3df2128e19b6f0047899d34 100644 (file)
@@ -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.57 2003/10/16 16:50:41 tgl Exp $
+ * $Id: xact.h,v 1.58 2003/11/06 22:08:15 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
 /*
  * Xact isolation levels
  */
-#define XACT_DIRTY_READ                        0               /* not implemented */
+#define XACT_READ_UNCOMMITTED  0
 #define XACT_READ_COMMITTED            1
-#define XACT_REPEATABLE_READ   2               /* not implemented */
+#define XACT_REPEATABLE_READ   2
 #define XACT_SERIALIZABLE              3
 
 extern int     DefaultXactIsoLevel;
 extern int     XactIsoLevel;
 
+/*
+ * We only implement two distinct levels, so this is a convenience to
+ * check which level we're really using internally.
+ */
+#define IsXactIsoLevelSerializable ((XactIsoLevel == XACT_REPEATABLE_READ || XactIsoLevel == XACT_SERIALIZABLE))
+
 /* Xact read-only state */
 extern bool DefaultXactReadOnly;
 extern bool XactReadOnly;