From: Kirill Yukhin <kyukhin@tarantool.org> To: v.shpilevoy@tarantool.org Cc: tarantool-patches@freelists.org, Kirill Yukhin <kyukhin@tarantool.org> Subject: [tarantool-patches] [PATCH] sql: refactor SQL delete to allow Lua spaces Date: Fri, 18 May 2018 16:36:56 +0300 [thread overview] Message-ID: <87358913270ee98c98bc276209289d6b7ac496b6.1526650490.git.kyukhin@tarantool.org> (raw) Branch: https://github.com/tarantool/tarantool/tree/kyukhin/gh-3235-sql-truncate-on-lua-spaces Issue: https://github.com/tarantool/tarantool/issues/3235 This is a first step toward fully-featured deletion of spaces created in Lua by means of SQL language. This change to handle most simple case: DELETE * FROM <space_name> and will be improved in nearest future. Part of #3235 --- src/box/sql/analyze.c | 3 +- src/box/sql/build.c | 3 +- src/box/sql/delete.c | 69 ++++++++++++++++++++++++++----------------- src/box/sql/vdbe.c | 2 +- test/sql-tap/delete1.test.lua | 23 ++++++++++++++- 5 files changed, 69 insertions(+), 31 deletions(-) diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c index 998dd5b..cc594a7 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -169,7 +169,8 @@ openStatTable(Parse * pParse, /* Parsing context */ * The sql_stat[134] table already exists. * Delete all rows. */ - sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], 0); + sqlite3VdbeAddOp2(v, OP_Clear, + SQLITE_PAGENO_TO_SPACEID(aRoot[i]), 0); } } diff --git a/src/box/sql/build.c b/src/box/sql/build.c index df75186..49e59f4 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -2672,7 +2672,8 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex, int memRootPage) VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); if (memRootPage < 0) - sqlite3VdbeAddOp2(v, OP_Clear, tnum, 0); + sqlite3VdbeAddOp2(v, OP_Clear, SQLITE_PAGENO_TO_SPACEID(tnum), + 0); emit_open_cursor(pParse, iIdx, tnum); sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR | ((memRootPage >= 0) ? diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c index f4d248e..dfc91cb 100644 --- a/src/box/sql/delete.c +++ b/src/box/sql/delete.c @@ -29,6 +29,7 @@ * SUCH DAMAGE. */ +#include "box/box.h" #include "box/session.h" #include "box/schema.h" #include "sqliteInt.h" @@ -86,35 +87,50 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, * with multiple tables and expect an SrcList* parameter * instead of just a Table* parameter. */ - struct Table *table = sql_list_lookup_table(parse, tab_list); - if (table == NULL) - goto delete_from_cleanup; - - struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(table->tnum)); - assert(space != NULL); + struct Table *table = NULL; + struct space *space; + uint32_t space_id; /* Figure out if we have any triggers and if the table * being deleted from is a view. */ - struct Trigger *trigger_list = sqlite3TriggersExist(table, TK_DELETE, - NULL, NULL); - - bool is_view = space->def->opts.is_view; + struct Trigger *trigger_list = NULL; /* True if there are triggers or FKs or subqueries in the * WHERE clause. */ - bool is_complex = trigger_list != NULL || - sqlite3FkRequired(table, NULL); + bool is_complex = false; + const char *tab_name = tab_list->a->zName; + if (sqlite3LocateTable(parse, LOCATE_NOERR, tab_name) == NULL) { + space_id = box_space_id_by_name(tab_name, + strlen(tab_name)); + if (space_id == BOX_ID_NIL) + goto delete_from_cleanup; + } else { + table = sql_list_lookup_table(parse, tab_list); + if (table == NULL) + goto delete_from_cleanup; + space_id = SQLITE_PAGENO_TO_SPACEID(table->tnum); + trigger_list =sqlite3TriggersExist(table, TK_DELETE, + NULL, NULL); + is_complex = trigger_list != NULL || + sqlite3FkRequired(table, NULL); + } + space = space_by_id(space_id); + assert(space != NULL); + + bool is_view = space->def->opts.is_view; /* If table is really a view, make sure it has been * initialized. */ - if (sqlite3ViewGetColumnNames(parse, table)) - goto delete_from_cleanup; + if (is_view) { + if (sqlite3ViewGetColumnNames(parse, table)) + goto delete_from_cleanup; - if (is_view && trigger_list == NULL) { - sqlite3ErrorMsg(parse, "cannot modify %s because it is a view", - space->def->name); - goto delete_from_cleanup; + if (trigger_list == NULL) { + sqlite3ErrorMsg(parse, "cannot modify %s because it is a" + " view", space->def->name); + goto delete_from_cleanup; + } } /* Assign cursor numbers to the table and all its indices. @@ -139,14 +155,6 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, tab_cursor); } - /* Resolve the column names in the WHERE clause. */ - struct NameContext nc; - memset(&nc, 0, sizeof(nc)); - nc.pParse = parse; - nc.pSrcList = tab_list; - if (sqlite3ResolveExprNames(&nc, where)) - goto delete_from_cleanup; - /* Initialize the counter of the number of rows deleted, * if we are counting rows. */ @@ -162,7 +170,7 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, if (where == NULL && !is_complex) { assert(!is_view); - sqlite3VdbeAddOp1(v, OP_Clear, table->tnum); + sqlite3VdbeAddOp1(v, OP_Clear, space_id); /* Do not start Tarantool's transaction in case of * truncate optimization. This is workaround until @@ -171,6 +179,13 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, */ parse->initiateTTrans = false; } else { + /* Resolve the column names in the WHERE clause. */ + struct NameContext nc; + memset(&nc, 0, sizeof(nc)); + nc.pParse = parse; + nc.pSrcList = tab_list; + if (sqlite3ResolveExprNames(&nc, where)) + goto delete_from_cleanup; uint16_t wcf = WHERE_ONEPASS_DESIRED | WHERE_DUPLICATES_OK | WHERE_SEEK_TABLE; if (nc.ncFlags & NC_VarSelect) diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 455198d..9acb9b6 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -4614,7 +4614,7 @@ case OP_IdxGE: { /* jump */ */ case OP_Clear: { assert(pOp->p1 > 0); - uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(pOp->p1); + uint32_t space_id = pOp->p1; struct space *space = space_by_id(space_id); assert(space != NULL); rc = tarantoolSqlite3ClearTable(space); diff --git a/test/sql-tap/delete1.test.lua b/test/sql-tap/delete1.test.lua index 61d7756..810ca8a 100755 --- a/test/sql-tap/delete1.test.lua +++ b/test/sql-tap/delete1.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool test = require("sqltester") -test:plan(7) +test:plan(9) --!./tcltestrunner.lua -- ["set","testdir",[["file","dirname",["argv0"]]]] @@ -131,5 +131,26 @@ test:do_test( -- </delete1-5.0> }) +-- Tests for data dictionary integration. +s = box.schema.create_space('t') +i = s:create_index('i', {parts={1, 'unsigned'}}) +test:do_test( + "delete1-6.0", + function() + s:replace({1}) + s:replace({2}) + s:replace({3}) + return s:count() + end, + 3) + +test:do_test( + "delete1-6.1", + function() + box.sql.execute([[delete from "t"]]) + return s:count() + end, + 0) + test:finish_test() -- 2.16.2
next reply other threads:[~2018-05-18 13:37 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-18 13:36 Kirill Yukhin [this message] 2018-05-18 21:07 ` [tarantool-patches] " Vladislav Shpilevoy 2018-05-21 8:20 ` Kirill Yukhin 2018-05-21 9:47 ` Vladislav Shpilevoy 2018-05-21 10:25 ` Kirill Yukhin 2018-05-21 10:49 ` Vladislav Shpilevoy 2018-05-21 11:24 ` Kirill Yukhin 2018-05-21 11:39 ` Vladislav Shpilevoy
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=87358913270ee98c98bc276209289d6b7ac496b6.1526650490.git.kyukhin@tarantool.org \ --to=kyukhin@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH] sql: refactor SQL delete to allow Lua spaces' \ /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