diff --git a/ext/fts3/fts3_aux.c b/ext/fts3/fts3_aux.c index cb18079b2a..f9d801580c 100644 --- a/ext/fts3/fts3_aux.c +++ b/ext/fts3/fts3_aux.c @@ -66,7 +66,9 @@ static int fts3auxConnectMethod( /* The user should specify a single argument - the name of an fts3 table. */ if( argc!=4 ){ - *pzErr = sqlite3_mprintf("wrong number of arguments"); + *pzErr = sqlite3_mprintf( + "wrong number of arguments to fts4aux constructor" + ); return SQLITE_ERROR; } @@ -153,19 +155,22 @@ static int fts3auxBestIndexMethod( if( iEq>=0 ){ pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT; pInfo->aConstraintUsage[iEq].argvIndex = 1; + pInfo->estimatedCost = 5; }else{ pInfo->idxNum = 0; + pInfo->estimatedCost = 20000; if( iGe>=0 ){ pInfo->idxNum += FTS4AUX_GE_CONSTRAINT; pInfo->aConstraintUsage[iGe].argvIndex = 1; + pInfo->estimatedCost /= 2; } if( iLe>=0 ){ pInfo->idxNum += FTS4AUX_LE_CONSTRAINT; pInfo->aConstraintUsage[iLe].argvIndex = 1 + (iGe>=0); + pInfo->estimatedCost /= 2; } } - pInfo->estimatedCost = 20000; return SQLITE_OK; } @@ -281,7 +286,7 @@ static int fts3auxFilterMethod( if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; if( idxNum&(FTS4AUX_EQ_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) ){ - const char *zStr = sqlite3_value_text(apVal[0]); + const unsigned char *zStr = sqlite3_value_text(apVal[0]); if( zStr ){ pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]); diff --git a/manifest b/manifest index 1d8341f7f4..a99513bc9c 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fix\sa\ssuperlock\stest\scase\sto\sconform\sto\sthe\snew\swal_checkpoint\sreturns. -D 2011-02-03T01:26:32.247 +C Extra\stests\sfor\sthe\sfts4aux\smodule. +D 2011-02-03T10:56:00.411 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in de6498556d536ae60bb8bb10e8c1ba011448658c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -67,7 +64,7 @@ F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts3/fts3.c f93f5d614e92b0221e954ea3bd800f11f6f00191 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 945926ea4b6a686c3e9834640a252d9870b7191e -F ext/fts3/fts3_aux.c 03bc785b04965325ac48a6a6fb0e7babb7751298 +F ext/fts3/fts3_aux.c 233a9f0bd8fa336d78f5905b2c94c8860d237dd9 F ext/fts3/fts3_expr.c 5f49e0deaf723724b08100bb3ff40aab02ad0c93 F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec @@ -441,7 +438,7 @@ F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8 F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18 F test/fts3ao.test b83f99f70e9eec85f27d75801a974b3f820e01f9 F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa -F test/fts3aux1.test 709323862e88b3e4be8278151bee2c56087feeed +F test/fts3aux1.test 6145608289e8a6337acb3432d592e57b8e46ad35 F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test ef36e5ddf9811c9801f52b2988bca1fce7dc8ce8 @@ -455,6 +452,7 @@ F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851 F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3fault.test f83e556465bb69dc8bc676339eca408dce4ca246 +F test/fts3fault2.test 5657d83759338d93ef8029518de3214c33a1c560 F test/fts3malloc.test 9c8cc3f885bb4dfc66d0460c52f68f45e4710d1b F test/fts3matchinfo.test cc0b009edbbf575283d5fdb53271179e0d8019ba F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844 @@ -906,14 +904,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P aef61036b31963e4c3ff4e8acf8c1734dc9394af -R 89ebf5c5b7c59e9a79de525a6ebb77b1 -U drh -Z 5699430fdf5a52fd056eaf0d48c3354d ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.10 (Darwin) - -iEYEARECAAYFAk1KBEgACgkQoxKgR168RlGuLgCfTeoTY7w4JwnLR7XHUbjNF+o1 -Ui8An2r3tegTKD67g40gncFgB71KrDyc -=cJV+ ------END PGP SIGNATURE----- +P 8bf2d51b6a50da84cf6b0d2bd78e633d6810160b +R ddc2098046dae72dcd5cb0c3ae07050f +U dan +Z 24b73331b8700cbc651162882517a9c3 diff --git a/manifest.uuid b/manifest.uuid index 330be42933..ac29c97b66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bf2d51b6a50da84cf6b0d2bd78e633d6810160b \ No newline at end of file +cfc475690d85ea7e3547424289d9837f46ab7ef4 \ No newline at end of file diff --git a/test/fts3aux1.test b/test/fts3aux1.test index 3a4278a38b..68b1103082 100644 --- a/test/fts3aux1.test +++ b/test/fts3aux1.test @@ -145,6 +145,10 @@ do_execsql_test 2.1.4.6 { SELECT * FROM terms WHERE +term='cba' } {} do_execsql_test 2.1.4.7 { SELECT * FROM terms WHERE term='abc' } {} do_execsql_test 2.1.4.8 { SELECT * FROM terms WHERE +term='abc' } {} +# Special case: term=NULL +# +do_execsql_test 2.1.5 { SELECT * FROM terms WHERE term=NULL } {} + do_execsql_test 2.2.1.1 { EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term>'brain' } { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 2: (~0 rows)} } @@ -312,16 +316,123 @@ do_execsql_test 2.2.4.6 { braid 1 1 braided 1 1 braiding 1 1 braids 1 1 } -do_execsql_test 2.3.1.1 { - EXPLAIN QUERY PLAN SELECT * FROM terms ORDER BY term ASC; +# Check that "ORDER BY term ASC" and equivalents are sorted by the +# virtual table implementation. Any other ORDER BY clause requires +# SQLite to sort results using a temporary b-tree. +# +foreach {tn sort orderby} { + 1 0 "ORDER BY term ASC" + 2 0 "ORDER BY term" + 3 1 "ORDER BY term DESC" + 4 1 "ORDER BY documents ASC" + 5 1 "ORDER BY documents" + 6 1 "ORDER BY documents DESC" + 7 1 "ORDER BY occurrences ASC" + 8 1 "ORDER BY occurrences" + 9 1 "ORDER BY occurrences DESC" } { - 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0: (~0 rows)} -} -do_execsql_test 2.3.1.2 { - EXPLAIN QUERY PLAN SELECT * FROM terms ORDER BY term DESC; -} { - 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0: (~0 rows)} - 0 0 0 {USE TEMP B-TREE FOR ORDER BY} + + set res [list 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0: (~0 rows)}] + if {$sort} { lappend res 0 0 0 {USE TEMP B-TREE FOR ORDER BY} } + + set sql "SELECT * FROM terms $orderby" + do_execsql_test 2.3.1.$tn "EXPLAIN QUERY PLAN $sql" $res } +#------------------------------------------------------------------------- +# The next set of tests, fts3aux1-3.*, test error conditions in the +# fts4aux module. Except, fault injection testing (OOM, IO error etc.) is +# done in fts3fault2.test +# + +do_execsql_test 3.1.1 { + CREATE VIRTUAL TABLE t2 USING fts4; +} + +do_catchsql_test 3.1.2 { + CREATE VIRTUAL TABLE terms2 USING fts4aux; +} {1 {wrong number of arguments to fts4aux constructor}} +do_catchsql_test 3.1.3 { + CREATE VIRTUAL TABLE terms2 USING fts4aux(t2, t2); +} {1 {wrong number of arguments to fts4aux constructor}} + +do_execsql_test 3.2.1 { + CREATE VIRTUAL TABLE terms3 USING fts4aux(does_not_exist) +} +do_catchsql_test 3.2.2 { + SELECT * FROM terms3 +} {1 {SQL logic error or missing database}} +do_catchsql_test 3.2.3 { + SELECT * FROM terms3 WHERE term = 'abc' +} {1 {SQL logic error or missing database}} + +do_catchsql_test 3.3.1 { + INSERT INTO terms VALUES(1,2,3); +} {1 {table terms may not be modified}} +do_catchsql_test 3.3.2 { + DELETE FROM terms +} {1 {table terms may not be modified}} +do_catchsql_test 3.3.3 { + UPDATE terms set documents = documents+1; +} {1 {table terms may not be modified}} + + +#------------------------------------------------------------------------- +# +db close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 4.1 { + CREATE VIRTUAL TABLE x1 USING fts4(x); + CREATE VIRTUAL TABLE terms USING fts4aux(x1); + CREATE TABLE x2(y); + CREATE TABLE x3(y); + CREATE INDEX i1 ON x3(y); + + INSERT INTO x1 VALUES('a b c d e'); + INSERT INTO x1 VALUES('f g h i j'); + INSERT INTO x1 VALUES('k k l l a'); + + INSERT INTO x2 SELECT term FROM terms; + INSERT INTO x3 SELECT term FROM terms; +} + +proc do_plansql_test {tn sql r} { + uplevel do_execsql_test $tn [list "EXPLAIN QUERY PLAN $sql ; $sql"] [list $r] +} + + +do_plansql_test 4.2 { + SELECT y FROM x2, terms WHERE y = term +} { + 0 0 0 {SCAN TABLE x2 (~1000000 rows)} + 0 1 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 1: (~0 rows)} + a b c d e f g h i j k l +} + +do_plansql_test 4.3 { + SELECT y FROM terms, x2 WHERE y = term +} { + 0 0 1 {SCAN TABLE x2 (~1000000 rows)} + 0 1 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 1: (~0 rows)} + a b c d e f g h i j k l +} + +do_plansql_test 4.4 { + SELECT y FROM x3, terms WHERE y = term +} { + 0 0 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 0: (~0 rows)} + 0 1 0 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?) (~10 rows)} + a b c d e f g h i j k l +} + +do_plansql_test 4.5 { + SELECT y FROM terms, x3 WHERE y = term AND occurrences>1 +} { + 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0: (~0 rows)} + 0 1 1 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?) (~10 rows)} + a k l +} + + finish_test diff --git a/test/fts3fault2.test b/test/fts3fault2.test new file mode 100644 index 0000000000..977bd47a16 --- /dev/null +++ b/test/fts3fault2.test @@ -0,0 +1,65 @@ +# 2011 February 3 +# +# 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 fts3fault2 + +do_test 1.0 { + execsql { + CREATE VIRTUAL TABLE t1 USING fts4(x); + INSERT INTO t1 VALUES('a b c'); + INSERT INTO t1 VALUES('c d e'); + CREATE VIRTUAL TABLE terms USING fts4aux(t1); + } + faultsim_save_and_close +} {} + +do_faultsim_test 1.1 -prep { + faultsim_restore_and_reopen + db eval {SELECT * FROM sqlite_master} +} -body { + execsql "CREATE VIRTUAL TABLE terms2 USING fts4aux(t1)" +} -test { + faultsim_test_result {0 {}} +} + +do_faultsim_test 1.2 -prep { + faultsim_restore_and_reopen + db eval {SELECT * FROM sqlite_master} +} -body { + execsql "SELECT * FROM terms" +} -test { + faultsim_test_result {0 {a 1 1 b 1 1 c 2 2 d 1 1 e 1 1}} +} + +do_faultsim_test 1.3 -prep { + faultsim_restore_and_reopen + db eval {SELECT * FROM sqlite_master} +} -body { + execsql "SELECT * FROM terms WHERE term>'a' AND TERM < 'd'" +} -test { + faultsim_test_result {0 {b 1 1 c 2 2}} +} + +do_faultsim_test 1.4 -prep { + faultsim_restore_and_reopen + db eval {SELECT * FROM sqlite_master} +} -body { + execsql "SELECT * FROM terms WHERE term='c'" +} -test { + faultsim_test_result {0 {c 2 2}} +} + + + +finish_test