]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem with virtual tables in shared schemas.
authordan <dan@noemail.net>
Mon, 19 Nov 2018 20:41:26 +0000 (20:41 +0000)
committerdan <dan@noemail.net>
Mon, 19 Nov 2018 20:41:26 +0000 (20:41 +0000)
FossilOrigin-Name: 84be9220db4adaf4873cf38d7259a321900608d63be4d08603e74f8b7ae120ac

13 files changed:
manifest
manifest.uuid
src/alter.c
src/build.c
src/delete.c
src/insert.c
src/pragma.c
src/select.c
src/sqliteInt.h
src/update.c
src/vtab.c
src/where.c
src/whereexpr.c

index caef7c6d3c201c2206a1905b5332877dd477c0cd..81da51bb484f973667aa7052629bc6f4323b5b30 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sanother\sname\sresolution\sproblem\soccurring\swhen\stwo\sor\smore\sattached\ndatabases\suse\sthe\ssame\sSchema\sobject.
-D 2018-11-17T19:15:25.212
+C Fix\sa\sproblem\swith\svirtual\stables\sin\sshared\sschemas.
+D 2018-11-19T20:41:26.113
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in b730006b54c990461d864c5387f2e6f13aadb0236804555fb010ed6865a5f058
@@ -440,7 +440,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c ab7f9763c0c422d1944d2cfdf52ddf971b88d44b13e58639835964ffc8c286d0
+F src/alter.c 3e283b5726186d72fa67c972487e2cd5898def7a2e891953c937e3f1b535e5aa
 F src/analyze.c 09c9684253a328735c63f714e1c50360e977b4020b7b1325d11dd46f2f192123
 F src/attach.c 92b51739a885da8bd84bc9a05485f1e48148bce5c15432f059b45af98fff75cd
 F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df
@@ -450,14 +450,14 @@ F src/btmutex.c aeee7f0458949b8d4a33ffc1a5c4f4a28dd7d5d754385096cb9494655afba02b
 F src/btree.c 3ef104ecae8b1b5f0458be1f5fa7c1ecf25fdc322a9d63bb8151f89eb32d381e
 F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
-F src/build.c 20c584fc7da90631f2028cd281c033cb19b3fadde3071334d9114b0419ba395f
+F src/build.c 6ef4b77f666dc68afa79aba8a5dc65faf9cdb85a6c3ccf64cbce5db6a8a43307
 F src/callback.c e5031c28f6e8eb2f290298e262eb1eb5f201ef2ae25db54b396882ae2059e944
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
 F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
 F src/dbstat.c 3c8bd4e77f0244fd2bd7cc90acf116ad2f8e82d70e536637f35ac2bc99b726f9
-F src/delete.c 4a49ac22abb8b88a4c323af87e67289e4e802ebf336d745733e930bf928c0b80
+F src/delete.c 326f92e69ffc35e2006f9498b0fc7e1ff6acdb28c6848a4b75c204a51320a2ca
 F src/expr.c ddbc6be9e14869cce303f7a9ceed281e018b08762be9603c07eb1152ad85a8c5
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 2c112c00667b3c4668023a000489261d5b72441c67f969b526a1af831d297d96
@@ -467,7 +467,7 @@ F src/hash.c 931ec82d7e070654a8facb42549bbb3a25720171d73ba94c3d3160580d01ef1f
 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c bf2717516bc3fb395f488cd42975a2c3a5badbca8c84425f9c2c32c7b85f0a4e
+F src/insert.c 1b72e96ae672c512e8e680594f13ef00d08e6fdd65ac845fa5a445579bf7af37
 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
 F src/loadext.c 448eab53ecdb566a1259ee2d45ebff9c0bc4a2cf393774488775c33e4fbe89bf
 F src/main.c 63ec9559c244c7e10eafc0efe0f66387fc40b8683ba20aeb0422e334f4eb0a52
@@ -499,19 +499,19 @@ F src/parse.y 6840fe7c0b5eb4dd25ee5d075213bc8255ed4c0678d71bfb6744d0520d91c179
 F src/pcache.c 4196eb6ed3bbf00b80596c8e0b4f50e57eb7d890c19fb27a7354306abb7f983d
 F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
