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 2E3CF2A770 for ; Mon, 19 Mar 2018 14:10:51 -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 ghQFanmuofhF for ; Mon, 19 Mar 2018 14:10:51 -0400 (EDT) Received: from smtp44.i.mail.ru (smtp44.i.mail.ru [94.100.177.104]) (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 6F5D72A704 for ; Mon, 19 Mar 2018 14:10:50 -0400 (EDT) From: Nikita Pettik Subject: [tarantool-patches] [PATCH 2/4] sql: rework OP_Clear internals Date: Mon, 19 Mar 2018 21:10:38 +0300 Message-Id: <48d971ed5d65bb116a6b6719cbf5f13b6328b136.1521479592.git.korablev@tarantool.org> In-Reply-To: References: In-Reply-To: References: 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: tarantool-patches@freelists.org Cc: Nikita Pettik This patch makes OP_Clear use pointer to space instead of space id. Moreover, in order to avoid excess function calls (such as box_delete() -> box_process1(), which in its turn makes additional space lookup), sql_execute_dml() function is introduced. It is an analogue of process_rw() from BOX internals. Its purpose is to handle transaction routine and call DML executor. This function will be also used later as well during insertion and deletion. Part of #3122 --- src/box/sql.c | 54 +++++++++++++++++++++++++++++++--------------- src/box/sql/opcodes.c | 2 +- src/box/sql/opcodes.h | 2 +- src/box/sql/tarantoolInt.h | 2 +- src/box/sql/vdbe.c | 28 ++++++++++-------------- 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/box/sql.c b/src/box/sql.c index 256985793..4f8b39810 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -191,6 +191,27 @@ is_tarantool_error(int rc) rc == SQL_TARANTOOL_INSERT_FAIL); } +/** + * This function is analogue of process_rw() from box module. + * Apart of calling space_execute_dml(), it handles transaction + * routine. + */ +static int +sql_execute_dml(struct request *request, struct space *space) +{ + struct txn *txn = txn_begin_stmt(space); + if (txn == NULL) + return -1; + struct tuple *unused = NULL; + if (space_execute_dml(space, txn, request, &unused) != 0) { + txn_rollback_stmt(); + return -1; + } + if (txn_commit_stmt(txn, request) != 0) + return -1; + return 0; +} + int tarantoolSqlite3CloseCursor(BtCursor *pCur) { assert(pCur->curFlags & BTCF_TaCursor || @@ -659,10 +680,8 @@ int tarantoolSqlite3EphemeralClearTable(BtCursor *pCur) /* * Removes all instances from table. */ -int tarantoolSqlite3ClearTable(int iTable) +int tarantoolSqlite3ClearTable(struct space *space) { - int space_id = SQLITE_PAGENO_TO_SPACEID(iTable); - /* * There are two cases when we have to delete tuples one by one: * 1. When we are inside of another transaction, we can not use @@ -670,30 +689,31 @@ int tarantoolSqlite3ClearTable(int iTable) * 2. Truncate on system spaces is disallowed. (because of triggers) * (main usecase is _sql_stat4 table editing) */ - if (box_txn() || space_id < BOX_SYSTEM_ID_MAX) { - int primary_index_id = 0; - char *key; + if (box_txn() || space_is_system(space)) { uint32_t key_size; box_tuple_t *tuple; int rc; - box_iterator_t *iter; - iter = box_index_iterator(space_id, primary_index_id, ITER_ALL, - nil_key, nil_key + sizeof(nil_key)); + struct request request; + memset(&request, 0, sizeof(request)); + request.type = IPROTO_DELETE; + request.space_id = space->def->id; + struct index *pk = space_index(space, 0 /* PK */); + struct iterator *iter = + index_create_iterator(pk, ITER_ALL, nil_key, 0); if (iter == NULL) return SQL_TARANTOOL_ITERATOR_FAIL; - while (box_iterator_next(iter, &tuple) == 0 && tuple != NULL) { - key = tuple_extract_key(tuple, - box_iterator_key_def(iter), + while (iterator_next(iter, &tuple) == 0 && tuple != NULL) { + request.key = tuple_extract_key(tuple, pk->def->key_def, &key_size); - rc = box_delete(space_id, primary_index_id, key, - key + key_size, NULL); + request.key_end = request.key + key_size; + rc = sql_execute_dml(&request, space); if (rc != 0) { - box_iterator_free(iter); + iterator_delete(iter); return SQL_TARANTOOL_DELETE_FAIL; } } - box_iterator_free(iter); - } else if (box_truncate(space_id) != 0) { + iterator_delete(iter); + } else if (box_truncate(space->def->id) != 0) { return SQL_TARANTOOL_DELETE_FAIL; } diff --git a/src/box/sql/opcodes.c b/src/box/sql/opcodes.c index 53603037d..7a40b28a8 100644 --- a/src/box/sql/opcodes.c +++ b/src/box/sql/opcodes.c @@ -129,7 +129,7 @@ const char *sqlite3OpcodeName(int i){ /* 115 */ "Real" OpHelp("r[P2]=P4"), /* 116 */ "IdxInsert" OpHelp("key=r[P2]"), /* 117 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 118 */ "Clear" OpHelp(""), + /* 118 */ "Clear" OpHelp("space id = P1"), /* 119 */ "ResetSorter" OpHelp(""), /* 120 */ "ParseSchema2" OpHelp("rows=r[P1@P2]"), /* 121 */ "ParseSchema3" OpHelp("name=r[P1] sql=r[P1+1]"), diff --git a/src/box/sql/opcodes.h b/src/box/sql/opcodes.h index 1fbb6b690..af2ba1963 100644 --- a/src/box/sql/opcodes.h +++ b/src/box/sql/opcodes.h @@ -118,7 +118,7 @@ #define OP_Real 115 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_IdxInsert 116 /* synopsis: key=r[P2] */ #define OP_IdxDelete 117 /* synopsis: key=r[P2@P3] */ -#define OP_Clear 118 +#define OP_Clear 118 /* synopsis: space id = P1 */ #define OP_ResetSorter 119 #define OP_ParseSchema2 120 /* synopsis: rows=r[P1@P2] */ #define OP_ParseSchema3 121 /* synopsis: name=r[P1] sql=r[P1+1] */ diff --git a/src/box/sql/tarantoolInt.h b/src/box/sql/tarantoolInt.h index 39fdbcd76..c98871cd5 100644 --- a/src/box/sql/tarantoolInt.h +++ b/src/box/sql/tarantoolInt.h @@ -77,7 +77,7 @@ int tarantoolSqlite3Count(BtCursor * pCur, i64 * pnEntry); int tarantoolSqlite3Insert(BtCursor * pCur); int tarantoolSqlite3Replace(BtCursor * pCur); int tarantoolSqlite3Delete(BtCursor * pCur, u8 flags); -int tarantoolSqlite3ClearTable(int iTable); +int tarantoolSqlite3ClearTable(struct space *space); /* Rename table pTab with zNewName by inserting new tuple to _space. * SQL statement, which creates table with new name is saved in pzSqlStmt. diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 49ce51096..7de9b67c1 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -4590,26 +4590,20 @@ case OP_IdxGE: { /* jump */ break; } -/* Opcode: Clear P1 P2 P3 +/* Opcode: Clear P1 * * * * + * Synopsis: space id = P1 * - * Delete all contents of the database table or index whose root page - * in the database file is given by P1. But, unlike Destroy, do not - * remove the table or index from the database file. - * - * The table being clear is in the main database file if P2==0. If - * P2==1 then the table to be clear is in the auxiliary database file - * that is used to store tables create using CREATE TEMPORARY TABLE. - * - * If the P3 value is non-zero, then the table referred to must be an - * intkey table (an SQL table, not an index). In this case the row change - * count is incremented by the number of rows in the table being cleared. - * If P3 is greater than zero, then the value stored in register P3 is - * also incremented by the number of rows in the table being cleared. - * - * See also: Destroy + * Delete all contents of the space, which space id is given + * in P1 argument. Notice, that execution of this opcode inside + * active transaction would slow down perfomance, since it + * becomes impossible to use truncate feature. */ case OP_Clear: { - rc = tarantoolSqlite3ClearTable(pOp->p1); + assert(pOp->p1 > 0); + uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(pOp->p1); + struct space *space = space_by_id(space_id); + assert(space != NULL); + rc = tarantoolSqlite3ClearTable(space); if (rc) goto abort_due_to_error; break; } -- 2.15.1