[tarantool-patches] [PATCH 07/10] sql: remove index type from struct Index
Nikita Pettik
korablev at tarantool.org
Sun Aug 12 17:13:03 MSK 2018
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
More information about the Tarantool-patches
mailing list