]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Changes to FTS to ensure that it does not access the database from within the xConnec...
authordan <dan@noemail.net>
Wed, 12 Mar 2014 19:20:36 +0000 (19:20 +0000)
committerdan <dan@noemail.net>
Wed, 12 Mar 2014 19:20:36 +0000 (19:20 +0000)
FossilOrigin-Name: c67a52c356416cc200f51f9168d942e78db11d34

ext/fts3/fts3.c
ext/fts3/fts3Int.h
ext/fts3/fts3_write.c
manifest
manifest.uuid
test/fts3d.test

index 44b7f431dfedc4b1d4673ddff208084f5361030d..f7b2232902251fd6898115603a54657e470915b6 100644 (file)
@@ -1410,10 +1410,7 @@ static int fts3InitVtab(
   ** addition of a %_stat table so that it can use incremental merge.
   */
   if( !isFts4 && !isCreate ){
-    int rc2 = SQLITE_OK;
-    fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2",
-               p->zDb, p->zName);
-    if( rc2==SQLITE_OK ) p->bHasStat = 1;
+    p->bHasStat = 2;
   }
 
   /* Figure out the page-size for the database. This is required in order to
@@ -3320,7 +3317,34 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
 }
 
 /*
-** Implementation of xBegin() method. This is a no-op.
+** If it is currently unknown whether or not the FTS table has an %_stat
+** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat
+** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code
+** if an error occurs.
+*/
+static int fts3SetHasStat(Fts3Table *p){
+  int rc = SQLITE_OK;
+  if( p->bHasStat==2 ){
+    const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
+    char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
+    if( zSql ){
+      sqlite3_stmt *pStmt = 0;
+      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+      if( rc==SQLITE_OK ){
+        int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
+        rc = sqlite3_finalize(pStmt);
+        if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
+      }
+      sqlite3_free(zSql);
+    }else{
+      rc = SQLITE_NOMEM;
+    }
+  }
+  return rc;
+}
+
+/*
+** Implementation of xBegin() method. 
 */
 static int fts3BeginMethod(sqlite3_vtab *pVtab){
   Fts3Table *p = (Fts3Table*)pVtab;
@@ -3331,7 +3355,7 @@ static int fts3BeginMethod(sqlite3_vtab *pVtab){
   TESTONLY( p->inTransaction = 1 );
   TESTONLY( p->mxSavepoint = -1; );
   p->nLeafAdd = 0;
-  return SQLITE_OK;
+  return fts3SetHasStat(p);
 }
 
 /*
@@ -3580,6 +3604,10 @@ static int fts3RenameMethod(
   sqlite3 *db = p->db;            /* Database connection */
   int rc;                         /* Return Code */
 
+  /* At this point it must be known if the %_stat table exists or not.
+  ** So bHasStat may not be 2.  */
+  rc = fts3SetHasStat(p);
+  
   /* As it happens, the pending terms table is always empty here. This is
   ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction 
   ** always opens a savepoint transaction. And the xSavepoint() method 
@@ -3587,7 +3615,9 @@ static int fts3RenameMethod(
   ** PendingTermsFlush() in in case that changes.
   */
   assert( p->nPendingData==0 );
-  rc = sqlite3Fts3PendingTermsFlush(p);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3Fts3PendingTermsFlush(p);
+  }
 
   if( p->zContentTbl==0 ){
     fts3DbExec(&rc, db,
index 7f71736888594830848b75539cf6544c702fc2aa..a5bb2f0041bbe2bb8ff0634f156abe9a615d7828 100644 (file)
@@ -223,7 +223,7 @@ struct Fts3Table {
 
   int nNodeSize;                  /* Soft limit for node size */
   u8 bFts4;                       /* True for FTS4, false for FTS3 */
-  u8 bHasStat;                    /* True if %_stat table exists */
+  u8 bHasStat;                    /* True if %_stat table exists (2==unknown) */
   u8 bHasDocsize;                 /* True if %_docsize table exists */
   u8 bDescIdx;                    /* True if doclists are in reverse order */
   u8 bIgnoreSavepoint;            /* True to ignore xSavepoint invocations */
index 3564cf8206da05b3b4adee94e4281e8f14f25ae4..90d1609226b53c75c3ba91e4aa90b663291ef401 100644 (file)
@@ -5271,6 +5271,10 @@ int sqlite3Fts3UpdateMethod(
   int nChng = 0;                  /* Net change in number of documents */
   int bInsertDone = 0;
 
+  /* At this point it must be known if the %_stat table exists or not.
+  ** So bHasStat may not be 2.  */
+  assert( p->bHasStat==0 || p->bHasStat==1 );
+
   assert( p->pSegments==0 );
   assert( 
       nArg==1                     /* DELETE operations */
index 8dd646f40adc8f4d9949c88304fd4270316751f4..313f58078484d2d719a6483b8afddcdec46c5d09 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Prevent\sthe\srtree\smodule\sfrom\sreading\ssqlite_stat1\sdata\sfrom\sthe\swrong\sdatabase.
-D 2014-03-12T12:44:46.777
+C Changes\sto\sFTS\sto\sensure\sthat\sit\sdoes\snot\saccess\sthe\sdatabase\sfrom\swithin\sthe\sxConnect\smethod.
+D 2014-03-12T19:20:36.904
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -78,9 +78,9 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
 F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c 3fe91e36a0304ad4b35020f0e22ff37e95873166
+F ext/fts3/fts3.c 41b1920b9a8657963f09cb93b208c2671c5568db
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1
+F ext/fts3/fts3Int.h bdeb9015405e8facffb8fc7e09174521a2a780f4
 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
 F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac
 F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
@@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
 F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9
 F ext/fts3/fts3_unicode2.c 0113d3acf13429e6dc38e0647d1bc71211c31a4d
-F ext/fts3/fts3_write.c cdebe72171a217b1465032dec103f8d17f7dad4d
+F ext/fts3/fts3_write.c 74c00329006c3ed6325ba4e5ab7c9b5fc99c8934
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
 F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
@@ -535,7 +535,7 @@ F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de
 F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
 F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
 F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
-F test/fts3d.test c8a193513a269ec4c205ca09645e26e0bc71b860
+F test/fts3d.test 597b0b76e41f0d672e2731c4d7b631d628efd13f
 F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963
 F test/fts3defer2.test a3b6cbeabaf28c9398652a4d101ea224d9358479
 F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd
@@ -1156,7 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 018d317b1257ce68a92908b05c9c7cf1494050d0
-R 771148b6f32577641865e57d520a643c
+P 7ce03c1b5552d830300575c5b41a874db7a2ec77
+R deefc2d49a0ad1f14f370fa09b6f4e09
 U dan
-Z 84dfe23ccda2d3e1d846c6ac2ce685a0
+Z 287a2bd2233940be3dc25c35e9cb956e
index b36a223a45ec3cb29d7f1e89d25b4d0777690e5d..1a5538a0a1430a54ed63356a7dd9b9657c559d07 100644 (file)
@@ -1 +1 @@
-7ce03c1b5552d830300575c5b41a874db7a2ec77
\ No newline at end of file
+c67a52c356416cc200f51f9168d942e78db11d34
\ No newline at end of file
index 818456bfae560330c508e928431da1796e3d89b5..2914818d4e1ba46241b45be4d77e59f73a09da39 100644 (file)
@@ -354,6 +354,17 @@ do_test fts3d-6.5 {
     SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
   }
 } {xyz_content xyz_segdir xyz_segments}
+
+# ALTER TABLE RENAME on an FTS3 table following an incr-merge op.
+#
+do_test fts3d-6.6 {
+  execsql { INSERT INTO xyz(xyz) VALUES('merge=2,2') }
+  sqlite3 db test.db
+  execsql { 
+    ALTER TABLE xyz RENAME TO ott;
+    SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
+  }
+} {ott_content ott_segdir ott_segments ott_stat}
  
 
 finish_test