diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c index 054c0856c583e97e715528811ed1b0a8d7afc6fc..129ef823c65073fcffeb4355ce2f65b18678a9c8 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]); - if (!pTab) + pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName); + if (pTab == NULL) 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,8 +256,8 @@ sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc) assert(pParse->pNewTable == 0); if (db->mallocFailed) goto exit_begin_add_column; - pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); - if (!pTab) + pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName); + if (pTab == NULL) goto exit_begin_add_column; /* Make sure this is not an attempt to ALTER a view. */ @@ -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, false); 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 4eae896abfc4fd02f083bc526f18dfdaffe4c3ed..665bfbcb59a913559c655ea480511e921660e8fa 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -156,7 +156,8 @@ 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); + assert(pStat != NULL); aRoot[i] = pStat->tnum; aCreateTbl[i] = 0; if (zWhere) { @@ -831,7 +832,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 +907,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 +1027,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)); @@ -1121,7 +1120,7 @@ analyzeDatabase(Parse * pParse) int iMem; int iTab; - sqlite3BeginWriteOperation(pParse, 0); + sql_set_multi_write(pParse, false); iStatCur = pParse->nTab; pParse->nTab += 3; openStatTable(pParse, iStatCur, 0, 0); @@ -1145,8 +1144,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, false); iStatCur = pParse->nTab; pParse->nTab += 3; if (pOnlyIdx) { @@ -1293,16 +1291,15 @@ 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]); - if (pTable == 0) { + pTable = sqlite3HashFind(&pInfo->db->pSchema->tblHash, argv[0]); + if (pTable == NULL) return 0; - } if (argv[1] == 0) { pIndex = 0; } 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]; @@ -1631,19 +1628,17 @@ loadStatTbl(sqlite3 * db, /* Database handle */ static int loadStat4(sqlite3 * db) { - int rc = SQLITE_OK; /* Result codes from subroutines */ Table *pTab = 0; /* Pointer to stat table */ assert(db->lookaside.bDisable); - pTab = sqlite3FindTable(db, "_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; + pTab = sqlite3HashFind(&db->pSchema->tblHash, "_sql_stat4"); + /* _slq_stat4 is a system space, so it always exists. */ + assert(pTab != NULL); + return loadStatTbl(db, pTab, + "SELECT \"tbl\",\"idx\",count(*) FROM \"_sql_stat4\"" + " GROUP BY \"tbl\",\"idx\"", + "SELECT \"tbl\",\"idx\",\"neq\",\"nlt\",\"ndlt\"," + "\"sample\" FROM \"_sql_stat4\""); } /* @@ -1687,10 +1682,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 15b1d15d8647d6b9e383b7256a553e2681f18591..252474197852f6974e5837dd13fcf19f075e939b 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -86,26 +86,14 @@ sqlite3FinishCoding(Parse * pParse) || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if (v) { sqlite3VdbeAddOp0(v, OP_Halt); - - /* The cookie mask contains one bit for each database file open. - * (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are - * set for each database that is used. Generate code to start a - * 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); - } + if (pParse->initiateTTrans) + sqlite3VdbeAddOp0(v, OP_TTransaction); + if (db->init.busy == 0) + sqlite3VdbeChangeP5(v, 1); /* Code constant expressions that where factored out of inner loops */ if (pParse->pConstExpr) { @@ -179,32 +167,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 */ @@ -216,8 +182,8 @@ sqlite3LocateTable(Parse * pParse, /* context in which to report errors */ assert(pParse->db->pSchema != NULL); - p = sqlite3FindTable(pParse->db, zName); - if (p == 0) { + p = sqlite3HashFind(&pParse->db->pSchema->tblHash, zName); + if (p == NULL) { const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; if ((flags & LOCATE_NOERR) == 0) { @@ -229,48 +195,18 @@ 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; - } + if (pTab == NULL) + return NULL; - return sqlite3FindIndex(db, zName, pTab); + return sqlite3HashFind(&pTab->idxHash, zName); } /* @@ -553,18 +489,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 @@ -610,15 +534,14 @@ sqlite3StartTable(Parse *pParse, Token *pName, int noErr) return; assert(db->pSchema != NULL); - pTable = sqlite3FindTable(db, zName); - if (pTable) { + pTable = sqlite3HashFind(&db->pSchema->tblHash, zName); + if (pTable != NULL) { if (!noErr) { sqlite3ErrorMsg(pParse, "table %s already exists", zName); } else { assert(!db->init.busy || CORRUPT_DB); - sqlite3CodeVerifySchema(pParse); } goto begin_table_error; } @@ -650,7 +573,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, true); /* Normal (non-error) return. */ return; @@ -2035,7 +1958,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; @@ -2202,26 +2124,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); } /* @@ -2236,7 +2154,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 @@ -2372,15 +2289,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 == NULL) 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. @@ -2410,8 +2324,7 @@ sqlite3DropTable(Parse * pParse, SrcList * pName, int isView, int noErr) * space_id from _space. */ - sqlite3BeginWriteOperation(pParse, 1); - sqlite3ClearStatTables(pParse, "tbl", pTab->zName); + sql_clear_stat_spaces(pParse, "tbl", pTab->zName); sqlite3FkDropTable(pParse, pName, pTab); sqlite3CodeDropTable(pParse, pTab, isView); @@ -2876,7 +2789,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; @@ -2916,21 +2829,21 @@ 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) != + NULL) { 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) != NULL) { if (!ifNotExist) { sqlite3ErrorMsg(pParse, "index %s.%s already exists", pTab->zName, zName); } else { assert(!db->init.busy); - sqlite3CodeVerifySchema(pParse); } goto exit_create_index; } @@ -3075,9 +2988,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 @@ -3186,7 +3096,7 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */ if (v == 0) goto exit_create_index; - sqlite3BeginWriteOperation(pParse, 1); + sql_set_multi_write(pParse, true); sqlite3VdbeAddOp2(v, OP_SIDtoPtr, BOX_INDEX_ID, @@ -3382,8 +3292,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; @@ -3412,7 +3320,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), @@ -3929,56 +3837,15 @@ 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. - */ -void -sqlite3BeginWriteOperation(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. +/** + * Set flag in parse context, which indicates that during query + * execution multiple insertion/updates may occur. */ void -sqlite3MultiWrite(Parse * pParse) +sql_set_multi_write(struct Parse *parse_context, bool is_set) { - Parse *pToplevel = sqlite3ParseToplevel(pParse); - pToplevel->isMultiWrite = 1; + Parse *pToplevel = sqlite3ParseToplevel(parse_context); + pToplevel->isMultiWrite |= is_set; } /* @@ -4095,7 +3962,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, false); sqlite3RefillIndex(pParse, pIndex, -1); } } @@ -4170,8 +4037,8 @@ sqlite3Reindex(Parse * pParse, Token * pName1, Token * pName2) z = sqlite3NameFromToken(db, pName1); if (z == 0) return; - pTab = sqlite3FindTable(db, z); - if (pTab) { + pTab = sqlite3HashFind(&db->pSchema->tblHash, z); + if (pTab != NULL) { reindexTable(pParse, pTab, 0); sqlite3DbFree(db, z); return; @@ -4180,16 +4047,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); - - if (pIndex) { - sqlite3BeginWriteOperation(pParse, 0); + pIndex = sqlite3HashFind(&pTab->idxHash, z); + if (pIndex != NULL) { + sql_set_multi_write(pParse, false); sqlite3RefillIndex(pParse, pIndex, -1); return; } diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c index ab8dd0bc3f8f936a4bfcf59f13a878c1f5f10630..bb4338f4777b273338b4f8c80b9fbc3c6c1b420c 100644 --- a/src/box/sql/delete.c +++ b/src/box/sql/delete.c @@ -56,15 +56,13 @@ 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) { + if (pTab != NULL) pTab->nTabRef++; - } - if (sqlite3IndexedByLookup(pParse, pItem)) { - pTab = 0; - } + if (sqlite3IndexedByLookup(pParse, pItem)) + pTab = NULL; return pTab; } @@ -113,7 +111,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 +322,7 @@ sqlite3DeleteFrom(Parse * pParse, /* The parser context */ } if (pParse->nested == 0) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, 1); + sql_set_multi_write(pParse, true); /* 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 78ebc91a591ef269f9097fa7e285c06f5b782177..8071314670efbe83a691a1e17d681b3a7b437385 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 */ @@ -3584,8 +3581,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); } @@ -5314,8 +5310,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 f4a6b2707e023a1afab8c8fe56c7816962fe845b..f56b6d9cde759d031560731fd665ff5534b84cd2 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 c76910e5b07085b7680fea30dee52f154ab74d8c..b24d55b070c0cb7deefad5a4c07790e66196cb8c 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 @@ -1382,8 +1382,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, @@ -1446,7 +1445,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ default: { Trigger *pTrigger = 0; assert(onError == ON_CONFLICT_ACTION_REPLACE); - sqlite3MultiWrite(pParse); + sql_set_multi_write(pParse, true); if (user_session-> sql_flags & SQLITE_RecTriggers) { pTrigger = @@ -1708,9 +1707,8 @@ xferOptimization(Parse * pParse, /* Parser context */ int regData, regTupleid; /* Registers holding data and tupleid */ struct session *user_session = current_session(); - if (pSelect == 0) { + if (pSelect == NULL) return 0; /* Must be of the form INSERT INTO ... SELECT ... */ - } if (pParse->pWith || pSelect->pWith) { /* Do not attempt to process this query if there are an WITH clauses * attached to it. Proceeding may generate a false "no such table: xxx" @@ -1771,8 +1769,8 @@ xferOptimization(Parse * pParse, /* Parser context */ * we have to check the semantics. */ pItem = pSelect->pSrc->a; - pSrc = sqlite3LocateTableItem(pParse, 0, pItem); - if (pSrc == 0) { + pSrc = sqlite3LocateTable(pParse, 0, pItem->zName); + if (pSrc == NULL) { return 0; /* FROM clause does not contain a real table */ } if (pSrc == pDest) { @@ -1857,7 +1855,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 2804cc777eea86cbd8cd25b150ddb0b318701385..b724c9845d38a41201351c0fc4e9a806ec08f82a 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -356,7 +356,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++) { @@ -395,7 +394,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); @@ -439,7 +437,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++) { @@ -479,10 +476,10 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ Index *pIdx; Table *pTab; int i; - pTab = sqlite3FindTable(db, zRight); - if (pTab) { + pTab = sqlite3HashFind(&db->pSchema->tblHash, + zRight); + if (pTab != NULL) { pParse->nMem = 5; - sqlite3CodeVerifySchema(pParse); for (pIdx = pTab->pIndex, i = 0; pIdx; pIdx = pIdx->pNext, i++) { const char *azOrigin[] = @@ -539,13 +536,13 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ if (zRight) { FKey *pFK; Table *pTab; - pTab = sqlite3FindTable(db, zRight); - if (pTab) { + pTab = sqlite3HashFind(&db->pSchema->tblHash, + zRight); + if (pTab != NULL) { pFK = pTab->pFKey; if (pFK) { int i = 0; pParse->nMem = 8; - sqlite3CodeVerifySchema(pParse); while (pFK) { int j; for (j = 0; @@ -595,7 +592,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) { @@ -617,8 +613,9 @@ 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); - if (pParent == 0) + sqlite3HashFind(&db->pSchema->tblHash, + pFK->zTo); + if (pParent == NULL) continue; pIdx = 0; x = sqlite3FkLocateIndex(pParse, @@ -655,7 +652,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 0ea181d444a21746229c5c8fa5764a8e446956d5..7a16074dc7391454e73f3bb0342618a5fdaeda9e 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 9e64b434e4c32555964b1f33b946145e5fc96401..d97e466b5dcaa73f336954affb339712516ff68d 100644 --- a/src/box/sql/select.c +++ b/src/box/sql/select.c @@ -4737,8 +4737,8 @@ 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); - if (pTab == 0) + sqlite3LocateTable(pParse, 0, pFrom->zName); + if (pTab == NULL) return WRC_Abort; if (pTab->nTabRef >= 0xffff) { sqlite3ErrorMsg(pParse, @@ -6147,8 +6147,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 e26239fd4fed84f21d6d1bfd816dc503ccf5dcf3..d4e1f9201be70e0b0c8849fc4e545b15c8e1f0e8 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -2901,25 +2901,6 @@ struct TriggerPrg { u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ }; -/* - * The yDbMask datatype for the bitmask of all attached databases. - */ -#if SQLITE_MAX_ATTACHED>30 -typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED + 9) / 8]; -#define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) -#define DbMaskZero(M) memset((M),0,sizeof(M)) -#define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) -#define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) -#define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) -#else -typedef unsigned int yDbMask; -#define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) -#define DbMaskZero(M) (M)=0 -#define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) -#define DbMaskAllZero(M) (M)==0 -#define DbMaskNonZero(M) (M)!=0 -#endif - /* * An SQL parser context. A copy of this structure is passed through * the parser and down into all the parser action routine in order to @@ -2960,8 +2941,6 @@ struct Parse { int *aLabel; /* Space to hold the labels */ 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 @@ -3562,7 +3541,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); @@ -3599,9 +3577,6 @@ int sqlite3ViewGetColumnNames(Parse *, Table *); #define sqlite3ViewGetColumnNames(A,B) 0 #endif -#if SQLITE_MAX_ATTACHED>30 -int sqlite3DbMaskAllZero(yDbMask); -#endif void sqlite3DropTable(Parse *, SrcList *, int, int); void sqlite3DeleteTable(sqlite3 *, Table *); void sqlite3Insert(Parse *, SrcList *, Select *, IdList *, int); @@ -3681,12 +3656,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 *); @@ -3704,7 +3676,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 *); @@ -3742,8 +3713,8 @@ vdbe_emit_insertion_completion(Vdbe *v, int cursor_id, int tuple_id, int sqlite3OpenTableAndIndices(Parse *, Table *, int, u8, int, u8 *, int *, int *, u8, u8); -void sqlite3BeginWriteOperation(Parse *, int); -void sqlite3MultiWrite(Parse *); +void +sql_set_multi_write(Parse *, bool); void sqlite3MayAbort(Parse *); void sqlite3HaltConstraint(Parse *, int, int, char *, i8, u8); void sqlite3UniqueConstraint(Parse *, int, Index *); @@ -3936,8 +3907,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 *); @@ -3949,7 +3918,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 eaa08eb4c60ab406960d810728f55207c091aded..ed7b948aba8173bb3fd56f4621919fffda5b4d18 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; @@ -294,7 +292,7 @@ sqlite3FinishTrigger(Parse * pParse, /* Parser context */ iFirstCol = pParse->nMem + 1; pParse->nMem += 2; - sqlite3BeginWriteOperation(pParse, 0); + sql_set_multi_write(pParse, false); sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol, 0, zName, P4_STATIC); @@ -527,8 +525,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; @@ -673,7 +669,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 98e696ddfd0f3675a5b76c62619b599a57cf2289..83c05ab489df4c03b8b4e55323c30b78bfdc783a 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, true); /* Allocate required registers. */ regOldPk = regNewPk = ++pParse->nMem; diff --git a/src/box/sql/where.c b/src/box/sql/where.c index c51bd7455b30f83ab618fa5d5c00095aa8371766..2a2630281a6bb00fbae2e3259b87621b857f90dc 100644 --- a/src/box/sql/where.c +++ b/src/box/sql/where.c @@ -4615,7 +4615,6 @@ sqlite3WhereBegin(Parse * pParse, /* The parser context */ #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ } } - sqlite3CodeVerifySchema(pParse); } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); if (db->mallocFailed) @@ -4813,7 +4812,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 aaffa7c1c6827ceb19f1ede6e143819e92e251ea..6aec4ae795b8526dcfb20cad402f4be71b5ef38d 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); }