Commit 7f7e8cc3 authored by Tom Lane's avatar Tom Lane

Allow commas in BEGIN, START TRANSACTION, and SET TRANSACTION, as required

by the SQL standard.  For backwards compatibility, however, continue to
accept the syntax without.  Minor editorialization in the reference pages
for these commands, too.
parent 9e01aaa8
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/begin.sgml,v 1.32 2004/08/08 01:48:31 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/begin.sgml,v 1.33 2004/08/12 21:00:21 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -20,9 +20,12 @@ PostgreSQL documentation ...@@ -20,9 +20,12 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
BEGIN [ WORK | TRANSACTION ] BEGIN [ WORK | TRANSACTION ] [ <replaceable class="parameter">transaction_mode</replaceable> [, ...] ]
[ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
[ READ WRITE | READ ONLY ] where <replaceable class="parameter">transaction_mode</replaceable> is one of:
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
READ WRITE | READ ONLY
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -101,8 +104,13 @@ BEGIN [ WORK | TRANSACTION ] ...@@ -101,8 +104,13 @@ BEGIN [ WORK | TRANSACTION ]
Issuing <command>BEGIN</> when already inside a transaction block will Issuing <command>BEGIN</> when already inside a transaction block will
provoke a warning message. The state of the transaction is not affected. provoke a warning message. The state of the transaction is not affected.
To nest transactions within a transaction block, use savepoints To nest transactions within a transaction block, use savepoints
(See <xref linkend="sql-start-transaction" endterm="sql-start-transaction-title"> (see <xref linkend="sql-savepoint" endterm="sql-savepoint-title">).
for more information). </para>
<para>
For reasons of backwards compatibility, the commas between successive
<replaceable class="parameter">transaction_modes</replaceable> may be
omitted.
</para> </para>
</refsect1> </refsect1>
...@@ -123,15 +131,10 @@ BEGIN; ...@@ -123,15 +131,10 @@ BEGIN;
<para> <para>
<command>BEGIN</command> is a <productname>PostgreSQL</productname> <command>BEGIN</command> is a <productname>PostgreSQL</productname>
language extension. There is no explicit <command>BEGIN</command> language extension. It is equivalent to the SQL-standard command
command in the SQL standard; transaction initiation is <xref linkend="sql-start-transaction"
always implicit and it terminates either with a endterm="sql-start-transaction-title">, which see for additional
<command>COMMIT</command> or <command>ROLLBACK</command> statement. compatibility information.
</para>
<para>
Other relational database systems may offer an autocommit feature
as a convenience.
</para> </para>
<para> <para>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/ref/set_transaction.sgml,v 1.19 2003/11/29 19:51:39 pgsql Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/ref/set_transaction.sgml,v 1.20 2004/08/12 21:00:22 tgl 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>
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
SET TRANSACTION SET TRANSACTION <replaceable class="parameter">transaction_mode</replaceable> [, ...]
[ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ] SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transaction_mode</replaceable> [, ...]
[ READ WRITE | READ ONLY ]
SET SESSION CHARACTERISTICS AS TRANSACTION where <replaceable class="parameter">transaction_mode</replaceable> is one of:
[ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
[ READ WRITE | READ ONLY ] ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
READ WRITE | READ ONLY
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -34,7 +34,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION ...@@ -34,7 +34,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
characteristics of the current transaction. It has no effect on any characteristics of the current transaction. It has no effect on any
subsequent transactions. <command>SET SESSION subsequent transactions. <command>SET SESSION
CHARACTERISTICS</command> sets the default transaction CHARACTERISTICS</command> sets the default transaction
characteristics for each transaction of a session. <command>SET characteristics for subsequent transactions of a session. <command>SET
TRANSACTION</command> can override it for an individual TRANSACTION</command> can override it for an individual
transaction. transaction.
</para> </para>
...@@ -47,7 +47,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION ...@@ -47,7 +47,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
<para> <para>
The isolation level of a transaction determines what data the The isolation level of a transaction determines what data the
transaction can see when other transactions are running concurrently. transaction can see when other transactions are running concurrently:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
...@@ -64,28 +64,35 @@ SET SESSION CHARACTERISTICS AS TRANSACTION ...@@ -64,28 +64,35 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
<term><literal>SERIALIZABLE</literal></term> <term><literal>SERIALIZABLE</literal></term>
<listitem> <listitem>
<para> <para>
The current transaction can only see rows committed before All statements of the current transaction can only see rows committed
first query or data-modification statement was executed in this transaction. before the first query or data-modification statement was executed in
this transaction.
</para> </para>
<tip> <tip>
<para> <para>
Intuitively, serializable means that two concurrent Intuitively, serializable means that two concurrent
transactions will leave the database in the same state as if transactions will leave the database in the same state as if
the two has been executed strictly after one another in either the two had been executed strictly one after the other (in one
order. order or the other).
</para> </para>
</tip> </tip>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
The level <literal>READ UNCOMMITTED</literal> is mapped to The SQL standard defines two additional levels, <literal>READ
<literal>READ COMMITTED</literal>, the level <literal>REPEATABLE UNCOMMITTED</literal> and <literal>REPEATABLE READ</literal>.
READ</literal> is mapped to <literal>SERIALIZABLE</literal>, The In <productname>PostgreSQL</productname> <literal>READ
transaction isolation level cannot be set after the first query or UNCOMMITTED</literal> is treated as
<literal>READ COMMITTED</literal>, while <literal>REPEATABLE
READ</literal> is treated as <literal>SERIALIZABLE</literal>.
</para>
<para>
The transaction isolation level cannot be changed after the first query or
data-modification statement (<command>SELECT</command>, 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>, or
<command>COPY</command>) of a transaction has been executed. See <command>COPY</command>) of a transaction has been executed. See
<xref linkend="mvcc"> for more information about transaction <xref linkend="mvcc"> for more information about transaction
isolation and concurrency control. isolation and concurrency control.
...@@ -112,13 +119,27 @@ SET SESSION CHARACTERISTICS AS TRANSACTION ...@@ -112,13 +119,27 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
<title>Notes</title> <title>Notes</title>
<para> <para>
The session default transaction isolation level can also be set If <command>SET TRANSACTION</command> is executed without a prior
with the command <command>START TRANSACTION</command> or <command>BEGIN</command>,
<programlisting> it will appear to have no effect, since the transaction will immediately
SET default_transaction_isolation = '<replaceable>value</replaceable>' end.
</programlisting> </para>
and in the configuration file. Consult <xref linkend="runtime-config"> for more
information. <para>
It is possible to dispense with <command>SET TRANSACTION</command> by
instead specifying the desired <replaceable
class="parameter">transaction_modes</replaceable> in
<command>START TRANSACTION</command>.
</para>
<para>
The session default transaction modes can also be set by setting the
configuration parameters <xref linkend="guc-default-transaction-isolation">
and <xref linkend="guc-default-transaction-read-only">.
(In fact <command>SET SESSION CHARACTERISTICS</command> is just a
verbose equivalent for setting these variables with <command>SET</>.)
This allows them to be set in the configuration file. Consult <xref
linkend="runtime-config"> for more information.
</para> </para>
</refsect1> </refsect1>
...@@ -131,7 +152,7 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>' ...@@ -131,7 +152,7 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>'
isolation level in the standard; in isolation level in the standard; in
<productname>PostgreSQL</productname> the default is ordinarily <productname>PostgreSQL</productname> the default is ordinarily
<literal>READ COMMITTED</literal>, but you can change it as <literal>READ COMMITTED</literal>, but you can change it as
described above. Because of multiversion concurrency control, the mentioned above. Because of multiversion concurrency control, the
<literal>SERIALIZABLE</literal> level is not truly <literal>SERIALIZABLE</literal> level is not truly
serializable. See <xref linkend="mvcc"> for details. serializable. See <xref linkend="mvcc"> for details.
</para> </para>
...@@ -139,7 +160,15 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>' ...@@ -139,7 +160,15 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>'
<para> <para>
In the SQL standard, there is one other transaction characteristic In the SQL standard, there is one other transaction characteristic
that can be set with these commands: the size of the diagnostics that can be set with these commands: the size of the diagnostics
area. This concept is only for use in embedded SQL. area. This concept is specific to embedded SQL, and therefore is
not implemented in the <productname>PostgreSQL</productname> server.
</para>
<para>
The SQL standard requires commas between successive <replaceable
class="parameter">transaction_modes</replaceable>, but for historical
reasons <productname>PostgreSQL</productname> allows the commas to be
omitted.
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/start_transaction.sgml,v 1.12 2004/08/01 17:32:13 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/start_transaction.sgml,v 1.13 2004/08/12 21:00:23 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -20,9 +20,12 @@ PostgreSQL documentation ...@@ -20,9 +20,12 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
START TRANSACTION START TRANSACTION [ <replaceable class="parameter">transaction_mode</replaceable> [, ...] ]
[ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
[ READ WRITE | READ ONLY ] where <replaceable class="parameter">transaction_mode</replaceable> is one of:
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
READ WRITE | READ ONLY
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -30,10 +33,10 @@ START TRANSACTION ...@@ -30,10 +33,10 @@ START TRANSACTION
<title>Description</title> <title>Description</title>
<para> <para>
This command begins a new transaction. If the isolation level or This command begins a new transaction block. If the isolation level or
read/write mode is specified, the new transaction has those read/write mode is specified, the new transaction has those
characteristics, as if <xref linkend="sql-set-transaction" characteristics, as if <xref linkend="sql-set-transaction"
endterm="sql-set-transaction-title"> was executed. It is the same endterm="sql-set-transaction-title"> was executed. This is the same
as the <xref linkend="sql-begin" endterm="sql-begin-title"> command. as the <xref linkend="sql-begin" endterm="sql-begin-title"> command.
</para> </para>
</refsect1> </refsect1>
...@@ -52,8 +55,25 @@ START TRANSACTION ...@@ -52,8 +55,25 @@ START TRANSACTION
<title>Compatibility</title> <title>Compatibility</title>
<para> <para>
This command conforms to the SQL standard; but see also the In the standard, it is not necessary to issue <command>START TRANSACTION</>
compatibility section of <xref linkend="sql-set-transaction" to start a transaction block: any SQL command implicitly begins a block.
<productname>PostgreSQL</productname>'s behavior can be seen as implicitly
issuing a <command>COMMIT</command> after each command that does not
follow <command>START TRANSACTION</> (or <command>BEGIN</command>),
and it is therefore often called <quote>autocommit</>.
Other relational database systems may offer an autocommit feature
as a convenience.
</para>
<para>
The SQL standard requires commas between successive <replaceable
class="parameter">transaction_modes</replaceable>, but for historical
reasons <productname>PostgreSQL</productname> allows the commas to be
omitted.
</para>
<para>
See also the compatibility section of <xref linkend="sql-set-transaction"
endterm="sql-set-transaction-title">. endterm="sql-set-transaction-title">.
</para> </para>
</refsect1> </refsect1>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.470 2004/08/12 19:12:21 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.471 2004/08/12 21:00:28 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -161,11 +161,11 @@ static void doNegateFloat(Value *v); ...@@ -161,11 +161,11 @@ static void doNegateFloat(Value *v);
%type <dbehavior> opt_drop_behavior %type <dbehavior> opt_drop_behavior
%type <list> createdb_opt_list copy_opt_list %type <list> createdb_opt_list copy_opt_list transaction_mode_list
%type <defelt> createdb_opt_item copy_opt_item %type <defelt> createdb_opt_item copy_opt_item transaction_mode_item
%type <ival> opt_lock lock_type cast_context %type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace transaction_access_mode %type <boolean> opt_force opt_or_replace
opt_grant_grant_option opt_revoke_grant_option opt_grant_grant_option opt_revoke_grant_option
opt_nowait opt_nowait
...@@ -222,7 +222,7 @@ static void doNegateFloat(Value *v); ...@@ -222,7 +222,7 @@ static void doNegateFloat(Value *v);
target_list update_target_list insert_column_list target_list update_target_list insert_column_list
insert_target_list def_list indirection opt_indirection insert_target_list def_list indirection opt_indirection
group_clause TriggerFuncArgs select_limit group_clause TriggerFuncArgs select_limit
opt_select_limit opclass_item_list transaction_mode_list opt_select_limit opclass_item_list
transaction_mode_list_or_empty transaction_mode_list_or_empty
TableFuncElementList TableFuncElementList
prep_type_clause prep_type_list prep_type_clause prep_type_list
...@@ -4021,27 +4021,26 @@ opt_transaction: WORK {} ...@@ -4021,27 +4021,26 @@ opt_transaction: WORK {}
| /*EMPTY*/ {} | /*EMPTY*/ {}
; ;
transaction_mode_list: transaction_mode_item:
ISOLATION LEVEL iso_level ISOLATION LEVEL iso_level
{ $$ = list_make1(makeDefElem("transaction_isolation", { $$ = makeDefElem("transaction_isolation",
makeStringConst($3, NULL))); } makeStringConst($3, NULL)); }
| transaction_access_mode | READ ONLY
{ $$ = list_make1(makeDefElem("transaction_read_only", { $$ = makeDefElem("transaction_read_only",
makeIntConst($1))); } makeIntConst(TRUE)); }
| ISOLATION LEVEL iso_level transaction_access_mode | READ WRITE
{ { $$ = makeDefElem("transaction_read_only",
$$ = list_make2(makeDefElem("transaction_isolation", makeIntConst(FALSE)); }
makeStringConst($3, NULL)), ;
makeDefElem("transaction_read_only",
makeIntConst($4))); /* Syntax with commas is SQL-spec, without commas is Postgres historical */
} transaction_mode_list:
| transaction_access_mode ISOLATION LEVEL iso_level transaction_mode_item
{ { $$ = list_make1($1); }
$$ = list_make2(makeDefElem("transaction_read_only", | transaction_mode_list ',' transaction_mode_item
makeIntConst($1)), { $$ = lappend($1, $3); }
makeDefElem("transaction_isolation", | transaction_mode_list transaction_mode_item
makeStringConst($4, NULL))); { $$ = lappend($1, $2); }
}
; ;
transaction_mode_list_or_empty: transaction_mode_list_or_empty:
...@@ -4050,11 +4049,6 @@ transaction_mode_list_or_empty: ...@@ -4050,11 +4049,6 @@ transaction_mode_list_or_empty:
{ $$ = NIL; } { $$ = NIL; }
; ;
transaction_access_mode:
READ ONLY { $$ = TRUE; }
| READ WRITE { $$ = FALSE; }
;
/***************************************************************************** /*****************************************************************************
* *
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.224 2004/08/12 19:12:21 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.225 2004/08/12 21:00:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -333,23 +333,21 @@ ProcessUtility(Node *parsetree, ...@@ -333,23 +333,21 @@ ProcessUtility(Node *parsetree,
case TRANS_STMT_BEGIN: case TRANS_STMT_BEGIN:
case TRANS_STMT_START: case TRANS_STMT_START:
{ {
BeginTransactionBlock(); ListCell *lc;
if (stmt->options) BeginTransactionBlock();
foreach(lc, stmt->options)
{ {
ListCell *head; DefElem *item = (DefElem *) lfirst(lc);
foreach(head, stmt->options)
{
DefElem *item = (DefElem *) lfirst(head);
if (strcmp(item->defname, "transaction_isolation") == 0) if (strcmp(item->defname, "transaction_isolation") == 0)
SetPGVariable("transaction_isolation", SetPGVariable("transaction_isolation",
list_make1(item->arg), false); list_make1(item->arg),
false);
else if (strcmp(item->defname, "transaction_read_only") == 0) else if (strcmp(item->defname, "transaction_read_only") == 0)
SetPGVariable("transaction_read_only", SetPGVariable("transaction_read_only",
list_make1(item->arg), false); list_make1(item->arg),
} false);
} }
} }
break; break;
......
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