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 ED70B2AA8A for ; Mon, 26 Mar 2018 19:03: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 Mj3qlry7gM8Q for ; Mon, 26 Mar 2018 19:03:45 -0400 (EDT) Received: from smtp29.i.mail.ru (smtp29.i.mail.ru [94.100.177.89]) (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 2C0E52A9BA for ; Mon, 26 Mar 2018 19:03:45 -0400 (EDT) From: Nikita Pettik Subject: [tarantool-patches] [PATCH v2 2/2] sql: use 'view' opts from space Date: Tue, 27 Mar 2018 02:03:33 +0300 Message-Id: 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@freelist.org Cc: tarantool-patches@freelists.org, Nikita Pettik Originally in SQLite, table which represented view had not null pointer to struct Select. However, after 'view' space option is introduced, it has become possible to fetch 'view' property directly from struct space. This patch introduces simple wrapper to get this option. Moreover, TF_View flag is no more needed, so it is also removed. --- src/box/sql/alter.c | 4 ++-- src/box/sql/build.c | 27 +++++++++++++++++++-------- src/box/sql/delete.c | 2 +- src/box/sql/fkey.c | 3 ++- src/box/sql/insert.c | 10 ++++++---- src/box/sql/parse.c | 4 ++-- src/box/sql/parse.y | 5 ++--- src/box/sql/select.c | 4 ++-- src/box/sql/sqliteInt.h | 5 +++-- src/box/sql/trigger.c | 4 ++-- src/box/sql/update.c | 2 +- src/box/sql/vdbeaux.c | 2 +- src/box/sql/where.c | 3 ++- test/sql/transition.result | 7 ------- test/sql/transition.test.lua | 4 ---- 15 files changed, 45 insertions(+), 41 deletions(-) diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c index a52ba8d7a..054c0856c 100644 --- a/src/box/sql/alter.c +++ b/src/box/sql/alter.c @@ -107,7 +107,7 @@ sqlite3AlterRenameTable(Parse * pParse, /* Parser context. */ } #ifndef SQLITE_OMIT_VIEW - if (pTab->pSelect) { + if (space_is_view(pTab)) { sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); goto exit_rename_table; @@ -262,7 +262,7 @@ sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc) goto exit_begin_add_column; /* Make sure this is not an attempt to ALTER a view. */ - if (pTab->pSelect) { + if (space_is_view(pTab)) { sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } diff --git a/src/box/sql/build.c b/src/box/sql/build.c index dd0f45cf6..a9cb76717 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -1160,6 +1160,20 @@ index_collation_name(Index *idx, uint32_t column) return index->def->key_def->parts[column].coll->name; } +/** + * Return true if space which corresponds to + * given table has view option. + */ +bool +space_is_view(Table *table) +{ + assert(table != NULL); + uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(table->tnum); + struct space *space = space_by_id(space_id); + assert(space != NULL); + return space->def->opts.view; +} + /* * This function returns the collation sequence for database native text * encoding identified by the string zName, length nName. @@ -1839,7 +1853,6 @@ void sqlite3EndTable(Parse * pParse, /* Parse context */ Token * pCons, /* The ',' token after the last column defn. */ Token * pEnd, /* The ')' before options in the CREATE TABLE */ - u8 tabOpts, /* Extra table options. Usually 0. */ Select * pSelect /* Select from a "CREATE ... AS SELECT" */ ) { @@ -1864,9 +1877,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */ if (db->init.busy) p->tnum = db->init.newTnum; - if (p->pSelect) { - tabOpts |= TF_View; - } else { + if (!p->pSelect) { if ((p->tabFlags & TF_HasPrimaryKey) == 0) { sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", @@ -1957,7 +1968,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */ if (pSelect) { zStmt = createTableStmt(db, p); } else { - Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd; + Token *pEnd2 = p->pSelect ? &pParse->sLastToken : pEnd; n = (int)(pEnd2->z - pParse->sNameToken.z); if (pEnd2->z[0] != ';') n += pEnd2->n; @@ -2123,7 +2134,7 @@ sqlite3CreateView(Parse * pParse, /* The parsing context */ sEnd.n = 1; /* Use sqlite3EndTable() to add the view to the Tarantool. */ - sqlite3EndTable(pParse, 0, &sEnd, 0, 0); + sqlite3EndTable(pParse, 0, &sEnd, 0); create_view_fail: sqlite3SelectDelete(db, pSelect); @@ -2414,12 +2425,12 @@ sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr) /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used * on a table. */ - if (isView && pTab->pSelect == 0) { + if (isView && !space_is_view(pTab)) { sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); goto exit_drop_table; } - if (!isView && pTab->pSelect) { + if (!isView && space_is_view(pTab)) { sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); goto exit_drop_table; diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c index 61845aa27..2e09d926a 100644 --- a/src/box/sql/delete.c +++ b/src/box/sql/delete.c @@ -88,7 +88,7 @@ sqlite3IsReadOnly(Parse * pParse, Table * pTab, int viewOk) return 1; } #ifndef SQLITE_OMIT_VIEW - if (!viewOk && pTab->pSelect) { + if (!viewOk && space_is_view(pTab)) { sqlite3ErrorMsg(pParse, "cannot modify %s because it is a view", pTab->zName); return 1; diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c index 793f2f640..9286f4c5a 100644 --- a/src/box/sql/fkey.c +++ b/src/box/sql/fkey.c @@ -769,7 +769,8 @@ sqlite3FkDropTable(Parse * pParse, SrcList * pName, Table * pTab) sqlite3 *db = pParse->db; struct session *user_session = current_session(); - if ((user_session->sql_flags & SQLITE_ForeignKeys) && !pTab->pSelect) { + if ((user_session->sql_flags & SQLITE_ForeignKeys) && + !space_is_view(pTab)) { int iSkip = 0; Vdbe *v = sqlite3GetVdbe(pParse); diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index 28c01092d..42254ddf4 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -381,7 +381,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */ */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pTab, TK_INSERT, 0, &tmask); - isView = pTab->pSelect != 0; + isView = space_is_view(pTab); #else #define pTrigger 0 #define tmask 0 @@ -1074,7 +1074,8 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ db = pParse->db; v = sqlite3GetVdbe(pParse); assert(v != 0); - assert(pTab->pSelect == 0); /* This table is not a VIEW */ + /* This table is not a VIEW */ + assert(!space_is_view(pTab)); nCol = pTab->nCol; pPk = sqlite3PrimaryKeyIndex(pTab); @@ -1482,7 +1483,8 @@ sqlite3CompleteInsertion(Parse * pParse, /* The parser context */ v = sqlite3GetVdbe(pParse); assert(v != 0); - assert(pTab->pSelect == 0); /* This table is not a VIEW */ + /* This table is not a VIEW */ + assert(!space_is_view(pTab)); /* * The for loop which purpose in sqlite was to insert new * values to all indexes is replaced to inserting new @@ -1802,7 +1804,7 @@ xferOptimization(Parse * pParse, /* Parser context */ if (pSrc == pDest) { return 0; /* tab1 and tab2 may not be the same table */ } - if (pSrc->pSelect) { + if (space_is_view(pSrc)) { return 0; /* tab2 may not be a view */ } if (pDest->nCol != pSrc->nCol) { diff --git a/src/box/sql/parse.c b/src/box/sql/parse.c index f938a9a3c..17ce309da 100644 --- a/src/box/sql/parse.c +++ b/src/box/sql/parse.c @@ -2262,14 +2262,14 @@ static void yy_reduce( case 17: /* create_table_args ::= LP columnlist conslist_opt RP */ #line 185 "parse.y" { - sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0); + sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0); } #line 2268 "parse.c" break; case 18: /* create_table_args ::= AS select */ #line 188 "parse.y" { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy279); + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy279); sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy279); } #line 2276 "parse.c" diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index 11db58d94..e2acf2423 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -183,10 +183,10 @@ ifnotexists(A) ::= . {A = 0;} ifnotexists(A) ::= IF NOT EXISTS. {A = 1;} create_table_args ::= LP columnlist conslist_opt(X) RP(E). { - sqlite3EndTable(pParse,&X,&E,0,0); + sqlite3EndTable(pParse,&X,&E,0); } create_table_args ::= AS select(S). { - sqlite3EndTable(pParse,0,0,0,S); + sqlite3EndTable(pParse,0,0,S); sqlite3SelectDelete(pParse->db, S); } columnlist ::= columnlist COMMA columnname carglist. @@ -1357,7 +1357,6 @@ cmd ::= createkw trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). { trigger_decl(A) ::= TRIGGER ifnotexists(NOERR) nm(B) trigger_time(C) trigger_event(D) ON fullname(E) foreach_clause when_clause(G). { - pParse->initiateTTrans = false; sqlite3BeginTrigger(pParse, &B, C, D.a, D.b, E, G, NOERR); A = B; /*A-overwrites-T*/ } diff --git a/src/box/sql/select.c b/src/box/sql/select.c index a76286f23..c14bd7462 100644 --- a/src/box/sql/select.c +++ b/src/box/sql/select.c @@ -4295,7 +4295,7 @@ isSimpleCount(Select * p, AggInfo * pAggInfo) } pTab = p->pSrc->a[0].pTab; pExpr = p->pEList->a[0].pExpr; - assert(pTab && !pTab->pSelect && pExpr); + assert(pTab && !space_is_view(pTab) && pExpr); if (pExpr->op != TK_AGG_FUNCTION) return 0; if (NEVER(pAggInfo->nFunc == 0)) @@ -4760,7 +4760,7 @@ selectExpander(Walker * pWalker, Select * p) return WRC_Abort; } #if !defined(SQLITE_OMIT_VIEW) - if (pTab->pSelect) { + if (space_is_view(pTab)) { i16 nCol; if (sqlite3ViewGetColumnNames(pParse, pTab)) return WRC_Abort; diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index 0856bc729..effc0ffd5 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -1355,7 +1355,6 @@ struct Table { #define TF_Ephemeral 0x02 /* An ephemeral table */ #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ -#define TF_View 0x20 /* A view */ /* * Each foreign key constraint is an instance of the following structure. @@ -2983,7 +2982,9 @@ const char * index_collation_name(Index *, uint32_t); struct coll * sql_default_coll(); -void sqlite3EndTable(Parse *, Token *, Token *, u8, Select *); +bool +space_is_view(Table *); +void sqlite3EndTable(Parse *, Token *, Token *, Select *); int sqlite3ParseUri(const char *, const char *, unsigned int *, sqlite3_vfs **, char **, char **); diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c index 08963cb79..5460d1a54 100644 --- a/src/box/sql/trigger.c +++ b/src/box/sql/trigger.c @@ -144,13 +144,13 @@ sqlite3BeginTrigger(Parse * pParse, /* The parse context of the CREATE TRIGGER s /* INSTEAD of triggers are only for views and views only support INSTEAD * of triggers. */ - if (pTab->pSelect && tr_tm != TK_INSTEAD) { + if (space_is_view(pTab) && tr_tm != TK_INSTEAD) { sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE) ? "BEFORE" : "AFTER", pTableName, 0); goto trigger_cleanup; } - if (!pTab->pSelect && tr_tm == TK_INSTEAD) { + if (!space_is_view(pTab) && tr_tm == TK_INSTEAD) { sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName, 0); goto trigger_cleanup; diff --git a/src/box/sql/update.c b/src/box/sql/update.c index 47500ec9e..bf413252d 100644 --- a/src/box/sql/update.c +++ b/src/box/sql/update.c @@ -163,7 +163,7 @@ sqlite3Update(Parse * pParse, /* The parser context */ */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pTab, TK_UPDATE, pChanges, &tmask); - isView = pTab->pSelect != 0; + isView = space_is_view(pTab); assert(pTrigger || tmask == 0); #else #define pTrigger 0 diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c index 92bf9943b..773290b28 100644 --- a/src/box/sql/vdbeaux.c +++ b/src/box/sql/vdbeaux.c @@ -4717,7 +4717,7 @@ table_column_is_nullable(struct Table *tab, uint32_t column) { /* Temporary hack: until Tarantoool's ephemeral spaces are on-boarded, * views are not handled properly in Tarantool as well. */ - if (!(tab->tabFlags | TF_Ephemeral || tab->pSelect != NULL)) { + if (!(tab->tabFlags | TF_Ephemeral || space_is_view(tab))) { uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(tab->tnum); struct space *space = space_cache_find(space_id); diff --git a/src/box/sql/where.c b/src/box/sql/where.c index ae1ca6d9f..af87d52bd 100644 --- a/src/box/sql/where.c +++ b/src/box/sql/where.c @@ -4511,7 +4511,8 @@ sqlite3WhereBegin(Parse * pParse, /* The parser context */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; pLoop = pLevel->pWLoop; - if ((pTab->tabFlags & TF_Ephemeral) != 0 || pTab->pSelect) { + if ((pTab->tabFlags & TF_Ephemeral) != 0 || + space_is_view(pTab)) { /* Do nothing */ } else if ((pLoop->wsFlags & WHERE_IDX_ONLY) == 0 && (wctrlFlags & WHERE_OR_SUBCLAUSE) == 0) { diff --git a/test/sql/transition.result b/test/sql/transition.result index 500fe85c6..7c4a2c813 100644 --- a/test/sql/transition.result +++ b/test/sql/transition.result @@ -112,10 +112,6 @@ box.sql.execute("SELECT COUNT(*) FROM foobar WHERE bar='cacodaemon'") --- - - [0] ... --- cleanup -box.space.FOOBAR:drop() ---- -... -- multi-index -- create space box.sql.execute("CREATE TABLE barfoo (bar, foo NUM PRIMARY KEY)") @@ -188,9 +184,6 @@ box.sql.execute("CREATE TABLE rowid(x)") box.sql.execute("CREATE TABLE implicit_indices(a PRIMARY KEY,b,c,d UNIQUE)") --- ... -box.space.IMPLICIT_INDICES:drop() ---- -... box.sql.execute("DROP TABLE implicit_indices") --- ... diff --git a/test/sql/transition.test.lua b/test/sql/transition.test.lua index 996e634ec..50ee7f569 100644 --- a/test/sql/transition.test.lua +++ b/test/sql/transition.test.lua @@ -33,9 +33,6 @@ box.sql.execute("SELECT COUNT(*) FROM foobar WHERE bar='cacodaemon'") box.sql.execute("DELETE FROM foobar WHERE bar='cacodaemon'") box.sql.execute("SELECT COUNT(*) FROM foobar WHERE bar='cacodaemon'") --- cleanup -box.space.FOOBAR:drop() - -- multi-index -- create space @@ -69,5 +66,4 @@ box.sql.execute("CREATE TABLE rowid(x)") -- create a table with implicit indices (used to SEGFAULT) box.sql.execute("CREATE TABLE implicit_indices(a PRIMARY KEY,b,c,d UNIQUE)") -box.space.IMPLICIT_INDICES:drop() box.sql.execute("DROP TABLE implicit_indices") -- 2.15.1