* [tarantool-patches] [PATCH 1/2] sql: remove obsolete SQLite routine
2018-04-03 16:14 [tarantool-patches] [PATCH 0/2] rework SQL 'DROP' routine Nikita Pettik
@ 2018-04-03 16:14 ` Nikita Pettik
2018-04-03 17:54 ` [tarantool-patches] " Vladislav Shpilevoy
2018-04-03 16:14 ` [tarantool-patches] [PATCH 2/2] sql: rework 'DROP INDEX' and 'DROP TABLE' handling Nikita Pettik
2018-04-05 14:12 ` [tarantool-patches] Re: [PATCH 0/2] rework SQL 'DROP' routine Kirill Yukhin
2 siblings, 1 reply; 12+ messages in thread
From: Nikita Pettik @ 2018-04-03 16:14 UTC (permalink / raw)
To: tarantool-patches; +Cc: v.shpilevoy, Nikita Pettik
Some of legacy functions seem to be useless, since they serve as
wrappers around others; the rest rely on capabilities which are no
longer relevant. This patch provides slight refactoring of such
functions.
Removed entities:
- sqlite3LocateTableItem() - replaced with sqlite3LocateTable();
- sqlite3FindTable() - replaced with sqlite3HashFind();
- sqlite3ColumnOfIndex() - in Tarantool order of columns always the same;
- sqlite3FindIndex() - replaced with sqlite3LocateIndex();
- sqlite3CodeVerifySchema();
- sqlite3SchemaToIndex();
- sqlite3MultiWrite();
- Parse->cookieMast;
- Vdbe->usesStmtJournal;
---
src/box/sql/alter.c | 13 ++-
src/box/sql/analyze.c | 25 +++---
src/box/sql/build.c | 213 ++++++++++--------------------------------------
src/box/sql/delete.c | 5 +-
src/box/sql/expr.c | 9 +-
src/box/sql/fkey.c | 3 +-
src/box/sql/insert.c | 10 +--
src/box/sql/pragma.c | 18 ++--
src/box/sql/prepare.c | 29 -------
src/box/sql/select.c | 4 +-
src/box/sql/sqliteInt.h | 11 +--
src/box/sql/trigger.c | 7 +-
src/box/sql/update.c | 2 +-
src/box/sql/vdbe.c | 1 -
src/box/sql/vdbeInt.h | 1 -
src/box/sql/vdbeaux.c | 1 -
src/box/sql/where.c | 2 -
src/box/sql/wherecode.c | 7 +-
18 files changed, 83 insertions(+), 278 deletions(-)
diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c
index 054c0856c..a19324ed2 100644
--- a/src/box/sql/alter.c
+++ b/src/box/sql/alter.c
@@ -84,10 +84,9 @@ sqlite3AlterRenameTable(Parse * pParse, /* Parser context. */
goto exit_rename_table;
assert(pSrc->nSrc == 1);
- pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
+ pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName);
if (!pTab)
goto exit_rename_table;
- assert(sqlite3SchemaToIndex(pParse->db, pTab->pSchema) == 0);
user_session->sql_flags |= SQLITE_PreferBuiltin;
@@ -99,7 +98,7 @@ sqlite3AlterRenameTable(Parse * pParse, /* Parser context. */
/* Check that a table named 'zName' does not already exist
* in database. If so, this is an error.
*/
- if (sqlite3FindTable(db, zName)) {
+ if (sqlite3HashFind(&db->pSchema->tblHash, zName) != NULL) {
sqlite3ErrorMsg(pParse,
"there is already another table or index with this name: %s",
zName);
@@ -122,7 +121,7 @@ sqlite3AlterRenameTable(Parse * pParse, /* Parser context. */
if (v == 0) {
goto exit_rename_table;
}
- sqlite3BeginWriteOperation(pParse, false);
+ sql_set_multi_write(pParse, false);
/* Drop and reload the internal table schema. */
reloadTableSchema(pParse, pTab, zName);
@@ -163,7 +162,7 @@ sqlite3AlterFinishAddColumn(Parse * pParse, Token * pColDef)
zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
pCol = &pNew->aCol[pNew->nCol - 1];
pDflt = pCol->pDflt;
- pTab = sqlite3FindTable(db, zTab);
+ pTab = sqlite3HashFind(&db->pSchema->tblHash, zTab);;
assert(pTab);
/* If the default value for the new column was specified with a
@@ -257,7 +256,7 @@ sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc)
assert(pParse->pNewTable == 0);
if (db->mallocFailed)
goto exit_begin_add_column;
- pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
+ pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName);
if (!pTab)
goto exit_begin_add_column;
@@ -305,7 +304,7 @@ sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc)
pNew->nTabRef = 1;
/* Begin a transaction and increment the schema cookie. */
- sqlite3BeginWriteOperation(pParse, 0);
+ sql_set_multi_write(pParse, 0);
v = sqlite3GetVdbe(pParse);
if (!v)
goto exit_begin_add_column;
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index fb46641a2..25e93aa15 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -156,7 +156,7 @@ openStatTable(Parse * pParse, /* Parsing context */
const char *zTab = aTable[i];
Table *pStat;
/* The table already exists, because it is a system space */
- pStat = sqlite3FindTable(db, zTab);
+ pStat = sqlite3HashFind(&db->pSchema->tblHash, zTab);
aRoot[i] = pStat->tnum;
aCreateTbl[i] = 0;
if (zWhere) {
@@ -831,7 +831,6 @@ analyzeOneTable(Parse * pParse, /* Parser context */
/* Do not gather statistics on system tables */
return;
}
- assert(sqlite3SchemaToIndex(db, pTab->pSchema) == 0);
/* Establish a read-lock on the table at the shared-cache level.
* Open a read-only cursor on the table. Also allocate a cursor number
@@ -907,7 +906,6 @@ analyzeOneTable(Parse * pParse, /* Parser context */
pParse->nMem = MAX(pParse->nMem, regPrev + nColTest);
/* Open a read-only cursor on the index being analyzed. */
- assert(sqlite3SchemaToIndex(db, pIdx->pSchema) == 0);
struct space *space =
space_by_id(SQLITE_PAGENO_TO_SPACEID(pIdx->tnum));
assert(space != NULL);
@@ -1028,7 +1026,7 @@ analyzeOneTable(Parse * pParse, /* Parser context */
int nPkColumn = (int)index_column_count(pPk);
regKeyStat = sqlite3GetTempRange(pParse, nPkColumn);
for (j = 0; j < nPkColumn; j++) {
- k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ k = pPk->aiColumn[j];
assert(k >= 0 && k < pTab->nCol);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKeyStat + j);
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
@@ -1124,7 +1122,7 @@ analyzeDatabase(Parse * pParse)
int iMem;
int iTab;
- sqlite3BeginWriteOperation(pParse, 0);
+ sql_set_multi_write(pParse, 0);
iStatCur = pParse->nTab;
pParse->nTab += 3;
openStatTable(pParse, iStatCur, 0, 0);
@@ -1148,8 +1146,7 @@ analyzeTable(Parse * pParse, Table * pTab, Index * pOnlyIdx)
int iStatCur;
assert(pTab != 0);
- assert(sqlite3SchemaToIndex(pParse->db, pTab->pSchema) == 0);
- sqlite3BeginWriteOperation(pParse, 0);
+ sql_set_multi_write(pParse, 0);
iStatCur = pParse->nTab;
pParse->nTab += 3;
if (pOnlyIdx) {
@@ -1296,7 +1293,7 @@ analysisLoader(void *pData, int argc, char **argv, char **NotUsed)
if (argv == 0 || argv[0] == 0 || argv[2] == 0) {
return 0;
}
- pTable = sqlite3FindTable(pInfo->db, argv[0]);
+ pTable = sqlite3HashFind(&pInfo->db->pSchema->tblHash, argv[0]);
if (pTable == 0) {
return 0;
}
@@ -1305,7 +1302,7 @@ analysisLoader(void *pData, int argc, char **argv, char **NotUsed)
} else if (sqlite3_stricmp(argv[0], argv[1]) == 0) {
pIndex = sqlite3PrimaryKeyIndex(pTable);
} else {
- pIndex = sqlite3FindIndex(pInfo->db, argv[1], pTable);
+ pIndex = sqlite3HashFind(&pTable->idxHash, argv[1]);
}
z = argv[2];
@@ -1638,14 +1635,14 @@ loadStat4(sqlite3 * db)
Table *pTab = 0; /* Pointer to stat table */
assert(db->lookaside.bDisable);
- pTab = sqlite3FindTable(db, "_sql_stat4");
+ pTab = sqlite3HashFind(&db->pSchema->tblHash, "_sql_stat4");
if (pTab) {
rc = loadStatTbl(db,
pTab,
"SELECT \"tbl\",\"idx\",count(*) FROM \"_sql_stat4\" GROUP BY \"tbl\",\"idx\"",
"SELECT \"tbl\",\"idx\",\"neq\",\"nlt\",\"ndlt\",\"sample\" FROM \"_sql_stat4\"");
}
-
+
return rc;
}
@@ -1690,10 +1687,8 @@ sqlite3AnalysisLoad(sqlite3 * db)
/* Load new statistics out of the _sql_stat1 table */
sInfo.db = db;
- if (sqlite3FindTable(db, "_sql_stat1") != 0) {
- zSql = "SELECT \"tbl\",\"idx\",\"stat\" FROM \"_sql_stat1\"";
- rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
- }
+ zSql = "SELECT \"tbl\",\"idx\",\"stat\" FROM \"_sql_stat1\"";
+ rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
/* Set appropriate defaults on all indexes not in the _sql_stat1 table */
for (j = sqliteHashFirst(&db->pSchema->tblHash); j;
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 5e3ed0f39..61194e06b 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -93,23 +93,16 @@ sqlite3FinishCoding(Parse * pParse)
* transaction on each used database and to verify the schema cookie
* on each used database.
*/
- if (db->mallocFailed == 0
- && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
- ) {
+ if (db->mallocFailed == 0 || pParse->pConstExpr) {
int i;
assert(sqlite3VdbeGetOp(v, 0)->opcode == OP_Init);
sqlite3VdbeJumpHere(v, 0);
- if (DbMaskTest(pParse->cookieMask, 0) != 0) {
- if (pParse->initiateTTrans)
- sqlite3VdbeAddOp0(v, OP_TTransaction);
-
- if (db->init.busy == 0)
- sqlite3VdbeChangeP5(v, 1);
-
- VdbeComment((v, "usesStmtJournal=%d",
- pParse->mayAbort
- && pParse->isMultiWrite));
- }
+ if (pParse->initiateTTrans)
+ sqlite3VdbeAddOp0(v, OP_TTransaction);
+ if (db->init.busy == 0)
+ sqlite3VdbeChangeP5(v, 1);
+ VdbeComment((v, "Multiple changes: %d, may abort: %d",
+ pParse->isMultiWrite, pParse->mayAbort));
/* Code constant expressions that where factored out of inner loops */
if (pParse->pConstExpr) {
@@ -183,32 +176,10 @@ sqlite3NestedParse(Parse * pParse, const char *zFormat, ...)
pParse->nested--;
}
-/*
- * Locate the in-memory structure that describes a particular database
- * table given the name of that table and (optionally) the name of the
- * database containing the table. Return NULL if not found.
- *
- * If zDatabase is 0, all databases are searched for the table and the
- * first matching table is returned. (No checking for duplicate table
- * names is done.) The search order is TEMP first, then MAIN, then any
- * auxiliary databases added using the ATTACH command.
- *
- * See also sqlite3LocateTable().
- */
-Table *
-sqlite3FindTable(sqlite3 * db, const char *zName)
-{
- return sqlite3HashFind(&db->pSchema->tblHash, zName);
-}
-
/*
* Locate the in-memory structure that describes a particular database
* table given the name of that table. Return NULL if not found.
* Also leave an error message in pParse->zErrMsg.
- *
- * The difference between this routine and sqlite3FindTable() is that this
- * routine leaves an error message in pParse->zErrMsg where
- * sqlite3FindTable() does not.
*/
Table *
sqlite3LocateTable(Parse * pParse, /* context in which to report errors */
@@ -220,7 +191,7 @@ sqlite3LocateTable(Parse * pParse, /* context in which to report errors */
assert(pParse->db->pSchema != NULL);
- p = sqlite3FindTable(pParse->db, zName);
+ p = sqlite3HashFind(&pParse->db->pSchema->tblHash, zName);
if (p == 0) {
const char *zMsg =
flags & LOCATE_VIEW ? "no such view" : "no such table";
@@ -233,48 +204,19 @@ sqlite3LocateTable(Parse * pParse, /* context in which to report errors */
return p;
}
-/*
- * Locate the table identified by *p.
- *
- * This is a wrapper around sqlite3LocateTable(). The difference between
- * sqlite3LocateTable() and this function is that this function restricts
- * the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
- * non-NULL if it is part of a view or trigger program definition. See
- * sqlite3FixSrcList() for details.
- */
-Table *
-sqlite3LocateTableItem(Parse * pParse, u32 flags, struct SrcList_item * p)
-{
- return sqlite3LocateTable(pParse, flags, p->zName);
-}
-
-/*
- * Locate the in-memory structure that describes
- * a particular index given the name of that index
- * and the name of the database that contains the index.
- * Return NULL if not found.
- */
-Index *
-sqlite3FindIndex(MAYBE_UNUSED sqlite3 * db, const char *zName, Table * pTab)
-{
- assert(pTab);
-
- return sqlite3HashFind(&pTab->idxHash, zName);
-}
-
Index *
sqlite3LocateIndex(sqlite3 * db, const char *zName, const char *zTable)
{
assert(zName);
assert(zTable);
- Table *pTab = sqlite3FindTable(db, zTable);
+ Table *pTab = sqlite3HashFind(&db->pSchema->tblHash, zTable);
if (pTab == 0) {
return 0;
}
- return sqlite3FindIndex(db, zName, pTab);
+ return sqlite3HashFind(&pTab->idxHash, zName);
}
/*
@@ -557,18 +499,6 @@ sqlite3PrimaryKeyIndex(Table * pTab)
return p;
}
-/*
- * Return the column of index pIdx that corresponds to table
- * column iCol. Return -1 if not found.
- */
-i16
-sqlite3ColumnOfIndex(Index * pIdx, i16 iCol)
-{
- /* TARANTOOL: Data layout is the same in every index. */
- (void) pIdx;
- return iCol;
-}
-
/*
* Begin constructing a new table representation in memory. This is
* the first of several action routines that get called in response
@@ -614,7 +544,7 @@ sqlite3StartTable(Parse *pParse, Token *pName, int noErr)
return;
assert(db->pSchema != NULL);
- pTable = sqlite3FindTable(db, zName);
+ pTable = sqlite3HashFind(&db->pSchema->tblHash, zName);
if (pTable) {
if (!noErr) {
sqlite3ErrorMsg(pParse,
@@ -622,7 +552,6 @@ sqlite3StartTable(Parse *pParse, Token *pName, int noErr)
zName);
} else {
assert(!db->init.busy || CORRUPT_DB);
- sqlite3CodeVerifySchema(pParse);
}
goto begin_table_error;
}
@@ -654,7 +583,7 @@ sqlite3StartTable(Parse *pParse, Token *pName, int noErr)
* now.
*/
if (!db->init.busy && (v = sqlite3GetVdbe(pParse)) != 0)
- sqlite3BeginWriteOperation(pParse, 1);
+ sql_set_multi_write(pParse, 1);
/* Normal (non-error) return. */
return;
@@ -2039,7 +1968,6 @@ sqlite3CreateView(Parse * pParse, /* The parsing context */
p = pParse->pNewTable;
if (p == 0 || pParse->nErr)
goto create_view_fail;
- sqlite3SchemaToIndex(db, p->pSchema);
sqlite3FixInit(&sFix, pParse, "view", pName);
if (sqlite3FixSelect(&sFix, pSelect))
goto create_view_fail;
@@ -2206,26 +2134,22 @@ sqliteViewResetAll(sqlite3 * db)
#define sqliteViewResetAll(A,B)
#endif /* SQLITE_OMIT_VIEW */
-/*
- * Remove entries from the sqlite_statN tables (for N in (1,2,3))
- * after a DROP INDEX or DROP TABLE command.
+/**
+ * Remove entries from the _sql_stat1 and _sql_stat4
+ * system spaces after a DROP INDEX or DROP TABLE command.
+ *
+ * @param pParse Parsing context.
+ * @param zType Type of entry to be deleted:
+ * 'idx' or 'tbl' string literal.
+ * @param zName Name of index or table.
*/
static void
-sqlite3ClearStatTables(Parse * pParse, /* The parsing context */
- const char *zType, /* "idx" or "tbl" */
- const char *zName /* Name of index or table */
- )
+sql_clear_stat_spaces(Parse * pParse, const char *zType, const char *zName)
{
- int i;
- for (i = 1; i <= 4; i++) {
- char zTab[24];
- sqlite3_snprintf(sizeof(zTab), zTab, "_sql_stat%d", i);
- if (sqlite3FindTable(pParse->db, zTab)) {
- sqlite3NestedParse(pParse,
- "DELETE FROM \"%s\" WHERE \"%s\"=%Q",
- zTab, zType, zName);
- }
- }
+ sqlite3NestedParse(pParse, "DELETE FROM \"_sql_stat1\" WHERE \"%s\"=%Q",
+ zType, zName);
+ sqlite3NestedParse(pParse, "DELETE FROM \"_sql_stat4\" WHERE \"%s\"=%Q",
+ zType, zName);
}
/*
@@ -2240,7 +2164,6 @@ sqlite3CodeDropTable(Parse * pParse, Table * pTab, int isView)
v = sqlite3GetVdbe(pParse);
assert(v != 0);
- sqlite3BeginWriteOperation(pParse, 1);
/*
* Drop all triggers associated with the table being
* dropped. Code is generated to remove entries from
@@ -2376,15 +2299,12 @@ sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr)
if (noErr)
db->suppressErr++;
assert(isView == 0 || isView == LOCATE_VIEW);
- pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
+ pTab = sqlite3LocateTable(pParse, isView, pName->a[0].zName);
if (noErr)
db->suppressErr--;
- if (pTab == 0) {
- if (noErr)
- sqlite3CodeVerifySchema(pParse);
+ if (pTab == 0)
goto exit_drop_table;
- }
#ifndef SQLITE_OMIT_VIEW
/* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
* on a table.
@@ -2414,8 +2334,8 @@ sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr)
* space_id from _space.
*/
- sqlite3BeginWriteOperation(pParse, 1);
- sqlite3ClearStatTables(pParse, "tbl", pTab->zName);
+ sql_set_multi_write(pParse, 1);
+ sql_clear_stat_spaces(pParse, "tbl", pTab->zName);
sqlite3FkDropTable(pParse, pName, pTab);
sqlite3CodeDropTable(pParse, pTab, isView);
@@ -2881,7 +2801,7 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */
*/
assert(0);
}
- pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
+ pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName);
assert(db->mallocFailed == 0 || pTab == 0);
if (pTab == 0)
goto exit_create_index;
@@ -2921,21 +2841,20 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */
goto exit_create_index;
assert(pName->z != 0);
if (!db->init.busy) {
- if (sqlite3FindTable(db, zName) != 0) {
+ if (sqlite3HashFind(&db->pSchema->tblHash, zName) != 0) {
sqlite3ErrorMsg(pParse,
"there is already a table named %s",
zName);
goto exit_create_index;
}
}
- if (sqlite3FindIndex(db, zName, pTab) != 0) {
+ if (sqlite3HashFind(&pTab->idxHash, zName) != 0) {
if (!ifNotExist) {
sqlite3ErrorMsg(pParse,
"index %s.%s already exists",
pTab->zName, zName);
} else {
assert(!db->init.busy);
- sqlite3CodeVerifySchema(pParse);
}
goto exit_create_index;
}
@@ -3080,9 +2999,6 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */
if (pParse->pNewTable == 0)
estimateIndexWidth(pIndex);
- assert(pTab->iPKey < 0
- || sqlite3ColumnOfIndex(pIndex, pTab->iPKey) >= 0);
-
if (pTab == pParse->pNewTable) {
/* This routine has been called to create an automatic index as a
* result of a PRIMARY KEY or UNIQUE clause on a column definition, or
@@ -3191,7 +3107,7 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */
if (v == 0)
goto exit_create_index;
- sqlite3BeginWriteOperation(pParse, 1);
+ sql_set_multi_write(pParse, 1);
sqlite3VdbeAddOp2(v, OP_SIDtoPtr, BOX_INDEX_ID,
@@ -3387,8 +3303,6 @@ sqlite3DropIndex(Parse * pParse, SrcList * pName, Token * pName2, int ifExists)
if (!ifExists) {
sqlite3ErrorMsg(pParse, "no such index: %s.%S",
zTableName, pName, 0);
- } else {
- sqlite3CodeVerifySchema(pParse);
}
pParse->checkSchema = 1;
goto exit_drop_index;
@@ -3417,7 +3331,7 @@ sqlite3DropIndex(Parse * pParse, SrcList * pName, Token * pName2, int ifExists)
* But firstly, delete statistics since schema
* changes after DDL.
*/
- sqlite3ClearStatTables(pParse, "idx", pIndex->zName);
+ sql_clear_stat_spaces(pParse, "idx", pIndex->zName);
int record_reg = ++pParse->nMem;
int space_id_reg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_PAGENO_TO_SPACEID(pIndex->tnum),
@@ -3934,58 +3848,18 @@ sqlite3Savepoint(Parse * pParse, int op, Token * pName)
}
}
-/*
- * Record the fact that the schema cookie will need to be verified
- * for database. The code to actually verify the schema cookie
- * will occur at the end of the top-level VDBE and will be generated
- * later, by sqlite3FinishCoding().
- */
-void
-sqlite3CodeVerifySchema(Parse * pParse)
-{
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
-
- if (DbMaskTest(pToplevel->cookieMask, 0) == 0) {
- DbMaskSet(pToplevel->cookieMask, 0);
- }
-}
-
-/*
- * Generate VDBE code that prepares for doing an operation that
- * might change the database.
- *
- * This routine starts a new transaction if we are not already within
- * a transaction. If we are already within a transaction, then a checkpoint
- * is set if the setStatement parameter is true. A checkpoint should
- * be set for operations that might fail (due to a constraint) part of
- * the way through and which will need to undo some writes without having to
- * rollback the whole transaction. For operations where all constraints
- * can be checked before any changes are made to the database, it is never
- * necessary to undo a write and the checkpoint should not be set.
+/**
+ * Set flag in parse context, which indicates that during query
+ * execution multiple insertion/updates may occur.
*/
void
-sqlite3BeginWriteOperation(Parse * pParse, int setStatement)
+sql_set_multi_write(Parse *pParse, int setStatement)
{
Parse *pToplevel = sqlite3ParseToplevel(pParse);
- sqlite3CodeVerifySchema(pParse);
DbMaskSet(pToplevel->writeMask, 0);
pToplevel->isMultiWrite |= setStatement;
}
-/*
- * Indicate that the statement currently under construction might write
- * more than one entry (example: deleting one row then inserting another,
- * inserting multiple rows in a table, or inserting a row and index entries.)
- * If an abort occurs after some of these writes have completed, then it will
- * be necessary to undo the completed writes.
- */
-void
-sqlite3MultiWrite(Parse * pParse)
-{
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- pToplevel->isMultiWrite = 1;
-}
-
/*
* The code generator calls this routine if is discovers that it is
* possible to abort a statement prior to completion. In order to
@@ -4100,7 +3974,7 @@ reindexTable(Parse * pParse, Table * pTab, char const *zColl)
for (pIndex = pTab->pIndex; pIndex; pIndex = pIndex->pNext) {
if (zColl == 0 || collationMatch(zColl, pIndex)) {
- sqlite3BeginWriteOperation(pParse, 0);
+ sql_set_multi_write(pParse, 0);
sqlite3RefillIndex(pParse, pIndex, -1);
}
}
@@ -4175,7 +4049,7 @@ sqlite3Reindex(Parse * pParse, Token * pName1, Token * pName2)
z = sqlite3NameFromToken(db, pName1);
if (z == 0)
return;
- pTab = sqlite3FindTable(db, z);
+ pTab = sqlite3HashFind(&db->pSchema->tblHash, z);
if (pTab) {
reindexTable(pParse, pTab, 0);
sqlite3DbFree(db, z);
@@ -4185,16 +4059,15 @@ sqlite3Reindex(Parse * pParse, Token * pName1, Token * pName2)
zTable = sqlite3NameFromToken(db, pName2);
}
- pTab = sqlite3FindTable(db, zTable);
+ pTab = sqlite3HashFind(&db->pSchema->tblHash, zTable);
if (pTab == 0) {
sqlite3ErrorMsg(pParse, "no such table: %s", zTable);
goto exit_reindex;
}
- pIndex = sqlite3FindIndex(db, z, pTab);
-
+ pIndex = sqlite3HashFind(&pTab->idxHash, z);
if (pIndex) {
- sqlite3BeginWriteOperation(pParse, 0);
+ sql_set_multi_write(pParse, 0);
sqlite3RefillIndex(pParse, pIndex, -1);
return;
}
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index 7d1d71577..a07ef1980 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -56,7 +56,7 @@ sqlite3SrcListLookup(Parse * pParse, SrcList * pSrc)
struct SrcList_item *pItem = pSrc->a;
Table *pTab;
assert(pItem && pSrc->nSrc == 1);
- pTab = sqlite3LocateTableItem(pParse, 0, pItem);
+ pTab = sqlite3LocateTable(pParse, 0, pItem->zName);
sqlite3DeleteTable(pParse->db, pItem->pTab);
pItem->pTab = pTab;
if (pTab) {
@@ -113,7 +113,6 @@ sqlite3MaterializeView(Parse * pParse, /* Parsing context */
Select *pSel;
SrcList *pFrom;
sqlite3 *db = pParse->db;
- assert(sqlite3SchemaToIndex(db, pView->pSchema) == 0);
pWhere = sqlite3ExprDup(db, pWhere, 0);
pFrom = sqlite3SrcListAppend(db, 0, 0);
if (pFrom) {
@@ -325,7 +324,7 @@ sqlite3DeleteFrom(Parse * pParse, /* The parser context */
}
if (pParse->nested == 0)
sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, 1);
+ sql_set_multi_write(pParse, 1);
/* If we are trying to delete from a view, realize that view into
* an ephemeral table.
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index f4e3cf735..d981790e6 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -2455,9 +2455,6 @@ sqlite3FindInIndex(Parse * pParse, /* Parsing context */
assert(p->pEList->a[0].pExpr != 0); /* Because of isCandidateForInOpt(p) */
assert(p->pSrc != 0); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
-
- sqlite3CodeVerifySchema(pParse);
-
assert(v); /* sqlite3GetVdbe() has always been previously called */
Index *pIdx; /* Iterator variable */
@@ -3585,8 +3582,7 @@ sqlite3ExprCodeGetColumnOfTable(Vdbe * v, /* The VDBE under construction */
int regOut /* Extract the value into this register */
)
{
- int x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
- sqlite3VdbeAddOp3(v, OP_Column, iTabCur, x, regOut);
+ sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
if (iCol >= 0) {
sqlite3ColumnDefault(v, pTab, iCol, regOut);
}
@@ -5315,8 +5311,7 @@ exprIdxCover(Walker * pWalker, Expr * pExpr)
{
if (pExpr->op == TK_COLUMN
&& pExpr->iTable == pWalker->u.pIdxCover->iCur
- && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx,
- pExpr->iColumn) < 0) {
+ && pExpr->iColumn < 0) {
pWalker->eCode = 1;
return WRC_Abort;
}
diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c
index f4a6b2707..f56b6d9cd 100644
--- a/src/box/sql/fkey.c
+++ b/src/box/sql/fkey.c
@@ -961,7 +961,8 @@ sqlite3FkCheck(Parse * pParse, /* Parse context */
* early.
*/
if (pParse->disableTriggers) {
- pTo = sqlite3FindTable(db, pFKey->zTo);
+ pTo = sqlite3HashFind(&db->pSchema->tblHash,
+ pFKey->zTo);
} else {
pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo);
}
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 4a57b23f5..2719bbaf4 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -422,7 +422,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */
goto insert_cleanup;
if (pParse->nested == 0)
sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, pSelect || pTrigger);
+ sql_set_multi_write(pParse, pSelect || pTrigger);
#ifndef SQLITE_OMIT_XFER_OPT
/* If the statement is of the form
@@ -1398,8 +1398,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */
if (pIdx != pPk) {
for (i = 0; i < nPkCol; i++) {
assert(pPk->aiColumn[i] >= 0);
- x = sqlite3ColumnOfIndex(pIdx,
- pPk->aiColumn[i]);
+ x = pPk->aiColumn[i];
sqlite3VdbeAddOp3(v, OP_Column,
iThisCur, x, regR + i);
VdbeComment((v, "%s.%s", pTab->zName,
@@ -1462,7 +1461,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */
default: {
Trigger *pTrigger = 0;
assert(onError == ON_CONFLICT_ACTION_REPLACE);
- sqlite3MultiWrite(pParse);
+ sql_set_multi_write(pParse, 1);
if (user_session->
sql_flags & SQLITE_RecTriggers) {
pTrigger =
@@ -1833,7 +1832,7 @@ xferOptimization(Parse * pParse, /* Parser context */
* we have to check the semantics.
*/
pItem = pSelect->pSrc->a;
- pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
+ pSrc = sqlite3LocateTable(pParse, 0, pItem->zName);
if (pSrc == 0) {
return 0; /* FROM clause does not contain a real table */
}
@@ -1919,7 +1918,6 @@ xferOptimization(Parse * pParse, /* Parser context */
sqlite3_xferopt_count++;
#endif
v = sqlite3GetVdbe(pParse);
- sqlite3CodeVerifySchema(pParse);
iSrc = pParse->nTab++;
iDest = pParse->nTab++;
regData = sqlite3GetTempReg(pParse);
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index 23b4c73b5..04b4020dd 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -358,7 +358,6 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
Column *pCol;
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
pParse->nMem = 6;
- sqlite3CodeVerifySchema(pParse);
sqlite3ViewGetColumnNames(pParse, pTab);
for (i = 0, pCol = pTab->aCol; i < pTab->nCol;
i++, pCol++) {
@@ -397,7 +396,6 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
Index *pIdx;
HashElem *i;
pParse->nMem = 4;
- sqlite3CodeVerifySchema(pParse);
for (i = sqliteHashFirst(&db->pSchema->tblHash); i;
i = sqliteHashNext(i)) {
Table *pTab = sqliteHashData(i);
@@ -441,7 +439,6 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
pParse->nMem = 3;
}
mx = index_column_count(pIdx);
- sqlite3CodeVerifySchema(pParse);
assert(pParse->nMem <=
pPragma->nPragCName);
for (i = 0; i < mx; i++) {
@@ -481,10 +478,10 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
Index *pIdx;
Table *pTab;
int i;
- pTab = sqlite3FindTable(db, zRight);
+ pTab = sqlite3HashFind(&db->pSchema->tblHash,
+ zRight);
if (pTab) {
pParse->nMem = 5;
- sqlite3CodeVerifySchema(pParse);
for (pIdx = pTab->pIndex, i = 0; pIdx;
pIdx = pIdx->pNext, i++) {
const char *azOrigin[] =
@@ -541,13 +538,13 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
if (zRight) {
FKey *pFK;
Table *pTab;
- pTab = sqlite3FindTable(db, zRight);
+ pTab = sqlite3HashFind(&db->pSchema->tblHash,
+ zRight);
if (pTab) {
pFK = pTab->pFKey;
if (pFK) {
int i = 0;
pParse->nMem = 8;
- sqlite3CodeVerifySchema(pParse);
while (pFK) {
int j;
for (j = 0;
@@ -597,7 +594,6 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
pParse->nMem += 4;
regKey = ++pParse->nMem;
regRow = ++pParse->nMem;
- sqlite3CodeVerifySchema(pParse);
k = sqliteHashFirst(&db->pSchema->tblHash);
while (k) {
if (zRight) {
@@ -619,7 +615,8 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
for (i = 1, pFK = pTab->pFKey; pFK;
i++, pFK = pFK->pNextFrom) {
pParent =
- sqlite3FindTable(db, pFK->zTo);
+ sqlite3HashFind(&db->pSchema->tblHash,
+ pFK->zTo);
if (pParent == 0)
continue;
pIdx = 0;
@@ -657,7 +654,8 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
for (i = 1, pFK = pTab->pFKey; pFK;
i++, pFK = pFK->pNextFrom) {
pParent =
- sqlite3FindTable(db, pFK->zTo);
+ sqlite3HashFind(&db->pSchema->tblHash,
+ pFK->zTo);
pIdx = 0;
aiCols = 0;
if (pParent) {
diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c
index 0ea181d44..7a16074dc 100644
--- a/src/box/sql/prepare.c
+++ b/src/box/sql/prepare.c
@@ -204,35 +204,6 @@ sqlite3InitDatabase(sqlite3 * db)
return rc;
}
-/*
- * Convert a schema pointer into the 0 index that indicates
- * that schema refers to a single database.
- * This method is inherited from SQLite, which has several dbs.
- * But we have only one, so it is used only in assertions.
- */
-int
-sqlite3SchemaToIndex(sqlite3 * db, Schema * pSchema)
-{
- int i = -1000000;
-
- /* If pSchema is NULL, then return -1000000. This happens when code in
- * expr.c is trying to resolve a reference to a transient table (i.e. one
- * created by a sub-select). In this case the return value of this
- * function should never be used.
- *
- * We return -1000000 instead of the more usual -1 simply because using
- * -1000000 as the incorrect index into db->aDb[] is much
- * more likely to cause a segfault than -1 (of course there are assert()
- * statements too, but it never hurts to play the odds).
- */
- if (pSchema) {
- if (db->pSchema == pSchema) {
- i = 0;
- }
- assert(i == 0);
- }
- return i;
-}
/*
* Free all memory allocations in the pParse object
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index c7f87f340..6ff8dc25e 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -4745,7 +4745,7 @@ selectExpander(Walker * pWalker, Select * p)
/* An ordinary table or view name in the FROM clause */
assert(pFrom->pTab == 0);
pFrom->pTab = pTab =
- sqlite3LocateTableItem(pParse, 0, pFrom);
+ sqlite3LocateTable(pParse, 0, pFrom->zName);
if (pTab == 0)
return WRC_Abort;
if (pTab->nTabRef >= 0xffff) {
@@ -6155,8 +6155,6 @@ sqlite3Select(Parse * pParse, /* The parser context */
Index *pBest; /* Best index found so far */
int iRoot = pTab->tnum; /* Root page of scanned b-tree */
- sqlite3CodeVerifySchema(pParse);
-
/* Search for the index that has the lowest scan cost.
*
* (2011-04-15) Do not do a full scan of an unordered index.
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index f43711a7f..fcafb65b4 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -2947,7 +2947,6 @@ struct Parse {
ExprList *pConstExpr; /* Constant expressions */
Token constraintName; /* Name of the constraint currently being parsed */
yDbMask writeMask; /* Start a write transaction on these databases */
- yDbMask cookieMask; /* Bitmask of schema verified databases */
int regRoot; /* Register holding root page number for new objects */
int nMaxArg; /* Max args passed to user function by sub-program */
#ifdef SELECTTRACE_ENABLED
@@ -3550,7 +3549,6 @@ int sqlite3ColumnsFromExprList(Parse *, ExprList *, i16 *, Column **);
void sqlite3SelectAddColumnTypeAndCollation(Parse *, Table *, Select *);
Table *sqlite3ResultSetOfSelect(Parse *, Select *);
Index *sqlite3PrimaryKeyIndex(Table *);
-i16 sqlite3ColumnOfIndex(Index *, i16);
void sqlite3StartTable(Parse *, Token *, int);
void sqlite3AddColumn(Parse *, Token *, Token *);
void sqlite3AddNotNull(Parse *, int);
@@ -3669,12 +3667,9 @@ int sqlite3ExprCodeExprList(Parse *, ExprList *, int, int, u8);
void sqlite3ExprIfTrue(Parse *, Expr *, int, int);
void sqlite3ExprIfFalse(Parse *, Expr *, int, int);
void sqlite3ExprIfFalseDup(Parse *, Expr *, int, int);
-Table *sqlite3FindTable(sqlite3 *, const char *);
#define LOCATE_VIEW 0x01
#define LOCATE_NOERR 0x02
Table *sqlite3LocateTable(Parse *, u32 flags, const char *);
-Table *sqlite3LocateTableItem(Parse *, u32 flags, struct SrcList_item *);
-Index *sqlite3FindIndex(sqlite3 *, const char *, Table *);
Index *sqlite3LocateIndex(sqlite3 *, const char *, const char *);
void sqlite3UnlinkAndDeleteTable(sqlite3 *, const char *);
void sqlite3UnlinkAndDeleteIndex(sqlite3 *, Index *);
@@ -3692,7 +3687,6 @@ void sqlite3PrngSaveState(void);
void sqlite3PrngRestoreState(void);
#endif
void sqlite3RollbackAll(Vdbe *, int);
-void sqlite3CodeVerifySchema(Parse *);
void sqlite3BeginTransaction(Parse *, int);
void sqlite3CommitTransaction(Parse *);
void sqlite3RollbackTransaction(Parse *);
@@ -3718,7 +3712,7 @@ void sqlite3GenerateConstraintChecks(Parse *, Table *, int *, int, int, int,
void sqlite3CompleteInsertion(Parse *, Table *, int, int *, int, u8);
int sqlite3OpenTableAndIndices(Parse *, Table *, int, u8, int, u8 *, int *,
int *, u8, u8);
-void sqlite3BeginWriteOperation(Parse *, int);
+void sql_set_multi_write(Parse *, int);
void sqlite3MultiWrite(Parse *);
void sqlite3MayAbort(Parse *);
void sqlite3HaltConstraint(Parse *, int, int, char *, i8, u8);
@@ -3912,8 +3906,6 @@ struct coll *sqlite3GetCollSeq(Parse *, struct coll *, const char *);
char sqlite3AffinityType(const char *, u8 *);
void sqlite3Analyze(Parse *, Token *);
int sqlite3InvokeBusyHandler(BusyHandler *);
-int sqlite3FindDb(sqlite3 *, Token *);
-int sqlite3FindDbName(const char *);
int sqlite3AnalysisLoad(sqlite3 *);
void sqlite3DeleteIndexSamples(sqlite3 *, Index *);
void sqlite3DefaultRowEst(Index *);
@@ -3925,7 +3917,6 @@ void sqlite3RegisterLikeFunctions(sqlite3 *, int);
int sqlite3IsLikeFunction(sqlite3 *, Expr *, int *, char *);
void sqlite3SchemaClear(sqlite3 *);
Schema *sqlite3SchemaCreate(sqlite3 *);
-int sqlite3SchemaToIndex(sqlite3 * db, Schema *);
KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *, int, int);
void sqlite3KeyInfoUnref(KeyInfo *);
KeyInfo *sqlite3KeyInfoRef(KeyInfo *);
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index 859b421db..decbc8c21 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -129,7 +129,6 @@ sqlite3BeginTrigger(Parse * pParse, /* The parse context of the CREATE TRIGGER s
zName);
} else {
assert(!db->init.busy);
- sqlite3CodeVerifySchema(pParse);
}
goto trigger_cleanup;
}
@@ -215,7 +214,6 @@ sqlite3FinishTrigger(Parse * pParse, /* Parser context */
if (NEVER(pParse->nErr) || !pTrig)
goto triggerfinish_cleanup;
zName = pTrig->zName;
- assert(sqlite3SchemaToIndex(pParse->db, pTrig->pSchema) == 0);
pTrig->step_list = pStepList;
while (pStepList) {
pStepList->pTrig = pTrig;
@@ -295,7 +293,7 @@ sqlite3FinishTrigger(Parse * pParse, /* Parser context */
iFirstCol = pParse->nMem + 1;
pParse->nMem += 2;
- sqlite3BeginWriteOperation(pParse, 0);
+ sql_set_multi_write(pParse, 0);
sqlite3VdbeAddOp4(v,
OP_String8, 0, iFirstCol, 0,
zName, P4_STATIC);
@@ -528,8 +526,6 @@ sqlite3DropTrigger(Parse * pParse, SrcList * pName, int noErr)
if (!noErr) {
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName,
0);
- } else {
- sqlite3CodeVerifySchema(pParse);
}
pParse->checkSchema = 1;
goto drop_trigger_cleanup;
@@ -674,7 +670,6 @@ targetSrcList(Parse * pParse, /* The parsing context */
assert(pSrc->nSrc > 0);
pSrc->a[pSrc->nSrc - 1].zName =
sqlite3DbStrDup(db, pStep->zTarget);
- assert(sqlite3SchemaToIndex(db, pStep->pTrig->pSchema) == 0);
}
return pSrc;
}
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 7727ae5d5..ad6aad5e6 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -288,7 +288,7 @@ sqlite3Update(Parse * pParse, /* The parser context */
goto update_cleanup;
if (pParse->nested == 0)
sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, 1);
+ sql_set_multi_write(pParse, 1);
/* Allocate required registers. */
regOldPk = regNewPk = ++pParse->nMem;
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 329d46886..6de1b917a 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1419,7 +1419,6 @@ case OP_ResultRow: {
*/
if (SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0))) {
assert(user_session->sql_flags&SQLITE_CountRows);
- assert(p->usesStmtJournal);
goto abort_due_to_error;
}
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index fcb45c8a8..f23879b1c 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -428,7 +428,6 @@ struct Vdbe {
bft explain:2; /* True if EXPLAIN present on SQL command */
bft changeCntOn:1; /* True to update the change-counter */
bft runOnlyOnce:1; /* Automatically expire on reset */
- bft usesStmtJournal:1; /* True if uses a statement journal */
bft isPrepareV2:1; /* True if prepared with prepare_v2() */
u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
char *zSql; /* Text of the SQL statement that generated this */
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index e4335524a..bb121a318 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -2148,7 +2148,6 @@ sqlite3VdbeMakeReady(Vdbe * p, /* The VDBE */
assert(EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]));
resolveP2Values(p, &nArg);
- p->usesStmtJournal = (u8) (pParse->isMultiWrite && pParse->mayAbort);
if (pParse->explain && nMem < 10) {
nMem = 10;
}
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index 79de5d69a..d34faef9e 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -4616,7 +4616,6 @@ sqlite3WhereBegin(Parse * pParse, /* The parser context */
#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
}
}
- sqlite3CodeVerifySchema(pParse);
}
pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
if (db->mallocFailed)
@@ -4814,7 +4813,6 @@ sqlite3WhereEnd(WhereInfo * pWInfo)
if (pOp->opcode == OP_Column) {
int x = pOp->p2;
assert(pIdx->pTable == pTab);
- x = sqlite3ColumnOfIndex(pIdx, x);
if (x >= 0) {
pOp->p2 = x;
pOp->p1 = pLevel->iIdxCur;
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 8b06baeff..53cd30f14 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -847,7 +847,7 @@ codeCursorHintCheckExpr(Walker * pWalker, Expr * pExpr)
assert(pHint->pIdx != 0);
if (pExpr->op == TK_COLUMN
&& pExpr->iTable == pHint->iTabCur
- && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn) < 0) {
+ && (pExpr->iColumn < 0)) {
pWalker->eCode = 1;
}
return WRC_Continue;
@@ -921,8 +921,6 @@ codeCursorHintFixExpr(Walker * pWalker, Expr * pExpr)
pExpr->iTable = reg;
} else if (pHint->pIdx != 0) {
pExpr->iTable = pHint->iIdxCur;
- pExpr->iColumn =
- sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn);
assert(pExpr->iColumn >= 0);
}
} else if (pExpr->op == TK_AGG_FUNCTION) {
@@ -1517,8 +1515,7 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t
int nPkCol = index_column_count(pPk);
int iKeyReg = sqlite3GetTempRange(pParse, nPkCol);
for (j = 0; j < nPkCol; j++) {
- k = sqlite3ColumnOfIndex(pIdx,
- pPk->aiColumn[j]);
+ k = pPk->aiColumn[j];
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k,
iKeyReg + j);
}
--
2.15.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [tarantool-patches] [PATCH 2/2] sql: rework 'DROP INDEX' and 'DROP TABLE' handling
2018-04-03 16:14 [tarantool-patches] [PATCH 0/2] rework SQL 'DROP' routine Nikita Pettik
2018-04-03 16:14 ` [tarantool-patches] [PATCH 1/2] sql: remove obsolete SQLite routine Nikita Pettik
@ 2018-04-03 16:14 ` Nikita Pettik
2018-04-03 18:27 ` [tarantool-patches] " Vladislav Shpilevoy
2018-04-05 14:12 ` [tarantool-patches] Re: [PATCH 0/2] rework SQL 'DROP' routine Kirill Yukhin
2 siblings, 1 reply; 12+ messages in thread
From: Nikita Pettik @ 2018-04-03 16:14 UTC (permalink / raw)
To: tarantool-patches; +Cc: v.shpilevoy, Nikita Pettik
As a part of SQL data dictionary integration, 'DROP INDEX' and
'DROP TABLE' statements proccessing has been refactored in order
to avoid using SQL specific internal structures.
However, triggers still aren't transfered to server, so to drop them
it is required to lookup SQL table and emit apporpriate opcodes.
Also, added comments and fixed codestyle for functions processing
'DROP' routine.
Part of #3222.
---
src/box/sql/build.c | 241 ++++++++++++++++++++++++++----------------------
src/box/sql/parse.c | 6 +-
src/box/sql/parse.y | 6 +-
src/box/sql/sqliteInt.h | 6 +-
4 files changed, 140 insertions(+), 119 deletions(-)
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 61194e06b..219cc974b 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -46,6 +46,7 @@
#include "sqliteInt.h"
#include "vdbeInt.h"
#include "tarantoolInt.h"
+#include "box/box.h"
#include "box/sequence.h"
#include "box/session.h"
#include "box/identifier.h"
@@ -2152,48 +2153,50 @@ sql_clear_stat_spaces(Parse * pParse, const char *zType, const char *zName)
zType, zName);
}
-/*
+/**
* Generate code to drop a table.
+ * This routine includes dropping triggers, sequences,
+ * all indexes and entry from _space space.
+ *
+ * @param parse_context Current parsing context.
+ * @param space Space to be dropped.
+ * @param is_view True, if space is
*/
static void
-sqlite3CodeDropTable(Parse * pParse, Table * pTab, int isView)
+sql_code_drop_table(struct Parse *parse_context, struct space *space,
+ bool is_view)
{
- Vdbe *v;
- sqlite3 *db = pParse->db;
- Trigger *pTrigger;
-
- v = sqlite3GetVdbe(pParse);
+ struct sqlite3 *db = parse_context->db;
+ struct Vdbe *v = sqlite3GetVdbe(parse_context);
assert(v != 0);
/*
* Drop all triggers associated with the table being
* dropped. Code is generated to remove entries from
* _trigger. OP_DropTrigger will remove it from internal
* SQL structures.
- */
- pTrigger = pTab->pTrigger;
- /* Do not account triggers deletion - they will be accounted
+ *
+ * Do not account triggers deletion - they will be accounted
* in DELETE from _space below.
*/
- pParse->nested++;
-
- while (pTrigger) {
- assert(pTrigger->pSchema == pTab->pSchema);
- sqlite3DropTriggerPtr(pParse, pTrigger);
- pTrigger = pTrigger->pNext;
- }
- pParse->nested--;
+ parse_context->nested++;
+ Table *table = sqlite3HashFind(&parse_context->db->pSchema->tblHash,
+ space->def->name);
+ struct Trigger *trigger = table->pTrigger;
+ while (trigger != NULL) {
+ sqlite3DropTriggerPtr(parse_context, trigger);
+ trigger = trigger->pNext;
+ }
+ parse_context->nested--;
/*
* Remove any entries of the _sequence and _space_sequence
* space associated with the table being dropped. This is
* done before the table is dropped from internal schema.
*/
- int idx_rec_reg = ++pParse->nMem;
- int space_id_reg = ++pParse->nMem;
- int space_id = SQLITE_PAGENO_TO_SPACEID(pTab->tnum);
- struct space *space = space_by_id(space_id);
- assert(space != NULL);
+ int idx_rec_reg = ++parse_context->nMem;
+ int space_id_reg = ++parse_context->nMem;
+ int space_id = space->def->id;
sqlite3VdbeAddOp2(v, OP_Integer, space_id, space_id_reg);
- if (pTab->tabFlags & TF_Autoincrement) {
+ if (space->sequence != NULL) {
/* Delete entry from _space_sequence. */
sqlite3VdbeAddOp3(v, OP_MakeRecord, space_id_reg, 1,
idx_rec_reg);
@@ -2201,8 +2204,7 @@ sqlite3CodeDropTable(Parse * pParse, Table * pTab, int isView)
idx_rec_reg);
VdbeComment((v, "Delete entry from _space_sequence"));
/* Delete entry by id from _sequence. */
- assert(space->sequence != NULL);
- int sequence_id_reg = ++pParse->nMem;
+ int sequence_id_reg = ++parse_context->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, space->sequence->def->id,
sequence_id_reg);
sqlite3VdbeAddOp3(v, OP_MakeRecord, sequence_id_reg, 1,
@@ -2214,7 +2216,7 @@ sqlite3CodeDropTable(Parse * pParse, Table * pTab, int isView)
* Drop all _space and _index entries that refer to the
* table.
*/
- if (!isView) {
+ if (!is_view) {
uint32_t index_count = space->index_count;
if (index_count > 1) {
/*
@@ -2257,71 +2259,78 @@ sqlite3CodeDropTable(Parse * pParse, Table * pTab, int isView)
sqlite3VdbeAddOp2(v, OP_SDelete, BOX_SPACE_ID, idx_rec_reg);
sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);
VdbeComment((v, "Delete entry from _space"));
- /* Remove the table entry from SQLite's internal schema and modify
- * the schema cookie.
+ /*
+ * Remove the table entry from SQLite's internal schema
+ * and modify the schema cookie.
*/
+ sqlite3VdbeAddOp4(v, OP_DropTable, 0, 0, 0, space->def->name, 0);
- sqlite3VdbeAddOp4(v, OP_DropTable, 0, 0, 0, pTab->zName, 0);
-
- /* FIXME: DDL is impossible inside a transaction so far.
+ /*
* Replace to _space/_index will fail if active
* transaction. So, don't pretend, that we are able to
* anything back. To be fixed when transactions
* DDL are enabled.
*/
- /* sqlite3ChangeCookie(pParse); */
sqliteViewResetAll(db);
}
-/*
+/**
* This routine is called to do the work of a DROP TABLE statement.
- * pName is the name of the table to be dropped.
+ *
+ * @param parse_context Current parsing context.
+ * @param table_name_list List containing table name.
+ * @param is_view True, if statement is really 'DROP VIEW'.
+ * @param if_exists True, if statement contains 'IF EXISTS' clause.
*/
void
-sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr)
+sql_drop_table(struct Parse *parse_context, struct SrcList *table_name_list,
+ bool is_view, bool if_exists)
{
- Table *pTab;
- Vdbe *v = sqlite3GetVdbe(pParse);
- sqlite3 *db = pParse->db;
-
+ struct Vdbe *v = sqlite3GetVdbe(parse_context);
+ struct sqlite3 *db = parse_context->db;
if (v == NULL || db->mallocFailed) {
goto exit_drop_table;
}
- /* Activate changes counting here to account
+ /*
+ * Activate changes counting here to account
* DROP TABLE IF NOT EXISTS, if the table really does not
* exist.
*/
- if (!pParse->nested)
+ if (!parse_context->nested)
sqlite3VdbeCountChanges(v);
- assert(pParse->nErr == 0);
- assert(pName->nSrc == 1);
- assert(db->pSchema != NULL);
- if (noErr)
- db->suppressErr++;
- assert(isView == 0 || isView == LOCATE_VIEW);
- pTab = sqlite3LocateTable(pParse, isView, pName->a[0].zName);
- if (noErr)
- db->suppressErr--;
-
- if (pTab == 0)
+ assert(parse_context->nErr == 0);
+ assert(table_name_list->nSrc == 1);
+ assert(is_view == 0 || is_view == LOCATE_VIEW);
+ const char *space_name = table_name_list->a[0].zName;
+ uint32_t space_id = box_space_id_by_name(space_name,
+ strlen(space_name));
+ if (space_id == BOX_ID_NIL) {
+ if (!is_view && !if_exists)
+ sqlite3ErrorMsg(parse_context, "no such table: %s",
+ space_name);
+ if (is_view && !if_exists)
+ sqlite3ErrorMsg(parse_context, "no such view: %s",
+ space_name);
goto exit_drop_table;
-#ifndef SQLITE_OMIT_VIEW
- /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
- * on a table.
+ }
+ struct space *space = space_by_id(space_id);
+ assert(space != NULL);
+ /*
+ * Ensure DROP TABLE is not used on a view,
+ * and DROP VIEW is not used on a table.
*/
- if (isView && !space_is_view(pTab)) {
- sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s",
- pTab->zName);
+ if (is_view && !space->def->opts.is_view) {
+ sqlite3ErrorMsg(parse_context, "use DROP TABLE to delete table %s",
+ space_name);
goto exit_drop_table;
}
- if (!isView && space_is_view(pTab)) {
- sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s",
- pTab->zName);
+ if (!is_view && space->def->opts.is_view) {
+ sqlite3ErrorMsg(parse_context, "use DROP VIEW to delete view %s",
+ space_name);
goto exit_drop_table;
}
-#endif
-
- /* Generate code to remove the table from Tarantool and internal SQL
+ /*
+ * Generate code to remove the table from Tarantool and internal SQL
* tables. Basically, it consists from 3 stages:
* 1. Delete statistics from _stat1 and _stat4 tables (if any exist)
* 2. In case of presence of FK constraints, i.e. current table is child
@@ -2334,13 +2343,14 @@ sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr)
* space_id from _space.
*/
- sql_set_multi_write(pParse, 1);
- sql_clear_stat_spaces(pParse, "tbl", pTab->zName);
- sqlite3FkDropTable(pParse, pName, pTab);
- sqlite3CodeDropTable(pParse, pTab, isView);
+ sql_set_multi_write(parse_context, 1);
+ sql_clear_stat_spaces(parse_context, "tbl", space_name);
+ struct Table *tab = sqlite3HashFind(&db->pSchema->tblHash, space_name);
+ sqlite3FkDropTable(parse_context, table_name_list, tab);
+ sql_code_drop_table(parse_context, space, is_view);
exit_drop_table:
- sqlite3SrcListDelete(db, pName);
+ sqlite3SrcListDelete(db, table_name_list);
}
/*
@@ -3267,60 +3277,66 @@ index_is_unique_not_null(const Index *idx)
!index->def->key_def->is_nullable);
}
-/*
+/**
* This routine will drop an existing named index. This routine
* implements the DROP INDEX statement.
+ *
+ * @param parse_context Current parsing context.
+ * @param index_name_list List containing index name.
+ * @param table_token Token representing table name.
+ * @param if_exists True, if statement contains 'IF EXISTS' clause.
*/
void
-sqlite3DropIndex(Parse * pParse, SrcList * pName, Token * pName2, int ifExists)
+sql_drop_index(struct Parse *parse_context, struct SrcList *index_name_list,
+ struct Token *table_token, bool if_exists)
{
- Index *pIndex;
- Vdbe *v = sqlite3GetVdbe(pParse);
- sqlite3 *db = pParse->db;
- char *zTableName = 0;
-
- assert(pParse->nErr == 0); /* Never called with prior errors */
- assert(pName2 != 0);
-
+ struct Vdbe *v = sqlite3GetVdbe(parse_context);
+ assert(v != NULL);
+ struct sqlite3 *db = parse_context->db;
+ /* Never called with prior errors. */
+ assert(parse_context->nErr == 0);
+ assert(table_token != NULL);
+ const char *table_name = sqlite3NameFromToken(db, table_token);
if (db->mallocFailed) {
goto exit_drop_index;
}
- assert(v != NULL);
- /* Do not account nested operations: the count of such
+ /*
+ * Do not account nested operations: the count of such
* operations depends on Tarantool data dictionary internals,
* such as data layout in system spaces.
*/
- if (!pParse->nested)
+ if (!parse_context->nested)
sqlite3VdbeCountChanges(v);
- assert(pName->nSrc == 1);
- assert(db->pSchema != NULL);
-
- assert(pName2->n > 0);
- zTableName = sqlite3NameFromToken(db, pName2);
-
- pIndex = sqlite3LocateIndex(db, pName->a[0].zName, zTableName);
- if (pIndex == 0) {
- if (!ifExists) {
- sqlite3ErrorMsg(pParse, "no such index: %s.%S",
- zTableName, pName, 0);
- }
- pParse->checkSchema = 1;
+ assert(index_name_list->nSrc == 1);
+ assert(table_token->n > 0);
+ uint32_t space_id = box_space_id_by_name(table_name,
+ strlen(table_name));
+ if (space_id == BOX_ID_NIL) {
+ if (!if_exists)
+ sqlite3ErrorMsg(parse_context, "no such space: %s",
+ table_name);
+ goto exit_drop_index;
+ }
+ const char *index_name = index_name_list->a[0].zName;
+ uint32_t index_id = box_index_id_by_name(space_id, index_name,
+ strlen(index_name));
+ if (index_id == BOX_ID_NIL) {
+ if (!if_exists)
+ sqlite3ErrorMsg(parse_context, "no such index: %s.%s",
+ table_name, index_name);
goto exit_drop_index;
}
- uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(pIndex->tnum);
- uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(pIndex->tnum);
struct space *space = space_by_id(space_id);
assert(space != NULL);
struct index *index = space_index(space, index_id);
assert(index != NULL);
-
/*
* If index has been created by user, it has its SQL
* statement. Otherwise (i.e. PK and UNIQUE indexes,
* which are created alongside with table) it is NULL.
*/
if (index->def->opts.sql == NULL) {
- sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
+ sqlite3ErrorMsg(parse_context, "index associated with UNIQUE "
"or PRIMARY KEY constraint cannot be dropped",
0);
goto exit_drop_index;
@@ -3331,24 +3347,27 @@ sqlite3DropIndex(Parse * pParse, SrcList * pName, Token * pName2, int ifExists)
* But firstly, delete statistics since schema
* changes after DDL.
*/
- sql_clear_stat_spaces(pParse, "idx", pIndex->zName);
- int record_reg = ++pParse->nMem;
- int space_id_reg = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_PAGENO_TO_SPACEID(pIndex->tnum),
- space_id_reg);
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_PAGENO_TO_INDEXID(pIndex->tnum),
- space_id_reg + 1);
+ sql_clear_stat_spaces(parse_context, "idx", index->def->name);
+ int record_reg = ++parse_context->nMem;
+ int space_id_reg = ++parse_context->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, space_id, space_id_reg);
+ sqlite3VdbeAddOp2(v, OP_Integer, index_id, space_id_reg + 1);
sqlite3VdbeAddOp3(v, OP_MakeRecord, space_id_reg, 2, record_reg);
sqlite3VdbeAddOp2(v, OP_SDelete, BOX_INDEX_ID, record_reg);
sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);
- sqlite3ChangeCookie(pParse);
-
+ /*
+ * Still need to cleanup internal SQL structures.
+ * Should be removed when SQL and Tarantool
+ * data-dictionaries will be completely merged.
+ */
+ Index *pIndex = sqlite3LocateIndex(db, index_name, table_name);
+ assert(pIndex != NULL);
sqlite3VdbeAddOp3(v, OP_DropIndex, 0, 0, 0);
sqlite3VdbeAppendP4(v, pIndex, P4_INDEX);
exit_drop_index:
- sqlite3SrcListDelete(db, pName);
- sqlite3DbFree(db, zTableName);
+ sqlite3SrcListDelete(db, index_name_list);
+ sqlite3DbFree(db, (void *) table_name);
}
/*
diff --git a/src/box/sql/parse.c b/src/box/sql/parse.c
index 9f547d25e..bf34b2cab 100644
--- a/src/box/sql/parse.c
+++ b/src/box/sql/parse.c
@@ -2530,7 +2530,7 @@ static void yy_reduce(
case 70: /* cmd ::= DROP TABLE ifexists fullname */
#line 361 "parse.y"
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy387, 0, yymsp[-1].minor.yy52);
+ sql_drop_table(pParse, yymsp[0].minor.yy387, 0, yymsp[-1].minor.yy52);
}
#line 2536 "parse.c"
break;
@@ -2544,7 +2544,7 @@ static void yy_reduce(
case 74: /* cmd ::= DROP VIEW ifexists fullname */
#line 375 "parse.y"
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy387, 1, yymsp[-1].minor.yy52);
+ sql_drop_table(pParse, yymsp[0].minor.yy387, 1, yymsp[-1].minor.yy52);
}
#line 2550 "parse.c"
break;
@@ -3445,7 +3445,7 @@ static void yy_reduce(
case 210: /* cmd ::= DROP INDEX ifexists fullname ON nm */
#line 1310 "parse.y"
{
- sqlite3DropIndex(pParse, yymsp[-2].minor.yy387, &yymsp[0].minor.yy0, yymsp[-3].minor.yy52);
+ sql_drop_index(pParse, yymsp[-2].minor.yy387, &yymsp[0].minor.yy0, yymsp[-3].minor.yy52);
}
#line 3451 "parse.c"
break;
diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index 9ee7daccf..6440c2ea0 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -359,7 +359,7 @@ resolvetype(A) ::= REPLACE. {A = ON_CONFLICT_ACTION_REPLACE;}
////////////////////////// The DROP TABLE /////////////////////////////////////
//
cmd ::= DROP TABLE ifexists(E) fullname(X). {
- sqlite3DropTable(pParse, X, 0, E);
+ sql_drop_table(pParse, X, 0, E);
}
%type ifexists {int}
ifexists(A) ::= IF EXISTS. {A = 1;}
@@ -373,7 +373,7 @@ cmd ::= createkw(X) VIEW ifnotexists(E) nm(Y) eidlist_opt(C)
sqlite3CreateView(pParse, &X, &Y, C, S, E);
}
cmd ::= DROP VIEW ifexists(E) fullname(X). {
- sqlite3DropTable(pParse, X, 1, E);
+ sql_drop_table(pParse, X, 1, E);
}
%endif SQLITE_OMIT_VIEW
@@ -1308,7 +1308,7 @@ collate(C) ::= COLLATE id. {C = 1;}
///////////////////////////// The DROP INDEX command /////////////////////////
//
cmd ::= DROP INDEX ifexists(E) fullname(X) ON nm(Y). {
- sqlite3DropIndex(pParse, X, &Y, E);
+ sql_drop_index(pParse, X, &Y, E);
}
///////////////////////////// The PRAGMA command /////////////////////////////
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index fcafb65b4..5e19b565a 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -3588,7 +3588,8 @@ int sqlite3ViewGetColumnNames(Parse *, Table *);
#if SQLITE_MAX_ATTACHED>30
int sqlite3DbMaskAllZero(yDbMask);
#endif
-void sqlite3DropTable(Parse *, SrcList *, int, int);
+void
+sql_drop_table(struct Parse *, struct SrcList *, bool, bool);
void sqlite3DeleteTable(sqlite3 *, Table *);
void sqlite3Insert(Parse *, SrcList *, Select *, IdList *, int);
void *sqlite3ArrayAllocate(sqlite3 *, void *, int, int *, int *);
@@ -3612,7 +3613,8 @@ bool
index_is_unique(Index *);
void sqlite3CreateIndex(Parse *, Token *, SrcList *, ExprList *, int, Token *,
Expr *, int, int, u8);
-void sqlite3DropIndex(Parse *, SrcList *, Token *, int);
+void
+sql_drop_index(struct Parse *, struct SrcList *, struct Token *, bool);
int sqlite3Select(Parse *, Select *, SelectDest *);
Select *sqlite3SelectNew(Parse *, ExprList *, SrcList *, Expr *, ExprList *,
Expr *, ExprList *, u32, Expr *, Expr *);
--
2.15.1
^ permalink raw reply [flat|nested] 12+ messages in thread