From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id BBC5823D44 for ; Fri, 4 May 2018 10:12:28 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WaVY9vLaSlBx for ; Fri, 4 May 2018 10:12:28 -0400 (EDT) Received: from smtp63.i.mail.ru (smtp63.i.mail.ru [217.69.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 7642123D19 for ; Fri, 4 May 2018 10:12:28 -0400 (EDT) Subject: [tarantool-patches] Re: [PATCH 1/4] sql: remove OP_AutoCommit opcode References: <7a43fd8723207263f3531d20b305e497bcf64e44.1525368399.git.korablev@tarantool.org> From: Vladislav Shpilevoy Message-ID: <5f3205b3-cd3b-e50a-e185-f7ea91067f99@tarantool.org> Date: Fri, 4 May 2018 17:12:25 +0300 MIME-Version: 1.0 In-Reply-To: <7a43fd8723207263f3531d20b305e497bcf64e44.1525368399.git.korablev@tarantool.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: Nikita Pettik , tarantool-patches@freelists.org Hello. Thanks for contributing! See 6 comments below. 1. OP_AutoCommit still exists in mkopcodeh.sh. On 03/05/2018 21:49, Nikita Pettik wrote: > In SQLite OP_AutoCommit opcode used to set transaction operation: > BEGIN, ROLLBACK and COMMIT, switching auto-commit flag in VDBE. > As for Tarantool, it is confusing, since there are some differences > between auto-commit modes: 'INSERT ... VALUES (1), (2), (3)' is one > indivisible operation for SQLite, and three operations in real > auto-commit mode for Tarantool. To simulate SQLite auto-commit mode, > these three insertions are wrapped into one SEPARATE transaction, > which is, in fact, not real autocommit mode. > So, lets add separate explicit opcodes to BEGIN, ROLLBACK and COMMIT > transactions as user's operations. Auto-commit mode is set once at VDBE > creation and can be changed only by implicit opcode OP_TTransaction, > which is added to each DML statement, or by 'BEGIN' SQL statement. > --- > src/box/sql/build.c | 51 +++++------------- > src/box/sql/main.c | 3 +- > src/box/sql/parse.y | 11 ++-- > src/box/sql/sqliteInt.h | 31 +++++++++-- > src/box/sql/vdbe.c | 136 +++++++++++++++++++++++++----------------------- > src/box/sql/vdbeInt.h | 3 +- > src/box/sql/vdbeapi.c | 5 +- > src/box/sql/vdbeaux.c | 34 ++++++------ > 8 files changed, 138 insertions(+), 136 deletions(-) > > diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c > index 013460f79..cf2b769c7 100644 > --- a/src/box/sql/vdbe.c > +++ b/src/box/sql/vdbe.c > @@ -2875,7 +2875,7 @@ case OP_Savepoint: { > /* Assert that the p1 parameter is valid. Also that if there is no open > * transaction, then there cannot be any savepoints. > */ > - assert(psql_txn->pSavepoint == 0 || p->autoCommit == 0); > + assert(psql_txn->pSavepoint == 0 || box_txn()); 2. Please, use explicit ==/!= NULL (pSavepoint is pointer). > +/* Opcode: TransactionBegin * * * * * > + * > + * Start Tarantool's transaction. > + * Only do that if there is no other active transactions. > + * Otherwise, raise an error with appropriate error message. > + */ > +case OP_TransactionBegin: { > + if (!box_txn()) { 3. sql_txn_begin() does this check for you. Here you can always call sql_txn_begin() and check result code. After this you can remove manual error message creating, and just goto abort_due_to_error. Error code is always SQL_TARANTOOL_ERROR. > + > +/* Opcode: TransactionCommit * * * * * > + * > + * Commit Tarantool's transaction. > + * If there is no active transaction, raise an error. > + */ > +case OP_TransactionCommit: { > + if (box_txn()) { > + if (box_txn_commit() != 0) { > + rc = SQL_TARANTOOL_ERROR; > + goto abort_due_to_error; > } > - rc = SQLITE_DONE; > - goto vdbe_return; > } else { > - sqlite3VdbeError(p, > - (!desiredAutoCommit)?"cannot start a transaction within a transaction":( > - (iRollback)?"cannot rollback - no transaction is active": > - "cannot commit - no transaction is active")); > + sqlite3VdbeError(p, "cannot commit - no transaction is active"); > + rc = SQLITE_ERROR; > + goto abort_due_to_error; 4. I am not sure, that we must throw on commit/rollback with no transaction. In Lua it is ok. Possibly you should ask in the server team chat. > @@ -3052,18 +3052,26 @@ case OP_AutoCommit: { > > /* Opcode: TTransaction * * * * * > * > - * Start Tarantool's transaction. > - * Only do that if auto commit mode is on. This should be no-op > - * if this opcode was emitted inside a transaction. > + * Start Tarantool's transaction, if there is no active > + * transactions. Otherwise, create anonymous savepoint, > + * which is used to correctly process ABORT statement inside > + * outer transaction. > + * > + * In contrast to OP_TransactionBegin, this is service opcode, > + * generated automatically alongside with DML routine. > */ > case OP_TTransaction: { > - if (p->autoCommit) { > - rc = box_txn_begin() == 0 ? SQLITE_OK : SQL_TARANTOOL_ERROR; > - } > - if (box_txn() > - && p->autoCommit == 0){ > + if (!box_txn()) { > + if (box_txn_begin() != 0) { 5. Same as 3. If you need error code, then use box_error_code() when begin() fails. > diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c > index b3998ea27..0bd0d455b 100644 > --- a/src/box/sql/vdbeaux.c > +++ b/src/box/sql/vdbeaux.c > @@ -2477,31 +2477,27 @@ sqlite3VdbeCheckFk(Vdbe * p, int deferred) > int > sql_txn_begin(Vdbe *p) > { > - struct txn *ptxn; > - > if (in_txn()) { > diag_set(ClientError, ER_ACTIVE_TRANSACTION); > - return -1; > + return SQL_TARANTOOL_ERROR; 6. It is step backwards to sqlite result codes style. Lets return 0/-1, and set errors via diag_set. If sql_txn_begin() returns -1, it is always SQL_TARANTOOL_ERROR.