-F src/pragma.c 705cffb85e319dc2dcb6ae862e93ed84941237b4e923f2b76c99dc92bc04cec2
+F src/pragma.c 1c96a1f32407caf1854a5525fc2fcd6228ba4dd44bd20abe8a86d1ab830931fc
 F src/pragma.h fdd03d78a7497f74a3f652909f945328480089189526841ae829ce7313d98d13
 F src/prepare.c b64a19ee9b0ba1f3a67c4f5d1be308e9f67f8fb07fe90725982dfa9b616d211f
 F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c d6580c08986e4b42bfc88b37a792ba116b55cc3b8c2e9d42233e453c7a579bed
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
-F src/select.c eabefcb57edafcac6baeaec83289816e9409a23957b5a2d3efe1265f597ce6bd
+F src/select.c 594fd2e0a13c25921b59898874a494263f6aeb47f136aa9fcb53f0cfc6f159cd
 F src/shell.c.in 91ccfc85bcd28015c5db01449275e7fba3e9f97aa2533b53b73e81906eebaac0
 F src/sqlite.h.in 3baffc1c299e0c10dc63f31ce4b322d14548dae6ac73b0719ba505b37966bac3
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
-F src/sqliteInt.h f677e57fdcfe2a165133494bd0c210c9ab464e3f14a620f1d81b96b38885bfd6
+F src/sqliteInt.h aae85408ebe7cd65ffb6ca3365fd086c1f52e3e73149fe9df16685dd68cc3a70
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c b651e68af3cb859e4083c79e0e7177e2aeb35ed23e3892d7bbe5b732d38bf2b9
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -572,7 +572,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c 9e781e1ca80eefe7b5d6a9e2cd5c678c847da55fd6f093781fad7950934d4c83
 F src/treeview.c 7b12ac059de54c939b6eb0dbffc9410c29c80d2470cee5cbe07d5ff9ea2d9253
 F src/trigger.c dc20aaa75197d06cef02529cc97bada3d3e830065828b693f66c00754863724a
-F src/update.c 336eec2af108be3203c7ea174ca7cc17d13fd67a3c5b23c0164190b6eaaede3e
+F src/update.c 6659f40af73ac786b788b35c98038579052a80bcd8784b79dfd33a6710a0a6bc
 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
@@ -586,15 +586,15 @@ F src/vdbeblob.c 377746310196c8c1751049349716630ef3e4df54d1f08f863009b70971f5294
 F src/vdbemem.c 7b3305bc4a5139f4536ac9b5f61da0f915e49d2e3fdfa87dfdfa9d7aba8bc1e9
 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
-F src/vtab.c df409cbabcb98568981da6f3b6ae5465fc82da6f213bbdbb535a25714836b7e6
+F src/vtab.c bad08f463f8aa4bb86e9e2be322394bbe23b02db8cc6843d038306ccef831676
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c 3f4f653daf234fe713edbcbca3fec2350417d159d28801feabc702a22c4e213f
 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
 F src/walker.c fb94aadc9099ff9c6506d0a8b88d51266005bcaa265403f3d7caf732a562eb66
-F src/where.c 0248d4467925d14796099e21c2d31a78e5521ac54d5a8e8dd08e2dab777ca617
+F src/where.c 9cf0501bb13f9ba6e3135d38d83dd55ce4772a298a9686b84c8ce02402591fed
 F src/whereInt.h f125f29fca80890768e0b2caa14f95db74b2dacd3a122a168f97aa7b64d6968f
 F src/wherecode.c c45f03aefc2266b990df0fc4d7acc4e27f56f881f4fc0fc355b7cbc4d7189da5
-F src/whereexpr.c 491f0894ad9903750cdecb7894437a0cabdffdd88f574d2b1c9ac85d14fe4b9c
+F src/whereexpr.c 833b58f9d34fa8118bf671b695a9929028707e13bf7e16e932d80c9c64d5f0a3
 F src/window.c 6550e2850ebced51100ef83d49b00a1cf03f81a482dafedafb0320df647ed8fc
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -1779,7 +1779,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 9fdd186897abea8ebfe575b9b3ce705033a06b2b00b50beb54ebaf892543c227
-R 0695924c22f471777454311c14501bdb
+P 5328f89951b34c9543a7289efd830acb252422a976819eadd036725c1553ec0f
+R 464926b3663738e00ae8bff21674de23
 U dan
