diff --git a/doc/src/sgml/ref/begin.sgml b/doc/src/sgml/ref/begin.sgml index bf1195f52772882fbf4845f3c0d2fa39bdfa88fb..741d8aa997a14ed8625fed933477191a2e0e96ef 100644 --- a/doc/src/sgml/ref/begin.sgml +++ b/doc/src/sgml/ref/begin.sgml @@ -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> diff --git a/doc/src/sgml/ref/set_transaction.sgml b/doc/src/sgml/ref/set_transaction.sgml index ef6dea1ac18e000743949b444aa4cd16b18f92bd..50a8908825078e6e2c326794a6e13a32b51c247a 100644 --- a/doc/src/sgml/ref/set_transaction.sgml +++ b/doc/src/sgml/ref/set_transaction.sgml @@ -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> diff --git a/doc/src/sgml/ref/start_transaction.sgml b/doc/src/sgml/ref/start_transaction.sgml index 1a7bc363ce7fc2ced03323dcc2dd6bb26a555f9f..823bd99195322a796d2e0062dbfdeaf6c2bc0b1f 100644 --- a/doc/src/sgml/ref/start_transaction.sgml +++ b/doc/src/sgml/ref/start_transaction.sgml @@ -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> diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 6a27714b05e5ad7a8f12b2d2b80a19762afe5ef8..e8bc3cf5adec80667e41f483e87b842de672e872 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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; } - ; - /***************************************************************************** * diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 89ac4843ba8ba99d5e48740f3de8edae04d840bd..0fff253a61c5fede4c42cdf313e72df3a8274455 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -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: { - BeginTransactionBlock(); + ListCell *lc; - if (stmt->options) + BeginTransactionBlock(); + foreach(lc, stmt->options) { - ListCell *head; - - 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); - } + DefElem *item = (DefElem *) lfirst(lc); + + 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;