Use a mini Bloom filter to help reduce the number of pointless searches for
[sqlite.git] / test / fts3snippet.test
blobae022b68a601814401b918ddbcfd25676d30ccfb
1 # 2010 January 07
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #*************************************************************************
12 # The tests in this file test the FTS3 auxillary functions offsets(), 
13 # snippet() and matchinfo() work. At time of writing, running this file 
14 # provides full coverage of fts3_snippet.c.
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
19 set testprefix fts3snippet
21 # If SQLITE_ENABLE_FTS3 is not defined, omit this file.
22 ifcapable !fts3 { finish_test ; return }
23 source $testdir/fts3_common.tcl
25 set sqlite_fts3_enable_parentheses 1
26 set DO_MALLOC_TEST 0
28 # Transform the list $L to its "normal" form. So that it can be compared to
29 # another list with the same set of elements using [string compare].
31 proc normalize {L} {
32   set ret [list]
33   foreach l $L {lappend ret $l}
34   return $ret
37 proc do_offsets_test {name expr args} {
38   set result [list]
39   foreach a $args {
40     lappend result [normalize $a]
41   }
42   do_select_test $name {
43     SELECT offsets(ft) FROM ft WHERE ft MATCH $expr
44   } $result
46   
47 # Document text used by a few tests. Contains the English names of all
48 # integers between 1 and 300.
50 set numbers [normalize {
51   one two three four five six seven eight nine ten eleven twelve thirteen
52   fourteen fifteen sixteen seventeen eighteen nineteen twenty twentyone
53   twentytwo twentythree twentyfour twentyfive twentysix twentyseven
54   twentyeight twentynine thirty thirtyone thirtytwo thirtythree thirtyfour
55   thirtyfive thirtysix thirtyseven thirtyeight thirtynine forty fortyone
56   fortytwo fortythree fortyfour fortyfive fortysix fortyseven fortyeight
57   fortynine fifty fiftyone fiftytwo fiftythree fiftyfour fiftyfive fiftysix
58   fiftyseven fiftyeight fiftynine sixty sixtyone sixtytwo sixtythree sixtyfour
59   sixtyfive sixtysix sixtyseven sixtyeight sixtynine seventy seventyone
60   seventytwo seventythree seventyfour seventyfive seventysix seventyseven
61   seventyeight seventynine eighty eightyone eightytwo eightythree eightyfour
62   eightyfive eightysix eightyseven eightyeight eightynine ninety ninetyone
63   ninetytwo ninetythree ninetyfour ninetyfive ninetysix ninetyseven
64   ninetyeight ninetynine onehundred onehundredone onehundredtwo
65   onehundredthree onehundredfour onehundredfive onehundredsix onehundredseven
66   onehundredeight onehundrednine onehundredten onehundredeleven
67   onehundredtwelve onehundredthirteen onehundredfourteen onehundredfifteen
68   onehundredsixteen onehundredseventeen onehundredeighteen onehundrednineteen
69   onehundredtwenty onehundredtwentyone onehundredtwentytwo
70   onehundredtwentythree onehundredtwentyfour onehundredtwentyfive
71   onehundredtwentysix onehundredtwentyseven onehundredtwentyeight
72   onehundredtwentynine onehundredthirty onehundredthirtyone
73   onehundredthirtytwo onehundredthirtythree onehundredthirtyfour
74   onehundredthirtyfive onehundredthirtysix onehundredthirtyseven
75   onehundredthirtyeight onehundredthirtynine onehundredforty
76   onehundredfortyone onehundredfortytwo onehundredfortythree
77   onehundredfortyfour onehundredfortyfive onehundredfortysix
78   onehundredfortyseven onehundredfortyeight onehundredfortynine
79   onehundredfifty onehundredfiftyone onehundredfiftytwo onehundredfiftythree
80   onehundredfiftyfour onehundredfiftyfive onehundredfiftysix
81   onehundredfiftyseven onehundredfiftyeight onehundredfiftynine
82   onehundredsixty onehundredsixtyone onehundredsixtytwo onehundredsixtythree
83   onehundredsixtyfour onehundredsixtyfive onehundredsixtysix
84   onehundredsixtyseven onehundredsixtyeight onehundredsixtynine
85   onehundredseventy onehundredseventyone onehundredseventytwo
86   onehundredseventythree onehundredseventyfour onehundredseventyfive
87   onehundredseventysix onehundredseventyseven onehundredseventyeight
88   onehundredseventynine onehundredeighty onehundredeightyone
89   onehundredeightytwo onehundredeightythree onehundredeightyfour
90   onehundredeightyfive onehundredeightysix onehundredeightyseven
91   onehundredeightyeight onehundredeightynine onehundredninety
92   onehundredninetyone onehundredninetytwo onehundredninetythree
93   onehundredninetyfour onehundredninetyfive onehundredninetysix
94   onehundredninetyseven onehundredninetyeight onehundredninetynine twohundred
95   twohundredone twohundredtwo twohundredthree twohundredfour twohundredfive
96   twohundredsix twohundredseven twohundredeight twohundrednine twohundredten
97   twohundredeleven twohundredtwelve twohundredthirteen twohundredfourteen
98   twohundredfifteen twohundredsixteen twohundredseventeen twohundredeighteen
99   twohundrednineteen twohundredtwenty twohundredtwentyone twohundredtwentytwo
100   twohundredtwentythree twohundredtwentyfour twohundredtwentyfive
101   twohundredtwentysix twohundredtwentyseven twohundredtwentyeight
102   twohundredtwentynine twohundredthirty twohundredthirtyone
103   twohundredthirtytwo twohundredthirtythree twohundredthirtyfour
104   twohundredthirtyfive twohundredthirtysix twohundredthirtyseven
105   twohundredthirtyeight twohundredthirtynine twohundredforty
106   twohundredfortyone twohundredfortytwo twohundredfortythree
107   twohundredfortyfour twohundredfortyfive twohundredfortysix
108   twohundredfortyseven twohundredfortyeight twohundredfortynine
109   twohundredfifty twohundredfiftyone twohundredfiftytwo twohundredfiftythree
110   twohundredfiftyfour twohundredfiftyfive twohundredfiftysix
111   twohundredfiftyseven twohundredfiftyeight twohundredfiftynine
112   twohundredsixty twohundredsixtyone twohundredsixtytwo twohundredsixtythree
113   twohundredsixtyfour twohundredsixtyfive twohundredsixtysix
114   twohundredsixtyseven twohundredsixtyeight twohundredsixtynine
115   twohundredseventy twohundredseventyone twohundredseventytwo
116   twohundredseventythree twohundredseventyfour twohundredseventyfive
117   twohundredseventysix twohundredseventyseven twohundredseventyeight
118   twohundredseventynine twohundredeighty twohundredeightyone
119   twohundredeightytwo twohundredeightythree twohundredeightyfour
120   twohundredeightyfive twohundredeightysix twohundredeightyseven
121   twohundredeightyeight twohundredeightynine twohundredninety
122   twohundredninetyone twohundredninetytwo twohundredninetythree
123   twohundredninetyfour twohundredninetyfive twohundredninetysix
124   twohundredninetyseven twohundredninetyeight twohundredninetynine
125   threehundred
128 foreach {DO_MALLOC_TEST enc} {
129   0 utf8
130   1 utf8
131   1 utf16
132 } {
134   db close
135   forcedelete test.db
136   sqlite3 db test.db
137   sqlite3_db_config_lookaside db 0 0 0
138   db eval "PRAGMA encoding = \"$enc\""
140   # Set variable $T to the test name prefix for this iteration of the loop.
141   #
142   set T "fts3snippet-1.$enc"
144   ##########################################################################
145   # Test the offset function.
146   #
147   do_test $T.1.1 {
148     execsql {
149       CREATE VIRTUAL TABLE ft USING fts3;
150       INSERT INTO ft VALUES('xxx xxx xxx xxx');
151     }
152   } {}
153   do_offsets_test $T.1.2 {xxx} {0 0 0 3 0 0 4 3 0 0 8 3 0 0 12 3}
154   do_offsets_test $T.1.3 {"xxx xxx"} {
155       0 0  0 3     0 0  4 3     0 1  4 3     0 0  8 3 
156       0 1  8 3     0 1 12 3
157   }
158   do_offsets_test $T.1.4 {"xxx xxx" xxx} {
159       0 0  0 3     0 2  0 3     0 0  4 3     0 1  4 3 
160       0 2  4 3     0 0  8 3     0 1  8 3     0 2  8 3 
161       0 1 12 3     0 2 12 3
162   }
163   do_offsets_test $T.1.5 {xxx "xxx xxx"} {
164       0 0  0 3     0 1  0 3     0 0  4 3     0 1  4 3 
165       0 2  4 3     0 0  8 3     0 1  8 3     0 2  8 3 
166       0 0 12 3     0 2 12 3
167   }
169   do_test $T.2.1 {
170     set v1 [lrange $numbers 0 99]
171     execsql {
172       DROP TABLE IF EXISTS ft;
173       CREATE VIRTUAL TABLE ft USING fts3(a, b);
174       INSERT INTO ft VALUES($v1, $numbers);
175       INSERT INTO ft VALUES($v1, NULL);
176     }
177   } {}
179   set off [string first "twohundred " $numbers]
180   do_offsets_test $T.2.1 {twohundred} [list 1 0 $off 10]
182   set off [string first "onehundred " $numbers]
183   do_offsets_test $T.2.2 {onehundred} \
184     [list 0 0 $off 10 1 0 $off 10] [list 0 0 $off 10]
186   # Test a corruption case:
187   sqlite3_db_config db DEFENSIVE 0
188   execsql { UPDATE ft_content SET c1b = 'hello world' WHERE c1b = $numbers }
189   do_error_test $T.2.3 {
190     SELECT offsets(ft) FROM ft WHERE ft MATCH 'onehundred'
191   } {database disk image is malformed}
192   
193   ##########################################################################
194   # Test the snippet function.
195   #
196   proc do_snippet_test {name expr iCol nTok args} {
197     set res [list]
198     foreach a $args { lappend res [string trim $a] }
199     do_select_test $name {
200       SELECT snippet(ft,'{','}','...',$iCol,$nTok) FROM ft WHERE ft MATCH $expr
201     } $res
202   }
203   do_test $T.3.1 {
204     execsql {
205       DROP TABLE IF EXISTS ft;
206       CREATE VIRTUAL TABLE ft USING fts3;
207       INSERT INTO ft VALUES('one two three four five six seven eight nine ten');
208     }
209   } {}
210   do_snippet_test $T.3.2  one    0 5 "{one} two three four five..."
211   do_snippet_test $T.3.3  two    0 5 "one {two} three four five..."
212   do_snippet_test $T.3.4  three  0 5 "one two {three} four five..."
213   do_snippet_test $T.3.5  four   0 5 "...two three {four} five six..."
214   do_snippet_test $T.3.6  five   0 5 "...three four {five} six seven..."
215   do_snippet_test $T.3.7  six    0 5 "...four five {six} seven eight..."
216   do_snippet_test $T.3.8  seven  0 5 "...five six {seven} eight nine..."
217   do_snippet_test $T.3.9  eight  0 5 "...six seven {eight} nine ten"
218   do_snippet_test $T.3.10 nine   0 5 "...six seven eight {nine} ten"
219   do_snippet_test $T.3.11 ten    0 5 "...six seven eight nine {ten}"
220   
221   do_test $T.4.1 {
222     execsql {
223       INSERT INTO ft VALUES(
224            'one two three four five '
225         || 'six seven eight nine ten '
226         || 'eleven twelve thirteen fourteen fifteen '
227         || 'sixteen seventeen eighteen nineteen twenty '
228         || 'one two three four five '
229         || 'six seven eight nine ten '
230         || 'eleven twelve thirteen fourteen fifteen '
231         || 'sixteen seventeen eighteen nineteen twenty'
232       );
233     }
234   } {}
235   
236   do_snippet_test $T.4.2 {one nine} 0 5 {
237      {one} two three...eight {nine} ten
238   } {
239      {one} two three...eight {nine} ten...
240   }
241   
242   do_snippet_test $T.4.3 {one nine} 0 -5 {
243      {one} two three four five...six seven eight {nine} ten
244   } {
245      {one} two three four five...seven eight {nine} ten eleven...
246   }
247   do_snippet_test $T.4.3 {one nineteen} 0 -5 {
248      ...eighteen {nineteen} twenty {one} two...
249   }
250   do_snippet_test $T.4.4 {two nineteen} 0 -5 {
251      ...eighteen {nineteen} twenty one {two}...
252   }
253   do_snippet_test $T.4.5 {three nineteen} 0 -5 {
254      ...{nineteen} twenty one two {three}...
255   }
256   
257   do_snippet_test $T.4.6 {four nineteen} 0 -5 {
258      ...two three {four} five six...seventeen eighteen {nineteen} twenty one...
259   }
260   do_snippet_test $T.4.7 {four NEAR nineteen} 0 -5 {
261      ...seventeen eighteen {nineteen} twenty one...two three {four} five six...
262   }
263   
264   do_snippet_test $T.4.8 {four nineteen} 0 5 {
265      ...three {four} five...eighteen {nineteen} twenty...
266   }
267   do_snippet_test $T.4.9 {four NEAR nineteen} 0 5 {
268      ...eighteen {nineteen} twenty...three {four} five...
269   }
270   do_snippet_test $T.4.10 {four NEAR nineteen} 0 -5 {
271      ...seventeen eighteen {nineteen} twenty one...two three {four} five six...
272   }
273   do_snippet_test $T.4.11 {four NOT (nineteen twentyone)} 0 5 {
274      ...two three {four} five six...
275   } {
276      ...two three {four} five six...
277   }
278   do_snippet_test $T.4.12 {four OR nineteen NEAR twentyone} 0 5 {
279      ...two three {four} five six...
280   } {
281      ...two three {four} five six...
282   }
283   
284   do_test $T.5.1 {
285     execsql {
286       DROP TABLE IF EXISTS ft;
287       CREATE VIRTUAL TABLE ft USING fts3(a, b, c);
288       INSERT INTO ft VALUES(
289         'one two three four five', 
290         'four five six seven eight', 
291         'seven eight nine ten eleven'
292       );
293     }
294   } {}
295   
296   do_snippet_test $T.5.2 {five} -1 3 {...three four {five}}
297   do_snippet_test $T.5.3 {five}  0 3 {...three four {five}}
298   do_snippet_test $T.5.4 {five}  1 3 {four {five} six...}
299   do_snippet_test $T.5.5 {five}  2 3 {seven eight nine...}
300   
301   do_test $T.5.6 {
302     execsql { UPDATE ft SET b = NULL }
303   } {}
304   
305   do_snippet_test $T.5.7  {five} -1 3 {...three four {five}}
306   do_snippet_test $T.5.8  {five}  0 3 {...three four {five}}
307   do_snippet_test $T.5.9  {five}  1 3 {}
308   do_snippet_test $T.5.10 {five}  2 3 {seven eight nine...}
309   
310   do_snippet_test $T.5.11 {one "seven eight nine"} -1 -3 {
311     {one} two three...{seven} {eight} {nine}...
312   }
314   do_test $T.6.1 {
315     execsql {
316       DROP TABLE IF EXISTS ft;
317       CREATE VIRTUAL TABLE ft USING fts3(x);
318       INSERT INTO ft VALUES($numbers);
319     }
320   } {}
321   do_snippet_test $T.6.2 {
322     one fifty onehundred onehundredfifty twohundredfifty threehundred
323   } -1 4 {
324     {one}...{fifty}...{onehundred}...{onehundredfifty}...
325   }
326   do_snippet_test $T.6.3 {
327     one fifty onehundred onehundredfifty twohundredfifty threehundred
328   } -1 -4 {
329     {one} two three four...fortyeight fortynine {fifty} fiftyone...ninetyeight ninetynine {onehundred} onehundredone...onehundredfortyeight onehundredfortynine {onehundredfifty} onehundredfiftyone...
330   }
332   do_test $T.7.1 {
333     execsql {
334       BEGIN;
335         DROP TABLE IF EXISTS ft;
336         CREATE VIRTUAL TABLE ft USING fts3(x);
337     }
338     set testresults [list]
339     for {set i 1} {$i < 150} {incr i} {
340       set commas [string repeat , $i]
341       execsql {INSERT INTO ft VALUES('one' || $commas || 'two')}
342       lappend testresults "{one}$commas{two}"
343     }
344     execsql COMMIT
345   } {}
346   eval [list do_snippet_test $T.7.2 {one two} -1 3] $testresults
347   
348   ##########################################################################
349   # Test the matchinfo function.
350   #
351   proc mit {blob} {
352     set scan(littleEndian) i*
353     set scan(bigEndian) I*
354     binary scan $blob $scan($::tcl_platform(byteOrder)) r
355     return $r
356   }
357   db func mit mit
358   proc do_matchinfo_test {name expr args} {
359     set res [list]
360     foreach a $args { lappend res [normalize $a] }
361     do_select_test $name {
362       SELECT mit(matchinfo(ft)) FROM ft WHERE ft MATCH $expr
363     } $res
364   }
365   do_test $T.8.1 {
366     set ten {one two three four five six seven eight nine ten}
367     execsql {
368       DROP TABLE IF EXISTS ft;
369       CREATE VIRTUAL TABLE ft USING fts3;
370       INSERT INTO ft VALUES($ten);
371       INSERT INTO ft VALUES($ten || ' ' || $ten);
372     }
373   } {}
374   
375   do_matchinfo_test $T.8.2 "one" {1 1  1 3 2} {1 1  2 3 2}
376   do_matchinfo_test $T.8.3 "one NEAR/3 ten" {2 1  1 1 1 1 1 1}
377   do_matchinfo_test $T.8.4 "five NEAR/4 ten" \
378     {2 1  1 3 2  1 3 2} {2 1  2 3 2  2 3 2}
379   do_matchinfo_test $T.8.5 "six NEAR/3 ten NEAR/3 two" \
380     {3 1  1 1 1  1 1 1  1 1 1}
381   do_matchinfo_test $T.8.6 "five NEAR/4 ten NEAR/3 two" \
382     {3 1  2 2 1  1 1 1  1 1 1}
384   do_test $T.9.1 {
385     execsql {
386       DROP TABLE IF EXISTS ft;
387       CREATE VIRTUAL TABLE ft USING fts3(x, y);
388     }
389     foreach n {1 2 3} {
390       set v1 [lrange $numbers 0 [expr $n*100]]
391       set v2 [string trim [string repeat "$numbers " $n]]
392       set docid [expr $n * 1000000]
393       execsql { INSERT INTO ft(docid, x, y) VALUES($docid, $v1, $v2) }
394     }
395   } {}
396   do_matchinfo_test $T.9.2 {two*}     \
397     { 1 2    1   105 3   101 606 3}   \
398     { 1 2    3   105 3   202 606 3}   \
399     { 1 2    101 105 3   303 606 3}
401   do_matchinfo_test $T.9.4 {"one* two*"}  \
402     { 1 2    1 5 3   2 12 3}              \
403     { 1 2    2 5 3   4 12 3}              \
404     { 1 2    2 5 3   6 12 3}
406   do_matchinfo_test $T.9.5 {twohundredfifty}  \
407     { 1 2    0 1 1   1 6 3}                   \
408     { 1 2    0 1 1   2 6 3}                   \
409     { 1 2    1 1 1   3 6 3}
411   do_matchinfo_test $T.9.6 {"threehundred one"} \
412     { 1 2    0 0 0   1 3 2}                     \
413     { 1 2    0 0 0   2 3 2}
415   do_matchinfo_test $T.9.7 {one OR fivehundred} \
416     { 2 2    1 3 3   1 6 3   0 0 0   0 0 0 }    \
417     { 2 2    1 3 3   2 6 3   0 0 0   0 0 0 }    \
418     { 2 2    1 3 3   3 6 3   0 0 0   0 0 0 }
420   do_matchinfo_test $T.9.8 {two OR "threehundred one"} \
421     { 2 2    1 3 3   1 6 3   0 0 0   0 3 2 }           \
422     { 2 2    1 3 3   2 6 3   0 0 0   1 3 2 }           \
423     { 2 2    1 3 3   3 6 3   0 0 0   2 3 2 }
425   do_select_test $T.9.9 {
426     SELECT mit(matchinfo(ft)), mit(matchinfo(ft))
427     FROM ft WHERE ft MATCH 'two OR "threehundred one"' 
428   } [normalize {
429     {2 2 1 3 3 1 6 3 0 0 0 0 3 2}
430     {2 2 1 3 3 1 6 3 0 0 0 0 3 2}
431     {2 2 1 3 3 2 6 3 0 0 0 1 3 2}
432     {2 2 1 3 3 2 6 3 0 0 0 1 3 2}
433     {2 2 1 3 3 3 6 3 0 0 0 2 3 2}          
434     {2 2 1 3 3 3 6 3 0 0 0 2 3 2}
435   }]
437   # EVIDENCE-OF: R-40630-02268 If used within a SELECT that uses the
438   # "query by rowid" or "linear scan" strategies, then the snippet and
439   # offsets both return an empty string, and the matchinfo function
440   # returns a blob value zero bytes in size.
441   #
442   set r 1000000                   ;# A rowid that exists in table ft
443   do_select_test $T.10.0 { SELECT rowid FROM ft WHERE rowid = $r } $r
444   do_select_test $T.10.1 {
445     SELECT length(offsets(ft)), typeof(offsets(ft)) FROM ft;
446   } {0 text 0 text 0 text}
447   do_select_test $T.10.2 {
448     SELECT length(offsets(ft)), typeof(offsets(ft)) FROM ft WHERE rowid = $r
449   } {0 text}
450   do_select_test $T.10.3 {
451     SELECT length(snippet(ft)), typeof(snippet(ft)) FROM ft;
452   } {0 text 0 text 0 text}
453   do_select_test $T.10.4 {
454     SELECT length(snippet(ft)), typeof(snippet(ft)) FROM ft WHERE rowid = $r;
455   } {0 text}
456   do_select_test $T.10.5 {
457     SELECT length(matchinfo(ft)), typeof(matchinfo(ft)) FROM ft;
458   } {0 blob 0 blob 0 blob}
459   do_select_test $T.10.6 {
460     SELECT length(matchinfo(ft)), typeof(matchinfo(ft)) FROM ft WHERE rowid = $r
461   } {0 blob}
464 #-------------------------------------------------------------------------
465 # Test an interaction between the snippet() function and OR clauses.
467 do_execsql_test 2.1 {
468   CREATE VIRTUAL TABLE t2 USING fts4;
469   INSERT INTO t2 VALUES('one two three four five');
470   INSERT INTO t2 VALUES('two three four five one');
471   INSERT INTO t2 VALUES('three four five one two');
472   INSERT INTO t2 VALUES('four five one two three');
473   INSERT INTO t2 VALUES('five one two three four');
476 do_execsql_test 2.2 {
477   SELECT snippet(t2, '[', ']') FROM t2 WHERE t2 MATCH 'one OR (four AND six)'
478 } {
479   {[one] two three [four] five}
480   {two three [four] five [one]}
481   {three [four] five [one] two}
482   {[four] five [one] two three}
483   {five [one] two three [four]}
486 do_execsql_test 2.3 {
487   SELECT snippet(t2, '[', ']') FROM t2 
488   WHERE t2 MATCH 'one OR (four AND six)' 
489   ORDER BY docid DESC
490 } {
491   {five [one] two three [four]}
492   {[four] five [one] two three}
493   {three [four] five [one] two}
494   {two three [four] five [one]}
495   {[one] two three [four] five}
498 do_execsql_test 2.4 {
499   INSERT INTO t2 VALUES('six');
502 do_execsql_test 2.5 {
503   SELECT snippet(t2, '[', ']') FROM t2 WHERE t2 MATCH 'one OR (four AND six)'
504 } {
505   {[one] two three [four] five}
506   {two three [four] five [one]}
507   {three [four] five [one] two}
508   {[four] five [one] two three}
509   {five [one] two three [four]}
512 do_execsql_test 2.6 {
513   SELECT snippet(t2, '[', ']') FROM t2 
514   WHERE t2 MATCH 'one OR (four AND six)' 
515   ORDER BY docid DESC
516 } {
517   {five [one] two three [four]}
518   {[four] five [one] two three}
519   {three [four] five [one] two}
520   {two three [four] five [one]}
521   {[one] two three [four] five}
524 #-------------------------------------------------------------------------
525 do_execsql_test 3 {
526   CREATE VIRTUAL TABLE t3 USING fts4;
527   INSERT INTO t3 VALUES('[one two three]');
529 do_execsql_test 3.1 {
530   SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'one';
531 } {{[<b>one</b> two three]}}
532 do_execsql_test 3.2 {
533   SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'two';
534 } {{[one <b>two</b> three]}}
535 do_execsql_test 3.3 {
536   SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'three';
537 } {{[one two <b>three</b>]}}
538 do_execsql_test 3.4 {
539   SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'one OR two OR three';
540 } {{[<b>one</b> <b>two</b> <b>three</b>]}}
542 #-------------------------------------------------------------------------
543 # Request a snippet 0 tokens in size. This is always an empty string.
544 do_execsql_test 4.1 {
545   CREATE VIRTUAL TABLE t4 USING fts4;
546   INSERT INTO t4 VALUES('a b c d');
547   SELECT snippet(t4, '[', ']', '...', 0, 0) FROM t4 WHERE t4 MATCH 'b';
548 } {{}}
550 do_test 4.2 {
551   set x35 [string trim [string repeat "x " 35]]
552   execsql "INSERT INTO t4 VALUES('$x35 E $x35 F $x35 G $x35');"
553   llength [db one {
554     SELECT snippet(t4, '', '', '', 0, 64) FROM t4 WHERE t4 MATCH 'E'
555   }]
556 } {64}
558 do_test 4.3 {
559   llength [db one {
560     SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E'
561   }]
562 } {64}
565 #-------------------------------------------------------------------------
566 # Request a snippet from a query with more than 64 phrases.
568 do_execsql_test 5.0 {
569   CREATE VIRTUAL TABLE t5 USING fts3(x);
570   INSERT INTO t5 VALUES('a1 a2 a3');
571   INSERT INTO t5 VALUES('a4 a5 a6');
572   INSERT INTO t5 VALUES('a70 a71 a72');
575 do_execsql_test 5.1 {
576   SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH 
577   'a1 OR a2 OR a3 OR a4 OR a5 OR a6 OR a7 OR a8 OR a9 OR a10 OR ' ||
578   'a11 OR a12 OR a13 OR a14 OR a15 OR a16 OR a17 OR a18 OR a19 OR a10 OR ' ||
579   'a21 OR a22 OR a23 OR a24 OR a25 OR a26 OR a27 OR a28 OR a29 OR a20 OR ' ||
580   'a31 OR a32 OR a33 OR a34 OR a35 OR a36 OR a37 OR a38 OR a39 OR a30 OR ' ||
581   'a41 OR a42 OR a43 OR a44 OR a45 OR a46 OR a47 OR a48 OR a49 OR a40 OR ' ||
582   'a51 OR a52 OR a53 OR a54 OR a55 OR a56 OR a57 OR a58 OR a59 OR a50 OR ' ||
583   'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' ||
584   'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70'
585 } {
586   {[a1] [a2] [a3]}
587   {[a4] [a5] [a6]}
588   {[a70] [a71] [a72]}
591 set sqlite_fts3_enable_parentheses 0
592 finish_test