From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org, Nikita Pettik <korablev@tarantool.org> Subject: [tarantool-patches] Re: [PATCH v1 1/1] sql: introduce TRUNCATE TABLE operation Date: Thu, 19 Jul 2018 12:01:51 +0300 [thread overview] Message-ID: <0beec187-ba71-773d-6064-da37276e8a88@tarantool.org> (raw) In-Reply-To: <A198A326-D7F5-4720-9352-FC51C3C3EA50@tarantool.org> Hi! Thank you for your ideas. I've reworked the 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..56dbbe5 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 is_truncate) { struct sqlite3 *db = parse->db; if (parse->nErr || db->mallocFailed) @@ -185,8 +185,11 @@ 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 (!is_truncate) { + sqlite3VdbeAddOp1(v, OP_Clear, space_id); + } else { + sqlite3VdbeAddOp2(v, OP_Clear, space_id, true); + } /* Do not start Tarantool's transaction in case of * truncate optimization. This is workaround until @@ -195,6 +198,13 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, */ parse->initiateTTrans = false; } else { + if (is_truncate) { + diag_set(ClientError, ER_SQL, + "Specified space could not be truncated."); + parse->nErr++; + parse->rc = SQL_TARANTOOL_ERROR; + goto delete_from_cleanup; + } /* Resolve the column names in the WHERE clause. */ struct NameContext nc; memset(&nc, 0, sizeof(nc)); 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 <tbl> */ 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..700f40d 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,false); +} + +/////////////////////////// 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..5eb4825 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -3703,7 +3703,7 @@ void sqlite3OpenTable(Parse *, int iCur, Table *, int); */ void sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, - struct Expr *where); + struct Expr *where, bool is_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..357beaa 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" @@ -4566,8 +4567,9 @@ case OP_IdxGE: { /* jump */ break; } -/* Opcode: Clear P1 * * * * +/* Opcode: Clear P1 P2 * * * * Synopsis: space id = P1 + * If P2 is not 0, use Truncate semantics. * * Delete all contents of the space, which space id is given * in P1 argument. It is worth mentioning, that clearing routine @@ -4579,7 +4581,13 @@ case OP_Clear: { uint32_t space_id = pOp->p1; struct space *space = space_by_id(space_id); assert(space != NULL); - rc = tarantoolSqlite3ClearTable(space); + rc = 0; + if (pOp->p2 > 0) { + if (box_truncate(space_id) != 0) + rc = SQL_TARANTOOL_ERROR; + } else { + rc = tarantoolSqlite3ClearTable(space); + } if (rc) goto abort_due_to_error; break; } diff --git a/test/sql/delete.result b/test/sql/delete.result index c33079c..0ab8c6a 100644 --- a/test/sql/delete.result +++ b/test/sql/delete.result @@ -33,6 +33,34 @@ box.sql.execute("SELECT * FROM t1;"); --- - - [2, 4] ... +-- +-- gh-2201: TRUNCATE TABLE operation +-- +box.sql.execute("TRUNCATE TABLE \"_sql_stat1\";") +--- +- error: Can't truncate a system space, space '_sql_stat1' +... +box.sql.execute("START TRANSACTION") +--- +... +box.sql.execute("TRUNCATE TABLE t1;") +--- +- error: DDL does not support multi-statement transactions +... +box.sql.execute("ROLLBACK") +--- +... +box.sql.execute("SELECT * FROM t1;") +--- +- - [2, 4] +... +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..afe843b 100644 --- a/test/sql/delete.test.lua +++ b/test/sql/delete.test.lua @@ -21,6 +21,19 @@ 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 \"_sql_stat1\";") + +box.sql.execute("START TRANSACTION") +box.sql.execute("TRUNCATE TABLE t1;") +box.sql.execute("ROLLBACK") +box.sql.execute("SELECT * FROM t1;") + +box.sql.execute("TRUNCATE TABLE t1;") +box.sql.execute("SELECT * FROM t1;") + -- Cleanup box.sql.execute("DROP TABLE t1;");
next prev parent reply other threads:[~2018-07-19 9:01 UTC|newest] Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-07-18 8:22 [tarantool-patches] " Kirill Shcherbatov 2018-07-18 8:31 ` [tarantool-patches] " Vladislav Shpilevoy 2018-07-18 13:01 ` Kirill Shcherbatov 2018-07-18 16:40 ` n.pettik 2018-07-19 9:01 ` Kirill Shcherbatov [this message] 2018-07-19 10:00 ` Kirill Shcherbatov 2018-07-20 2:16 ` n.pettik 2018-07-20 8:29 ` Kirill Shcherbatov 2018-07-20 16:33 ` n.pettik 2018-07-23 10:33 ` Kirill Shcherbatov 2018-07-25 12:58 ` n.pettik 2018-07-25 16:59 ` Kirill Shcherbatov 2018-07-26 9:10 ` n.pettik 2018-07-26 20:40 ` Vladislav Shpilevoy 2018-07-27 7:09 ` Kirill Shcherbatov 2018-07-27 7:16 ` Kirill Yukhin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=0beec187-ba71-773d-6064-da37276e8a88@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='[tarantool-patches] Re: [PATCH v1 1/1] sql: introduce TRUNCATE TABLE operation' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox