From 19e0e35bcd3d0a1e46cb294ab08fbe062d4cf0d6 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sun, 4 Aug 2002 04:31:44 +0000 Subject: [PATCH] The attached patch implements START TRANSACTION, per SQL99. The functionality of the command is basically identical to that of BEGIN; it just accepts a few extra options (only one of which PostgreSQL currently implements), and is standards-compliant. The patch includes a simple regression test and documentation. [ Regression tests removed, per Peter.] Neil Conway --- doc/src/sgml/ref/allfiles.sgml | 3 +- doc/src/sgml/ref/begin.sgml | 4 +- doc/src/sgml/ref/set_transaction.sgml | 12 +++--- doc/src/sgml/reference.sgml | 3 +- src/backend/nodes/copyfuncs.c | 3 +- src/backend/nodes/equalfuncs.c | 4 +- src/backend/parser/gram.y | 55 ++++++++++++--------------- src/backend/tcop/postgres.c | 8 +++- src/backend/tcop/utility.c | 24 +++++++++++- src/include/nodes/parsenodes.h | 7 ++-- 10 files changed, 74 insertions(+), 49 deletions(-) diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml index 1ee6f2f2004..502cdb0e42c 100644 --- a/doc/src/sgml/ref/allfiles.sgml +++ b/doc/src/sgml/ref/allfiles.sgml @@ -1,5 +1,5 @@ @@ -113,6 +113,7 @@ Complete list of usable sgml source files in this directory. + diff --git a/doc/src/sgml/ref/begin.sgml b/doc/src/sgml/ref/begin.sgml index 53899f85560..850bfd77e68 100644 --- a/doc/src/sgml/ref/begin.sgml +++ b/doc/src/sgml/ref/begin.sgml @@ -1,5 +1,5 @@ @@ -21,7 +21,7 @@ PostgreSQL documentation 1999-07-20 - + BEGIN [ WORK | TRANSACTION ] diff --git a/doc/src/sgml/ref/set_transaction.sgml b/doc/src/sgml/ref/set_transaction.sgml index 5a253d85806..315a999330f 100644 --- a/doc/src/sgml/ref/set_transaction.sgml +++ b/doc/src/sgml/ref/set_transaction.sgml @@ -1,4 +1,4 @@ - + 2000-11-24 @@ -97,11 +97,11 @@ SET default_transaction_isolation = 'value' SQL92, SQL99 - SERIALIZABLE is the default level in SQL. - PostgreSQL does not provide the - isolation levels - and . Because - of multiversion concurrency control, the serializable level is not + is the default level in + SQL. PostgreSQL does + not provide the isolation levels + and . Because of multiversion + concurrency control, the level is not truly serializable. See the User's Guide for details. diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml index 2101dfe8a1b..3c6af16730b 100644 --- a/doc/src/sgml/reference.sgml +++ b/doc/src/sgml/reference.sgml @@ -1,5 +1,5 @@ @@ -122,6 +122,7 @@ PostgreSQL Reference Manual &setSessionAuth; &setTransaction; &show; + &startTransaction; &truncate; &unlisten; &update; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index f3c19635dfe..d7aefc9acfe 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.198 2002/07/29 22:14:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.199 2002/08/04 04:31:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -2226,6 +2226,7 @@ _copyTransactionStmt(TransactionStmt *from) TransactionStmt *newnode = makeNode(TransactionStmt); newnode->command = from->command; + Node_Copy(from, newnode, options); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 55beb563c8a..9b655640b0d 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.145 2002/07/29 22:14:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.146 2002/08/04 04:31:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1055,6 +1055,8 @@ _equalTransactionStmt(TransactionStmt *a, TransactionStmt *b) { if (a->command != b->command) return false; + if (!equal(a->options, b->options)) + return false; return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 73c2875d1b7..76731f97d7a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.352 2002/07/31 17:19:51 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.353 2002/08/04 04:31:44 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -195,7 +195,7 @@ static void doNegateFloat(Value *v); %type opt_id, all_Op, MathOp, opt_name, SpecialRuleRelation -%type opt_level, opt_encoding +%type iso_level, opt_encoding %type grantee %type grantee_list %type privilege @@ -218,7 +218,7 @@ static void doNegateFloat(Value *v); target_list, update_target_list, insert_column_list, insert_target_list, def_list, opt_indirection, group_clause, TriggerFuncArgs, select_limit, - opt_select_limit, opclass_item_list + opt_select_limit, opclass_item_list, trans_options %type into_clause, OptTempTableName @@ -847,14 +847,14 @@ set_rest: ColId TO var_list_or_default n->args = makeList1($3); $$ = n; } - | TRANSACTION ISOLATION LEVEL opt_level opt_mode + | TRANSACTION ISOLATION LEVEL iso_level opt_mode { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "TRANSACTION ISOLATION LEVEL"; n->args = makeList1(makeStringConst($4, NULL)); $$ = n; } - | SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL opt_level + | SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL iso_level { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "default_transaction_isolation"; @@ -902,7 +902,7 @@ var_value: opt_boolean { $$ = makeAConst($1); } ; -opt_level: READ COMMITTED { $$ = "read committed"; } +iso_level: READ COMMITTED { $$ = "read committed"; } | SERIALIZABLE { $$ = "serializable"; } ; @@ -3445,67 +3445,60 @@ TransactionStmt: { TransactionStmt *n = makeNode(TransactionStmt); n->command = ROLLBACK; + n->options = NIL; $$ = (Node *)n; } | BEGIN_TRANS opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = BEGIN_TRANS; + n->options = NIL; + $$ = (Node *)n; + } + | START TRANSACTION trans_options + { + TransactionStmt *n = makeNode(TransactionStmt); + n->command = START; + n->options = $3; $$ = (Node *)n; } | COMMIT opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = COMMIT; - $$ = (Node *)n; - } - | COMMIT opt_trans opt_chain - { - TransactionStmt *n = makeNode(TransactionStmt); - n->command = COMMIT; + n->options = NIL; $$ = (Node *)n; } | END_TRANS opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = COMMIT; + n->options = NIL; $$ = (Node *)n; } | ROLLBACK opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = ROLLBACK; - $$ = (Node *)n; - } - | ROLLBACK opt_trans opt_chain - { - TransactionStmt *n = makeNode(TransactionStmt); - n->command = ROLLBACK; + n->options = NIL; $$ = (Node *)n; } ; +trans_options: ISOLATION LEVEL iso_level + { $$ = makeList1(makeStringConst($3, NULL)); } + | /* EMPTY */ { $$ = NIL; } + ; + opt_trans: WORK {} | TRANSACTION {} | /*EMPTY*/ {} ; -opt_chain: AND NO CHAIN {} - | AND CHAIN - { - /* SQL99 asks that conforming dbs reject AND CHAIN - * if they don't support it. So we can't just ignore it. - * - thomas 2000-08-06 - */ - elog(ERROR, "COMMIT/AND CHAIN not yet supported"); - } - ; - - /***************************************************************************** * * QUERY: - * define view '('target-list ')' [where ] + * create view '('target-list ')' AS * *****************************************************************************/ diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 8aae5f5406d..976d366fe78 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.276 2002/07/30 16:55:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.277 2002/08/04 04:31:44 momjian Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -1693,7 +1693,7 @@ PostgresMain(int argc, char *argv[], const char *username) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.276 $ $Date: 2002/07/30 16:55:45 $\n"); + puts("$Revision: 1.277 $ $Date: 2002/08/04 04:31:44 $\n"); } /* @@ -2160,6 +2160,10 @@ CreateCommandTag(Node *parsetree) tag = "BEGIN"; break; + case START: + tag = "START TRANSACTION"; + break; + case COMMIT: tag = "COMMIT"; break; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index fd0f10d58aa..8c3af9ac9ce 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.167 2002/07/30 16:55:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.168 2002/08/04 04:31:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -205,6 +205,28 @@ ProcessUtility(Node *parsetree, BeginTransactionBlock(); break; + /* + * START TRANSACTION, as defined by SQL99: Identical to BEGIN, + * except that it takes a few additional options. + */ + case START: + { + BeginTransactionBlock(); + + /* + * Currently, the only option that can be set is + * the transaction isolation level by START + * TRANSACTION. + */ + if (stmt->options) + { + SetPGVariable("TRANSACTION ISOLATION LEVEL", + stmt->options, + false); + } + } + break; + case COMMIT: EndTransactionBlock(); break; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 467208c95cd..07e985b377b 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.196 2002/07/30 16:55:45 momjian Exp $ + * $Id: parsenodes.h,v 1.197 2002/08/04 04:31:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1387,13 +1387,14 @@ typedef struct UnlistenStmt } UnlistenStmt; /* ---------------------- - * {Begin|Abort|End} Transaction Statement + * {Begin|Commit|Rollback} Transaction Statement * ---------------------- */ typedef struct TransactionStmt { NodeTag type; - int command; /* BEGIN|END|ABORT */ + int command; /* BEGIN_TRANS|START|COMMIT|ROLLBACK */ + List *options; } TransactionStmt; /* ----------------------