From: dan Date: Mon, 18 Feb 2019 18:16:05 +0000 (+0000) Subject: Ensure that creating temp schema items does not cause an OPEN_SHARABLE_SCHEMA connect... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a011145aae9315cb12db9d6a1d16e4162d28f980;p=thirdparty%2Fsqlite.git Ensure that creating temp schema items does not cause an OPEN_SHARABLE_SCHEMA connection to load all schemas into memory. FossilOrigin-Name: 88cbf54eee7845f9e40e6879fc38eb98a80e81c987b7edeb39f3058590003347 --- diff --git a/manifest b/manifest index ea2d6f0059..4bd929eda9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\svirtual\stable\sin\stest_schemapool.c\sso\sthat\sit\scan\sbe\sused\sto\scheck\sthat\sSHARED_SCHEMA\sconnections\sare\snot\sallocating\sand\sfreeing\sschemas\swhen\sthey\sshould\snot\sbe. -D 2019-02-15T19:36:47.869 +C Ensure\sthat\screating\stemp\sschema\sitems\sdoes\snot\scause\san\sOPEN_SHARABLE_SCHEMA\sconnection\sto\sload\sall\sschemas\sinto\smemory. +D 2019-02-18T18:16:05.585 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 56456706c4da271309914c756c9c8ea537685f1c79f8785afa72f968d6810482 @@ -449,8 +449,8 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 995b37de876639f1b6c14fcf15f3ee1004e3cbea354ebb43d7f5c4de0d649a64 -F src/analyze.c e75c3c1d6534265f74a4763282f17e9ad946606ef0a68c5517fcfb355cc243d0 +F src/alter.c 669e18e9ef4d98a2941d1a98fb356309534b6965ff221b5d72e747dfd33bdbbe +F src/analyze.c 9ffcf93866bffb8951a232f9ed770388847ac33dae2bf57fc6c7faf1f3fb7d75 F src/attach.c 06897ba0fa023ab6aea459afa813c767879c99c8cccedad41126369af455c254 F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab @@ -459,7 +459,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 161b6a57b91d160065e512a4d0be180e402a16a059034a380cbdc2411924f8ac F src/btree.h 63b94fb38ce571c15eb6a3661815561b501d23d5948b2d1e951fbd7a2d04e8d3 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 9ee9a6d4dc5e8cddd0657fc9f2208849e83a59b9cd862bd828260ff28dd972a6 +F src/build.c 87a0bc491b8bc9006f724fcda2eb1379ee83b665f0e5bcbb1ab3db9e6e907f63 F src/callback.c df42b5473587c3322038d594be585a6d92d532e1a67f5c340b324de887b8a44a F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b @@ -469,7 +469,7 @@ F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf F src/expr.c 182dc9ff30aa6a430b7f728ce84fda85ec10890e29fdf75be1e871d13222a99c F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 878bec1b4d9aab3b34585121b834fce9b2780352b7282510e4ffc94b75ce6c83 +F src/fkey.c 56ceea145999b1c077eb106bd4da37b197f85a249f37b755336223faa78005b7 F src/func.c 0341881d22903aac5ba7f352b188806d6436e1d6ae4235ff01e44d56879dfe63 F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a @@ -479,7 +479,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 4cf069988908f650bec92fd821a082f6eda87c01191047e49a1a5007af93274c F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c e6f10875d52aca3b7e57ce1ec174aeafc9b6c00b43000cd30d791f9cb490b7a6 -F src/main.c c86165813ba7aa00cde67fdca38074f1e26ed338d4980d00d562660658f6b448 +F src/main.c 519cbda96cd35cea76bee8403546db654c5ac1c93ebee63cb8ff609dd23a3903 F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -508,7 +508,7 @@ F src/parse.y 741a270b7f2f85bc5d026d06fb5a9ccba5335304ff2831e1cb44b36cd0da6006 F src/pcache.c 696a01f1a6370c1b50a09c15972bc3bee3333f8fcd1f2da8e9a76b1b062c59ee F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c a72804486dfa8e4b6bc30d666c97ecf1155f91a4351fc6e48ea4097e4eb304fb -F src/pragma.c af67dedaad8bafe9a5f9adcec32a0da6dd118617dd8220ad1d118f5a6bf83a02 +F src/pragma.c 06a6b3f0f9511e5f2c270009f0291b86ce25775ff3a4c93802525f5884e63235 F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177 F src/prepare.c 8335bb97dea9af5a79dd19f87e35bc0c2624578a7a8a07346bb7cc67ad3dd8f6 F src/printf.c cbf27c320091a83279d1738f68a27a9fe01698c607ce80516ab6bdb5a9c36a1a @@ -520,9 +520,9 @@ F src/shell.c.in d7d63fd1ecef44d19088adc188652252327eab782d59cf1958657943132b508 F src/sqlite.h.in cd9b7c397b942a4903c46ebbabee47f920a9916e96e70e0b4f793076d4b45e31 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683 -F src/sqliteInt.h 2e86c769cc0cca8e7f3324f33f2e1d59f75a861f279716f254b587dfe02de793 +F src/sqliteInt.h ad218b369baa15a16b7085f292405ac5e1f3efcf9ebf626409dc50e7f25bb76d F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b -F src/status.c 0361d78dabfd2a92c740911f42723d2f6775d619feb8f8910827f9c9fe8bc30f +F src/status.c 28fcf86faee5cc030ca2d5d6b356fc59999cffb478457fe343ae0f9c39b41f6b F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c f11d822fb2bd6e155d41535a629d1c34daf3d98a37b1f0ea6b4cb11d150d3c57 F src/test1.c 353b066e7ec761c4c715c1c20b888e0e7a0b0c0eda7f68c110e032d63713cade @@ -596,7 +596,7 @@ F src/vdbeblob.c 08e58c6bef990008b8c2dbad4c99c56d3b622ee79433004484cce29b536e2ab F src/vdbemem.c 3e89e087df928eba80e520824078dc563c579a0848b1557ac36845ec14392923 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 -F src/vtab.c 7d0f847060b3cfe8102b97a8c419866b44d600f2c2ed36e9c13c14c6581dd962 +F src/vtab.c be7ef1a321166bb664ed374d6dc7cc9051afa228f47ede6fac594208200f1e57 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 3f4f653daf234fe713edbcbca3fec2350417d159d28801feabc702a22c4e213f F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1228,8 +1228,8 @@ F test/releasetest.tcl 7712811e0f4e2f198ec786cb2e1352b3793d7395f48a3cceef0572d88 F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/reuse1.test 31c312375ccfcc5c2abc1fca5e4a89d6309c57ea6b1fa3179a5eee68016f9c74 -F test/reuse2.test 04d88621f0c51a8b3bf5512b9e61a5d7a61059e33097a1a6b1c6f6cf2d1f2a35 -F test/reuse3.test 624e389467085f6e1c06dcb5815740afce13639033beb108b3ef89796dd0f5f5 +F test/reuse2.test d3352a887a22870cf0946a314a79ee3b911d3a17b212188d25e73db23be7187f +F test/reuse3.test 3bc91bb1820217ac76002ec9aa439eeb90335b8fac188da1cee3b4fda269a52e F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a @@ -1714,7 +1714,7 @@ F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/addopcodes.tcl 0288d5b26b9b35f4cb5affb76eec63f1dfce117bbc2020066708069ef60b86ff F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 -F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x +F tool/cg_anno.tcl 82a433bb1b410714acd84c1c12bfb6d20e1e8ed9e37bd5bb2c7e5026ff092d11 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 F tool/dbtotxt.c 04e25f26be7c7743cdfb4111a8483de0b111925d6afeeb7559ade0ceb73f7f52 @@ -1809,7 +1809,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ecf6251ec0bb745a4ef9bad9f9ecd3babb687a3806fd96554b265313625270c5 -R af9505b450d481737fb31789b721e9d0 +P cb236cb98564b870317ba3e481a3c7d7f9769b0294a01246bcb724f04e1e7b10 +R 05377929d9ed918297527f74023065f3 U dan -Z e6a41c81ac1abbc49dfae8dadf58f8cc +Z 17f1c2a0d64857635db5ccb15bcd8205 diff --git a/manifest.uuid b/manifest.uuid index acfc5d098d..6d0c1eaaab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb236cb98564b870317ba3e481a3c7d7f9769b0294a01246bcb724f04e1e7b10 \ No newline at end of file +88cbf54eee7845f9e40e6879fc38eb98a80e81c987b7edeb39f3058590003347 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 4585beee59..0311a55826 100644 --- a/src/alter.c +++ b/src/alter.c @@ -124,7 +124,7 @@ void sqlite3AlterRenameTable( /* Check that a table or index named 'zName' does not already exist ** in database iDb. If so, this is an error. */ - if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ + if( sqlite3FindTable(0, 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; @@ -211,7 +211,7 @@ void sqlite3AlterRenameTable( /* If the sqlite_sequence table exists in this database, then update ** it with the new table name. */ - if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + if( sqlite3FindTable(0, db, "sqlite_sequence", zDb) ){ sqlite3NestedParse(pParse, "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", zDb, zName, pTab->zName); @@ -288,7 +288,7 @@ void 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, zDb); + pTab = sqlite3FindTable(0, db, zTab, zDb); assert( pTab ); #ifndef SQLITE_OMIT_AUTHORIZATION @@ -1086,7 +1086,7 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; assert( pNew->pTabSchema ); - pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, + pParse->pTriggerTab = sqlite3FindTable(0, db, pNew->table, db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; @@ -1250,7 +1250,7 @@ static void renameColumnFunc( if( zNew==0 ) return; if( iCol<0 ) return; sqlite3BtreeEnterAll(db); - pTab = sqlite3FindTable(db, zTable, zDb); + pTab = sqlite3FindTable(0, db, zTable, zDb); if( pTab==0 || iCol>=pTab->nCol ){ sqlite3BtreeLeaveAll(db); return; @@ -1452,7 +1452,7 @@ static void renameTableFunc( sqlite3BtreeEnterAll(db); memset(&sCtx, 0, sizeof(RenameCtx)); - sCtx.pTab = sqlite3FindTable(db, zOld, zDb); + sCtx.pTab = sqlite3FindTable(0, db, zOld, zDb); memset(&sWalker, 0, sizeof(Walker)); sWalker.pParse = &sParse; sWalker.xExprCallback = renameTableExprCb; diff --git a/src/analyze.c b/src/analyze.c index c9c57c864d..b6e613980b 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -210,7 +210,7 @@ static void openStatTable( for(i=0; izDbSName))==0 ){ + if( (pStat = sqlite3FindTable(0, 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 @@ -1536,7 +1536,7 @@ static int 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], pInfo->zDatabase); + pTable = sqlite3FindTable(0, pInfo->db, argv[0], pInfo->zDatabase); if( pTable==0 ){ return 0; } @@ -1678,7 +1678,7 @@ static Index *findIndexOrPrimaryKey( ){ Index *pIdx = sqlite3FindIndex(db, zName, zDb); if( pIdx==0 ){ - Table *pTab = sqlite3FindTable(db, zName, zDb); + Table *pTab = sqlite3FindTable(0, db, zName, zDb); if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); } return pIdx; @@ -1827,7 +1827,7 @@ static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ assert( db->lookaside.bDisable ); - if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ + if( sqlite3FindTable(0, 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", @@ -1835,7 +1835,7 @@ static int loadStat4(sqlite3 *db, const char *zDb){ ); } - if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ + if( rc==SQLITE_OK && sqlite3FindTable(0, 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", @@ -1895,7 +1895,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zDbSName; - if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ + if( sqlite3FindTable(0, db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ zSql = sqlite3MPrintf(db, "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ diff --git a/src/build.c b/src/build.c index b12c16353e..36dbceffec 100644 --- a/src/build.c +++ b/src/build.c @@ -294,20 +294,19 @@ int sqlite3UserAuthTable(const char *zTable){ ** Non-zero is returned if a schema is loaded, or zero if it was already ** loaded when this function was called.. */ -int sqlite3SchemaLoad(sqlite3 *db, int iDb){ +int sqlite3SchemaLoad(sqlite3 *db, int iDb, int *pbUnload, char **pzErr){ + int rc = SQLITE_OK; if( IsReuseSchema(db) - && DbHasProperty(db, iDb, DB_SchemaLoaded)==0 - && (db->init.busy==0 || (iDb!=1 && db->init.iDb==1)) + && DbHasProperty(db, iDb, DB_SchemaLoaded)==0 + && (db->init.busy==0 || (iDb!=1 && db->init.iDb==1)) ){ - char *zDummy = 0; struct sqlite3InitInfo sv = db->init; memset(&db->init, 0, sizeof(struct sqlite3InitInfo)); - sqlite3InitOne(db, iDb, &zDummy, 0); - sqlite3_free(zDummy); + rc = sqlite3InitOne(db, iDb, pzErr, 0); db->init = sv; - return (iDb!=1); + *pbUnload = (iDb!=1); } - return 0; + return rc; } /* @@ -322,7 +321,12 @@ int sqlite3SchemaLoad(sqlite3 *db, int iDb){ ** ** See also sqlite3LocateTable(). */ -Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ +Table *sqlite3FindTable( + Parse *pParse, + sqlite3 *db, + const char *zName, + const char *zDatabase +){ Table *p = 0; int i; @@ -339,9 +343,12 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ 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; + int bUnload = 0; assert( sqlite3SchemaMutexHeld(db, j, 0) ); - bUnload = sqlite3SchemaLoad(db, j); + if( IsReuseSchema(db) && 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 ){ @@ -386,7 +393,7 @@ Table *sqlite3LocateTable( return 0; } - p = sqlite3FindTable(db, zName, zDbase); + p = sqlite3FindTable(pParse, 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 @@ -398,7 +405,11 @@ Table *sqlite3LocateTable( pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod ){ - sqlite3SchemaLoad(db, 0); + if( IsReuseSchema(db) && pParse->nErr==0 ){ + int bDummy = 0; + pParse->rc = sqlite3SchemaLoad(db, 0, &bDummy, &pParse->zErrMsg); + if( pParse->rc ) pParse->nErr++; + } if( sqlite3VtabEponymousTableInit(pParse, pMod) ){ Table *pEpoTab = pMod->pEpoTab; assert( IsReuseSchema(db) || pEpoTab->pSchema==db->aDb[0].pSchema ); @@ -981,10 +992,10 @@ void sqlite3StartTable( */ if( !IN_SPECIAL_PARSE ){ char *zDb = db->aDb[iDb].zDbSName; - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + if( !IsReuseSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } - pTable = sqlite3FindTable(db, zName, zDb); + pTable = sqlite3FindTable(pParse, db, zName, zDb); if( pTable ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); @@ -1956,7 +1967,7 @@ static int isShadowTableName(sqlite3 *db, char *zName){ zTail = strrchr(zName, '_'); if( zTail==0 ) return 0; *zTail = 0; - pTab = sqlite3FindTable(db, zName, 0); + pTab = sqlite3FindTable(0, db, zName, 0); *zTail = '_'; if( pTab==0 ) return 0; if( !IsVirtual(pTab) ) return 0; @@ -2606,7 +2617,7 @@ static void sqlite3ClearStatTables( for(i=1; i<=4; i++){ char zTab[24]; sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); - if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ + if( sqlite3FindTable(0, pParse->db, zTab, zDbName) ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", zDbName, zTab, zType, zName @@ -2701,7 +2712,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); - if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; + if( !IsReuseSchema(db) && sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); @@ -3125,7 +3136,7 @@ void sqlite3CreateIndex( if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + if( !IsReuseSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_create_index; } @@ -3231,7 +3242,7 @@ void sqlite3CreateIndex( } if( !IN_RENAME_OBJECT ){ if( !db->init.busy ){ - if( sqlite3FindTable(db, zName, 0)!=0 ){ + if( sqlite3FindTable(0, db, zName, 0)!=0 ){ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } @@ -4585,7 +4596,7 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; zDb = db->aDb[iDb].zDbSName; - pTab = sqlite3FindTable(db, z, zDb); + pTab = sqlite3FindTable(0, db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); sqlite3DbFree(db, z); diff --git a/src/fkey.c b/src/fkey.c index 369c887e19..7746f22cab 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -908,7 +908,7 @@ void sqlite3FkCheck( ** schema items cannot be located, set an error in pParse and return ** early. */ if( pParse->disableTriggers ){ - pTo = sqlite3FindTable(db, pFKey->zTo, zDb); + pTo = sqlite3FindTable(0, db, pFKey->zTo, zDb); }else{ pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); } diff --git a/src/main.c b/src/main.c index c8b77f0dbf..5e219dc613 100644 --- a/src/main.c +++ b/src/main.c @@ -3616,7 +3616,6 @@ int sqlite3_table_column_metadata( int autoinc = 0; int bUnlock; - #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){ return SQLITE_MISUSE_BKPT; @@ -3630,13 +3629,17 @@ int sqlite3_table_column_metadata( if( IsReuseSchema(db)==0 ){ rc = sqlite3Init(db, &zErrMsg); } - if( SQLITE_OK!=rc ){ - goto error_out; - } - /* Locate the table in question */ - pTab = sqlite3FindTable(db, zTableName, zDbName); + if( rc==SQLITE_OK ){ + Parse sParse; /* Fake Parse object for FindTable */ + memset(&sParse, 0, sizeof(sParse)); + pTab = sqlite3FindTable(&sParse, db, zTableName, zDbName); + sqlite3_free(sParse.zErrMsg); + rc = sParse.rc; + } + if( SQLITE_OK!=rc ) goto error_out; + if( !pTab || pTab->pSelect ){ pTab = 0; goto error_out; diff --git a/src/pragma.c b/src/pragma.c index 1dcd21400c..6b1421c18a 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1188,7 +1188,7 @@ void sqlite3Pragma( Index *pIdx; Table *pTab; int i; - pTab = sqlite3FindTable(db, zRight, zDb); + pTab = sqlite3FindTable(0, db, zRight, zDb); if( pTab ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); pParse->nMem = 5; @@ -1277,7 +1277,7 @@ void sqlite3Pragma( case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ FKey *pFK; Table *pTab; - pTab = sqlite3FindTable(db, zRight, zDb); + pTab = sqlite3FindTable(0, db, zRight, zDb); if( pTab ){ pFK = pTab->pFKey; if( pFK ){ @@ -1347,7 +1347,7 @@ void sqlite3Pragma( 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(db, pFK->zTo, zDb); + pParent = sqlite3FindTable(0, db, pFK->zTo, zDb); if( pParent==0 ) continue; pIdx = 0; sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName); @@ -1369,7 +1369,7 @@ void sqlite3Pragma( 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(db, pFK->zTo, zDb); + pParent = sqlite3FindTable(0, db, pFK->zTo, zDb); pIdx = 0; aiCols = 0; if( pParent ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7e6c8a1815..bf489ccb86 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4013,7 +4013,7 @@ 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*, const char*); +Table *sqlite3FindTable(Parse*,sqlite3*,const char*, const char*); #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); @@ -4326,7 +4326,7 @@ int sqlite3SchemaConnect(sqlite3*, int, u64); int sqlite3SchemaDisconnect(sqlite3 *, int, int); void sqlite3SchemaClearOrDisconnect(sqlite3*, int); Schema *sqlite3SchemaExtract(SchemaPool*); -int sqlite3SchemaLoad(sqlite3*, int); +int sqlite3SchemaLoad(sqlite3*, int, int*, char**); void sqlite3SchemaReleaseAll(sqlite3*); void sqlite3SchemaRelease(sqlite3*, int); void sqlite3SchemaAdjustUsed(sqlite3*, int, int, int*); diff --git a/src/status.c b/src/status.c index f230e9f730..54218e3f4e 100644 --- a/src/status.c +++ b/src/status.c @@ -285,7 +285,10 @@ int sqlite3_db_status( int nUsed = nByte; Schema *pSchema; if( db->aDb[i].pSPool ){ - bUnload = sqlite3SchemaLoad(db, i); + char *zDummy = 0; + rc = sqlite3SchemaLoad(db, i, &bUnload, &zDummy); + sqlite3_free(zDummy); + if( rc ) break; } pSchema = db->aDb[i].pSchema; if( ALWAYS(pSchema!=0) ){ diff --git a/src/vtab.c b/src/vtab.c index 07813c5def..939ecbbcbe 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -719,7 +719,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ Module *pMod; const char *zMod; - pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + pTab = sqlite3FindTable(0, db, zTab, db->aDb[iDb].zDbSName); assert( pTab && IsVirtual(pTab) && !pTab->pVTable ); /* Locate the required virtual table module */ @@ -843,7 +843,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ int rc = SQLITE_OK; Table *pTab; - pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + pTab = sqlite3FindTable(0, db, zTab, db->aDb[iDb].zDbSName); if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ VTable *p; int (*xDestroy)(sqlite3_vtab *); diff --git a/test/reuse2.test b/test/reuse2.test index 50e03c1ac7..6f61906d4c 100644 --- a/test/reuse2.test +++ b/test/reuse2.test @@ -178,7 +178,7 @@ do_execsql_test -db db2 4.1.7 { do_execsql_test 4.1.8 { SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete FROM schemapool; -} {nref=6 nschema=1 ndelete=0} +} {nref=3 nschema=1 ndelete=0} do_test 4.2.1 { catchsql { SELECT * FROM abc } db2 diff --git a/test/reuse3.test b/test/reuse3.test index 11224789a9..b28e52a14e 100644 --- a/test/reuse3.test +++ b/test/reuse3.test @@ -129,7 +129,9 @@ catch { db3 close } catch { db4 close } #------------------------------------------------------------------------- -# Test the REINDEX command. +# 4.1 Test the REINDEX command. +# 4.2 Test CREATE TEMP ... commands. +# reset_db do_execsql_test 4.1.0 { CREATE TABLE x1(a, b, c); @@ -162,7 +164,6 @@ do_test 4.1.2 { } } {nref=5 nschema=1 ndelete=0} -breakpoint do_execsql_test 4.1.3 { REINDEX x1; REINDEX x1a; @@ -178,5 +179,67 @@ do_execsql_test 4.1.4 { FROM schemapool } {nref=5 nschema=1 ndelete=28} +#------------------------------------------------------------------------- +db close +sqlite3 db test.db -shared-schema 1 +register_schemapool_module db +do_execsql_test 4.2.0 { + ATTACH 'test.db1' AS db1; + ATTACH 'test.db2' AS db2; + ATTACH 'test.db3' AS db3; + ATTACH 'test.db4' AS db4; + + SELECT * FROM db1.x1; + SELECT * FROM db2.x1; + SELECT * FROM db3.x1; + SELECT * FROM db4.x1; +} + +do_execsql_test 4.2.1 { + SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete + FROM schemapool; +} {nref=5 nschema=1 ndelete=0} + +do_execsql_test 4.2.2 { + CREATE TEMP TABLE t1(a, b, c); + SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete + FROM schemapool; +} {nref=5 nschema=1 ndelete=0} + +do_execsql_test 4.2.3 { + CREATE INDEX t1a ON t1(a); + SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete + FROM schemapool; +} {nref=5 nschema=1 ndelete=0} + +do_execsql_test 4.2.4 { + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + SELECT 1,2,3,4; + END; + SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete + FROM schemapool; +} {nref=5 nschema=1 ndelete=0} + +do_execsql_test 4.2.5 { + DROP TABLE t1; + SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete + FROM schemapool; +} {nref=5 nschema=1 ndelete=0} + +do_execsql_test 4.2.6 { + CREATE TEMP TRIGGER tr1 AFTER INSERT ON db2.x1 BEGIN + SELECT 1,2,3,4; + END; + SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete + FROM schemapool; +} {nref=5 nschema=1 ndelete=0} + +do_execsql_test 4.2.7 { + DROP TRIGGER tr1; + SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete + FROM schemapool; +} {nref=5 nschema=1 ndelete=4} + + finish_test diff --git a/tool/cg_anno.tcl b/tool/cg_anno.tcl index 43d2b74fcd..3566d87782 100755 --- a/tool/cg_anno.tcl +++ b/tool/cg_anno.tcl @@ -1,5 +1,6 @@ -#!/usr/bin/tclsh -# +#!/bin/sh +# \ +exec tclsh "$0" ${1+"$@"} # A wrapper around cg_annotate that sets appropriate command-line options # and rearranges the output so that annotated files occur in a consistent # sorted order. Used by the speed-check.tcl script.