From: dan Date: Sat, 9 Feb 2019 17:47:14 +0000 (+0000) Subject: Fix virtual table support for SQLITE_OPEN_REUSABLE_SCHEMA connections. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5add6f25e2bc7516356348e8e0687b5d34ca3fc3;p=thirdparty%2Fsqlite.git Fix virtual table support for SQLITE_OPEN_REUSABLE_SCHEMA connections. FossilOrigin-Name: 3ca8856a7b1c36885cea007b8fb05b59f1fdc9d4b54436819193f498519a23c7 --- diff --git a/manifest b/manifest index 6928642f3e..963a935655 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sand\sfix\sproblems\son\sthis\sbranch. -D 2019-02-08T19:30:09.365 +C Fix\svirtual\stable\ssupport\sfor\sSQLITE_OPEN_REUSABLE_SCHEMA\sconnections. +D 2019-02-09T17:47:14.573 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 178d8eb6840771149cee40b322d1b3be30d330198c522c903c1b66fb5a1bfca4 @@ -459,7 +459,7 @@ F src/btree.c 84b7c5c3829b60823e15e7a8407462b69be3818f96518fef28f97ac0fbbca72b F src/btree.h 63b94fb38ce571c15eb6a3661815561b501d23d5948b2d1e951fbd7a2d04e8d3 F src/btreeInt.h cd82f0f08886078bf99b29e1a7045960b1ca5d9d5829c38607e1299c508eaf00 F src/build.c 5c99b58734e8a5ddb94b1f5734b550d91a762926d11094067aeb5e85da0541bf -F src/callback.c b7a60c23069922009e08cfea99fb97fea93a1d67fd59bf3360b01cc5355937f7 +F src/callback.c 6d9504d0d3c0af2e288d001b1077ba6ab924e3758b4cbf7bb358693e3855dd7b F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 @@ -478,7 +478,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3ed9ceaa4b7d56a6f2613355e1cd1ae5cfe31712bce2bf5aa93c5f1f130704b2 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c e6f10875d52aca3b7e57ce1ec174aeafc9b6c00b43000cd30d791f9cb490b7a6 -F src/main.c fcd4375915d94fcdfe710510ad112f4845d40dfaf8de5cc82f7f22856a7ee649 +F src/main.c 45866058b9cd1232901b17a76ea81157e87e114facee6686c3bffe696ef35e6a F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -519,7 +519,7 @@ F src/shell.c.in d3c5b1c021dd66b71086c62679bcdaa8cb66521efa74cbdebf55ae19073c578 F src/sqlite.h.in 528af7447d87ca678409b3280faa3905bab5fab265590821b0df0c8bc956e3a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683 -F src/sqliteInt.h 7cd0076d582b6248e3adae6517a8ae5b9319ef90e24bb145cc3e986a68d113bd +F src/sqliteInt.h 004eb50cdbc3d9ecdd880c415a0ae743673f50e1cf0fbbad8da68d0bdda4d16e F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 41d9cc5d5f9d2a470dcf0a28432c66e25c15b86e51535283e9aef632adf02ac8 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -594,7 +594,7 @@ F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c9419 F src/vdbemem.c 3173f0275cf8643a03ed02084ee56b97fc1a17a2edb5907facec504f59c3172d F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 -F src/vtab.c 79b66d04b97febfe94fbfcb5f6da16849f2fac5fdf8be418ad7b99a0f85702f2 +F src/vtab.c 7d0f847060b3cfe8102b97a8c419866b44d600f2c2ed36e9c13c14c6581dd962 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 3f4f653daf234fe713edbcbca3fec2350417d159d28801feabc702a22c4e213f F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1226,7 +1226,7 @@ F test/releasetest.tcl b290d538ffcb2ff711f09eadc7396c1a42580f3fb078605471dc8875c F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/reuse1.test 34781abbe671ec6858fb5969efadc1b3be1f95a6b46483c227fa6055645a8482 -F test/reuse2.test 39f4a78ddf2d9b1fe3e4131c70497db628cd3a313a4520860b98af2e024bf98d +F test/reuse2.test b17689a33e75c49a79d422cb112c26cbc198f8da412b16422d85a22469ea6e48 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a @@ -1806,7 +1806,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 c089cc4fbe2e5e53d76154146870d14fc3b8d342a49580e41a5616817099715c -R 77a59edee58243bf8d8613a9bd9be0bd +P 2b2e9f81cdc7a3ac1eacc087fbd0414ead732878aae296bab6b54b4a7cd0a06e +R c880c7120bfc1f9326a01d7ac35e8916 U dan -Z e97dab24c9f742264e19dce1e79156e6 +Z c5e2ad0351b6e43deaf12ac670af6294 diff --git a/manifest.uuid b/manifest.uuid index d3006b0bf2..5c31d7c1d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b2e9f81cdc7a3ac1eacc087fbd0414ead732878aae296bab6b54b4a7cd0a06e \ No newline at end of file +3ca8856a7b1c36885cea007b8fb05b59f1fdc9d4b54436819193f498519a23c7 \ No newline at end of file diff --git a/src/callback.c b/src/callback.c index 26239700cf..fdd1cf27e2 100644 --- a/src/callback.c +++ b/src/callback.c @@ -631,11 +631,19 @@ int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){ assert( pDb->pSchema ); if( pSPool==0 ){ + assert( pDb->pVTable==0 ); if( bNew==0 ){ schemaDelete(pDb->pSchema); pDb->pSchema = 0; } }else{ + VTable *p; + VTable *pNext; + for(p=pDb->pVTable; p; p=pNext){ + pNext = p->pNext; + sqlite3VtabUnlock(p); + } + pDb->pVTable = 0; sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); if( DbHasProperty(db, iDb, DB_SchemaLoaded) ){ schemaRelease(pDb); @@ -710,7 +718,7 @@ void sqlite3SchemaReleaseAll(sqlite3 *db){ ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ - Schema * p; + Schema *p; if( pBt && (db->openFlags & SQLITE_OPEN_REUSE_SCHEMA)==0 ){ p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ diff --git a/src/main.c b/src/main.c index 6389413af1..26530a8ea8 100644 --- a/src/main.c +++ b/src/main.c @@ -1054,6 +1054,15 @@ static void disconnectAllVtab(sqlite3 *db){ if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); } } + if( i!=1 && IsReuseSchema(db) ){ + VTable *pVTable; + VTable *pNext; + for(pVTable=db->aDb[i].pVTable; pVTable; pVTable=pNext){ + pNext = pVTable->pNext; + sqlite3VtabUnlock(pVTable); + } + db->aDb[i].pVTable = 0; + } } for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ Module *pMod = (Module *)sqliteHashData(p); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8ef150705c..aaf377002c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1204,6 +1204,7 @@ struct Db { u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */ Schema *pSchema; /* Pointer to database schema (possibly shared) */ SchemaPool *pSPool; /* For REUSE_SCHEMA mode */ + VTable *pVTable; /* List of all VTable objects (REUSE_SCHEMA mode only) */ }; /* @@ -1956,6 +1957,7 @@ struct VTable { u8 bConstraint; /* True if constraints are supported */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ + char *zName; /* Table name (REUSE_SCHEMA mode) */ }; /* diff --git a/src/vtab.c b/src/vtab.c index 8070095a78..07813c5def 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -144,6 +144,15 @@ void sqlite3VtabLock(VTable *pVTab){ VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ VTable *pVtab; assert( IsVirtual(pTab) ); + if( IsReuseSchema(db) ){ + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + if( iDb!=1 ){ + for(pVtab=db->aDb[iDb].pVTable; pVtab; pVtab=pVtab->pNext){ + if( sqlite3StrICmp(pTab->zName, pVtab->zName)==0 ) break; + } + return pVtab; + } + } for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); return pVtab; } @@ -508,6 +517,7 @@ static int vtabCallConstructor( char *zModuleName; int iDb; VtabCtx *pCtx; + int nByte; /* Bytes of space to allocate */ /* Check that the virtual-table is not already being initialized */ for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ @@ -524,7 +534,8 @@ static int vtabCallConstructor( return SQLITE_NOMEM_BKPT; } - pVTable = sqlite3MallocZero(sizeof(VTable)); + nByte = sizeof(VTable) + sqlite3Strlen30(pTab->zName) + 1; + pVTable = (VTable*)sqlite3MallocZero(nByte); if( !pVTable ){ sqlite3OomFault(db); sqlite3DbFree(db, zModuleName); @@ -532,6 +543,8 @@ static int vtabCallConstructor( } pVTable->db = db; pVTable->pMod = pMod; + pVTable->zName = (char*)&pVTable[1]; + memcpy(pVTable->zName, pTab->zName, nByte-sizeof(VTable)); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; @@ -572,12 +585,19 @@ static int vtabCallConstructor( int iCol; u8 oooHidden = 0; /* If everything went according to plan, link the new VTable structure - ** into the linked list headed by pTab->pVTable. Then loop through the - ** columns of the table to see if any of them contain the token "hidden". - ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from - ** the type string. */ - pVTable->pNext = pTab->pVTable; - pTab->pVTable = pVTable; + ** into the linked list headed by pTab->pVTable. Or, if this is a + ** reusable schema, into the linked list headed by Db.pVTable. + ** + ** Then loop through the columns of the table to see if any of them + ** contain the token "hidden". If so, set the Column COLFLAG_HIDDEN flag + ** and remove the token from the type string. */ + if( IsReuseSchema(db) && iDb!=1 ){ + pVTable->pNext = db->aDb[iDb].pVTable; + db->aDb[iDb].pVTable = pVTable; + }else{ + pVTable->pNext = pTab->pVTable; + pTab->pVTable = pVTable; + } for(iCol=0; iColnCol; iCol++){ char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); diff --git a/test/reuse2.test b/test/reuse2.test index 0cc2b05356..1913930d92 100644 --- a/test/reuse2.test +++ b/test/reuse2.test @@ -16,7 +16,6 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse2 - do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z); CREATE INDEX i1 ON t1(z); @@ -42,4 +41,19 @@ do_execsql_test 1.3.3 { SELECT * FROM t1; } {1 2 3 4 5 6} +#-------------------------------------------------------------------------- +reset_db +ifcapable fts5 { + do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft USING fts5(c); + INSERT INTO ft VALUES('one two three'); + } + db close + sqlite3 db test.db -reuse-schema 1 + + do_execsql_test 2.1 { + SELECT * FROM ft + } {{one two three}} +} + finish_test