000001 # 2010 January 07
000002 #
000003 # The author disclaims copyright to this source code. In place of
000004 # a legal notice, here is a blessing:
000005 #
000006 # May you do good and not evil.
000007 # May you find forgiveness for yourself and forgive others.
000008 # May you share freely, never taking more than you give.
000009 #
000010 #*************************************************************************
000011 #
000012 # The tests in this file test the FTS3 auxillary functions offsets(),
000013 # snippet() and matchinfo() work. At time of writing, running this file
000014 # provides full coverage of fts3_snippet.c.
000015 #
000016
000017 set testdir [file dirname $argv0]
000018 source $testdir/tester.tcl
000019 set testprefix fts3snippet
000020
000021 # If SQLITE_ENABLE_FTS3 is not defined, omit this file.
000022 ifcapable !fts3 { finish_test ; return }
000023 source $testdir/fts3_common.tcl
000024
000025 set sqlite_fts3_enable_parentheses 1
000026 set DO_MALLOC_TEST 0
000027
000028 # Transform the list $L to its "normal" form. So that it can be compared to
000029 # another list with the same set of elements using [string compare].
000030 #
000031 proc normalize {L} {
000032 set ret [list]
000033 foreach l $L {lappend ret $l}
000034 return $ret
000035 }
000036
000037 proc do_offsets_test {name expr args} {
000038 set result [list]
000039 foreach a $args {
000040 lappend result [normalize $a]
000041 }
000042 do_select_test $name {
000043 SELECT offsets(ft) FROM ft WHERE ft MATCH $expr
000044 } $result
000045 }
000046
000047 # Document text used by a few tests. Contains the English names of all
000048 # integers between 1 and 300.
000049 #
000050 set numbers [normalize {
000051 one two three four five six seven eight nine ten eleven twelve thirteen
000052 fourteen fifteen sixteen seventeen eighteen nineteen twenty twentyone
000053 twentytwo twentythree twentyfour twentyfive twentysix twentyseven
000054 twentyeight twentynine thirty thirtyone thirtytwo thirtythree thirtyfour
000055 thirtyfive thirtysix thirtyseven thirtyeight thirtynine forty fortyone
000056 fortytwo fortythree fortyfour fortyfive fortysix fortyseven fortyeight
000057 fortynine fifty fiftyone fiftytwo fiftythree fiftyfour fiftyfive fiftysix
000058 fiftyseven fiftyeight fiftynine sixty sixtyone sixtytwo sixtythree sixtyfour
000059 sixtyfive sixtysix sixtyseven sixtyeight sixtynine seventy seventyone
000060 seventytwo seventythree seventyfour seventyfive seventysix seventyseven
000061 seventyeight seventynine eighty eightyone eightytwo eightythree eightyfour
000062 eightyfive eightysix eightyseven eightyeight eightynine ninety ninetyone
000063 ninetytwo ninetythree ninetyfour ninetyfive ninetysix ninetyseven
000064 ninetyeight ninetynine onehundred onehundredone onehundredtwo
000065 onehundredthree onehundredfour onehundredfive onehundredsix onehundredseven
000066 onehundredeight onehundrednine onehundredten onehundredeleven
000067 onehundredtwelve onehundredthirteen onehundredfourteen onehundredfifteen
000068 onehundredsixteen onehundredseventeen onehundredeighteen onehundrednineteen
000069 onehundredtwenty onehundredtwentyone onehundredtwentytwo
000070 onehundredtwentythree onehundredtwentyfour onehundredtwentyfive
000071 onehundredtwentysix onehundredtwentyseven onehundredtwentyeight
000072 onehundredtwentynine onehundredthirty onehundredthirtyone
000073 onehundredthirtytwo onehundredthirtythree onehundredthirtyfour
000074 onehundredthirtyfive onehundredthirtysix onehundredthirtyseven
000075 onehundredthirtyeight onehundredthirtynine onehundredforty
000076 onehundredfortyone onehundredfortytwo onehundredfortythree
000077 onehundredfortyfour onehundredfortyfive onehundredfortysix
000078 onehundredfortyseven onehundredfortyeight onehundredfortynine
000079 onehundredfifty onehundredfiftyone onehundredfiftytwo onehundredfiftythree
000080 onehundredfiftyfour onehundredfiftyfive onehundredfiftysix
000081 onehundredfiftyseven onehundredfiftyeight onehundredfiftynine
000082 onehundredsixty onehundredsixtyone onehundredsixtytwo onehundredsixtythree
000083 onehundredsixtyfour onehundredsixtyfive onehundredsixtysix
000084 onehundredsixtyseven onehundredsixtyeight onehundredsixtynine
000085 onehundredseventy onehundredseventyone onehundredseventytwo
000086 onehundredseventythree onehundredseventyfour onehundredseventyfive
000087 onehundredseventysix onehundredseventyseven onehundredseventyeight
000088 onehundredseventynine onehundredeighty onehundredeightyone
000089 onehundredeightytwo onehundredeightythree onehundredeightyfour
000090 onehundredeightyfive onehundredeightysix onehundredeightyseven
000091 onehundredeightyeight onehundredeightynine onehundredninety
000092 onehundredninetyone onehundredninetytwo onehundredninetythree
000093 onehundredninetyfour onehundredninetyfive onehundredninetysix
000094 onehundredninetyseven onehundredninetyeight onehundredninetynine twohundred
000095 twohundredone twohundredtwo twohundredthree twohundredfour twohundredfive
000096 twohundredsix twohundredseven twohundredeight twohundrednine twohundredten
000097 twohundredeleven twohundredtwelve twohundredthirteen twohundredfourteen
000098 twohundredfifteen twohundredsixteen twohundredseventeen twohundredeighteen
000099 twohundrednineteen twohundredtwenty twohundredtwentyone twohundredtwentytwo
000100 twohundredtwentythree twohundredtwentyfour twohundredtwentyfive
000101 twohundredtwentysix twohundredtwentyseven twohundredtwentyeight
000102 twohundredtwentynine twohundredthirty twohundredthirtyone
000103 twohundredthirtytwo twohundredthirtythree twohundredthirtyfour
000104 twohundredthirtyfive twohundredthirtysix twohundredthirtyseven
000105 twohundredthirtyeight twohundredthirtynine twohundredforty
000106 twohundredfortyone twohundredfortytwo twohundredfortythree
000107 twohundredfortyfour twohundredfortyfive twohundredfortysix
000108 twohundredfortyseven twohundredfortyeight twohundredfortynine
000109 twohundredfifty twohundredfiftyone twohundredfiftytwo twohundredfiftythree
000110 twohundredfiftyfour twohundredfiftyfive twohundredfiftysix
000111 twohundredfiftyseven twohundredfiftyeight twohundredfiftynine
000112 twohundredsixty twohundredsixtyone twohundredsixtytwo twohundredsixtythree
000113 twohundredsixtyfour twohundredsixtyfive twohundredsixtysix
000114 twohundredsixtyseven twohundredsixtyeight twohundredsixtynine
000115 twohundredseventy twohundredseventyone twohundredseventytwo
000116 twohundredseventythree twohundredseventyfour twohundredseventyfive
000117 twohundredseventysix twohundredseventyseven twohundredseventyeight
000118 twohundredseventynine twohundredeighty twohundredeightyone
000119 twohundredeightytwo twohundredeightythree twohundredeightyfour
000120 twohundredeightyfive twohundredeightysix twohundredeightyseven
000121 twohundredeightyeight twohundredeightynine twohundredninety
000122 twohundredninetyone twohundredninetytwo twohundredninetythree
000123 twohundredninetyfour twohundredninetyfive twohundredninetysix
000124 twohundredninetyseven twohundredninetyeight twohundredninetynine
000125 threehundred
000126 }]
000127
000128 foreach {DO_MALLOC_TEST enc} {
000129 0 utf8
000130 1 utf8
000131 1 utf16
000132 } {
000133
000134 db close
000135 forcedelete test.db
000136 sqlite3 db test.db
000137 sqlite3_db_config_lookaside db 0 0 0
000138 db eval "PRAGMA encoding = \"$enc\""
000139
000140 # Set variable $T to the test name prefix for this iteration of the loop.
000141 #
000142 set T "fts3snippet-1.$enc"
000143
000144 ##########################################################################
000145 # Test the offset function.
000146 #
000147 do_test $T.1.1 {
000148 execsql {
000149 CREATE VIRTUAL TABLE ft USING fts3;
000150 INSERT INTO ft VALUES('xxx xxx xxx xxx');
000151 }
000152 } {}
000153 do_offsets_test $T.1.2 {xxx} {0 0 0 3 0 0 4 3 0 0 8 3 0 0 12 3}
000154 do_offsets_test $T.1.3 {"xxx xxx"} {
000155 0 0 0 3 0 0 4 3 0 1 4 3 0 0 8 3
000156 0 1 8 3 0 1 12 3
000157 }
000158 do_offsets_test $T.1.4 {"xxx xxx" xxx} {
000159 0 0 0 3 0 2 0 3 0 0 4 3 0 1 4 3
000160 0 2 4 3 0 0 8 3 0 1 8 3 0 2 8 3
000161 0 1 12 3 0 2 12 3
000162 }
000163 do_offsets_test $T.1.5 {xxx "xxx xxx"} {
000164 0 0 0 3 0 1 0 3 0 0 4 3 0 1 4 3
000165 0 2 4 3 0 0 8 3 0 1 8 3 0 2 8 3
000166 0 0 12 3 0 2 12 3
000167 }
000168
000169 do_test $T.2.1 {
000170 set v1 [lrange $numbers 0 99]
000171 execsql {
000172 DROP TABLE IF EXISTS ft;
000173 CREATE VIRTUAL TABLE ft USING fts3(a, b);
000174 INSERT INTO ft VALUES($v1, $numbers);
000175 INSERT INTO ft VALUES($v1, NULL);
000176 }
000177 } {}
000178
000179 set off [string first "twohundred " $numbers]
000180 do_offsets_test $T.2.1 {twohundred} [list 1 0 $off 10]
000181
000182 set off [string first "onehundred " $numbers]
000183 do_offsets_test $T.2.2 {onehundred} \
000184 [list 0 0 $off 10 1 0 $off 10] [list 0 0 $off 10]
000185
000186 # Test a corruption case:
000187 sqlite3_db_config db DEFENSIVE 0
000188 execsql { UPDATE ft_content SET c1b = 'hello world' WHERE c1b = $numbers }
000189 do_error_test $T.2.3 {
000190 SELECT offsets(ft) FROM ft WHERE ft MATCH 'onehundred'
000191 } {database disk image is malformed}
000192
000193 ##########################################################################
000194 # Test the snippet function.
000195 #
000196 proc do_snippet_test {name expr iCol nTok args} {
000197 set res [list]
000198 foreach a $args { lappend res [string trim $a] }
000199 do_select_test $name {
000200 SELECT snippet(ft,'{','}','...',$iCol,$nTok) FROM ft WHERE ft MATCH $expr
000201 } $res
000202 }
000203 do_test $T.3.1 {
000204 execsql {
000205 DROP TABLE IF EXISTS ft;
000206 CREATE VIRTUAL TABLE ft USING fts3;
000207 INSERT INTO ft VALUES('one two three four five six seven eight nine ten');
000208 }
000209 } {}
000210 do_snippet_test $T.3.2 one 0 5 "{one} two three four five..."
000211 do_snippet_test $T.3.3 two 0 5 "one {two} three four five..."
000212 do_snippet_test $T.3.4 three 0 5 "one two {three} four five..."
000213 do_snippet_test $T.3.5 four 0 5 "...two three {four} five six..."
000214 do_snippet_test $T.3.6 five 0 5 "...three four {five} six seven..."
000215 do_snippet_test $T.3.7 six 0 5 "...four five {six} seven eight..."
000216 do_snippet_test $T.3.8 seven 0 5 "...five six {seven} eight nine..."
000217 do_snippet_test $T.3.9 eight 0 5 "...six seven {eight} nine ten"
000218 do_snippet_test $T.3.10 nine 0 5 "...six seven eight {nine} ten"
000219 do_snippet_test $T.3.11 ten 0 5 "...six seven eight nine {ten}"
000220
000221 do_test $T.4.1 {
000222 execsql {
000223 INSERT INTO ft VALUES(
000224 'one two three four five '
000225 || 'six seven eight nine ten '
000226 || 'eleven twelve thirteen fourteen fifteen '
000227 || 'sixteen seventeen eighteen nineteen twenty '
000228 || 'one two three four five '
000229 || 'six seven eight nine ten '
000230 || 'eleven twelve thirteen fourteen fifteen '
000231 || 'sixteen seventeen eighteen nineteen twenty'
000232 );
000233 }
000234 } {}
000235
000236 do_snippet_test $T.4.2 {one nine} 0 5 {
000237 {one} two three...eight {nine} ten
000238 } {
000239 {one} two three...eight {nine} ten...
000240 }
000241
000242 do_snippet_test $T.4.3 {one nine} 0 -5 {
000243 {one} two three four five...six seven eight {nine} ten
000244 } {
000245 {one} two three four five...seven eight {nine} ten eleven...
000246 }
000247 do_snippet_test $T.4.3 {one nineteen} 0 -5 {
000248 ...eighteen {nineteen} twenty {one} two...
000249 }
000250 do_snippet_test $T.4.4 {two nineteen} 0 -5 {
000251 ...eighteen {nineteen} twenty one {two}...
000252 }
000253 do_snippet_test $T.4.5 {three nineteen} 0 -5 {
000254 ...{nineteen} twenty one two {three}...
000255 }
000256
000257 do_snippet_test $T.4.6 {four nineteen} 0 -5 {
000258 ...two three {four} five six...seventeen eighteen {nineteen} twenty one...
000259 }
000260 do_snippet_test $T.4.7 {four NEAR nineteen} 0 -5 {
000261 ...seventeen eighteen {nineteen} twenty one...two three {four} five six...
000262 }
000263
000264 do_snippet_test $T.4.8 {four nineteen} 0 5 {
000265 ...three {four} five...eighteen {nineteen} twenty...
000266 }
000267 do_snippet_test $T.4.9 {four NEAR nineteen} 0 5 {
000268 ...eighteen {nineteen} twenty...three {four} five...
000269 }
000270 do_snippet_test $T.4.10 {four NEAR nineteen} 0 -5 {
000271 ...seventeen eighteen {nineteen} twenty one...two three {four} five six...
000272 }
000273 do_snippet_test $T.4.11 {four NOT (nineteen twentyone)} 0 5 {
000274 ...two three {four} five six...
000275 } {
000276 ...two three {four} five six...
000277 }
000278 do_snippet_test $T.4.12 {four OR nineteen NEAR twentyone} 0 5 {
000279 ...two three {four} five six...
000280 } {
000281 ...two three {four} five six...
000282 }
000283
000284 do_test $T.5.1 {
000285 execsql {
000286 DROP TABLE IF EXISTS ft;
000287 CREATE VIRTUAL TABLE ft USING fts3(a, b, c);
000288 INSERT INTO ft VALUES(
000289 'one two three four five',
000290 'four five six seven eight',
000291 'seven eight nine ten eleven'
000292 );
000293 }
000294 } {}
000295
000296 do_snippet_test $T.5.2 {five} -1 3 {...three four {five}}
000297 do_snippet_test $T.5.3 {five} 0 3 {...three four {five}}
000298 do_snippet_test $T.5.4 {five} 1 3 {four {five} six...}
000299 do_snippet_test $T.5.5 {five} 2 3 {seven eight nine...}
000300
000301 do_test $T.5.6 {
000302 execsql { UPDATE ft SET b = NULL }
000303 } {}
000304
000305 do_snippet_test $T.5.7 {five} -1 3 {...three four {five}}
000306 do_snippet_test $T.5.8 {five} 0 3 {...three four {five}}
000307 do_snippet_test $T.5.9 {five} 1 3 {}
000308 do_snippet_test $T.5.10 {five} 2 3 {seven eight nine...}
000309
000310 do_snippet_test $T.5.11 {one "seven eight nine"} -1 -3 {
000311 {one} two three...{seven} {eight} {nine}...
000312 }
000313
000314 do_test $T.6.1 {
000315 execsql {
000316 DROP TABLE IF EXISTS ft;
000317 CREATE VIRTUAL TABLE ft USING fts3(x);
000318 INSERT INTO ft VALUES($numbers);
000319 }
000320 } {}
000321 do_snippet_test $T.6.2 {
000322 one fifty onehundred onehundredfifty twohundredfifty threehundred
000323 } -1 4 {
000324 {one}...{fifty}...{onehundred}...{onehundredfifty}...
000325 }
000326 do_snippet_test $T.6.3 {
000327 one fifty onehundred onehundredfifty twohundredfifty threehundred
000328 } -1 -4 {
000329 {one} two three four...fortyeight fortynine {fifty} fiftyone...ninetyeight ninetynine {onehundred} onehundredone...onehundredfortyeight onehundredfortynine {onehundredfifty} onehundredfiftyone...
000330 }
000331
000332 do_test $T.7.1 {
000333 execsql {
000334 BEGIN;
000335 DROP TABLE IF EXISTS ft;
000336 CREATE VIRTUAL TABLE ft USING fts3(x);
000337 }
000338 set testresults [list]
000339 for {set i 1} {$i < 150} {incr i} {
000340 set commas [string repeat , $i]
000341 execsql {INSERT INTO ft VALUES('one' || $commas || 'two')}
000342 lappend testresults "{one}$commas{two}"
000343 }
000344 execsql COMMIT
000345 } {}
000346 eval [list do_snippet_test $T.7.2 {one two} -1 3] $testresults
000347
000348 ##########################################################################
000349 # Test the matchinfo function.
000350 #
000351 proc mit {blob} {
000352 set scan(littleEndian) i*
000353 set scan(bigEndian) I*
000354 binary scan $blob $scan($::tcl_platform(byteOrder)) r
000355 return $r
000356 }
000357 db func mit mit
000358 proc do_matchinfo_test {name expr args} {
000359 set res [list]
000360 foreach a $args { lappend res [normalize $a] }
000361 do_select_test $name {
000362 SELECT mit(matchinfo(ft)) FROM ft WHERE ft MATCH $expr
000363 } $res
000364 }
000365 do_test $T.8.1 {
000366 set ten {one two three four five six seven eight nine ten}
000367 execsql {
000368 DROP TABLE IF EXISTS ft;
000369 CREATE VIRTUAL TABLE ft USING fts3;
000370 INSERT INTO ft VALUES($ten);
000371 INSERT INTO ft VALUES($ten || ' ' || $ten);
000372 }
000373 } {}
000374
000375 do_matchinfo_test $T.8.2 "one" {1 1 1 3 2} {1 1 2 3 2}
000376 do_matchinfo_test $T.8.3 "one NEAR/3 ten" {2 1 1 1 1 1 1 1}
000377 do_matchinfo_test $T.8.4 "five NEAR/4 ten" \
000378 {2 1 1 3 2 1 3 2} {2 1 2 3 2 2 3 2}
000379 do_matchinfo_test $T.8.5 "six NEAR/3 ten NEAR/3 two" \
000380 {3 1 1 1 1 1 1 1 1 1 1}
000381 do_matchinfo_test $T.8.6 "five NEAR/4 ten NEAR/3 two" \
000382 {3 1 2 2 1 1 1 1 1 1 1}
000383
000384 do_test $T.9.1 {
000385 execsql {
000386 DROP TABLE IF EXISTS ft;
000387 CREATE VIRTUAL TABLE ft USING fts3(x, y);
000388 }
000389 foreach n {1 2 3} {
000390 set v1 [lrange $numbers 0 [expr $n*100]]
000391 set v2 [string trim [string repeat "$numbers " $n]]
000392 set docid [expr $n * 1000000]
000393 execsql { INSERT INTO ft(docid, x, y) VALUES($docid, $v1, $v2) }
000394 }
000395 } {}
000396 do_matchinfo_test $T.9.2 {two*} \
000397 { 1 2 1 105 3 101 606 3} \
000398 { 1 2 3 105 3 202 606 3} \
000399 { 1 2 101 105 3 303 606 3}
000400
000401 do_matchinfo_test $T.9.4 {"one* two*"} \
000402 { 1 2 1 5 3 2 12 3} \
000403 { 1 2 2 5 3 4 12 3} \
000404 { 1 2 2 5 3 6 12 3}
000405
000406 do_matchinfo_test $T.9.5 {twohundredfifty} \
000407 { 1 2 0 1 1 1 6 3} \
000408 { 1 2 0 1 1 2 6 3} \
000409 { 1 2 1 1 1 3 6 3}
000410
000411 do_matchinfo_test $T.9.6 {"threehundred one"} \
000412 { 1 2 0 0 0 1 3 2} \
000413 { 1 2 0 0 0 2 3 2}
000414
000415 do_matchinfo_test $T.9.7 {one OR fivehundred} \
000416 { 2 2 1 3 3 1 6 3 0 0 0 0 0 0 } \
000417 { 2 2 1 3 3 2 6 3 0 0 0 0 0 0 } \
000418 { 2 2 1 3 3 3 6 3 0 0 0 0 0 0 }
000419
000420 do_matchinfo_test $T.9.8 {two OR "threehundred one"} \
000421 { 2 2 1 3 3 1 6 3 0 0 0 0 3 2 } \
000422 { 2 2 1 3 3 2 6 3 0 0 0 1 3 2 } \
000423 { 2 2 1 3 3 3 6 3 0 0 0 2 3 2 }
000424
000425 do_select_test $T.9.9 {
000426 SELECT mit(matchinfo(ft)), mit(matchinfo(ft))
000427 FROM ft WHERE ft MATCH 'two OR "threehundred one"'
000428 } [normalize {
000429 {2 2 1 3 3 1 6 3 0 0 0 0 3 2}
000430 {2 2 1 3 3 1 6 3 0 0 0 0 3 2}
000431 {2 2 1 3 3 2 6 3 0 0 0 1 3 2}
000432 {2 2 1 3 3 2 6 3 0 0 0 1 3 2}
000433 {2 2 1 3 3 3 6 3 0 0 0 2 3 2}
000434 {2 2 1 3 3 3 6 3 0 0 0 2 3 2}
000435 }]
000436
000437 # EVIDENCE-OF: R-40630-02268 If used within a SELECT that uses the
000438 # "query by rowid" or "linear scan" strategies, then the snippet and
000439 # offsets both return an empty string, and the matchinfo function
000440 # returns a blob value zero bytes in size.
000441 #
000442 set r 1000000 ;# A rowid that exists in table ft
000443 do_select_test $T.10.0 { SELECT rowid FROM ft WHERE rowid = $r } $r
000444 do_select_test $T.10.1 {
000445 SELECT length(offsets(ft)), typeof(offsets(ft)) FROM ft;
000446 } {0 text 0 text 0 text}
000447 do_select_test $T.10.2 {
000448 SELECT length(offsets(ft)), typeof(offsets(ft)) FROM ft WHERE rowid = $r
000449 } {0 text}
000450 do_select_test $T.10.3 {
000451 SELECT length(snippet(ft)), typeof(snippet(ft)) FROM ft;
000452 } {0 text 0 text 0 text}
000453 do_select_test $T.10.4 {
000454 SELECT length(snippet(ft)), typeof(snippet(ft)) FROM ft WHERE rowid = $r;
000455 } {0 text}
000456 do_select_test $T.10.5 {
000457 SELECT length(matchinfo(ft)), typeof(matchinfo(ft)) FROM ft;
000458 } {0 blob 0 blob 0 blob}
000459 do_select_test $T.10.6 {
000460 SELECT length(matchinfo(ft)), typeof(matchinfo(ft)) FROM ft WHERE rowid = $r
000461 } {0 blob}
000462 }
000463
000464 #-------------------------------------------------------------------------
000465 # Test an interaction between the snippet() function and OR clauses.
000466 #
000467 do_execsql_test 2.1 {
000468 CREATE VIRTUAL TABLE t2 USING fts4;
000469 INSERT INTO t2 VALUES('one two three four five');
000470 INSERT INTO t2 VALUES('two three four five one');
000471 INSERT INTO t2 VALUES('three four five one two');
000472 INSERT INTO t2 VALUES('four five one two three');
000473 INSERT INTO t2 VALUES('five one two three four');
000474 }
000475
000476 do_execsql_test 2.2 {
000477 SELECT snippet(t2, '[', ']') FROM t2 WHERE t2 MATCH 'one OR (four AND six)'
000478 } {
000479 {[one] two three [four] five}
000480 {two three [four] five [one]}
000481 {three [four] five [one] two}
000482 {[four] five [one] two three}
000483 {five [one] two three [four]}
000484 }
000485
000486 do_execsql_test 2.3 {
000487 SELECT snippet(t2, '[', ']') FROM t2
000488 WHERE t2 MATCH 'one OR (four AND six)'
000489 ORDER BY docid DESC
000490 } {
000491 {five [one] two three [four]}
000492 {[four] five [one] two three}
000493 {three [four] five [one] two}
000494 {two three [four] five [one]}
000495 {[one] two three [four] five}
000496 }
000497
000498 do_execsql_test 2.4 {
000499 INSERT INTO t2 VALUES('six');
000500 }
000501
000502 do_execsql_test 2.5 {
000503 SELECT snippet(t2, '[', ']') FROM t2 WHERE t2 MATCH 'one OR (four AND six)'
000504 } {
000505 {[one] two three [four] five}
000506 {two three [four] five [one]}
000507 {three [four] five [one] two}
000508 {[four] five [one] two three}
000509 {five [one] two three [four]}
000510 }
000511
000512 do_execsql_test 2.6 {
000513 SELECT snippet(t2, '[', ']') FROM t2
000514 WHERE t2 MATCH 'one OR (four AND six)'
000515 ORDER BY docid DESC
000516 } {
000517 {five [one] two three [four]}
000518 {[four] five [one] two three}
000519 {three [four] five [one] two}
000520 {two three [four] five [one]}
000521 {[one] two three [four] five}
000522 }
000523
000524 #-------------------------------------------------------------------------
000525 do_execsql_test 3 {
000526 CREATE VIRTUAL TABLE t3 USING fts4;
000527 INSERT INTO t3 VALUES('[one two three]');
000528 }
000529 do_execsql_test 3.1 {
000530 SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'one';
000531 } {{[<b>one</b> two three]}}
000532 do_execsql_test 3.2 {
000533 SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'two';
000534 } {{[one <b>two</b> three]}}
000535 do_execsql_test 3.3 {
000536 SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'three';
000537 } {{[one two <b>three</b>]}}
000538 do_execsql_test 3.4 {
000539 SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'one OR two OR three';
000540 } {{[<b>one</b> <b>two</b> <b>three</b>]}}
000541
000542 #-------------------------------------------------------------------------
000543 # Request a snippet 0 tokens in size. This is always an empty string.
000544 do_execsql_test 4.1 {
000545 CREATE VIRTUAL TABLE t4 USING fts4;
000546 INSERT INTO t4 VALUES('a b c d');
000547 SELECT snippet(t4, '[', ']', '...', 0, 0) FROM t4 WHERE t4 MATCH 'b';
000548 } {{}}
000549
000550 do_test 4.2 {
000551 set x35 [string trim [string repeat "x " 35]]
000552 execsql "INSERT INTO t4 VALUES('$x35 E $x35 F $x35 G $x35');"
000553 llength [db one {
000554 SELECT snippet(t4, '', '', '', 0, 64) FROM t4 WHERE t4 MATCH 'E'
000555 }]
000556 } {64}
000557
000558 do_test 4.3 {
000559 llength [db one {
000560 SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E'
000561 }]
000562 } {64}
000563
000564 #-------------------------------------------------------------------------
000565 # Request a snippet from a query with more than 64 phrases.
000566 #
000567 do_execsql_test 5.0 {
000568 CREATE VIRTUAL TABLE t5 USING fts3(x);
000569 INSERT INTO t5 VALUES('a1 a2 a3');
000570 INSERT INTO t5 VALUES('a4 a5 a6');
000571 INSERT INTO t5 VALUES('a70 a71 a72');
000572 }
000573
000574 do_execsql_test 5.1 {
000575 SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH
000576 'a1 OR a2 OR a3 OR a4 OR a5 OR a6 OR a7 OR a8 OR a9 OR a10 OR ' ||
000577 'a11 OR a12 OR a13 OR a14 OR a15 OR a16 OR a17 OR a18 OR a19 OR a10 OR ' ||
000578 'a21 OR a22 OR a23 OR a24 OR a25 OR a26 OR a27 OR a28 OR a29 OR a20 OR ' ||
000579 'a31 OR a32 OR a33 OR a34 OR a35 OR a36 OR a37 OR a38 OR a39 OR a30 OR ' ||
000580 'a41 OR a42 OR a43 OR a44 OR a45 OR a46 OR a47 OR a48 OR a49 OR a40 OR ' ||
000581 'a51 OR a52 OR a53 OR a54 OR a55 OR a56 OR a57 OR a58 OR a59 OR a50 OR ' ||
000582 'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' ||
000583 'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70'
000584 } {
000585 {[a1] [a2] [a3]}
000586 {[a4] [a5] [a6]}
000587 {[a70] [a71] [a72]}
000588 }
000589
000590 do_execsql_test 5.2 {
000591 SELECT snippet(t5, '[', ']', -1, 0) FROM t5 WHERE t5 MATCH 'a5'
000592 } {{a4 [a5] a6}}
000593
000594 set sqlite_fts3_enable_parentheses 0
000595 finish_test