-Z 30566e13df9b2aa78f25523eaa391d30
+Z 562020b0df1fe8643da9b450b53b8ef5
index 98ecea408aad2c0963050603a4bf587f1ac1d6fb..978a74c8923e7fd3b2c1f558e5272dc55b60fd48 100644 (file)
@@ -1 +1 @@
-5328f89951b34c9543a7289efd830acb252422a976819eadd036725c1553ec0f
\ No newline at end of file
+84be9220db4adaf4873cf38d7259a321900608d63be4d08603e74f8b7ae120ac
\ No newline at end of file
index 1816bc424e062f238fa04904ab3dd5a81ab4c922..ed781f8533b5485ec5605a464ae5ff9c287dc39e 100644 (file)
@@ -148,11 +148,11 @@ void sqlite3AlterRenameTable(
 #endif
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+  if( sqlite3ViewGetColumnNames(pParse, iDb, pTab) ){
     goto exit_rename_table;
   }
   if( IsVirtual(pTab) ){
-    pVTab = sqlite3GetVTable(db, pTab);
+    pVTab = sqlite3GetVTable(db, -1, pTab);
     if( pVTab->pVtab->pModule->xRename==0 ){
       pVTab = 0;
     }
@@ -1064,7 +1064,8 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
   /* ALWAYS() because if the table of the trigger does not exist, the
   ** error would have been hit before this point */
   if( ALWAYS(pParse->pTriggerTab) ){
-    rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
+    int iDb = sqlite3SchemaToIndex2(db, pParse->pTriggerTab->pSchema, 0);
+    rc = sqlite3ViewGetColumnNames(pParse, iDb, pParse->pTriggerTab);
   }
 
   /* Resolve symbols in WHEN clause */
@@ -1081,38 +1082,41 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
       Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb);
       if( pTarget==0 ){
         rc = SQLITE_ERROR;
-      }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){
-        SrcList sSrc;
-        memset(&sSrc, 0, sizeof(sSrc));
-        sSrc.nSrc = 1;
-        sSrc.a[0].zName = pStep->zTarget;
-        sSrc.a[0].pTab = pTarget;
-        sNC.pSrcList = &sSrc;
-        if( pStep->pWhere ){
-          rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
-        }
-        if( rc==SQLITE_OK ){
-          rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
-        }
-        assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
-        if( pStep->pUpsert ){
-          Upsert *pUpsert = pStep->pUpsert;
-          assert( rc==SQLITE_OK );
-          pUpsert->pUpsertSrc = &sSrc;
-          sNC.uNC.pUpsert = pUpsert;
-          sNC.ncFlags = NC_UUpsert;
-          rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
-          if( rc==SQLITE_OK ){
-            ExprList *pUpsertSet = pUpsert->pUpsertSet;
-            rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
+      }else{
+        int iDb = sqlite3SchemaToIndex2(db, pTarget->pSchema, 0);
+        if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, iDb, pTarget)) ){
+          SrcList sSrc;
+          memset(&sSrc, 0, sizeof(sSrc));
+          sSrc.nSrc = 1;
+          sSrc.a[0].zName = pStep->zTarget;
+          sSrc.a[0].pTab = pTarget;
+          sNC.pSrcList = &sSrc;
+          if( pStep->pWhere ){
+            rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
           }
           if( rc==SQLITE_OK ){
-            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere);
+            rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
           }
-          if( rc==SQLITE_OK ){
-            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
+          assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
+          if( pStep->pUpsert ){
+            Upsert *pUpsert = pStep->pUpsert;
+            assert( rc==SQLITE_OK );
+            pUpsert->pUpsertSrc = &sSrc;
+            sNC.uNC.pUpsert = pUpsert;
+            sNC.ncFlags = NC_UUpsert;
+            rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
+            if( rc==SQLITE_OK ){
+              ExprList *pUpsertSet = pUpsert->pUpsertSet;
+              rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
+            }
+            if( rc==SQLITE_OK ){
+              rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere);
+            }
+            if( rc==SQLITE_OK ){
+              rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
+            }
+            sNC.ncFlags = 0;
           }
