Index: src/alter.c ================================================================== --- src/alter.c +++ src/alter.c @@ -122,11 +122,11 @@ if( !zName ) goto exit_rename_table; /* Check that a table or index named 'zName' does not already exist ** in database iDb. If so, this is an error. */ - if( sqlite3FindTable(0, db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ + if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ sqlite3ErrorMsg(pParse, "there is already another table or index with this name: %s", zName); goto exit_rename_table; } @@ -209,11 +209,11 @@ #ifndef SQLITE_OMIT_AUTOINCREMENT /* If the sqlite_sequence table exists in this database, then update ** it with the new table name. */ - if( sqlite3FindTable(0, db, "sqlite_sequence", zDb) ){ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ sqlite3NestedParse(pParse, "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", zDb, zName, pTab->zName); } #endif @@ -286,11 +286,11 @@ iDb = sqlite3SchemaToIndex(db, pNew->pSchema); zDb = db->aDb[iDb].zDbSName; zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ pCol = &pNew->aCol[pNew->nCol-1]; pDflt = pCol->pDflt; - pTab = sqlite3FindTable(0, db, zTab, zDb); + pTab = sqlite3FindTable(db, zTab, zDb); assert( pTab ); #ifndef SQLITE_OMIT_AUTHORIZATION /* Invoke the authorization callback. */ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ @@ -1084,11 +1084,11 @@ int rc = SQLITE_OK; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; assert( pNew->pTabSchema ); - pParse->pTriggerTab = sqlite3FindTable(0, db, pNew->table, + pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ @@ -1248,11 +1248,11 @@ if( zSql==0 ) return; if( zTable==0 ) return; if( zNew==0 ) return; if( iCol<0 ) return; sqlite3BtreeEnterAll(db); - pTab = sqlite3FindTable(0, db, zTable, zDb); + pTab = sqlite3FindTable(db, zTable, zDb); if( pTab==0 || iCol>=pTab->nCol ){ sqlite3BtreeLeaveAll(db); return; } zOld = pTab->aCol[iCol].zName; @@ -1450,11 +1450,11 @@ #endif sqlite3BtreeEnterAll(db); memset(&sCtx, 0, sizeof(RenameCtx)); - sCtx.pTab = sqlite3FindTable(0, db, zOld, zDb); + sCtx.pTab = sqlite3FindTable(db, zOld, zDb); memset(&sWalker, 0, sizeof(Walker)); sWalker.pParse = &sParse; sWalker.xExprCallback = renameTableExprCb; sWalker.xSelectCallback = renameTableSelectCb; sWalker.u.pRename = &sCtx; Index: src/analyze.c ================================================================== --- src/analyze.c +++ src/analyze.c @@ -208,11 +208,11 @@ ** if they do already exist. */ for(i=0; izDbSName))==0 ){ + if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){ if( aTable[i].zCols ){ /* The sqlite_statN table does not exist. Create it. Note that a ** side-effect of the CREATE TABLE statement is to leave the rootpage ** of the new table in register pParse->regRoot. This is important ** because the OpenWrite opcode below will be needing it. */ @@ -1534,11 +1534,11 @@ UNUSED_PARAMETER2(NotUsed, argc); if( argv==0 || argv[0]==0 || argv[2]==0 ){ return 0; } - pTable = sqlite3FindTable(0, pInfo->db, argv[0], pInfo->zDatabase); + pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); if( pTable==0 ){ return 0; } if( argv[1]==0 ){ pIndex = 0; @@ -1676,11 +1676,11 @@ const char *zName, const char *zDb ){ Index *pIdx = sqlite3FindIndex(db, zName, zDb); if( pIdx==0 ){ - Table *pTab = sqlite3FindTable(0, db, zName, zDb); + Table *pTab = sqlite3FindTable(db, zName, zDb); if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); } return pIdx; } @@ -1825,19 +1825,19 @@ */ static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ assert( db->lookaside.bDisable ); - if( sqlite3FindTable(0, db, "sqlite_stat4", zDb) ){ + if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ rc = loadStatTbl(db, 0, "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", zDb ); } - if( rc==SQLITE_OK && sqlite3FindTable(0, db, "sqlite_stat3", zDb) ){ + if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ rc = loadStatTbl(db, 1, "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3", zDb ); @@ -1893,11 +1893,11 @@ } /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zDbSName; - if( sqlite3FindTable(0, db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ + if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ zSql = sqlite3MPrintf(db, "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -319,16 +319,11 @@ ** 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( - Parse *pParse, - sqlite3 *db, - const char *zName, - const char *zDatabase -){ +Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ Table *p = 0; int i; /* All mutexes are required for schema access. Make sure we hold them. */ assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); @@ -343,13 +338,16 @@ for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ int bUnload = 0; assert( sqlite3SchemaMutexHeld(db, j, 0) ); - if( IsReuseSchema(db) && pParse && pParse->nErr==0 ){ - pParse->rc = sqlite3SchemaLoad(db, j, &bUnload, &pParse->zErrMsg); - if( pParse->rc ) pParse->nErr++; + if( IsReuseSchema(db) ){ + Parse *pParse = db->pParse; + if( pParse && pParse->nErr==0 ){ + pParse->rc = sqlite3SchemaLoad(db, j, &bUnload, &pParse->zErrMsg); + if( pParse->rc ) pParse->nErr++; + } } p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); if( p ) return p; if( bUnload ){ sqlite3SchemaRelease(db, j); @@ -391,11 +389,11 @@ && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ return 0; } - p = sqlite3FindTable(pParse, db, zName, zDbase); + p = sqlite3FindTable(db, zName, zDbase); if( p==0 ){ #ifndef SQLITE_OMIT_VIRTUALTABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ @@ -423,11 +421,11 @@ pParse->checkSchema = 1; }else if( IsVirtual(p) && pParse->disableVtab ){ p = 0; } - if( p==0 ){ + if( p==0 && pParse->nErr==0 ){ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; if( zDbase ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); }else{ sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); @@ -993,11 +991,11 @@ if( !IN_SPECIAL_PARSE ){ char *zDb = db->aDb[iDb].zDbSName; if( !IsReuseSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } - pTable = sqlite3FindTable(pParse, db, zName, zDb); + pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); }else{ assert( !db->init.busy || CORRUPT_DB ); @@ -1965,11 +1963,11 @@ Module *pMod; /* Module for the virtual table */ zTail = strrchr(zName, '_'); if( zTail==0 ) return 0; *zTail = 0; - pTab = sqlite3FindTable(0, db, zName, 0); + pTab = sqlite3FindTable(db, zName, 0); *zTail = '_'; if( pTab==0 ) return 0; if( !IsVirtual(pTab) ) return 0; pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); if( pMod==0 ) return 0; @@ -2615,11 +2613,11 @@ int i; const char *zDbName = pParse->db->aDb[iDb].zDbSName; for(i=1; i<=4; i++){ char zTab[24]; sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); - if( sqlite3FindTable(0, pParse->db, zTab, zDbName) ){ + if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", zDbName, zTab, zType, zName ); } @@ -3240,11 +3238,11 @@ if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto exit_create_index; } if( !IN_RENAME_OBJECT ){ if( !db->init.busy ){ - if( sqlite3FindTable(0, db, zName, 0)!=0 ){ + if( sqlite3FindTable(db, zName, 0)!=0 ){ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } } if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ @@ -4594,11 +4592,11 @@ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); if( iDb<0 ) return; z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; zDb = db->aDb[iDb].zDbSName; - pTab = sqlite3FindTable(0, db, z, zDb); + pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); sqlite3DbFree(db, z); return; } Index: src/fkey.c ================================================================== --- src/fkey.c +++ src/fkey.c @@ -906,11 +906,11 @@ /* Find the parent table of this foreign key. Also find a unique index ** on the parent key columns in the parent table. If either of these ** schema items cannot be located, set an error in pParse and return ** early. */ if( pParse->disableTriggers ){ - pTo = sqlite3FindTable(0, db, pFKey->zTo, zDb); + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); }else{ pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); } if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -3631,14 +3631,17 @@ } /* Locate the table in question */ if( rc==SQLITE_OK ){ Parse sParse; /* Fake Parse object for FindTable */ + Parse *pSaved = db->pParse; memset(&sParse, 0, sizeof(sParse)); - pTab = sqlite3FindTable(&sParse, db, zTableName, zDbName); + db->pParse = &sParse; + pTab = sqlite3FindTable(db, zTableName, zDbName); sqlite3_free(sParse.zErrMsg); rc = sParse.rc; + db->pParse = pSaved; } if( SQLITE_OK!=rc ) goto error_out; if( !pTab || pTab->pSelect ){ pTab = 0; Index: src/pragma.c ================================================================== --- src/pragma.c +++ src/pragma.c @@ -1186,11 +1186,11 @@ case PragTyp_INDEX_LIST: if( zRight ){ Index *pIdx; Table *pTab; int i; - pTab = sqlite3FindTable(0, db, zRight, zDb); + pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); pParse->nMem = 5; sqlite3CodeVerifySchema(pParse, iTabDb); for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ @@ -1275,11 +1275,11 @@ #ifndef SQLITE_OMIT_FOREIGN_KEY case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ FKey *pFK; Table *pTab; - pTab = sqlite3FindTable(0, db, zRight, zDb); + pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ pFK = pTab->pFKey; if( pFK ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int i = 0; @@ -1345,11 +1345,11 @@ sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName); if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead); sqlite3VdbeLoadString(v, regResult, pTab->zName); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3FindTable(0, db, pFK->zTo, zDb); + pParent = sqlite3FindTable(db, pFK->zTo, zDb); if( pParent==0 ) continue; pIdx = 0; sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName); x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); if( x==0 ){ @@ -1367,11 +1367,11 @@ assert( pParse->nErr>0 || pFK==0 ); if( pFK ) break; if( pParse->nTabnTab = i; addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3FindTable(0, db, pFK->zTo, zDb); + pParent = sqlite3FindTable(db, pFK->zTo, zDb); pIdx = 0; aiCols = 0; if( pParent ){ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); assert( x==0 ); Index: src/prepare.c ================================================================== --- src/prepare.c +++ src/prepare.c @@ -32,10 +32,15 @@ }else if( pData->mInitFlags & INITFLAG_AlterTable ){ *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); pData->rc = SQLITE_ERROR; }else if( db->flags & SQLITE_WriteSchema ){ pData->rc = SQLITE_CORRUPT_BKPT; + }else if( IsReuseSchema(db) + && 0==sqlite3StrNICmp(zExtra, "malformed database schema", 17) + ){ + pData->rc = SQLITE_CORRUPT_BKPT; + *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); }else{ char *z; if( zObj==0 ) zObj = "?"; z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -4011,11 +4011,11 @@ #define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */ #define SQLITE_ECEL_OMITREF 0x08 /* Omit if ExprList.u.x.iOrderByCol */ void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int); -Table *sqlite3FindTable(Parse*,sqlite3*,const char*, const char*); +Table *sqlite3FindTable(sqlite3*,const char*, const char*); #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); Index: src/vtab.c ================================================================== --- src/vtab.c +++ src/vtab.c @@ -717,11 +717,11 @@ int rc = SQLITE_OK; Table *pTab; Module *pMod; const char *zMod; - pTab = sqlite3FindTable(0, db, zTab, db->aDb[iDb].zDbSName); + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); assert( pTab && IsVirtual(pTab) && !pTab->pVTable ); /* Locate the required virtual table module */ zMod = pTab->azModuleArg[0]; pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); @@ -841,11 +841,11 @@ */ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ int rc = SQLITE_OK; Table *pTab; - pTab = sqlite3FindTable(0, db, zTab, db->aDb[iDb].zDbSName); + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ VTable *p; int (*xDestroy)(sqlite3_vtab *); for(p=pTab->pVTable; p; p=p->pNext){ assert( p->pVtab ); Index: test/reuse2.test ================================================================== --- test/reuse2.test +++ test/reuse2.test @@ -176,11 +176,11 @@ SELECT * FROM x1 } do_execsql_test 4.1.8 { SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete FROM schemapool; -} {nref=3 nschema=1 ndelete=0} +} {nref=6 nschema=1 ndelete=0} do_test 4.2.1 { catchsql { SELECT * FROM abc } db2 } {1 {no such table: abc}} do_execsql_test 4.2.2 { Index: test/reuse3.test ================================================================== --- test/reuse3.test +++ test/reuse3.test @@ -80,15 +80,15 @@ db close sqlite3 db test.db -shared-schema 1 do_catchsql_test 2.1 { SELECT * FROM x1; -} {1 {no such table: x1}} +} {1 {malformed database schema (y1) - near "TBL": syntax error}} do_catchsql_test 2.2 { SELECT * FROM x1; -} {1 {no such table: x1}} +} {1 {malformed database schema (y1) - near "TBL": syntax error}} #------------------------------------------------------------------------- reset_db do_execsql_test 3.0 { CREATE TABLE x1(a, b, c); @@ -238,8 +238,27 @@ DROP TRIGGER tr1; SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete FROM schemapool; } {nref=5 nschema=1 ndelete=4} +#-------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); + CREATE TABLE t3(a, b); +} + +sqlite3 db2 test.db -shared-schema 1 +register_schemapool_module db2 + +do_execsql_test 5.1 { + PRAGMA writable_schema = 1; + UPDATE sqlite_master SET sql='CREATE TABLE t3 a,b' WHERE name = 't3'; +} + +do_test 5.2 { + catchsql { SELECT * FROM t1 } db2 +} {1 {malformed database schema (t3) - near "a": syntax error}} finish_test Index: test/with3.test ================================================================== --- test/with3.test +++ test/with3.test @@ -28,11 +28,11 @@ WITH i(x) AS ( WITH j AS (SELECT 10) SELECT 5 FROM t0 UNION SELECT 8 FROM m ) SELECT * FROM i; -} {1 {no such table: m}} +} {1 {no such table: t0}} # Additional test cases that came out of the work to # fix for Kostya's problem. # do_execsql_test 2.0 {