1# 2009 December 20 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12# This file contains tests of fts3 queries that have been useful during 13# the development process as well as some that have been useful in tracking 14# down bugs. They are not focused on any particular functionality. 15# 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# If this build does not include FTS3, skip the tests in this file. 21# 22ifcapable !fts3 { finish_test ; return } 23source $testdir/malloc_common.tcl 24source $testdir/fts3_common.tcl 25set DO_MALLOC_TEST 0 26 27set testprefix fts3query 28 29do_test fts3query-1.1 { 30 execsql { 31 CREATE VIRTUAL TABLE t1 USING fts3(x); 32 BEGIN; 33 INSERT INTO t1 VALUES('The source code for SQLite is in the public'); 34 } 35} {} 36 37do_select_test fts3query-1.2 { 38 SELECT * FROM t1; 39} {{The source code for SQLite is in the public}} 40do_select_test fts3query-1.3 { 41 SELECT * FROM t1 WHERE t1 MATCH 'sqlite' 42} {{The source code for SQLite is in the public}} 43 44do_test fts3query-1.4 { execsql {COMMIT} } {} 45 46do_select_test fts3query-1.5 { 47 SELECT * FROM t1; 48} {{The source code for SQLite is in the public}} 49do_select_test fts3query-1.6 { 50 SELECT * FROM t1 WHERE t1 MATCH 'sqlite' 51} {{The source code for SQLite is in the public}} 52 53 54set sqlite_fts3_enable_parentheses 1 55do_test fts3query-2.1 { 56 execsql { 57 CREATE VIRTUAL TABLE zoink USING fts3; 58 INSERT INTO zoink VALUES('The apple falls far from the tree'); 59 } 60} {} 61do_test fts3query-2.2 { 62 execsql { 63 SELECT docid FROM zoink WHERE zoink MATCH '(apple oranges) AND apple' 64 } 65} {} 66do_test fts3query-2.3 { 67 execsql { 68 SELECT docid FROM zoink WHERE zoink MATCH 'apple AND (oranges apple)' 69 } 70} {} 71set sqlite_fts3_enable_parentheses 0 72 73do_test fts3query-3.1 { 74 execsql { 75 CREATE VIRTUAL TABLE foobar using FTS3(description, tokenize porter); 76 INSERT INTO foobar (description) values (' 77 Filed under: Emerging Technologies, EV/Plug-in, Hybrid, Chevrolet, GM, 78 ZENN 2011 Chevy Volt - Click above for high-res image gallery There are 79 16 days left in the month of December. Besides being time for most 80 Americans to kick their Christmas shopping sessions into high gear and 81 start planning their resolutions for 2010, it also means that there''s 82 precious little time for EEStor to "deliver functional technology" to 83 Zenn Motors as promised. Still, the promises held out by the secretive 84 company are too great for us to forget about entirely. We''d love for 85 EEStor''s claims to be independently verified and proven accurate, as 86 would just about anyone else looking to break free of petroleum in fav 87 '); 88 } 89} {} 90 91do_test fts3query-3.2 { 92 execsql { SELECT docid FROM foobar WHERE description MATCH '"high sp d"' } 93} {} 94 95proc mit {blob} { 96 set scan(littleEndian) i* 97 set scan(bigEndian) I* 98 binary scan $blob $scan($::tcl_platform(byteOrder)) r 99 return $r 100} 101db func mit mit 102 103do_test fts3query-3.3 { 104 execsql { SELECT mit(matchinfo(foobar)) FROM foobar WHERE foobar MATCH 'the' } 105} {{1 1 3 3 1}} 106 107# The following tests check that ticket 775b39dd3c has been fixed. 108# 109do_test fts3query-4.1 { 110 execsql { 111 DROP TABLE IF EXISTS t1; 112 CREATE TABLE t1(number INTEGER PRIMARY KEY, date); 113 CREATE INDEX i1 ON t1(date); 114 CREATE VIRTUAL TABLE ft USING fts3(title); 115 CREATE TABLE bt(title); 116 } 117} {} 118do_eqp_test fts3query-4.2 { 119 SELECT t1.number FROM t1, ft WHERE t1.number=ft.rowid ORDER BY t1.date 120} { 121 QUERY PLAN 122 |--SCAN TABLE t1 USING COVERING INDEX i1 123 `--SCAN TABLE ft VIRTUAL TABLE INDEX 1: 124} 125do_eqp_test fts3query-4.3 { 126 SELECT t1.number FROM ft, t1 WHERE t1.number=ft.rowid ORDER BY t1.date 127} { 128 QUERY PLAN 129 |--SCAN TABLE t1 USING COVERING INDEX i1 130 `--SCAN TABLE ft VIRTUAL TABLE INDEX 1: 131} 132do_eqp_test fts3query-4.4 { 133 SELECT t1.number FROM t1, bt WHERE t1.number=bt.rowid ORDER BY t1.date 134} { 135 QUERY PLAN 136 |--SCAN TABLE t1 USING COVERING INDEX i1 137 `--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?) 138} 139do_eqp_test fts3query-4.5 { 140 SELECT t1.number FROM bt, t1 WHERE t1.number=bt.rowid ORDER BY t1.date 141} { 142 QUERY PLAN 143 |--SCAN TABLE t1 USING COVERING INDEX i1 144 `--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?) 145} 146 147 148# Test that calling matchinfo() with the wrong number of arguments, or with 149# an invalid argument returns an error. 150# 151do_execsql_test 5.1 { 152 CREATE VIRTUAL TABLE t2 USING FTS4; 153 INSERT INTO t2 VALUES('it was the first time in history'); 154} 155do_select_tests 5.2 -errorformat { 156 wrong number of arguments to function %s() 157} { 158 1 "SELECT matchinfo() FROM t2 WHERE t2 MATCH 'history'" matchinfo 159 3 "SELECT snippet(t2, 1, 2, 3, 4, 5, 6) FROM t2 WHERE t2 MATCH 'history'" 160 snippet 161} 162do_select_tests 5.3 -errorformat { 163 illegal first argument to %s 164} { 165 1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo 166 2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'" offsets 167 3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'" snippet 168 4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'" optimize 169} 170do_execsql_test 5.4.0 { UPDATE t2_content SET c0content = X'1234' } 171do_select_tests 5.4 -errorformat { 172 illegal first argument to %s 173} { 174 1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo 175 2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'" offsets 176 3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'" snippet 177 4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'" optimize 178} 179do_catchsql_test 5.5.1 { 180 SELECT matchinfo(t2, 'abcd') FROM t2 WHERE t2 MATCH 'history' 181} {1 {unrecognized matchinfo request: d}} 182 183do_execsql_test 5.5 { DROP TABLE t2 } 184 185 186# Test the snippet() function with 1 to 6 arguments. 187# 188do_execsql_test 6.1 { 189 CREATE VIRTUAL TABLE t3 USING FTS4(a, b); 190 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'); 191} 192do_select_tests 6.2 { 193 1 "SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'gestures'" 194 {{<b>...</b>hand <b>gestures</b> (called beats) people make while speaking. Research has shown that such <b>gestures</b> do<b>...</b>}} 195 196 2 "SELECT snippet(t3, 'XXX') FROM t3 WHERE t3 MATCH 'gestures'" 197 {{<b>...</b>hand XXXgestures</b> (called beats) people make while speaking. Research has shown that such XXXgestures</b> do<b>...</b>}} 198 199 3 "SELECT snippet(t3, 'XXX', 'YYY') FROM t3 WHERE t3 MATCH 'gestures'" 200 {{<b>...</b>hand XXXgesturesYYY (called beats) people make while speaking. Research has shown that such XXXgesturesYYY do<b>...</b>}} 201 202 4 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ') FROM t3 WHERE t3 MATCH 'gestures'" 203 {{ZZZhand XXXgesturesYYY (called beats) people make while speaking. Research has shown that such XXXgesturesYYY doZZZ}} 204 205 5 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1) FROM t3 WHERE t3 MATCH 'gestures'" 206 {{ZZZhand XXXgesturesYYY (called beats) people make while speaking. Research has shown that such XXXgesturesYYY doZZZ}} 207 208 6 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 0) FROM t3 WHERE t3 MATCH 'gestures'" 209 {{no XXXgesturesYYY}} 210 211 7 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1, 5) FROM t3 WHERE t3 MATCH 'gestures'" 212 {{ZZZthe hand XXXgesturesYYY (called beatsZZZ}} 213} 214 215# Test some range queries on the rowid field. 216# 217do_execsql_test 7.1 { 218 CREATE VIRTUAL TABLE ft4 USING fts4(x); 219 CREATE TABLE t4(x); 220} 221 222set SMALLINT -9223372036854775808 223set LARGEINT 9223372036854775807 224do_test 7.2 { 225 db transaction { 226 foreach {iFirst nEntry} [subst { 227 0 100 228 $SMALLINT 100 229 [expr $LARGEINT - 99] 100 230 }] { 231 for {set i 0} {$i < $nEntry} {incr i} { 232 set iRowid [expr $i + $iFirst] 233 execsql { 234 INSERT INTO ft4(rowid, x) VALUES($iRowid, 'x y z'); 235 INSERT INTO t4(rowid, x) VALUES($iRowid, 'x y z'); 236 } 237 } 238 } 239 } 240} {} 241 242foreach {tn iFirst iLast} [subst { 243 1 5 10 244 2 $SMALLINT [expr $SMALLINT+5] 245 3 $SMALLINT [expr $SMALLINT+50] 246 4 [expr $LARGEINT-5] $LARGEINT 247 5 $LARGEINT $LARGEINT 248 6 $SMALLINT $LARGEINT 249 7 $SMALLINT $SMALLINT 250 8 $LARGEINT $SMALLINT 251}] { 252 set res [db eval { 253 SELECT rowid FROM t4 WHERE rowid BETWEEN $iFirst AND $iLast 254 } ] 255 256 do_execsql_test 7.2.$tn.1.[llength $res] { 257 SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast 258 } $res 259 set res [db eval { 260 SELECT rowid FROM t4 WHERE rowid BETWEEN $iFirst AND $iLast 261 ORDER BY +rowid DESC 262 } ] 263 do_execsql_test 7.2.$tn.2.[llength $res] { 264 SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast 265 ORDER BY rowid DESC 266 } $res 267} 268 269foreach ii [db eval {SELECT rowid FROM t4}] { 270 set res1 [db eval {SELECT rowid FROM t4 WHERE rowid > $ii}] 271 set res2 [db eval {SELECT rowid FROM t4 WHERE rowid < $ii}] 272 set res1s [db eval {SELECT rowid FROM t4 WHERE rowid > $ii ORDER BY +rowid DESC}] 273 set res2s [db eval {SELECT rowid FROM t4 WHERE rowid < $ii ORDER BY +rowid DESC}] 274 275 do_execsql_test 7.3.$ii.1 { 276 SELECT rowid FROM ft4 WHERE rowid > $ii 277 } $res1 278 279 do_execsql_test 7.3.$ii.2 { 280 SELECT rowid FROM ft4 WHERE rowid < $ii 281 } $res2 282 283 do_execsql_test 7.3.$ii.3 { 284 SELECT rowid FROM ft4 WHERE rowid > $ii ORDER BY rowid DESC 285 } $res1s 286 287 do_execsql_test 7.3.$ii.4 { 288 SELECT rowid FROM ft4 WHERE rowid < $ii ORDER BY rowid DESC 289 } $res2s 290} 291 292finish_test 293