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 4E90221BD1 for ; Wed, 18 Jul 2018 09:01:45 -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 yTLvAsXHj7ja for ; Wed, 18 Jul 2018 09:01:45 -0400 (EDT) Received: from smtpng2.m.smailru.net (smtpng2.m.smailru.net [94.100.179.3]) (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 EF221212D9 for ; Wed, 18 Jul 2018 09:01:43 -0400 (EDT) Subject: [tarantool-patches] Re: [PATCH v1 1/1] sql: introduce TRUNCATE TABLE operation References: <70326bb69fbe25215df79e2d5e01043f93ff7c5a.1531902074.git.kshcherbatov@tarantool.org> <797d52e5-1387-dd3d-1fb2-0fafbbbdcf56@tarantool.org> From: Kirill Shcherbatov Message-ID: <606f657b-26df-35b9-ddf1-d5bae5654d82@tarantool.org> Date: Wed, 18 Jul 2018 16:01:41 +0300 MIME-Version: 1.0 In-Reply-To: <797d52e5-1387-dd3d-1fb2-0fafbbbdcf56@tarantool.org> Content-Type: text/plain; charset=utf-8 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: tarantool-patches@freelists.org, Vladislav Shpilevoy > Hello. I do not see, where do you call box_truncate, and where is a > test that it is called. I've discussed this problem with Nikita and we have decided to make separate OP_Truncate code. ===================================== diff --git a/extra/mkkeywordhash.c b/extra/mkkeywordhash.c index 1ec1538..705caf1 100644 --- a/extra/mkkeywordhash.c +++ b/extra/mkkeywordhash.c @@ -281,6 +281,7 @@ static Keyword aKeywordTable[] = { { "VARCHAR", "TK_ID", RESERVED, true }, { "WHENEVER", "TK_STANDARD", RESERVED, true }, { "WHILE", "TK_STANDARD", RESERVED, true }, + { "TRUNCATE", "TK_TRUNCATE", ALWAYS, true }, }; /* Number of keywords */ diff --git a/src/box/sql/build.c b/src/box/sql/build.c index a64d723..be4c860 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -1953,7 +1953,7 @@ vdbe_emit_stat_space_clear(struct Parse *parse, const char *stat_table_name, * On memory allocation error sql_table delete_from * releases memory for its own. */ - sql_table_delete_from(parse, src_list, where); + sql_table_delete_from(parse, src_list, where, false); } /** diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c index f9d3498..ab6771d 100644 --- a/src/box/sql/delete.c +++ b/src/box/sql/delete.c @@ -73,7 +73,7 @@ sql_materialize_view(struct Parse *parse, const char *name, struct Expr *where, void sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, - struct Expr *where) + struct Expr *where, bool allow_truncate) { struct sqlite3 *db = parse->db; if (parse->nErr || db->mallocFailed) @@ -185,9 +185,10 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, */ if (where == NULL && !is_complex) { assert(!is_view); - - sqlite3VdbeAddOp1(v, OP_Clear, space_id); - + if (!allow_truncate || space_is_system(space) || in_txn() != NULL) + sqlite3VdbeAddOp1(v, OP_Clear, space_id); + else + sqlite3VdbeAddOp1(v, OP_Truncate, space_id); /* Do not start Tarantool's transaction in case of * truncate optimization. This is workaround until * system tables cannot be changes inside a diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c index 6a91890..e67866c 100644 --- a/src/box/sql/fkey.c +++ b/src/box/sql/fkey.c @@ -784,7 +784,7 @@ sqlite3FkDropTable(Parse *parser, SrcList *name, Table *table) /* Staring new transaction before DELETE FROM */ sqlite3VdbeAddOp0(v, OP_TTransaction); sql_table_delete_from(parser, sqlite3SrcListDup(parser->db, name, 0), - NULL); + NULL, false); parser->disableTriggers = 0; /* * If the DELETE has generated immediate foreign key diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index 0c510f5..18ca39b 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -722,7 +722,16 @@ cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { sqlSubProgramsRemaining = SQL_MAX_COMPILING_TRIGGERS; /* Instruct SQL to initate Tarantool's transaction. */ pParse->initiateTTrans = true; - sql_table_delete_from(pParse,X,W); + sql_table_delete_from(pParse,X,W,true); +} + +/////////////////////////// The TRUNCATE statement ///////////////////////////// +// +cmd ::= TRUNCATE TABLE fullname(X). { + sqlSubProgramsRemaining = SQL_MAX_COMPILING_TRIGGERS; + /* Instruct SQL to initate Tarantool's transaction. */ + pParse->initiateTTrans = true; + sql_table_delete_from(pParse, X, NULL,true); } %type where_opt {Expr*} diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index 54661cb..5c293bc 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -3700,10 +3700,11 @@ void sqlite3OpenTable(Parse *, int iCur, Table *, int); * @param tab_list List of single element which table from which * deletetion if performed. * @param where The WHERE clause. May be NULL. + * @param allow_truncate use truncate opcode if possible. */ void sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, - struct Expr *where); + struct Expr *where, bool allow_truncate); void sqlite3Update(Parse *, SrcList *, ExprList *, Expr *, enum on_conflict_action); diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c index ec0bc98..1949fdb 100644 --- a/src/box/sql/trigger.c +++ b/src/box/sql/trigger.c @@ -698,8 +698,8 @@ codeTriggerProgram(Parse * pParse, /* The parser context */ targetSrcList(pParse, pStep), sqlite3ExprDup(db, pStep->pWhere, - 0) - ); + 0), + false); break; } default: diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index f50e389..66a567b 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -39,6 +39,7 @@ * in this file for details. If in doubt, do not deviate from existing * commenting and indentation practices when changing or adding code. */ +#include "box/box.h" #include "box/txn.h" #include "box/session.h" #include "sqliteInt.h" @@ -4574,12 +4575,27 @@ case OP_IdxGE: { /* jump */ * doesn't involve truncating, since it features completely * different mechanism under hood. */ -case OP_Clear: { +/* Opcode: Truncate P1 * * * * + * Synopsis: space id = P1 + * + * Same as OP_Clear except this routine uses box_truncate that + * works faster, but have some restictions: the space_id is not an + * ID of system space, this routine mustn't be called by active + * transaction. + */ +case OP_Clear: +case OP_Truncate: { assert(pOp->p1 > 0); uint32_t space_id = pOp->p1; - struct space *space = space_by_id(space_id); - assert(space != NULL); - rc = tarantoolSqlite3ClearTable(space); + if (pOp->opcode == OP_Clear) { + struct space *space = space_by_id(space_id); + assert(space != NULL); + rc = tarantoolSqlite3ClearTable(space); + } else { + rc = box_truncate(space_id); + if (rc != 0) + rc = SQL_TARANTOOL_ERROR; + } if (rc) goto abort_due_to_error; break; } diff --git a/test/sql/delete.result b/test/sql/delete.result index c33079c..6026406 100644 --- a/test/sql/delete.result +++ b/test/sql/delete.result @@ -33,6 +33,16 @@ box.sql.execute("SELECT * FROM t1;"); --- - - [2, 4] ... +-- +-- gh-2201: TRUNCATE TABLE operation +-- +box.sql.execute("TRUNCATE TABLE t1;") +--- +... +box.sql.execute("SELECT * FROM t1;") +--- +- [] +... -- Cleanup box.sql.execute("DROP TABLE t1;"); --- diff --git a/test/sql/delete.test.lua b/test/sql/delete.test.lua index 1721989..7132302 100644 --- a/test/sql/delete.test.lua +++ b/test/sql/delete.test.lua @@ -21,6 +21,12 @@ box.sql.execute("DELETE FROM t1 WHERE a=1;"); -- Verify box.sql.execute("SELECT * FROM t1;"); +-- +-- gh-2201: TRUNCATE TABLE operation +-- +box.sql.execute("TRUNCATE TABLE t1;") +box.sql.execute("SELECT * FROM t1;") + -- Cleanup box.sql.execute("DROP TABLE t1;");