]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further improvements to coverage of fts3.c. Fixes for bugs revealed by the same.
authordan <dan@noemail.net>
Mon, 25 Oct 2010 19:01:25 +0000 (19:01 +0000)
committerdan <dan@noemail.net>
Mon, 25 Oct 2010 19:01:25 +0000 (19:01 +0000)
FossilOrigin-Name: 918b609290127f54326c638d82837d117398eade

ext/fts3/fts3.c
manifest
manifest.uuid
test/fts3cov.test
test/fts3defer.test
test/fts3fault.test [new file with mode: 0644]
test/fts3query.test

index d003cd6a4d0871125e18edf517e26d7dcc4b4226..c9766dafea3baa6094b2b8770e919a2c20e11663 100644 (file)
@@ -560,21 +560,19 @@ static int fts3CreateTables(Fts3Table *p){
   sqlite3 *db = p->db;            /* The database connection */
 
   /* Create a list of user columns for the content table */
-  if( p->bHasContent ){
-    zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
-    for(i=0; zContentCols && i<p->nColumn; i++){
-      char *z = p->azColumn[i];
-      zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
-    }
-    if( zContentCols==0 ) rc = SQLITE_NOMEM;
-
-    /* Create the content table */
-    fts3DbExec(&rc, db, 
-       "CREATE TABLE %Q.'%q_content'(%s)",
-       p->zDb, p->zName, zContentCols
-    );
-    sqlite3_free(zContentCols);
+  zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
+  for(i=0; zContentCols && i<p->nColumn; i++){
+    char *z = p->azColumn[i];
+    zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
   }
+  if( zContentCols==0 ) rc = SQLITE_NOMEM;
+
+  /* Create the content table */
+  fts3DbExec(&rc, db, 
+     "CREATE TABLE %Q.'%q_content'(%s)",
+     p->zDb, p->zName, zContentCols
+  );
+  sqlite3_free(zContentCols);
   /* Create other tables */
   fts3DbExec(&rc, db, 
       "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
@@ -1103,7 +1101,8 @@ static int fts3SelectLeaf(
 
   sqlite3Fts3GetVarint32(zNode, &iHeight);
   rc = fts3ScanInteriorNode(p, zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2);
-  
+  assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );
+
   if( rc==SQLITE_OK && iHeight>1 ){
     char *zBlob = 0;              /* Blob read from %_segments table */
     int nBlob;                    /* Size of zBlob in bytes */
@@ -1118,7 +1117,9 @@ static int fts3SelectLeaf(
       zBlob = 0;
     }
 
-    rc = sqlite3Fts3ReadBlock(p, piLeaf ? *piLeaf : *piLeaf2, &zBlob, &nBlob);
+    if( rc==SQLITE_OK ){
+      rc = sqlite3Fts3ReadBlock(p, piLeaf ? *piLeaf : *piLeaf2, &zBlob, &nBlob);
+    }
     if( rc==SQLITE_OK ){
       rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2);
     }
@@ -1750,7 +1751,7 @@ static int fts3TermSelectMerge(TermSelect *pTS){
       if( !aOut ){
         aOut = pTS->aaOutput[i];
         nOut = pTS->anOutput[i];
-        pTS->aaOutput[0] = 0;
+        pTS->aaOutput[i] = 0;
       }else{
         int nNew = nOut + pTS->anOutput[i];
         char *aNew = sqlite3_malloc(nNew);
@@ -2254,6 +2255,7 @@ static int fts3PhraseSelect(
         nDoc = fts3DoclistCountDocids(1, pOut, nOut);
       }
       isFirst = 0;
+      iPrevTok = iTok;
     }else{
       /* Merge the new term list and the current output. */
       char *aLeft, *aRight;
@@ -2275,6 +2277,7 @@ static int fts3PhraseSelect(
         aRight = pList;
         nRight = nList;
         nDist = iTok-iPrevTok;
+        iPrevTok = iTok;
       }else{
         aRight = pOut;
         nRight = nOut;
@@ -2289,8 +2292,6 @@ static int fts3PhraseSelect(
       sqlite3_free(aLeft);
     }
     assert( nOut==0 || pOut!=0 );
-
-    iPrevTok = iTok;
   }
 
   if( rc==SQLITE_OK ){
index b9ec4a41a4bece52156d04ba5defd569775f45d2..fe6cc27b77c96948610c7e0d002781a051ed4aea 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Test\scoverage\simprovements\sfor\sfts3.c.
-D 2010-10-25T12:47:43
+C Further\simprovements\sto\scoverage\sof\sfts3.c.\sFixes\sfor\sbugs\srevealed\sby\sthe\ssame.
+D 2010-10-25T19:01:25
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2c8cefd962eca0147132c7cf9eaa4bb24c656f3f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -61,7 +61,7 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
 F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c 8a3b4144b604e18a6736eb3a5812d07e5bc2cfef
+F ext/fts3/fts3.c 989ab87071f160f1459359058e629ca00cb13f70
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
 F ext/fts3/fts3Int.h 11fa12ce041bacbc6ac53db127eb0bcc0538af51
 F ext/fts3/fts3_expr.c ee48b9278b8b2432a05a03320fbcacba151dbaa5
@@ -431,16 +431,17 @@ F test/fts3ao.test b83f99f70e9eec85f27d75801a974b3f820e01f9
 F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa
 F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
-F test/fts3cov.test 54cf1f98c72abee246447cd688590898c9ecbaf7
+F test/fts3cov.test a02a9abee9e40a8e964e015e8e76abeacd1ea7e1
 F test/fts3d.test 95fb3c862cbc4297c93fceb9a635543744e9ef52
-F test/fts3defer.test bfd84a3110bf336c3799607c9708e171979736e5
+F test/fts3defer.test 422566346d8f2da95dc5be9b0d3ddae86990240a
 F test/fts3defer2.test 1a9f213ca79509b60d81460febc7e4e5b64af95c
 F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
 F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c
 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
+F test/fts3fault.test c45707ac123b511e4d8291ca3d84e25fd5029b43
 F test/fts3malloc.test 9c8cc3f885bb4dfc66d0460c52f68f45e4710d1b
 F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844
-F test/fts3query.test 464bc03de219f9601d94e37872fae4a763a0e9a8
+F test/fts3query.test 724a662dbbec4e9dbef66a1389588aa29aeb9b27
 F test/fts3rnd.test 707533ce943f490443ce5e696236bb1675a37635
 F test/fts3shared.test 8bb266521d7c5495c0ae522bb4d376ad5387d4a2
 F test/fts3snippet.test a12f22a3ba4dd59751a57c79b031d07ab5f51ddd
@@ -876,7 +877,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 80a54ebc41e4224ab93d92cb390524db1c398155
-R 6df91aa7490a2de6b071469ff6d77a7d
+P a8b1d99899678b72c2a487909eabed321593d55f
+R b112f25d96f2f7bfd00311268c363283
 U dan
-Z 56215669c25140b5bc6688ab1e20262b
+Z e6dd64e790348520f70c858c0027a456
index 6d2a8f42f012b0537643edbb357f241753dfd2d2..8757f8c717d563dcad74d79d935d9fe82d9eef92 100644 (file)
@@ -1 +1 @@
-a8b1d99899678b72c2a487909eabed321593d55f
\ No newline at end of file
+918b609290127f54326c638d82837d117398eade
\ No newline at end of file
index 89a42df8963757f3276d7e448e1cb9dea0ccd1c0..87e8b39562b066ec618e2dd98fcf1b11a85ecc10 100644 (file)
@@ -19,6 +19,7 @@ source $testdir/fts3_common.tcl
 source $testdir/malloc_common.tcl
 
 set DO_MALLOC_TEST 0
+set testprefix fts3cov
 
 #--------------------------------------------------------------------------
 # When it first needs to read a block from the %_segments table, the FTS3 
@@ -369,4 +370,51 @@ do_malloc_test fts3cov-13 -sqlprep {
   SELECT snippet(t13, '%%') FROM t13 WHERE t13 MATCH 'two';
 }
 
+do_execsql_test 14.0 {
+  CREATE VIRTUAL TABLE t14 USING fts4(a, b);
+  INSERT INTO t14 VALUES('one two three', 'one three four');
+  INSERT INTO t14 VALUES('a b c', 'd e a');
+}
+do_execsql_test 14.1 {
+  SELECT rowid FROM t14 WHERE t14 MATCH '"one two three"'
+} {1}
+do_execsql_test 14.2 {
+  SELECT rowid FROM t14 WHERE t14 MATCH '"one four"'
+} {}
+do_execsql_test 14.3 {
+  SELECT rowid FROM t14 WHERE t14 MATCH '"e a"'
+} {2}
+do_execsql_test 14.5 {
+  SELECT rowid FROM t14 WHERE t14 MATCH '"e b"'
+} {}
+do_catchsql_test 14.6 {
+  SELECT rowid FROM t14 WHERE rowid MATCH 'one'
+} {1 {unable to use function MATCH in the requested context}}
+do_catchsql_test 14.7 {
+  SELECT rowid FROM t14 WHERE docid MATCH 'one'
+} {1 {unable to use function MATCH in the requested context}}
+
+do_execsql_test 15.0 {
+  CREATE VIRTUAL TABLE t15 USING fts4(a, b, c);
+  INSERT INTO t15 VALUES('abc def ghi', 'abc2 def2 ghi2', 'abc3 def3 ghi3');
+  INSERT INTO t15 VALUES('abc2 def2 ghi2', 'abc2 def2 ghi2', 'abc def3 ghi3');
+}
+do_execsql_test 15.1 {
+  SELECT rowid FROM t15 WHERE t15 MATCH '"abc* def2"'
+} {1 2}
+
+# Test a corruption case.
+#
+do_execsql_test 16.1 {
+  CREATE VIRTUAL TABLE t16 USING fts4;
+  INSERT INTO t16 VALUES('theoretical work to examine the relationship');
+  INSERT INTO t16 VALUES('solution of our problems on the invisible');
+  DELETE FROM t16_content WHERE rowid = 2;
+}
+do_catchsql_test 16.2 {
+  SELECT * FROM t16 WHERE t16 MATCH 'invisible'
+} {1 {database disk image is malformed}}
+
+
+
 finish_test
index 49d4decadeb57c5f16bcfce969156e01dcecdcc6..67f89bab16637982a41958cac881ed6122d1e5a3 100644 (file)
@@ -210,7 +210,7 @@ foreach {tn setup} {
     foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
   }
   3 {
-    set dmt_modes {0 1 2}
+    #set dmt_modes {0 1 2}
     execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
     foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
     execsql $zero_long_doclists
@@ -260,6 +260,16 @@ foreach {tn setup} {
   do_select_test 1.9 {
     SELECT rowid FROM t1 WHERE t1 MATCH 'zm ubwrfqnbjf'
   } {7 70 98}
+  do_select_test 1.10 {
+    SELECT rowid FROM t1 WHERE t1 MATCH 'z* vgsld'
+  } {10 13 17 31 35 51 58 88 89 90 93 100}
+  do_select_test 1.11 {
+    SELECT rowid FROM t1 
+    WHERE t1 MATCH '(
+      zdu OR zexh OR zf OR zhbrzadb OR zidhxhbtv OR 
+      zk OR zkhdvkw OR zm OR zsmhnf
+    ) vgsld'
+  } {10 13 17 31 35 51 58 88 89 90 93 100}
 
   do_select_test 2.1 {
     SELECT rowid FROM t1 WHERE t1 MATCH '"zm agmckuiu"'
@@ -282,17 +292,9 @@ foreach {tn setup} {
   do_select_test 2.7 {
     SELECT rowid FROM t1 WHERE t1 MATCH '"zm jk vgsld"'
   } {13 17}
-
   do_select_test 2.8 {
-    SELECT rowid FROM t1 WHERE t1 MATCH 'z* vgsld'
-  } {10 13 17 31 35 51 58 88 89 90 93 100}
-  do_select_test 2.9 {
-    SELECT rowid FROM t1 
-    WHERE t1 MATCH '(
-      zdu OR zexh OR zf OR zhbrzadb OR zidhxhbtv OR 
-      zk OR zkhdvkw OR zm OR zsmhnf
-    ) vgsld'
-  } {10 13 17 31 35 51 58 88 89 90 93 100}
+    SELECT rowid FROM t1 WHERE t1 MATCH '"zm jk vgsld lkjlkjlkj"'
+  } {}
 
   do_select_test 3.1 {
     SELECT snippet(t1, '[', ']') FROM t1 WHERE t1 MATCH '"zm agmckuiu"'
@@ -389,7 +391,37 @@ foreach {tn setup} {
     SELECT rowid FROM t1 
     WHERE t1 MATCH 'vgsld (hrlipdm OR (aayxpmve duszemmzl))'
   } {10}
+  do_select_test 6.2.1 {
+    SELECT rowid FROM t1 WHERE t1 MATCH '"jk jcpiwj"'
+  } {39 40}
+  do_select_test 6.2.2 {
+    SELECT rowid FROM t1 WHERE t1 MATCH '"zm xnxhf"'
+  } {40 47}
+  do_select_test 6.2.3 {
+    SELECT rowid FROM t1 WHERE t1 MATCH '"jk jcpiwj" OR "zm xnxhf"'
+  } {39 40 47}
+}
+
+set testprefix fts3defer
+
+do_execsql_test 3.1 {
+  CREATE VIRTUAL TABLE x1 USING fts4(a, b);
+  INSERT INTO x1 VALUES('a b c', 'd e f');
+  INSERT INTO x1 SELECT * FROM x1;
+  INSERT INTO x1 SELECT * FROM x1;
+  INSERT INTO x1 SELECT * FROM x1;
+  INSERT INTO x1 SELECT * FROM x1;
 }
+do_execsql_test 3.2 "
+  INSERT INTO x1 VALUES(
+    '[string repeat {d } 3000]', '[string repeat {f } 30000]'
+  );
+  INSERT INTO x1(x1) VALUES('optimize');
+"
+
+do_execsql_test 3.3 {
+  SELECT count(*) FROM x1 WHERE x1 MATCH '"d e f"'
+} {16}
 
 
 finish_test
diff --git a/test/fts3fault.test b/test/fts3fault.test
new file mode 100644 (file)
index 0000000..67f47dd
--- /dev/null
@@ -0,0 +1,129 @@
+# 2010 June 15
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+set ::testprefix fts3fault
+
+# Test error handling in the sqlite3Fts3Init() function. This is the 
+# function that registers the FTS3 module and various support functions
+# with SQLite.
+#
+do_faultsim_test 1 -body { 
+  sqlite3 db test.db 
+  expr 0
+} -test {
+  catch { db close }
+}
+
+# Test error handling in an "ALTER TABLE ... RENAME TO" statement on an
+# FTS3 table. Specifically, test renaming the table within a transaction
+# after it has been written to.
+#
+faultsim_delete_and_reopen
+do_execsql_test 2.0 {
+  CREATE VIRTUAL TABLE t1 USING fts3;
+  INSERT INTO t1 VALUES('test renaming the table');
+  INSERT INTO t1 VALUES(' after it has been written');
+}
+do_faultsim_test 2 -prep { 
+  sqlite3 db test.db
+  execsql {
+    BEGIN;
+      INSERT INTO t1 VALUES('registers the FTS3 module');
+      INSERT INTO t1 VALUES('various support functions');
+  }
+} -body {
+  execsql { ALTER TABLE t1 RENAME TO t2 }
+} -test {
+  faultsim_test_result {0 {}} 
+}
+
+# Test error handling in the special case where a single prefix query 
+# matches terms that reside on a large range of leaf nodes.
+#
+do_test fts3fault-3.0 {
+  sqlite3 db test.db
+  execsql { CREATE VIRTUAL TABLE t3 USING fts4; }
+  execsql { INSERT INTO t3(t3) VALUES('nodesize=50') }
+  execsql { BEGIN }
+  for {set i 0} {$i < 1000} {incr i} {
+    execsql { INSERT INTO t3 VALUES('aaa' || $i) }
+  }
+  execsql { COMMIT }
+} {}
+
+do_faultsim_test 3 -faults oom-transient -prep { 
+  sqlite3 db test.db
+  execsql { SELECT * FROM t3 WHERE t3 MATCH 'x' }
+} -body {
+  execsql { SELECT count(rowid) FROM t3 WHERE t3 MATCH 'aa*' }
+} -test {
+  faultsim_test_result {0 1000} 
+}
+
+do_test fts3fault-4.0 {
+  faultsim_delete_and_reopen
+  execsql { 
+    CREATE VIRTUAL TABLE t4 USING fts4; 
+    INSERT INTO t4 VALUES('The British Government called on');
+    INSERT INTO t4 VALUES('as pesetas then became much');
+  }
+} {}
+faultsim_save_and_close
+do_faultsim_test 4 -prep { 
+  faultsim_restore_and_reopen
+  execsql { SELECT content FROM t4 }
+} -body {
+  execsql { SELECT optimize(t4) FROM t4 LIMIT 1 }
+} -test {
+  faultsim_test_result {0 {{Index optimized}}}
+}
+
+do_test fts3fault-5.0 {
+  faultsim_delete_and_reopen
+  execsql { 
+    CREATE VIRTUAL TABLE t5 USING fts4; 
+    INSERT INTO t5 VALUES('The British Government called on');
+    INSERT INTO t5 VALUES('as pesetas then became much');
+  }
+} {}
+faultsim_save_and_close
+do_faultsim_test 5 -prep { 
+  faultsim_restore_and_reopen
+  execsql { 
+    BEGIN;
+      INSERT INTO t5 VALUES('influential in shaping his future outlook');
+      INSERT INTO t5 VALUES('might be acceptable to the British electorate');
+  }
+} -body {
+  execsql { SELECT rowid FROM t5 WHERE t5 MATCH 'british' }
+} -test {
+  faultsim_test_result {0 {1 4}}
+}
+
+do_test fts3fault-6.0 {
+  faultsim_delete_and_reopen
+  execsql { CREATE VIRTUAL TABLE t6 USING fts4 }
+} {}
+faultsim_save_and_close
+do_faultsim_test 6 -prep { 
+  faultsim_restore_and_reopen
+  execsql { SELECT rowid FROM t6 }
+} -body {
+  execsql { DROP TABLE t6 }
+} -test {
+  faultsim_test_result {0 {}}
+}
+
+finish_test
index 7ee79cb408d9f3bc938906071c7d5644868ff62c..f62edae37f682d2899f3d5f4de2b823c382896b9 100644 (file)
@@ -173,7 +173,6 @@ do_execsql_test 6.1 {
   CREATE VIRTUAL TABLE t3 USING FTS4(a, b);
   INSERT INTO t3 VALUES('no gestures', 'another intriguing discovery by observing the hand gestures (called beats) people make while speaking. Research has shown that such gestures do more than add visual emphasis to our words (many people gesture while they''re on the telephone, for example); it seems they actually help our brains find words');
 }
-
 do_select_tests 6.2 {
   1 "SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'gestures'"
   {{<b>...</b>hand <b>gestures</b> (called beats) people make while speaking. Research has shown that such <b>gestures</b> do<b>...</b>}}
@@ -197,5 +196,6 @@ do_select_tests 6.2 {
   {{ZZZthe hand XXXgesturesYYY (called beatsZZZ}}
 }
 
+
 finish_test