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.
This commit is contained in:
Tom Lane 2004-08-12 21:00:34 +00:00
parent 9e01aaa8bf
commit 7f7e8cc3f2
5 changed files with 139 additions and 95 deletions

View File

@ -1,5 +1,5 @@
<!--
$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
-->
@ -20,9 +20,12 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
BEGIN [ WORK | TRANSACTION ]
[ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
[ READ WRITE | READ ONLY ]
BEGIN [ WORK | TRANSACTION ] [ <replaceable class="parameter">transaction_mode</replaceable> [, ...] ]
where <replaceable class="parameter">transaction_mode</replaceable> is one of:
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
READ WRITE | READ ONLY
</synopsis>
</refsynopsisdiv>
@ -101,8 +104,13 @@ BEGIN [ WORK | TRANSACTION ]
Issuing <command>BEGIN</> when already inside a transaction block will
provoke a warning message. The state of the transaction is not affected.
To nest transactions within a transaction block, use savepoints
(See <xref linkend="sql-start-transaction" endterm="sql-start-transaction-title">
for more information).
(see <xref linkend="sql-savepoint" endterm="sql-savepoint-title">).
</para>
<para>
For reasons of backwards compatibility, the commas between successive
<replaceable class="parameter">transaction_modes</replaceable> may be
omitted.
</para>
</refsect1>
@ -123,15 +131,10 @@ BEGIN;
<para>
<command>BEGIN</command> is a <productname>PostgreSQL</productname>
language extension. There is no explicit <command>BEGIN</command>
command in the SQL standard; transaction initiation is
always implicit and it terminates either with a
<command>COMMIT</command> or <command>ROLLBACK</command> statement.
</para>
<para>
Other relational database systems may offer an autocommit feature
as a convenience.
language extension. It is equivalent to the SQL-standard command
<xref linkend="sql-start-transaction"
endterm="sql-start-transaction-title">, which see for additional
compatibility information.
</para>
<para>

View File

@ -1,4 +1,4 @@
<!-- $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">
<refmeta>
<refentrytitle id="SQL-SET-TRANSACTION-TITLE">SET TRANSACTION</refentrytitle>
@ -16,13 +16,13 @@
<refsynopsisdiv>
<synopsis>
SET TRANSACTION
[ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
[ READ WRITE | READ ONLY ]
SET TRANSACTION <replaceable class="parameter">transaction_mode</replaceable> [, ...]
SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transaction_mode</replaceable> [, ...]
SET SESSION CHARACTERISTICS AS TRANSACTION
[ 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>
</refsynopsisdiv>
@ -34,7 +34,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
characteristics of the current transaction. It has no effect on any
subsequent transactions. <command>SET SESSION
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.
</para>
@ -47,7 +47,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
<para>
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>
<varlistentry>
@ -64,28 +64,35 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
<term><literal>SERIALIZABLE</literal></term>
<listitem>
<para>
The current transaction can only see rows committed before
first query or data-modification statement was executed in this transaction.
All statements of the current transaction can only see rows committed
before the first query or data-modification statement was executed in
this transaction.
</para>
<tip>
<para>
Intuitively, serializable means that two concurrent
transactions will leave the database in the same state as if
the two has been executed strictly after one another in either
order.
the two had been executed strictly one after the other (in one
order or the other).
</para>
</tip>
</listitem>
</varlistentry>
</variablelist>
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
The SQL standard defines two additional levels, <literal>READ
UNCOMMITTED</literal> and <literal>REPEATABLE READ</literal>.
In <productname>PostgreSQL</productname> <literal>READ
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>,
<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
<xref linkend="mvcc"> for more information about transaction
isolation and concurrency control.
@ -112,13 +119,27 @@ SET SESSION CHARACTERISTICS AS TRANSACTION
<title>Notes</title>
<para>
The session default transaction isolation level can also be set
with the command
<programlisting>
SET default_transaction_isolation = '<replaceable>value</replaceable>'
</programlisting>
and in the configuration file. Consult <xref linkend="runtime-config"> for more
information.
If <command>SET TRANSACTION</command> is executed without a prior
<command>START TRANSACTION</command> or <command>BEGIN</command>,
it will appear to have no effect, since the transaction will immediately
end.
</para>
<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>
</refsect1>
@ -131,7 +152,7 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>'
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
mentioned above. Because of multiversion concurrency control, the
<literal>SERIALIZABLE</literal> level is not truly
serializable. See <xref linkend="mvcc"> for details.
</para>
@ -139,7 +160,15 @@ SET default_transaction_isolation = '<replaceable>value</replaceable>'
<para>
In the SQL standard, there is one other transaction characteristic
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>
</refsect1>
</refentry>

View File

@ -1,5 +1,5 @@
<!--
$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
-->
@ -20,9 +20,12 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
START TRANSACTION
[ ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } ]
[ READ WRITE | READ ONLY ]
START TRANSACTION [ <replaceable class="parameter">transaction_mode</replaceable> [, ...] ]
where <replaceable class="parameter">transaction_mode</replaceable> is one of:
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
READ WRITE | READ ONLY
</synopsis>
</refsynopsisdiv>
@ -30,10 +33,10 @@ START TRANSACTION
<title>Description</title>
<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
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.
</para>
</refsect1>
@ -52,8 +55,25 @@ START TRANSACTION
<title>Compatibility</title>
<para>
This command conforms to the SQL standard; but see also the
compatibility section of <xref linkend="sql-set-transaction"
In the standard, it is not necessary to issue <command>START 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">.
</para>
</refsect1>

View File

@ -11,7 +11,7 @@
*
*
* 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
* AUTHOR DATE MAJOR EVENT
@ -161,11 +161,11 @@ static void doNegateFloat(Value *v);
%type <dbehavior> opt_drop_behavior
%type <list> createdb_opt_list copy_opt_list
%type <defelt> createdb_opt_item copy_opt_item
%type <list> createdb_opt_list copy_opt_list transaction_mode_list
%type <defelt> createdb_opt_item copy_opt_item transaction_mode_item
%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_nowait
@ -222,7 +222,7 @@ static void doNegateFloat(Value *v);
target_list update_target_list insert_column_list
insert_target_list def_list indirection opt_indirection
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
TableFuncElementList
prep_type_clause prep_type_list
@ -4021,27 +4021,26 @@ opt_transaction: WORK {}
| /*EMPTY*/ {}
;
transaction_mode_list:
transaction_mode_item:
ISOLATION LEVEL iso_level
{ $$ = list_make1(makeDefElem("transaction_isolation",
makeStringConst($3, NULL))); }
| transaction_access_mode
{ $$ = list_make1(makeDefElem("transaction_read_only",
makeIntConst($1))); }
| ISOLATION LEVEL iso_level transaction_access_mode
{
$$ = list_make2(makeDefElem("transaction_isolation",
makeStringConst($3, NULL)),
makeDefElem("transaction_read_only",
makeIntConst($4)));
}
| transaction_access_mode ISOLATION LEVEL iso_level
{
$$ = list_make2(makeDefElem("transaction_read_only",
makeIntConst($1)),
makeDefElem("transaction_isolation",
makeStringConst($4, NULL)));
}
{ $$ = makeDefElem("transaction_isolation",
makeStringConst($3, NULL)); }
| READ ONLY
{ $$ = makeDefElem("transaction_read_only",
makeIntConst(TRUE)); }
| READ WRITE
{ $$ = makeDefElem("transaction_read_only",
makeIntConst(FALSE)); }
;
/* Syntax with commas is SQL-spec, without commas is Postgres historical */
transaction_mode_list:
transaction_mode_item
{ $$ = list_make1($1); }
| transaction_mode_list ',' transaction_mode_item
{ $$ = lappend($1, $3); }
| transaction_mode_list transaction_mode_item
{ $$ = lappend($1, $2); }
;
transaction_mode_list_or_empty:
@ -4050,11 +4049,6 @@ transaction_mode_list_or_empty:
{ $$ = NIL; }
;
transaction_access_mode:
READ ONLY { $$ = TRUE; }
| READ WRITE { $$ = FALSE; }
;
/*****************************************************************************
*

View File

@ -10,7 +10,7 @@
*
*
* 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,
case TRANS_STMT_BEGIN:
case TRANS_STMT_START:
{
ListCell *lc;
BeginTransactionBlock();
if (stmt->options)
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)
SetPGVariable("transaction_isolation",
list_make1(item->arg), false);
else if (strcmp(item->defname, "transaction_read_only") == 0)
SetPGVariable("transaction_read_only",
list_make1(item->arg), false);
}
if (strcmp(item->defname, "transaction_isolation") == 0)
SetPGVariable("transaction_isolation",
list_make1(item->arg),
false);
else if (strcmp(item->defname, "transaction_read_only") == 0)
SetPGVariable("transaction_read_only",
list_make1(item->arg),
false);
}
}
break;