Commit 96889392 authored by Peter Eisentraut's avatar Peter Eisentraut

Implement isolation levels read uncommitted and repeatable read as acting

like the next higher one.
parent 144a2ecd
<!-- <!--
$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"> <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 ...@@ -206,8 +206,25 @@ $Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.40 2003/11/04 09:55:38 petere
</table> </table>
<para> <para>
<productname>PostgreSQL</productname> In <productname>PostgreSQL</productname>, you can use all four
offers the Read Committed and Serializable isolation levels. 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> </para>
<sect2 id="xact-read-committed"> <sect2 id="xact-read-committed">
......
<!-- $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"> <refentry id="SQL-SET-TRANSACTION">
<refmeta> <refmeta>
<refentrytitle id="SQL-SET-TRANSACTION-TITLE">SET TRANSACTION</refentrytitle> <refentrytitle id="SQL-SET-TRANSACTION-TITLE">SET TRANSACTION</refentrytitle>
...@@ -17,9 +17,12 @@ ...@@ -17,9 +17,12 @@
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
SET TRANSACTION 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 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> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -76,8 +79,11 @@ SET SESSION CHARACTERISTICS AS TRANSACTION ...@@ -76,8 +79,11 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
</varlistentry> </varlistentry>
</variablelist> </variablelist>
The transaction isolation level cannot be set after the first query The level <literal>READ UNCOMMITTED</literal> is mapped to
or data-modification statement (<command>SELECT</command>, <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>INSERT</command>, <command>DELETE</command>,
<command>UPDATE</command>, <command>FETCH</command>, <command>UPDATE</command>, <command>FETCH</command>,
<command>COPY</command>) of a transaction has been executed. See <command>COPY</command>) of a transaction has been executed. See
...@@ -122,13 +128,12 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>' ...@@ -122,13 +128,12 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>'
<para> <para>
Both commands are defined in the <acronym>SQL</acronym> standard. Both commands are defined in the <acronym>SQL</acronym> standard.
<literal>SERIALIZABLE</literal> is the default transaction <literal>SERIALIZABLE</literal> is the default transaction
isolation level in the standard; in <productname>PostgreSQL</productname> the default is isolation level in the standard; in
ordinarily <literal>READ COMMITTED</literal>, but you can change it as <productname>PostgreSQL</productname> the default is ordinarily
described above. <productname>PostgreSQL</productname> does not <literal>READ COMMITTED</literal>, but you can change it as
provide the isolation levels <literal>READ UNCOMMITTED</literal> described above. Because of multiversion concurrency control, the
and <literal>REPEATABLE READ</literal>. Because of multiversion <literal>SERIALIZABLE</literal> level is not truly
concurrency control, the <literal>SERIALIZABLE</literal> level is serializable. See <xref linkend="mvcc"> for details.
not truly serializable. See <xref linkend="mvcc"> for details.
</para> </para>
<para> <para>
......
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -20,7 +20,9 @@ PostgreSQL documentation ...@@ -20,7 +20,9 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <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> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
......
<!-- <!--
$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"> <Chapter Id="runtime">
...@@ -2043,10 +2043,12 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -2043,10 +2043,12 @@ SET ENABLE_SEQSCAN TO OFF;
<term><varname>default_transaction_isolation</varname> (<type>string</type>)</term> <term><varname>default_transaction_isolation</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
Each SQL transaction has an isolation level, which can be either Each SQL transaction has an isolation level, which can be
<quote>read committed</quote> or <quote>serializable</quote>. either <quote>read uncommitted</quote>, <quote>read
This parameter controls the default isolation level of each new committed</quote>, <quote>repeatable read</quote>, or
transaction. The default is <quote>read committed</quote>. <quote>serializable</quote>. This parameter controls the
default isolation level of each new transaction. The default
is <quote>read committed</quote>.
</para> </para>
<para> <para>
......
...@@ -156,10 +156,10 @@ F051 Basic date and time 07 LOCALTIME YES ...@@ -156,10 +156,10 @@ F051 Basic date and time 07 LOCALTIME YES
F051 Basic date and time 08 LOCALTIMESTAMP YES F051 Basic date and time 08 LOCALTIMESTAMP YES
F052 Intervals and datetime arithmetic YES F052 Intervals and datetime arithmetic YES
F081 UNION and EXCEPT in views YES F081 UNION and EXCEPT in views YES
F111 Isolation levels other than SERIALIZABLE NO F111 Isolation levels other than SERIALIZABLE YES
F111 Isolation levels other than SERIALIZABLE 01 READ UNCOMMITTED isolation level NO 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 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 NO
F121 Basic diagnostics management 01 GET DIAGNOSTICS statement NO F121 Basic diagnostics management 01 GET DIAGNOSTICS statement NO
F121 Basic diagnostics management 02 SET TRANSACTION statement: DIAGNOSTICS SIZE clause NO F121 Basic diagnostics management 02 SET TRANSACTION statement: DIAGNOSTICS SIZE clause NO
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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:; ...@@ -1576,7 +1576,7 @@ ltrmark:;
case HeapTupleUpdated: case HeapTupleUpdated:
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
if (XactIsoLevel == XACT_SERIALIZABLE) if (IsXactIsoLevelSerializable)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("could not serialize access due to concurrent update"))); errmsg("could not serialize access due to concurrent update")));
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -640,11 +640,21 @@ assign_XactIsoLevel(const char *value, bool doit, bool interactive)
if (doit) if (doit)
XactIsoLevel = XACT_SERIALIZABLE; XactIsoLevel = XACT_SERIALIZABLE;
} }
else if (strcmp(value, "repeatable read") == 0)
{
if (doit)
XactIsoLevel = XACT_REPEATABLE_READ;
}
else if (strcmp(value, "read committed") == 0) else if (strcmp(value, "read committed") == 0)
{ {
if (doit) if (doit)
XactIsoLevel = XACT_READ_COMMITTED; XactIsoLevel = XACT_READ_COMMITTED;
} }
else if (strcmp(value, "read uncommitted") == 0)
{
if (doit)
XactIsoLevel = XACT_READ_UNCOMMITTED;
}
else if (strcmp(value, "default") == 0) else if (strcmp(value, "default") == 0)
{ {
if (doit) if (doit)
...@@ -659,10 +669,19 @@ assign_XactIsoLevel(const char *value, bool doit, bool interactive) ...@@ -659,10 +669,19 @@ assign_XactIsoLevel(const char *value, bool doit, bool interactive)
const char * const char *
show_XactIsoLevel(void) show_XactIsoLevel(void)
{ {
if (XactIsoLevel == XACT_SERIALIZABLE) switch (XactIsoLevel)
return "serializable"; {
else case XACT_READ_UNCOMMITTED:
return "read committed"; 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";
}
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * 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: ; ...@@ -1139,7 +1139,7 @@ lnext: ;
break; break;
case HeapTupleUpdated: case HeapTupleUpdated:
if (XactIsoLevel == XACT_SERIALIZABLE) if (IsXactIsoLevelSerializable)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("could not serialize access due to concurrent update"))); errmsg("could not serialize access due to concurrent update")));
...@@ -1440,7 +1440,7 @@ ldelete:; ...@@ -1440,7 +1440,7 @@ ldelete:;
break; break;
case HeapTupleUpdated: case HeapTupleUpdated:
if (XactIsoLevel == XACT_SERIALIZABLE) if (IsXactIsoLevelSerializable)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("could not serialize access due to concurrent update"))); errmsg("could not serialize access due to concurrent update")));
...@@ -1576,7 +1576,7 @@ lreplace:; ...@@ -1576,7 +1576,7 @@ lreplace:;
break; break;
case HeapTupleUpdated: case HeapTupleUpdated:
if (XactIsoLevel == XACT_SERIALIZABLE) if (IsXactIsoLevelSerializable)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("could not serialize access due to concurrent update"))); errmsg("could not serialize access due to concurrent update")));
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -342,7 +342,7 @@ static void doNegateFloat(Value *v); ...@@ -342,7 +342,7 @@ static void doNegateFloat(Value *v);
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS 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 EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
...@@ -380,7 +380,7 @@ static void doNegateFloat(Value *v); ...@@ -380,7 +380,7 @@ static void doNegateFloat(Value *v);
PRECISION PRESERVE PREPARE PRIMARY PRECISION PRESERVE PREPARE PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE 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 RESET RESTART RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS
RULE RULE
...@@ -393,7 +393,7 @@ static void doNegateFloat(Value *v); ...@@ -393,7 +393,7 @@ static void doNegateFloat(Value *v);
TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
TRUNCATE TRUSTED TYPE_P TRUNCATE TRUSTED TYPE_P
UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
UPDATE USAGE USER USING UPDATE USAGE USER USING
VACUUM VALID VALIDATOR VALUES VARCHAR VARYING VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
...@@ -922,7 +922,9 @@ var_value: opt_boolean ...@@ -922,7 +922,9 @@ var_value: opt_boolean
{ $$ = makeAConst($1); } { $$ = makeAConst($1); }
; ;
iso_level: READ COMMITTED { $$ = "read committed"; } iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; }
| READ COMMITTED { $$ = "read committed"; }
| REPEATABLE READ { $$ = "repeatable read"; }
| SERIALIZABLE { $$ = "serializable"; } | SERIALIZABLE { $$ = "serializable"; }
; ;
...@@ -7407,6 +7409,7 @@ unreserved_keyword: ...@@ -7407,6 +7409,7 @@ unreserved_keyword:
| REINDEX | REINDEX
| RELATIVE_P | RELATIVE_P
| RENAME | RENAME
| REPEATABLE
| REPLACE | REPLACE
| RESET | RESET
| RESTART | RESTART
...@@ -7445,6 +7448,7 @@ unreserved_keyword: ...@@ -7445,6 +7448,7 @@ unreserved_keyword:
| TRUNCATE | TRUNCATE
| TRUSTED | TRUSTED
| TYPE_P | TYPE_P
| UNCOMMITTED
| UNENCRYPTED | UNENCRYPTED
| UNKNOWN | UNKNOWN
| UNLISTEN | UNLISTEN
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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[] = { ...@@ -251,6 +251,7 @@ static const ScanKeyword ScanKeywords[] = {
{"reindex", REINDEX}, {"reindex", REINDEX},
{"relative", RELATIVE_P}, {"relative", RELATIVE_P},
{"rename", RENAME}, {"rename", RENAME},
{"repeatable", REPEATABLE},
{"replace", REPLACE}, {"replace", REPLACE},
{"reset", RESET}, {"reset", RESET},
{"restart", RESTART}, {"restart", RESTART},
...@@ -307,6 +308,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -307,6 +308,7 @@ static const ScanKeyword ScanKeywords[] = {
{"truncate", TRUNCATE}, {"truncate", TRUNCATE},
{"trusted", TRUSTED}, {"trusted", TRUSTED},
{"type", TYPE_P}, {"type", TYPE_P},
{"uncommitted", UNCOMMITTED},
{"unencrypted", UNENCRYPTED}, {"unencrypted", UNENCRYPTED},
{"union", UNION}, {"union", UNION},
{"unique", UNIQUE}, {"unique", UNIQUE},
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* *
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * 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, ...@@ -3073,7 +3073,7 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
* rows under current snapshot that wouldn't be visible per the * rows under current snapshot that wouldn't be visible per the
* transaction snapshot). * transaction snapshot).
*/ */
if (XactIsoLevel == XACT_SERIALIZABLE) if (IsXactIsoLevelSerializable)
{ {
useCurrentSnapshot = detectNewRows; useCurrentSnapshot = detectNewRows;
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * 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[] = ...@@ -1346,7 +1346,7 @@ static struct config_string ConfigureNamesString[] =
{"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, {"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
gettext_noop("Sets the transaction isolation level of each new transaction."), gettext_noop("Sets the transaction isolation level of each new transaction."),
gettext_noop("Each SQL transaction has an isolation level, which " 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, &default_iso_level_string,
"read committed", assign_defaultxactisolevel, NULL "read committed", assign_defaultxactisolevel, NULL
...@@ -4238,11 +4238,21 @@ assign_defaultxactisolevel(const char *newval, bool doit, bool interactive) ...@@ -4238,11 +4238,21 @@ assign_defaultxactisolevel(const char *newval, bool doit, bool interactive)
if (doit) if (doit)
DefaultXactIsoLevel = XACT_SERIALIZABLE; DefaultXactIsoLevel = XACT_SERIALIZABLE;
} }
else if (strcasecmp(newval, "repeatable read") == 0)
{
if (doit)
DefaultXactIsoLevel = XACT_REPEATABLE_READ;
}
else if (strcasecmp(newval, "read committed") == 0) else if (strcasecmp(newval, "read committed") == 0)
{ {
if (doit) if (doit)
DefaultXactIsoLevel = XACT_READ_COMMITTED; DefaultXactIsoLevel = XACT_READ_COMMITTED;
} }
else if (strcasecmp(newval, "read uncommitted") == 0)
{
if (doit)
DefaultXactIsoLevel = XACT_READ_UNCOMMITTED;
}
else else
return NULL; return NULL;
return newval; return newval;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -984,7 +984,7 @@ SetQuerySnapshot(void)
return; return;
} }
if (XactIsoLevel == XACT_SERIALIZABLE) if (IsXactIsoLevelSerializable)
QuerySnapshot = SerializableSnapshot; QuerySnapshot = SerializableSnapshot;
else else
QuerySnapshot = GetSnapshotData(&QuerySnapshotData, false); QuerySnapshot = GetSnapshotData(&QuerySnapshotData, false);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * 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) ...@@ -466,7 +466,7 @@ psql_completion(char *text, int start, int end)
"ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT", "ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT",
"COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE", "DROP", "EXECUTE", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE", "DROP", "EXECUTE",
"EXPLAIN", "FETCH", "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "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 "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", NULL
}; };
...@@ -1101,30 +1101,36 @@ psql_completion(char *text, int start, int end) ...@@ -1101,30 +1101,36 @@ psql_completion(char *text, int start, int end)
strcasecmp(prev_wd, "SHOW") == 0) strcasecmp(prev_wd, "SHOW") == 0)
COMPLETE_WITH_LIST(pgsql_variables); COMPLETE_WITH_LIST(pgsql_variables);
/* Complete "SET TRANSACTION" */ /* Complete "SET TRANSACTION" */
else if ((strcasecmp(prev2_wd, "SET") == 0 && else if ((strcasecmp(prev2_wd, "SET") == 0
strcasecmp(prev_wd, "TRANSACTION") == 0) || && strcasecmp(prev_wd, "TRANSACTION") == 0)
(strcasecmp(prev4_wd, "SESSION") == 0 && || (strcasecmp(prev2_wd, "START") == 0
strcasecmp(prev3_wd, "CHARACTERISTICS") == 0 && && strcasecmp(prev_wd, "TRANSACTION") == 0)
strcasecmp(prev2_wd, "AS") == 0 && || (strcasecmp(prev4_wd, "SESSION") == 0
strcasecmp(prev_wd, "TRANSACTION") == 0)) && strcasecmp(prev3_wd, "CHARACTERISTICS") == 0
&& strcasecmp(prev2_wd, "AS") == 0
&& strcasecmp(prev_wd, "TRANSACTION") == 0))
{ {
static const char * const my_list[] = static const char * const my_list[] =
{"ISOLATION", "READ", NULL}; {"ISOLATION", "READ", NULL};
COMPLETE_WITH_LIST(my_list); COMPLETE_WITH_LIST(my_list);
} }
else if (strcasecmp(prev3_wd, "SET") == 0 && else if ((strcasecmp(prev3_wd, "SET") == 0
strcasecmp(prev2_wd, "TRANSACTION") == 0 && || strcasecmp(prev3_wd, "START") == 0
strcasecmp(prev_wd, "ISOLATION") == 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"); COMPLETE_WITH_CONST("LEVEL");
else if ((strcasecmp(prev4_wd, "SET") == 0 || else if ((strcasecmp(prev4_wd, "SET") == 0
strcasecmp(prev4_wd, "AS") == 0) && || strcasecmp(prev4_wd, "START") == 0
strcasecmp(prev3_wd, "TRANSACTION") == 0 && || strcasecmp(prev4_wd, "AS") == 0)
strcasecmp(prev2_wd, "ISOLATION") == 0 && && strcasecmp(prev3_wd, "TRANSACTION") == 0
strcasecmp(prev_wd, "LEVEL") == 0) && strcasecmp(prev2_wd, "ISOLATION") == 0
&& strcasecmp(prev_wd, "LEVEL") == 0)
{ {
static const char * const my_list[] = static const char * const my_list[] =
{"READ", "SERIALIZABLE", NULL}; {"READ", "REPEATABLE", "SERIALIZABLE", NULL};
COMPLETE_WITH_LIST(my_list); COMPLETE_WITH_LIST(my_list);
} }
...@@ -1132,7 +1138,17 @@ psql_completion(char *text, int start, int end) ...@@ -1132,7 +1138,17 @@ psql_completion(char *text, int start, int end)
strcasecmp(prev3_wd, "ISOLATION") == 0 && strcasecmp(prev3_wd, "ISOLATION") == 0 &&
strcasecmp(prev2_wd, "LEVEL") == 0 && strcasecmp(prev2_wd, "LEVEL") == 0 &&
strcasecmp(prev_wd, "READ") == 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 || else if ((strcasecmp(prev3_wd, "SET") == 0 ||
strcasecmp(prev3_wd, "AS") == 0) && strcasecmp(prev3_wd, "AS") == 0) &&
strcasecmp(prev2_wd, "TRANSACTION") == 0 && strcasecmp(prev2_wd, "TRANSACTION") == 0 &&
...@@ -1200,6 +1216,10 @@ psql_completion(char *text, int start, int end) ...@@ -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 */ /* TRUNCATE */
else if (strcasecmp(prev_wd, "TRUNCATE") == 0) else if (strcasecmp(prev_wd, "TRUNCATE") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -22,14 +22,20 @@ ...@@ -22,14 +22,20 @@
/* /*
* Xact isolation levels * Xact isolation levels
*/ */
#define XACT_DIRTY_READ 0 /* not implemented */ #define XACT_READ_UNCOMMITTED 0
#define XACT_READ_COMMITTED 1 #define XACT_READ_COMMITTED 1
#define XACT_REPEATABLE_READ 2 /* not implemented */ #define XACT_REPEATABLE_READ 2
#define XACT_SERIALIZABLE 3 #define XACT_SERIALIZABLE 3
extern int DefaultXactIsoLevel; extern int DefaultXactIsoLevel;
extern int XactIsoLevel; 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 */ /* Xact read-only state */
extern bool DefaultXactReadOnly; extern bool DefaultXactReadOnly;
extern bool XactReadOnly; extern bool XactReadOnly;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment