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 5F697281E8 for ; Sun, 12 Aug 2018 10:13:25 -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 aH_WoS70Xz0B for ; Sun, 12 Aug 2018 10:13:25 -0400 (EDT) Received: from smtp54.i.mail.ru (smtp54.i.mail.ru [217.69.128.34]) (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 584B4280D7 for ; Sun, 12 Aug 2018 10:13:24 -0400 (EDT) From: Nikita Pettik Subject: [tarantool-patches] [PATCH 07/10] sql: remove index type from struct Index Date: Sun, 12 Aug 2018 17:13:03 +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@freelists.org Cc: v.shpilevoy@tarantool.org, Nikita Pettik Part of #3561 --- src/box/sql.c | 2 +- src/box/sql/analyze.c | 2 +- src/box/sql/build.c | 92 +++++++++++++++++++------------------------------ src/box/sql/insert.c | 14 ++++---- src/box/sql/pragma.c | 7 +--- src/box/sql/prepare.c | 9 +---- src/box/sql/sqliteInt.h | 18 ++++------ src/box/sql/update.c | 2 +- src/box/sql/where.c | 4 +-- src/box/sql/wherecode.c | 4 +-- 10 files changed, 58 insertions(+), 96 deletions(-) diff --git a/src/box/sql.c b/src/box/sql.c index ae12cae36..a0aced27b 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -1511,7 +1511,7 @@ int tarantoolSqlite3MakeIdxOpts(SqliteIndex *index, const char *zSql, void *buf) * INSERT OR REPLACE/IGNORE uniqueness checks will be also done by * Tarantool. */ - p = enc->encode_bool(p, IsUniqueIndex(index)); + p = enc->encode_bool(p, sql_index_is_unique(index)); p = enc->encode_str(p, "sql", 3); p = enc->encode_str(p, zSql, zSql ? strlen(zSql) : 0); return (int)(p - base); diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c index 00d96d220..74f5ae827 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -831,7 +831,7 @@ analyzeOneTable(Parse * pParse, /* Parser context */ * names. Thus, for the sake of clarity, use * instead more familiar table name. */ - if (IsPrimaryKeyIndex(pIdx)) + if (sql_index_is_primary(pIdx)) idx_name = pTab->def->name; else idx_name = pIdx->def->name; diff --git a/src/box/sql/build.c b/src/box/sql/build.c index 01d4d52a3..3ef9ea96e 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -145,7 +145,7 @@ actualize_on_conflict_actions(struct Parse *parser, struct Table *table) for (struct Index *idx = table->pIndex; idx; idx = idx->pNext) { if (idx->onError == ON_CONFLICT_ACTION_REPLACE && - !IsPrimaryKeyIndex(idx)) + !sql_index_is_primary(idx)) goto non_pk_on_conflict_error; } @@ -421,8 +421,8 @@ Index * sqlite3PrimaryKeyIndex(Table * pTab) { Index *p; - for (p = pTab->pIndex; p && !IsPrimaryKeyIndex(p); p = p->pNext) { - } + for (p = pTab->pIndex; p != NULL && !sql_index_is_primary(p); + p = p->pNext); return p; } @@ -1280,8 +1280,11 @@ createIndex(Parse * pParse, Index * pIndex, int iSpaceId, int iIndexId, SQL_SUBTYPE_MSGPACK,zParts, P4_STATIC); sqlite3VdbeAddOp3(v, OP_MakeRecord, iFirstCol, 6, iRecord); sqlite3VdbeAddOp2(v, OP_SInsert, BOX_INDEX_ID, iRecord); - if (pIndex->index_type == SQL_INDEX_TYPE_NON_UNIQUE || - pIndex->index_type == SQL_INDEX_TYPE_UNIQUE) + /* + * Non-NULL value means that index has been created via + * separate CREATE INDEX statement. + */ + if (zSql != NULL) sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE); } @@ -1383,38 +1386,6 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt) sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE); } -/* - * Generate code to create implicit indexes in the new table. - * iSpaceId is a register storing the id of the space. - * iCursor is a cursor to access _index. - */ -static void -createImplicitIndices(Parse * pParse, int iSpaceId) -{ - Table *p = pParse->pNewTable; - Index *pIdx, *pPrimaryIdx = sqlite3PrimaryKeyIndex(p); - int i; - - if (pPrimaryIdx) { - /* Tarantool quirk: primary index is created first */ - createIndex(pParse, pPrimaryIdx, iSpaceId, 0, NULL); - } else { - /* - * This branch should not be taken. - * If it is, then the current CREATE TABLE statement fails to - * specify the PRIMARY KEY. The error is reported elsewhere. - */ - unreachable(); - } - - /* (pIdx->i) mapping must be consistent with parseTableSchemaRecord */ - for (pIdx = p->pIndex, i = 0; pIdx; pIdx = pIdx->pNext) { - if (pIdx == pPrimaryIdx) - continue; - createIndex(pParse, pIdx, iSpaceId, ++i, NULL); - } -} - /* * Generate code to emit and parse table schema record. * iSpaceId is a register storing the id of the space. @@ -1436,7 +1407,6 @@ parseTableSchemaRecord(Parse * pParse, int iSpaceId, char *zStmt) sqlite3VdbeAddOp4(v, OP_String8, 0, iTop + 3, 0, zStmt, P4_DYNAMIC); pPrimaryIdx = sqlite3PrimaryKeyIndex(p); - /* (pIdx->i) mapping must be consistent with createImplicitIndices */ for (pIdx = p->pIndex, i = 0; pIdx; pIdx = pIdx->pNext) { if (pIdx == pPrimaryIdx) continue; @@ -1753,8 +1723,12 @@ sqlite3EndTable(Parse * pParse, /* Parse context */ int reg_space_id = getNewSpaceId(pParse); createSpace(pParse, reg_space_id, stmt); /* Indexes aren't required for VIEW's.. */ - if (!p->def->opts.is_view) - createImplicitIndices(pParse, reg_space_id); + if (!p->def->opts.is_view) { + struct Index *idx = sqlite3PrimaryKeyIndex(p); + assert(idx != NULL); + for (uint32_t i = 0; idx != NULL; idx = idx->pNext, i++) + createIndex(pParse, idx, reg_space_id, i, NULL); + } /* * Check to see if we need to create an _sequence table @@ -2553,7 +2527,7 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex) addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); - if (IsUniqueIndex(pIndex)) { + if (sql_index_is_unique(pIndex)) { int j2 = sqlite3VdbeCurrentAddr(v) + 3; sqlite3VdbeGoto(v, j2); addr2 = sqlite3VdbeCurrentAddr(v); @@ -2749,6 +2723,18 @@ constraint_is_named(const char *name) strncmp(name, "unique_unnamed_", strlen("unique_unnamed_")); } +bool +sql_index_is_primary(const struct Index *idx) +{ + return idx->def->iid == 0; +} + +bool +sql_index_is_unique(const struct Index *idx) +{ + return idx->def->opts.is_unique; +} + void sql_create_index(struct Parse *parse, struct Token *token, struct SrcList *tbl_name, struct ExprList *col_list, @@ -2913,7 +2899,6 @@ sql_create_index(struct Parse *parse, struct Token *token, index->pTable = table; index->onError = (u8) on_error; - index->index_type = idx_type; /* * TODO: Issue a warning if two or more columns of the @@ -2939,9 +2924,6 @@ sql_create_index(struct Parse *parse, struct Token *token, * still must have iid == 0. */ uint32_t iid = idx_type != SQL_INDEX_TYPE_CONSTRAINT_PK; - if (db->init.busy) - iid = db->init.index_id; - if (index_fill_def(parse, index, table, iid, name, strlen(name), col_list, idx_type, sql_stmt) != 0) goto exit_create_index; @@ -3039,14 +3021,10 @@ sql_create_index(struct Parse *parse, struct Token *token, bool is_named = constraint_is_named(existing_idx->def->name); /* CREATE TABLE t(a, UNIQUE(a), PRIMARY KEY(a)). */ - if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_PK) { - if (existing_idx->index_type == - SQL_INDEX_TYPE_CONSTRAINT_UNIQUE && - !is_named) { - existing_idx->index_type = - SQL_INDEX_TYPE_CONSTRAINT_PK; - goto exit_create_index; - } + if (idx_type == SQL_INDEX_TYPE_CONSTRAINT_PK && + !sql_index_is_primary(existing_idx) && !is_named) { + existing_idx->def->iid = 0; + goto exit_create_index; } /* CREATE TABLE t(a, PRIMARY KEY(a), UNIQUE(a)). */ @@ -3057,10 +3035,12 @@ sql_create_index(struct Parse *parse, struct Token *token, } /* * Link the new Index structure to its table and to the - * other in-memory database structures. + * other in-memory database structures. If index created + * within CREATE TABLE statement, its iid is assigned + * in sql_init_callback(). */ assert(parse->nErr == 0); - if (db->init.busy) { + if (db->init.busy && tbl_name != NULL) { user_session->sql_flags |= SQLITE_InternChanges; index->def->iid = db->init.index_id; } @@ -3752,7 +3732,7 @@ parser_emit_unique_constraint(struct Parse *parser, sqlite3XPrintf(&err_accum, "%s.%s", def->name, col_name); } char *err_msg = sqlite3StrAccumFinish(&err_accum); - sqlite3HaltConstraint(parser, IsPrimaryKeyIndex(index) ? + sqlite3HaltConstraint(parser, sql_index_is_primary(index) ? SQLITE_CONSTRAINT_PRIMARYKEY : SQLITE_CONSTRAINT_UNIQUE, on_error, err_msg, P4_DYNAMIC, P5_ConstraintUnique); diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index 853265ead..cb120384a 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -1159,7 +1159,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ bool table_ipk_autoinc = false; int reg_pk = -1; - if (IsPrimaryKeyIndex(pIdx)) { + if (sql_index_is_primary(pIdx)) { /* If PK is marked as INTEGER, use it as strict type, * not as affinity. Emit code for type checking */ if (part_count == 1) { @@ -1197,7 +1197,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; } - if (!IsUniqueIndex(pIdx)) { + if (!sql_index_is_unique(pIdx)) { sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; } @@ -1304,7 +1304,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ int addrJump = sqlite3VdbeCurrentAddr(v) + pk_part_count; int op = OP_Ne; - int regCmp = IsPrimaryKeyIndex(pIdx) ? + int regCmp = sql_index_is_primary(pIdx) ? regIdx : regR; struct key_part *part = pPk->def->key_def->parts; @@ -1483,9 +1483,9 @@ sqlite3OpenTableAndIndices(Parse * pParse, /* Parsing context */ * iteration and don't open new index cursor */ - if (isUpdate || /* Condition 1 */ - IsPrimaryKeyIndex(pIdx) || /* Condition 2 */ + if (isUpdate || ! rlist_empty(&space->parent_fkey) || + sql_index_is_primary(pIdx) || /* Condition 4 */ (pIdx->def->opts.is_unique && pIdx->onError != ON_CONFLICT_ACTION_DEFAULT && @@ -1495,7 +1495,7 @@ sqlite3OpenTableAndIndices(Parse * pParse, /* Parsing context */ overrideError == ON_CONFLICT_ACTION_ROLLBACK) { int iIdxCur = iBase++; - if (IsPrimaryKeyIndex(pIdx)) { + if (sql_index_is_primary(pIdx)) { if (piDataCur) *piDataCur = iIdxCur; p5 = 0; @@ -1812,7 +1812,7 @@ xferOptimization(Parse * pParse, /* Parser context */ VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); - if (pDestIdx->index_type == SQL_INDEX_TYPE_CONSTRAINT_PK) + if (sql_index_is_primary(pDestIdx)) sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1 + 1); VdbeCoverage(v); diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c index 0ba651567..822db69ba 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -506,15 +506,10 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ pParse->nMem = 5; for (pIdx = pTab->pIndex, i = 0; pIdx; pIdx = pIdx->pNext, i++) { - const char *azOrigin[] = - { "c", "u", "u", "pk" }; sqlite3VdbeMultiLoad(v, 1, "isisi", i, pIdx->def->name, - pIdx->def->opts.is_unique, - azOrigin - [pIdx-> - index_type]); + pIdx->def->opts.is_unique); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c index db5ee5e97..e8b8e94ae 100644 --- a/src/box/sql/prepare.c +++ b/src/box/sql/prepare.c @@ -120,14 +120,7 @@ sql_init_callback(struct init_data *init, const char *name, struct space *space = space_by_id(space_id); const char *zSpace = space_name(space); pIndex = sqlite3LocateIndex(db, name, zSpace); - if (pIndex == NULL) { - /* This can occur if there exists an index on a TEMP table which - * has the same name as another index on a permanent index. Since - * the permanent table is hidden by the TEMP table, we can also - * safely ignore the index on the permanent table. - */ - /* Do Nothing */ ; - } + assert(pIndex != NULL); pIndex->def->iid = index_id; } return 0; diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index eb20fb31a..0ffc8d548 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -1987,13 +1987,13 @@ enum sql_index_type { SQL_INDEX_TYPE_CONSTRAINT_PK, }; -/* Return true if index X is a PRIMARY KEY index */ -#define IsPrimaryKeyIndex(X) ((X)->index_type==SQL_INDEX_TYPE_CONSTRAINT_PK) +/** Simple wrapper to test index id on zero. */ +bool +sql_index_is_primary(const struct Index *idx); -/* Return true if index X is a UNIQUE index */ -#define IsUniqueIndex(X) (((X)->index_type == SQL_INDEX_TYPE_CONSTRAINT_UNIQUE) || \ - ((X)->index_type == SQL_INDEX_TYPE_CONSTRAINT_PK) || \ - ((X)->index_type == SQL_INDEX_TYPE_UNIQUE)) +/** Simple getter around opts.is_unique. */ +bool +sql_index_is_unique(const struct Index *idx); /* * Each SQL index is represented in memory by an @@ -2015,12 +2015,6 @@ struct Index { * unique index. */ u8 onError; - /** - * Index type: non-unique index, unique index, index - * implementing UNIQUE constraint or index implementing - * PK constraint. - */ - enum sql_index_type index_type; /** Index definition. */ struct index_def *def; }; diff --git a/src/box/sql/update.c b/src/box/sql/update.c index 54b30705a..3fdf5a9af 100644 --- a/src/box/sql/update.c +++ b/src/box/sql/update.c @@ -162,7 +162,7 @@ sqlite3Update(Parse * pParse, /* The parser context */ iIdxCur = iDataCur + 1; pPk = is_view ? 0 : sqlite3PrimaryKeyIndex(pTab); for (nIdx = 0, pIdx = pTab->pIndex; pIdx; pIdx = pIdx->pNext, nIdx++) { - if (IsPrimaryKeyIndex(pIdx) && pPk != 0) { + if (sql_index_is_primary(pIdx) && pPk != 0) { iDataCur = pParse->nTab; pTabList->a[0].iCursor = iDataCur; } diff --git a/src/box/sql/where.c b/src/box/sql/where.c index a57bad5b7..73fe070fd 100644 --- a/src/box/sql/where.c +++ b/src/box/sql/where.c @@ -3009,7 +3009,7 @@ whereLoopAddBtree(WhereLoopBuilder * pBuilder, /* WHERE clause information */ * of secondary indexes, because secondary indexes * are not really store any data (only pointers to tuples). */ - int notPkPenalty = IsPrimaryKeyIndex(pProbe) ? 0 : 4; + int notPkPenalty = sql_index_is_primary(pProbe) ? 0 : 4; pNew->rRun = rSize + 16 + notPkPenalty; whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); @@ -4684,7 +4684,7 @@ sqlite3WhereBegin(Parse * pParse, /* The parser context */ */ if (idx_def == NULL && pIx == NULL) continue; - bool is_primary = (pIx != NULL && IsPrimaryKeyIndex(pIx)) || + bool is_primary = (pIx != NULL && sql_index_is_primary(pIx)) || (idx_def != NULL && (idx_def->iid == 0)); if (is_primary && (wctrlFlags & WHERE_OR_SUBCLAUSE) != 0) { diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c index 6b3f2f78a..1c16d5323 100644 --- a/src/box/sql/wherecode.c +++ b/src/box/sql/wherecode.c @@ -226,7 +226,7 @@ sqlite3WhereExplainOneScan(Parse * pParse, /* Parse context */ assert(pIdx != NULL || idx_def != NULL); assert(!(flags & WHERE_AUTO_INDEX) || (flags & WHERE_IDX_ONLY)); - if ((pIdx != NULL && IsPrimaryKeyIndex(pIdx)) || + if ((pIdx != NULL && sql_index_is_primary(pIdx)) || (idx_def != NULL && idx_def->iid == 0)) { if (isSearch) { zFmt = "PRIMARY KEY"; @@ -1626,7 +1626,7 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t assert((pSubLoop->wsFlags & WHERE_AUTO_INDEX) == 0); if ((pSubLoop->wsFlags & WHERE_INDEXED) != 0 && (ii == 0 || pSubLoop->pIndex == pCov) - && (!IsPrimaryKeyIndex(pSubLoop->pIndex)) + && (!sql_index_is_primary(pSubLoop->pIndex)) ) { assert(pSubWInfo->a[0]. iIdxCur == iCovCur); -- 2.15.1