]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix virtual table support for SQLITE_OPEN_REUSABLE_SCHEMA connections.
authordan <dan@noemail.net>
Sat, 9 Feb 2019 17:47:14 +0000 (17:47 +0000)
committerdan <dan@noemail.net>
Sat, 9 Feb 2019 17:47:14 +0000 (17:47 +0000)
FossilOrigin-Name: 3ca8856a7b1c36885cea007b8fb05b59f1fdc9d4b54436819193f498519a23c7

manifest
manifest.uuid
src/callback.c
src/main.c
src/sqliteInt.h
src/vtab.c
test/reuse2.test

index 6928642f3e764f2f5759085dd456539743e4e9b8..963a935655520ee5b8a89650c3c9ebe09774df62 100644 (file)
--- 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
index d3006b0bf2b3dfa385054a4c0de3392baf03f522..5c31d7c1d990a5c77f33aca42e3b53fa51b4fa35 100644 (file)
@@ -1 +1 @@
-2b2e9f81cdc7a3ac1eacc087fbd0414ead732878aae296bab6b54b4a7cd0a06e
\ No newline at end of file
+3ca8856a7b1c36885cea007b8fb05b59f1fdc9d4b54436819193f498519a23c7
\ No newline at end of file
index 26239700cf78834aa865912b2c88e110c88dc371..fdd1cf27e2cea0cc3ef0319b0cc6d4cf4160347d 100644 (file)
@@ -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{
index 6389413af1f0cf54411b2e81ae9eeb4770ad7cc9..26530a8ea800b8c9828175d5a1eff6a59c46a337 100644 (file)
@@ -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);
index 8ef150705cb14be0f5e40de7fac96653c744e2db..aaf377002c4adb01cba4622a1450fdefd7fbe356 100644 (file)
@@ -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) */
 };
 
 /*
index 8070095a7881e86cc7929d9594a79ac63688e55d..07813c5def2a17854bfd1262dc48b9d62a2e27f7 100644 (file)
@@ -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; iCol<pTab->nCol; iCol++){
         char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
index 0cc2b0535697c904a836137a2dbfa6ec068ec16f..1913930d923675d033bf9f20eb61c218346680e6 100644 (file)
@@ -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