-          sNC.ncFlags = 0;
         }
       }
     }
index c2c2e651f610386e2b94b4489cc0688463a9b649..263669720d0b7223bbfdb422d76cfc6b34af2cad 100644 (file)
@@ -191,7 +191,7 @@ void sqlite3FinishCoding(Parse *pParse){
       }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
       for(i=0; i<pParse->nVtabLock; i++){
-        char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
+        char *vtab = (char *)pParse->apVtabLock[i];
         sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
       }
       pParse->nVtabLock = 0;
@@ -2277,7 +2277,7 @@ create_view_fail:
 ** the columns of the view in the pTable structure.  Return the number
 ** of errors.  If an error is seen leave an error message in pParse->zErrMsg.
 */
-int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
+int sqlite3ViewGetColumnNames(Parse *pParse, int iDb, Table *pTable){
   Table *pSelTab;   /* A fake table from which we get the result set */
   Select *pSel;     /* Copy of the SELECT that implements the view */
   int nErr = 0;     /* Number of errors encountered */
@@ -2294,7 +2294,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   db->nSchemaLock++;
-  rc = sqlite3VtabCallConnect(pParse, pTable);
+  rc = sqlite3VtabCallConnect(pParse, iDb, pTable);
   db->nSchemaLock--;
   if( rc ){
     return 1;
@@ -2675,7 +2675,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
   /* If pTab is a virtual table, call ViewGetColumnNames() to ensure
   ** it is initialized.
   */
-  if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){
+  if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, iDb, pTab) ){
     goto exit_drop_table;
   }
 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -2696,7 +2696,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     }else if( IsVirtual(pTab) ){
       code = SQLITE_DROP_VTABLE;
-      zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName;
+      zArg2 = sqlite3GetVTable(db, -1, pTab)->pMod->zName;
 #endif
     }else{
       if( !OMIT_TEMPDB && iDb==1 ){
index 05f730cb40624f9814ff963b4ed14d94a7cce929..a3dd70d0462383b731c86626ed741aac6c59a3c4 100644 (file)
@@ -62,7 +62,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
 static int tabIsReadOnly(Parse *pParse, Table *pTab){
   sqlite3 *db;
   if( IsVirtual(pTab) ){
-    return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
+    return sqlite3GetVTable(pParse->db, -1, pTab)->pMod->pModule->xUpdate==0;
   }
   if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
   db = pParse->db;
@@ -318,17 +318,17 @@ void sqlite3DeleteFrom(
   }
 #endif
 
+  iDb = sqlite3SchemaToIndex2(db, pTab->pSchema, pTabList->a[0].zDatabase);
+  assert( iDb<db->nDb );
+
   /* If pTab is really a view, make sure it has been initialized.
   */
-  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+  if( sqlite3ViewGetColumnNames(pParse, iDb, pTab) ){
     goto delete_from_cleanup;
   }
-
   if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
     goto delete_from_cleanup;
   }
-  iDb = sqlite3SchemaToIndex2(db, pTab->pSchema, pTabList->a[0].zDatabase);
-  assert( iDb<db->nDb );
   rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, 
                             db->aDb[iDb].zDbSName);
   assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
@@ -563,8 +563,8 @@ void sqlite3DeleteFrom(
     /* Delete the row */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     if( IsVirtual(pTab) ){
-      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
-      sqlite3VtabMakeWritable(pParse, pTab);
+      const char *pVTab = (const char *)sqlite3GetVTable(db, iDb, pTab);
+      sqlite3VtabMakeWritable(pParse, iDb, pTab);
       assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
       sqlite3MayAbort(pParse);
       if( eOnePass==ONEPASS_SINGLE ){
index d9901b6aa1cf501c611b27995d4ad55ffa23f165..12347e6d592a30664e7023bf4efac194f6ffb32d 100644 (file)
@@ -168,7 +168,7 @@ static int readsTable(Parse *p, int iDb, Table *pTab){
   int i;
   int iEnd = sqlite3VdbeCurrentAddr(v);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
+  VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, iDb, pTab) : 0;
 #endif
 
   for(i=1; i<iEnd; i++){
@@ -596,7 +596,7 @@ void sqlite3Insert(
   /* If pTab is really a view, make sure it has been initialized.
   ** ViewGetColumnNames() is a no-op if pTab is not a view.
   */
-  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+  if( sqlite3ViewGetColumnNames(pParse, iDb, pTab) ){
     goto insert_cleanup;
   }
 
@@ -1027,8 +1027,8 @@ void sqlite3Insert(
     */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     if( IsVirtual(pTab) ){
-      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
-      sqlite3VtabMakeWritable(pParse, pTab);
+      const char *pVTab = (const char *)sqlite3GetVTable(db, iDb, pTab);
+      sqlite3VtabMakeWritable(pParse, iDb, pTab);
       sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
       sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
       sqlite3MayAbort(pParse);
index 2d16bb362fea73ef2795712304d13f6dd787bc4b..575dca5999a20a6264d59a0cf15f6025e8ca96f3 100644 (file)
@@ -1088,11 +1088,12 @@ void sqlite3Pragma(
     if( pTab ){
       int i, k;
       int nHidden = 0;
+      int iTabDb = sqlite3SchemaToIndex2(db, pTab->pSchema, zDb);
       Column *pCol;
       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
       pParse->nMem = 7;
-      sqlite3CodeVerifySchema(pParse, iDb);
-      sqlite3ViewGetColumnNames(pParse, pTab);
+      sqlite3CodeVerifySchema(pParse, iTabDb);
+      sqlite3ViewGetColumnNames(pParse, iTabDb, pTab);
       for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
         int isHidden = IsHiddenColumn(pCol);
         if( isHidden && pPragma->iArg==0 ){
index c02b282274ebc8047a567ee01ebe2a1f11dae3db..0bdc276904fae2398b40bb04b04ff37723923029 100644 (file)
@@ -4888,10 +4888,9 @@ static int selectExpander(Walker *pWalker, Select *p){
       if( IsVirtual(pTab) || pTab->pSelect ){
         int iSave = pParse->iFixDb;
         i16 nCol;
-        pParse->iFixDb = 1 + sqlite3SchemaToIndex2(
-            db, pTab->pSchema, pFrom->zDatabase
-        );
-        if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+        int iDb = sqlite3SchemaToIndex2(db, pTab->pSchema, pFrom->zDatabase);
+        pParse->iFixDb = 1 + iDb;
+        if( sqlite3ViewGetColumnNames(pParse, iDb, pTab) ){
           pParse->iFixDb = iSave;
           return WRC_Abort;
         }
index 4740a5c45785bdf037a0e030c70737dd19329d9b..e2f720e92fc37c918975d8876a30737ae413a5cc 100644 (file)
@@ -1941,7 +1941,8 @@ struct CollSeq {
 ** the first argument.
 */
 struct VTable {
-  sqlite3 *db;              /* Database connection associated with this table */
+  sqlite3 *db;              /* Database that owns this virtual table */
+  Btree *pBt;               /* Btree backend associated with this table */
   Module *pMod;             /* Pointer to module implementation */
   sqlite3_vtab *pVtab;      /* Pointer to vtab instance */
   int nRef;                 /* Number of pointers to this structure */
@@ -3137,7 +3138,7 @@ struct Parse {
   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   Token sArg;               /* Complete text of a module argument */
-  Table **apVtabLock;       /* Pointer to virtual tables needing locking */
+  VTable **apVtabLock;      /* Pointer to virtual tables needing locking */
 #endif
   Table *pZombieTab;        /* List of Table objects to delete after code gen */
   TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
@@ -3898,9 +3899,9 @@ int sqlite3RowSetNext(RowSet*, i64*);
 void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int);
 
 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
-  int sqlite3ViewGetColumnNames(Parse*,Table*);
+  int sqlite3ViewGetColumnNames(Parse*,int,Table*);
 #else
-# define sqlite3ViewGetColumnNames(A,B) 0
+# define sqlite3ViewGetColumnNames(A,B,C) 0
 #endif
 
 #if SQLITE_MAX_ATTACHED>30
@@ -4390,7 +4391,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
 #  define sqlite3VtabUnlock(X)
 #  define sqlite3VtabUnlockList(X)
 #  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
-#  define sqlite3GetVTable(X,Y)  ((VTable*)0)
+#  define sqlite3GetVTable(X,Y,Z)  ((VTable*)0)
 #else
    void sqlite3VtabClear(sqlite3 *db, Table*);
    void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
@@ -4402,7 +4403,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
    void sqlite3VtabUnlockList(sqlite3*);
    int sqlite3VtabSavepoint(sqlite3 *, int, int);
    void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
-   VTable *sqlite3GetVTable(sqlite3*, Table*);
+   VTable *sqlite3GetVTable(sqlite3*, int, Table*);
    Module *sqlite3VtabCreateModule(
      sqlite3*,
      const char*,
@@ -4414,13 +4415,13 @@ void sqlite3AutoLoadExtensions(sqlite3*);
 #endif
 int sqlite3VtabEponymousTableInit(Parse*,Module*);
 void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
-void sqlite3VtabMakeWritable(Parse*,Table*);
+void sqlite3VtabMakeWritable(Parse*,int,Table*);
 void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
 void sqlite3VtabFinishParse(Parse*, Token*);
 void sqlite3VtabArgInit(Parse*);
 void sqlite3VtabArgExtend(Parse*, Token*);
 int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
-int sqlite3VtabCallConnect(Parse*, Table*);
+int sqlite3VtabCallConnect(Parse*, int, Table*);
 int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
 int sqlite3VtabBegin(sqlite3 *, VTable *);
 FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
index c48066a77da20f4cc9ba9f4e774fc4d299c6d6d4..14f110b46d0d79d920f27487606b26783f5fd60c 100644 (file)
@@ -18,6 +18,7 @@
 /* Forward declaration */
 static void updateVirtualTable(
   Parse *pParse,       /* The parsing context */
+  int iDb,
   SrcList *pSrc,       /* The virtual table to be modified */
   Table *pTab,         /* The virtual table */
   ExprList *pChanges,  /* The columns to change in the UPDATE statement */
@@ -240,7 +241,7 @@ void sqlite3Update(
   }
 #endif
 
-  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+  if( sqlite3ViewGetColumnNames(pParse, iDb, pTab) ){
     goto update_cleanup;
   }
   if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
@@ -434,7 +435,7 @@ void sqlite3Update(
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   /* Virtual tables must be handled separately */
   if( IsVirtual(pTab) ){
-    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
+    updateVirtualTable(pParse, iDb, pTabList, pTab, pChanges, pRowidExpr, aXRef,
                        pWhere, onError);
     goto update_cleanup;
   }
@@ -869,6 +870,7 @@ update_cleanup:
 */
 static void updateVirtualTable(
   Parse *pParse,       /* The parsing context */
+  int iDb,
   SrcList *pSrc,       /* The virtual table to be modified */
   Table *pTab,         /* The virtual table */
   ExprList *pChanges,  /* The columns to change in the UPDATE statement */
@@ -881,7 +883,7 @@ static void updateVirtualTable(
   int ephemTab;             /* Table holding the result of the SELECT */
   int i;                    /* Loop counter */
   sqlite3 *db = pParse->db; /* Database connection */
-  const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
+  const char *pVTab = (const char*)sqlite3GetVTable(db, iDb, pTab);
   WhereInfo *pWInfo;
   int nArg = 2 + pTab->nCol;      /* Number of arguments to VUpdate */
   int regArg;                     /* First register in VUpdate arg array */
@@ -972,7 +974,7 @@ static void updateVirtualTable(
       sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i);
     }
   }
-  sqlite3VtabMakeWritable(pParse, pTab);
+  sqlite3VtabMakeWritable(pParse, iDb, pTab);
   sqlite3VdbeAddOp4(v, OP_VUpdate, 0, nArg, regArg, pVTab, P4_VTAB);
   sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
   sqlite3MayAbort(pParse);
index 27317806cc64114643274b51294a11084550bed8..b392f70c341674b5be8098ec64322e8e6e3c5014 100644 (file)
@@ -141,10 +141,15 @@ void sqlite3VtabLock(VTable *pVTab){
 ** Return a pointer to the VTable object used by connection db to access 
 ** this virtual-table, if one has been created, or NULL otherwise.
 */
-VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
+VTable *sqlite3GetVTable(sqlite3 *db, int iDb, Table *pTab){
   VTable *pVtab;
   assert( IsVirtual(pTab) );
-  for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
+  if( iDb>=0 ){
+    Btree *pBt = db->aDb[iDb].pBt;
+    for(pVtab=pTab->pVTable; pVtab && pVtab->pBt!=pBt; pVtab=pVtab->pNext);
+  }else{
+    for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
+  }
   return pVtab;
 }
 
@@ -218,17 +223,19 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
 */
 void sqlite3VtabDisconnect(sqlite3 *db, Table *p){
   VTable **ppVTab;
+  VTable **ppNext;
 
   assert( IsVirtual(p) );
   assert( sqlite3BtreeHoldsAllMutexes(db) );
   assert( sqlite3_mutex_held(db->mutex) );
 
-  for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){
+  for(ppVTab=&p->pVTable; *ppVTab; ){
     if( (*ppVTab)->db==db  ){
       VTable *pVTab = *ppVTab;
       *ppVTab = pVTab->pNext;
       sqlite3VtabUnlock(pVTab);
-      break;
+    }else{
+      ppVTab = &(*ppVTab)->pNext;
     }
   }
 }
@@ -494,6 +501,7 @@ void sqlite3VtabArgExtend(Parse *pParse, Token *p){
 */
 static int vtabCallConstructor(
   sqlite3 *db, 
+  int iDb,                        /* Database containing pTab */
   Table *pTab,
   Module *pMod,
   int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
@@ -506,7 +514,6 @@ static int vtabCallConstructor(
   int nArg = pTab->nModuleArg;
   char *zErr = 0;
   char *zModuleName;
-  int iDb;
   VtabCtx *pCtx;
 
   /* Check that the virtual-table is not already being initialized */
@@ -531,9 +538,9 @@ static int vtabCallConstructor(
     return SQLITE_NOMEM_BKPT;
   }
   pVTable->db = db;
+  pVTable->pBt = db->aDb[iDb].pBt;
   pVTable->pMod = pMod;
 
-  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   pTab->azModuleArg[1] = db->aDb[iDb].zDbSName;
 
   /* Invoke the virtual table constructor */
@@ -622,14 +629,14 @@ static int vtabCallConstructor(
 **
 ** This call is a no-op if table pTab is not a virtual table.
 */
-int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
+int sqlite3VtabCallConnect(Parse *pParse, int iDb, Table *pTab){
   sqlite3 *db = pParse->db;
   const char *zMod;
   Module *pMod;
   int rc;
 
   assert( pTab );
-  if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
+  if( !IsVirtual(pTab) || sqlite3GetVTable(db, iDb, pTab) ){
     return SQLITE_OK;
   }
 
@@ -643,7 +650,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
     rc = SQLITE_ERROR;
   }else{
     char *zErr = 0;
-    rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
+    rc = vtabCallConstructor(db, iDb, pTab, pMod,pMod->pModule->xConnect,&zErr);
     if( rc!=SQLITE_OK ){
       sqlite3ErrorMsg(pParse, "%s", zErr);
       pParse->rc = rc;
@@ -714,15 +721,15 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
     *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
     rc = SQLITE_ERROR;
   }else{
-    rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
+    rc = vtabCallConstructor(db, iDb, pTab, pMod, pMod->pModule->xCreate,pzErr);
   }
 
   /* Justification of ALWAYS():  The xConstructor method is required to
   ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
-  if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
+  if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, iDb, pTab)) ){
     rc = growVTrans(db);
     if( rc==SQLITE_OK ){
-      addToVTrans(db, sqlite3GetVTable(db, pTab));
+      addToVTrans(db, sqlite3GetVTable(db, iDb, pTab));
     }
   }
 
@@ -1055,7 +1062,7 @@ FuncDef *sqlite3VtabOverloadFunction(
   pTab = pExpr->y.pTab;
   if( pTab==0 ) return pDef;
   if( !IsVirtual(pTab) ) return pDef;
-  pVtab = sqlite3GetVTable(db, pTab)->pVtab;
+  pVtab = sqlite3GetVTable(db, -1, pTab)->pVtab;
   assert( pVtab!=0 );
   assert( pVtab->pModule!=0 );
   pMod = (sqlite3_module *)pVtab->pModule;
@@ -1104,20 +1111,21 @@ FuncDef *sqlite3VtabOverloadFunction(
 ** array if it is missing.  If pTab is already in the array, this routine
 ** is a no-op.
 */
-void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
+void sqlite3VtabMakeWritable(Parse *pParse, int iDb, Table *pTab){
   Parse *pToplevel = sqlite3ParseToplevel(pParse);
+  VTable *pVTab = sqlite3GetVTable(pParse->db, iDb, pTab);
   int i, n;
-  Table **apVtabLock;
+  VTable **apVtabLock;
 
   assert( IsVirtual(pTab) );
   for(i=0; i<pToplevel->nVtabLock; i++){
-    if( pTab==pToplevel->apVtabLock[i] ) return;
+    if( pVTab==pToplevel->apVtabLock[i] ) return;
   }
   n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
   apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
   if( apVtabLock ){
     pToplevel->apVtabLock = apVtabLock;
-    pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
+    pToplevel->apVtabLock[pToplevel->nVtabLock++] = pVTab;
   }else{
     sqlite3OomFault(pToplevel->db);
   }
@@ -1160,7 +1168,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
   addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
   addModuleArgument(db, pTab, 0);
   addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
-  rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
+  rc = vtabCallConstructor(db, 0, pTab, pMod, pModule->xConnect, &zErr);
   if( rc ){
     sqlite3ErrorMsg(pParse, "%s", zErr);
     sqlite3DbFree(db, zErr);
index 49eda97853f3a67a4753879c8b5c6ea8834896af..e61e62ec6b2e98cf04a9458d831a17730b600c7b 100644 (file)
@@ -1041,8 +1041,14 @@ static sqlite3_index_info *allocateIndexInfo(
 ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
 ** that this is required.
 */
-static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
-  sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
+static int vtabBestIndex(
+  Parse *pParse, 
+  struct SrcList_item *pSrc, 
+  sqlite3_index_info *p
+){
+  Table *pTab = pSrc->pTab;
+  int iDb = sqlite3SchemaToIndex2(pParse->db, pTab->pSchema, pSrc->zDatabase);
+  sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, iDb, pTab)->pVtab;
   int rc;
 
   TRACE_IDX_INPUTS(p);
@@ -3132,7 +3138,7 @@ static int whereLoopAddVirtualOne(
   pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
 
   /* Invoke the virtual table xBestIndex() method */
-  rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
+  rc = vtabBestIndex(pParse, pSrc, pIdxInfo);
   if( rc ){
     if( rc==SQLITE_CONSTRAINT ){
       /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
@@ -4949,7 +4955,7 @@ WhereInfo *sqlite3WhereBegin(
     }else
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
-      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
+      const char *pVTab = (const char *)sqlite3GetVTable(db, iDb, pTab);
       int iCur = pTabItem->iCursor;
       sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
     }else if( IsVirtual(pTab) ){
index dbb7f0d08e2cace4f29a0fb9212de2f07e16c6b5..d444d8c5e2d8a28f70ff22fa307ef35fee41d20b 100644 (file)
@@ -409,7 +409,7 @@ static int isAuxiliaryVtabOperator(
       sqlite3_module *pMod;
       void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
       void *pNotUsed;
-      pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
+      pVtab = sqlite3GetVTable(db, -1, pCol->y.pTab)->pVtab;
       assert( pVtab!=0 );
       assert( pVtab->pModule!=0 );
       pMod = (sqlite3_module *)pVtab->pModule;