3 # May you do good and not evil.
4 # May you find forgiveness for yourself and forgive others.
5 # May you share freely, never taking more than you give.
7 #***********************************************************************
10 set testdir [file dirname $argv0]
11 source $testdir/tester.tcl
13 # If this build does not include FTS3, skip the tests in this file.
15 ifcapable !fts3 { finish_test ; return }
16 source $testdir/fts3_common.tcl
17 source $testdir/malloc_common.tcl
19 set testprefix fts3auto
20 set sfep $sqlite_fts3_enable_parentheses
21 set sqlite_fts3_enable_parentheses 1
23 #--------------------------------------------------------------------------
24 # Start of Tcl infrastructure used by tests. The entry points are:
27 # fts3_make_deferrable
28 # fts3_zero_long_segments
32 # do_fts3query_test TESTNAME ?OPTIONS? TABLE MATCHEXPR
34 # This proc runs several test cases on FTS3/4 table $TABLE using match
35 # expression $MATCHEXPR. All documents in $TABLE must be formatted so that
36 # they can be "tokenized" using the Tcl list commands (llength, lindex etc.).
37 # The name and column names used by $TABLE must not require any quoting or
38 # escaping when used in SQL statements.
40 # $MATCHINFO may be any expression accepted by the FTS4 MATCH operator,
41 # except that the "<column-name>:token" syntax is not supported. Tcl list
42 # commands are used to tokenize the expression. Any parenthesis must appear
43 # either as separate list elements, or as the first (for opening) or last
44 # (for closing) character of a list element. i.e. the expression "(a OR b)c"
45 # will not be parsed correctly, but "( a OR b) c" will.
47 # Available OPTIONS are:
51 # If the "deferred" option is supplied, it is passed a list of tokens that
52 # are deferred by FTS and result in the relevant matchinfo() stats being an
55 set sqlite_fts3_enable_parentheses 1
56 proc do_fts3query_test {tn args} {
58 set nArg [llength $args]
59 if {$nArg < 2 || ($nArg % 2)} {
60 set cmd do_fts3query_test
61 error "wrong # args: should be \"$cmd ?-deferred LIST? TABLE MATCHEXPR\""
63 set tbl [lindex $args [expr $nArg-2]]
64 set match [lindex $args [expr $nArg-1]]
67 foreach {k v} [lrange $args 0 [expr $nArg-3]] {
70 ifcapable fts4_deferred { set deferred $v }
73 error "bad option \"$k\": must be -deferred"
78 get_near_results $tbl $match $deferred aHit
79 get_near_results $tbl [string map {AND OR} $match] $deferred aMatchinfo
81 set matchinfo_asc [list]
82 foreach docid [lsort -integer -incr [array names aHit]] {
83 lappend matchinfo_asc $docid $aMatchinfo($docid)
85 set matchinfo_desc [list]
86 foreach docid [lsort -integer -decr [array names aHit]] {
87 lappend matchinfo_desc $docid $aMatchinfo($docid)
90 set title "(\"$match\" -> [llength [array names aHit]] rows)"
92 do_execsql_test $tn$title.1 "
93 SELECT docid FROM $tbl WHERE $tbl MATCH '$match' ORDER BY docid ASC
94 " [lsort -integer -incr [array names aHit]]
96 do_execsql_test $tn$title.2 "
97 SELECT docid FROM $tbl WHERE $tbl MATCH '$match' ORDER BY docid DESC
98 " [lsort -integer -decr [array names aHit]]
100 do_execsql_test $tn$title.3 "
101 SELECT docid, mit(matchinfo($tbl, 'x')) FROM $tbl
102 WHERE $tbl MATCH '$match' ORDER BY docid DESC
105 do_execsql_test $tn$title.4 "
106 SELECT docid, mit(matchinfo($tbl, 'x')) FROM $tbl
107 WHERE $tbl MATCH '$match' ORDER BY docid ASC
111 # fts3_make_deferrable TABLE TOKEN ?NROW?
113 proc fts3_make_deferrable {tbl token {nRow 0}} {
115 set stmt [sqlite3_prepare db "SELECT * FROM $tbl" -1 dummy]
116 set name [sqlite3_column_name $stmt 0]
117 sqlite3_finalize $stmt
120 set nRow [db one "SELECT count(*) FROM $tbl"]
122 set pgsz [db one "PRAGMA page_size"]
124 for {set i 0} {$i < ($nRow * $pgsz * 1.2)/100} {incr i} {
125 set doc [string repeat "$token " 100]
126 execsql "INSERT INTO $tbl ($name) VALUES(\$doc)"
128 execsql "INSERT INTO $tbl ($name) VALUES('aaaaaaa ${token}aaaaa')"
131 return [expr $nRow*$pgsz]
134 # fts3_zero_long_segments TABLE ?LIMIT?
136 proc fts3_zero_long_segments {tbl limit} {
137 sqlite3_db_config db DEFENSIVE 0
139 UPDATE ${tbl}_segments
140 SET block = zeroblob(length(block))
141 WHERE length(block)>$limit
148 set scan(littleEndian) i*
149 set scan(bigEndian) I*
150 binary scan $blob $scan($::tcl_platform(byteOrder)) r
155 proc fix_phrase_expr {cols expr colfiltervar} {
156 upvar $colfiltervar iColFilter
160 if {[string match *:* $t]} {
161 set col [lindex [split $t :] 0]
162 set t [lindex [split $t :] 1]
163 set iCol [lsearch $cols $col]
164 if {$iCol<0} { error "unknown column: $col" }
165 if {$iColFilter < 0} {
167 } elseif {$iColFilter != $iCol} {
168 set iColFilter [llength $cols]
177 proc fix_near_expr {cols expr colfiltervar} {
178 upvar $colfiltervar iColFilter
183 lappend out [fix_phrase_expr $cols [lindex $expr 0] iColFilter]
184 foreach {a b} [lrange $expr 1 end] {
185 if {[string match -nocase near $a]} { set a 10 }
186 if {[string match -nocase near/* $a]} { set a [string range $a 5 end] }
188 lappend out [fix_phrase_expr $cols $b iColFilter]
193 proc get_single_near_results {tbl expr deferred arrayvar nullvar} {
194 upvar $arrayvar aMatchinfo
195 upvar $nullvar nullentry
196 catch {array unset aMatchinfo}
200 db eval "PRAGMA table_info($tbl)" A { lappend cols $A(name) ; lappend miss 0 }
201 set expr [fix_near_expr $cols $expr iColFilter]
203 # Calculate the expected results using [fts3_near_match]. The following
204 # loop populates the "hits" and "counts" arrays as follows:
206 # 1. For each document in the table that matches the NEAR expression,
207 # hits($docid) is set to 1. The set of docids that match the expression
208 # can therefore be found using [array names hits].
210 # 2. For each column of each document in the table, counts($docid,$iCol)
211 # is set to the -phrasecountvar output.
214 catch { array unset hits }
215 db eval "SELECT docid, * FROM $tbl" d {
217 foreach col [lrange $d(*) 1 end] {
219 if {$iColFilter<0 || $iCol==$iColFilter} {
220 set hit [fts3_near_match $d($col) $expr -p counts($docid,$iCol)]
221 if {$hit} { set hits($docid) 1 }
223 set counts($docid,$iCol) $miss
228 set nPhrase [expr ([llength $expr]+1)/2]
231 # This block populates the nHit and nDoc arrays. For each phrase/column
232 # in the query/table, array elements are set as follows:
234 # nHit($iPhrase,$iCol) - Total number of hits for phrase $iPhrase in
237 # nDoc($iPhrase,$iCol) - Number of documents with at least one hit for
238 # phrase $iPhrase in column $iCol.
240 for {set iPhrase 0} {$iPhrase < $nPhrase} {incr iPhrase} {
241 for {set iCol 0} {$iCol < $nCol} {incr iCol} {
242 set nHit($iPhrase,$iCol) 0
243 set nDoc($iPhrase,$iCol) 0
246 foreach key [array names counts] {
247 set iCol [lindex [split $key ,] 1]
249 foreach c $counts($key) {
250 if {$c>0} { incr nDoc($iPhrase,$iCol) 1 }
251 incr nHit($iPhrase,$iCol) $c
256 if {[llength $deferred] && [llength $expr]==1} {
257 set phrase [lindex $expr 0]
260 foreach tok $phrase {
261 if {[lsearch $deferred $tok]>=0} {
264 lappend rewritten $tok
269 set tblsize [db one "SELECT count(*) FROM $tbl"]
270 for {set iCol 0} {$iCol < $nCol} {incr iCol} {
271 set nHit(0,$iCol) $tblsize
272 set nDoc(0,$iCol) $tblsize
274 } elseif {$rewritten != $phrase} {
275 while {[lindex $rewritten end] == "*"} {
276 set rewritten [lrange $rewritten 0 end-1]
278 while {[lindex $rewritten 0] == "*"} {
279 set rewritten [lrange $rewritten 1 end]
281 get_single_near_results $tbl [list $rewritten] {} aRewrite nullentry
282 foreach docid [array names hits] {
283 set aMatchinfo($docid) $aRewrite($docid)
289 # Set up the aMatchinfo array. For each document, set aMatchinfo($docid) to
290 # contain the output of matchinfo('x') for the document.
292 foreach docid [array names hits] {
294 for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} {
295 for {set iCol 0} {$iCol<$nCol} {incr iCol} {
296 lappend mi [lindex $counts($docid,$iCol) $iPhrase]
297 lappend mi $nHit($iPhrase,$iCol)
298 lappend mi $nDoc($iPhrase,$iCol)
301 set aMatchinfo($docid) $mi
304 # Set up the nullentry output.
307 for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} {
308 for {set iCol 0} {$iCol<$nCol} {incr iCol} {
309 lappend nullentry 0 $nHit($iPhrase,$iCol) $nDoc($iPhrase,$iCol)
315 proc matching_brackets {expr} {
316 if {[string range $expr 0 0]!="(" || [string range $expr end end] !=")"} {
321 set nExpr [string length $expr]
322 for {set i 1} {$iBracket && $i < $nExpr} {incr i} {
323 set c [string range $expr $i $i]
324 if {$c == "("} {incr iBracket}
325 if {$c == ")"} {incr iBracket -1}
328 return [expr ($iBracket==0 && $i==$nExpr)]
331 proc get_near_results {tbl expr deferred arrayvar {nullvar ""}} {
332 upvar $arrayvar aMatchinfo
333 if {$nullvar != ""} { upvar $nullvar nullentry }
335 set expr [string trim $expr]
336 while { [matching_brackets $expr] } {
337 set expr [string trim [string range $expr 1 end-1]]
346 set expr_length [llength $expr]
347 for {set i 0} {$i < $expr_length} {incr i} {
348 set op [lindex $expr $i]
349 if {$iBracket==0 && [info exists prec($op)] && $prec($op)>=$currentprec } {
351 set currentprec $prec($op)
353 for {set j 0} {$j < [string length $op]} {incr j} {
354 set c [string range $op $j $j]
355 if {$c == "("} { incr iBracket +1 }
356 if {$c == ")"} { incr iBracket -1 }
360 if {$iBracket!=0} { error "mismatched brackets in: $expr" }
362 if {[info exists opidx]==0} {
363 get_single_near_results $tbl $expr $deferred aMatchinfo nullentry
365 set eLeft [lrange $expr 0 [expr $opidx-1]]
366 set eRight [lrange $expr [expr $opidx+1] end]
368 get_near_results $tbl $eLeft $deferred aLeft nullleft
369 get_near_results $tbl $eRight $deferred aRight nullright
371 switch -- [lindex $expr $opidx] {
373 foreach hit [array names aLeft] {
374 if {0==[info exists aRight($hit)]} {
375 set aMatchinfo($hit) $aLeft($hit)
378 set nullentry $nullleft
382 foreach hit [array names aLeft] {
383 if {[info exists aRight($hit)]} {
384 set aMatchinfo($hit) [concat $aLeft($hit) $aRight($hit)]
387 set nullentry [concat $nullleft $nullright]
391 foreach hit [array names aLeft] {
392 if {[info exists aRight($hit)]} {
393 set aMatchinfo($hit) [concat $aLeft($hit) $aRight($hit)]
396 set aMatchinfo($hit) [concat $aLeft($hit) $nullright]
399 foreach hit [array names aRight] {
400 set aMatchinfo($hit) [concat $nullleft $aRight($hit)]
403 set nullentry [concat $nullleft $nullright]
410 # End of test procs. Actual tests are below this line.
411 #--------------------------------------------------------------------------
413 #--------------------------------------------------------------------------
414 # The following test cases - fts3auto-1.* - focus on testing the Tcl
415 # command [fts3_near_match], which is used by other tests in this file.
417 proc test_fts3_near_match {tn doc expr res} {
418 fts3_near_match $doc $expr -phrasecountvar p
419 uplevel do_test [list $tn] [list [list set {} $p]] [list $res]
422 test_fts3_near_match 1.1.1 {a b c a b} a {2}
423 test_fts3_near_match 1.1.2 {a b c a b} {a 5 b 6 c} {2 2 1}
424 test_fts3_near_match 1.1.3 {a b c a b} {"a b"} {2}
425 test_fts3_near_match 1.1.4 {a b c a b} {"b c"} {1}
426 test_fts3_near_match 1.1.5 {a b c a b} {"c c"} {0}
428 test_fts3_near_match 1.2.1 "a b c d e f g" {b 2 f} {0 0}
429 test_fts3_near_match 1.2.2 "a b c d e f g" {b 3 f} {1 1}
430 test_fts3_near_match 1.2.3 "a b c d e f g" {f 2 b} {0 0}
431 test_fts3_near_match 1.2.4 "a b c d e f g" {f 3 b} {1 1}
432 test_fts3_near_match 1.2.5 "a b c d e f g" {"a b" 2 "f g"} {0 0}
433 test_fts3_near_match 1.2.6 "a b c d e f g" {"a b" 3 "f g"} {1 1}
435 set A "a b c d e f g h i j k l m n o p q r s t u v w x y z"
436 test_fts3_near_match 1.3.1 $A {"c d" 5 "i j" 1 "e f"} {0 0 0}
437 test_fts3_near_match 1.3.2 $A {"c d" 5 "i j" 2 "e f"} {1 1 1}
439 #--------------------------------------------------------------------------
440 # Test cases fts3auto-2.* run some simple tests using the
441 # [do_fts3query_test] proc.
443 foreach {tn create} {
445 2 "fts4(a, b, order=DESC)"
446 3 "fts4(a, b, order=ASC)"
447 4 "fts4(a, b, prefix=1)"
448 5 "fts4(a, b, order=DESC, prefix=1)"
449 6 "fts4(a, b, order=ASC, prefix=1)"
452 catchsql { DROP TABLE t1 }
453 execsql "CREATE VIRTUAL TABLE t1 USING $create"
454 for {set i 0} {$i<32} {incr i} {
456 if {$i&0x01} {lappend doc one}
457 if {$i&0x02} {lappend doc two}
458 if {$i&0x04} {lappend doc three}
459 if {$i&0x08} {lappend doc four}
460 if {$i&0x10} {lappend doc five}
461 execsql { INSERT INTO t1 VALUES($doc, null) }
471 6 {one NEAR five NEAR two NEAR four NEAR three}
476 11 {one AND two OR three}
477 12 {three OR one AND two}
478 13 {(three OR one) AND two}
479 14 {(three OR one) AND two NOT (five NOT four)}
481 16 {"one two" NOT "three four"}
483 do_fts3query_test 2.$tn.2.$tn2 t1 $expr
487 #--------------------------------------------------------------------------
488 # Some test cases involving deferred tokens.
491 foreach {tn create} {
493 2 "fts4(x, order=DESC)"
495 catchsql { DROP TABLE t1 }
496 execsql "CREATE VIRTUAL TABLE t1 USING $create"
497 do_execsql_test 3.$tn.1 {
498 INSERT INTO t1(docid, x) VALUES(-2, 'a b c d e f g h i j k');
499 INSERT INTO t1(docid, x) VALUES(-1, 'b c d e f g h i j k a');
500 INSERT INTO t1(docid, x) VALUES(0, 'c d e f g h i j k a b');
501 INSERT INTO t1(docid, x) VALUES(1, 'd e f g h i j k a b c');
502 INSERT INTO t1(docid, x) VALUES(2, 'e f g h i j k a b c d');
503 INSERT INTO t1(docid, x) VALUES(3, 'f g h i j k a b c d e');
504 INSERT INTO t1(docid, x) VALUES(4, 'a c e g i k');
505 INSERT INTO t1(docid, x) VALUES(5, 'a d g j');
506 INSERT INTO t1(docid, x) VALUES(6, 'c a b');
509 set limit [fts3_make_deferrable t1 c]
511 do_fts3query_test 3.$tn.2.1 t1 {a OR c}
513 ifcapable fts4_deferred {
514 do_test 3.$tn.3 { fts3_zero_long_segments t1 $limit } {1}
517 foreach {tn2 expr def} {
522 5 {"a c" NEAR/1 g} {}
523 6 {"a c" NEAR/0 g} {}
525 do_fts3query_test 3.$tn.4.$tn2 -deferred $def t1 $expr
529 #--------------------------------------------------------------------------
531 foreach {tn create} {
533 2 "fts4(x, y, order=DESC)"
534 3 "fts4(x, y, order=DESC, prefix=2)"
539 CREATE VIRTUAL TABLE t1 USING $create;
540 INSERT INTO t1 VALUES('one two five four five', '');
541 INSERT INTO t1 VALUES('', 'one two five four five');
542 INSERT INTO t1 VALUES('one two', 'five four five');
545 do_fts3query_test 4.$tn.1.1 t1 {one AND five}
546 do_fts3query_test 4.$tn.1.2 t1 {one NEAR five}
547 do_fts3query_test 4.$tn.1.3 t1 {one NEAR/1 five}
548 do_fts3query_test 4.$tn.1.4 t1 {one NEAR/2 five}
549 do_fts3query_test 4.$tn.1.5 t1 {one NEAR/3 five}
552 set limit [fts3_make_deferrable t1 five]
553 execsql { INSERT INTO t1(t1) VALUES('optimize') }
554 ifcapable fts4_deferred {
555 expr {[fts3_zero_long_segments t1 $limit]>0}
561 do_fts3query_test 4.$tn.3.1 -deferred five t1 {one AND five}
562 do_fts3query_test 4.$tn.3.2 -deferred five t1 {one NEAR five}
563 do_fts3query_test 4.$tn.3.3 -deferred five t1 {one NEAR/1 five}
564 do_fts3query_test 4.$tn.3.4 -deferred five t1 {one NEAR/2 five}
566 do_fts3query_test 4.$tn.3.5 -deferred five t1 {one NEAR/3 five}
568 do_fts3query_test 4.$tn.4.1 -deferred fi* t1 {on* AND fi*}
569 do_fts3query_test 4.$tn.4.2 -deferred fi* t1 {on* NEAR fi*}
570 do_fts3query_test 4.$tn.4.3 -deferred fi* t1 {on* NEAR/1 fi*}
571 do_fts3query_test 4.$tn.4.4 -deferred fi* t1 {on* NEAR/2 fi*}
572 do_fts3query_test 4.$tn.4.5 -deferred fi* t1 {on* NEAR/3 fi*}
574 ifcapable fts4_deferred {
575 db eval {UPDATE t1_stat SET value=x'' WHERE id=0}
576 do_catchsql_test 4.$tn.4.6 {
577 SELECT docid FROM t1 WHERE t1 MATCH 'on* NEAR/3 fi*'
578 } {1 {database disk image is malformed}}
582 #--------------------------------------------------------------------------
583 # The following test cases - fts3auto-5.* - focus on using prefix indexes.
585 set chunkconfig [fts3_configure_incr_load 1 1]
586 foreach {tn create pending} {
588 2 "fts4(a, b, order=ASC, prefix=1)" 1
589 3 "fts4(a, b, order=ASC, prefix=\"1,3\")" 0
590 4 "fts4(a, b, order=DESC, prefix=\"2,4\")" 0
591 5 "fts4(a, b, order=DESC, prefix=\"1\")" 0
592 6 "fts4(a, b, order=ASC, prefix=\"1,3\")" 0
596 DROP TABLE IF EXISTS t1;
597 CREATE VIRTUAL TABLE t1 USING $create;
600 if {$pending} {execsql BEGIN}
603 "the song of songs which is solomons"
604 "let him kiss me with the kisses of his mouth for thy love is better than wine"
605 "because of the savour of thy good ointments thy name is as ointment poured forth therefore do the virgins love thee"
606 "draw me we will run after thee the king hath brought me into his chambers we will be glad and rejoice in thee we will remember thy love more than wine the upright love thee"
607 "i am black but comely o ye daughters of jerusalem as the tents of kedar as the curtains of solomon"
608 "look not upon me because i am black because the sun hath looked upon me my mothers children were angry with me they made me the keeper of the vineyards but mine own vineyard have i not kept"
609 "tell me o thou whom my soul loveth where thou feedest where thou makest thy flock to rest at noon for why should i be as one that turneth aside by the flocks of thy companions?"
610 "if thou know not o thou fairest among women go thy way forth by the footsteps of the flock and feed thy kids beside the shepherds tents"
611 "i have compared thee o my love to a company of horses in pharaohs chariots"
612 "thy cheeks are comely with rows of jewels thy neck with chains of gold"
613 "we will make thee borders of gold with studs of silver"
614 "while the king sitteth at his table my spikenard sendeth forth the smell thereof"
615 "a bundle of myrrh is my wellbeloved unto me he shall lie all night betwixt my breasts"
616 "my beloved is unto me as a cluster of camphire in the vineyards of en gedi"
617 "behold thou art fair my love behold thou art fair thou hast doves eyes"
618 "behold thou art fair my beloved yea pleasant also our bed is green"
619 "the beams of our house are cedar and our rafters of fir"
621 execsql {INSERT INTO t1(a, b) VALUES($a, $b)}
625 do_fts3query_test 5.$tn.1.1 t1 {s*}
626 do_fts3query_test 5.$tn.1.2 t1 {so*}
627 do_fts3query_test 5.$tn.1.3 t1 {"s* o*"}
628 do_fts3query_test 5.$tn.1.4 t1 {b* NEAR/3 a*}
629 do_fts3query_test 5.$tn.1.5 t1 {a*}
630 do_fts3query_test 5.$tn.1.6 t1 {th* NEAR/5 a* NEAR/5 w*}
631 do_fts3query_test 5.$tn.1.7 t1 {"b* th* art* fair*"}
633 if {$pending} {execsql COMMIT}
635 eval fts3_configure_incr_load $chunkconfig
637 foreach {tn pending create} {
638 1 0 "fts4(a, b, c, d)"
639 2 1 "fts4(a, b, c, d)"
640 3 0 "fts4(a, b, c, d, order=DESC)"
641 4 1 "fts4(a, b, c, d, order=DESC)"
644 DROP TABLE IF EXISTS t1;
645 CREATE VIRTUAL TABLE t1 USING $create;
649 if {$pending} { execsql BEGIN }
652 "A B C" "D E F" "G H I" "J K L"
653 "B C D" "E F G" "H I J" "K L A"
654 "C D E" "F G H" "I J K" "L A B"
655 "D E F" "G H I" "J K L" "A B C"
656 "E F G" "H I J" "K L A" "B C D"
657 "F G H" "I J K" "L A B" "C D E"
659 execsql { INSERT INTO t1 VALUES($a, $b, $c, $d) }
662 do_fts3query_test 6.$tn.1 t1 {b:G}
663 do_fts3query_test 6.$tn.2 t1 {b:G AND c:I}
664 do_fts3query_test 6.$tn.3 t1 {b:G NEAR c:I}
665 do_fts3query_test 6.$tn.4 t1 {a:C OR b:G OR c:K OR d:C}
667 do_fts3query_test 6.$tn.5 t1 {a:G OR b:G}
672 foreach {tn create} {
674 2 "fts4(x, order=DESC)"
677 DROP TABLE IF EXISTS t1;
678 CREATE VIRTUAL TABLE t1 USING $create;
682 "F E N O T K X V A X I E X A P G Q V H U"
683 "R V A E T C V Q N I E L O N U G J K L U"
684 "U Y I G W M V F J L X I D C H F P J Q B"
685 "S G D Z X R P G S S Y B K A S G A I L L"
686 "L S I C H T Z S R Q P R N K J X L F M J"
687 "C C C D P X B Z C M A D A C X S B T X V"
688 "W Y J M D R G V R K B X S A W R I T N C"
689 "P K L W T M S P O Y Y V V O E H Q A I R"
690 "C D Y I C Z F H J C O Y A Q F L S B D K"
691 "P G S C Y C Y V I M B D S Z D D Y W I E"
692 "Z K Z U E E S F Y X T U A L W O U J C Q"
693 "P A T Z S W L P L Q V Y Y I P W U X S S"
694 "I U I H U O F Z F R H R F T N D X A G M"
695 "N A B M S H K X S O Y D T X S B R Y H Z"
696 "L U D A S K I L S V Z J P U B E B Y H M"
698 execsql { INSERT INTO t1 VALUES($x) }
701 # Add extra documents to the database such that token "B" will be considered
702 # deferrable if considering the other tokens means that 2 or fewer documents
703 # will be loaded into memory.
705 fts3_make_deferrable t1 B 2
707 # B is not deferred in either of the first two tests below, since filtering
708 # on "M" or "D" returns 10 documents or so. But filtering on "M * D" only
709 # returns 2, so B is deferred in this case.
711 do_fts3query_test 7.$tn.1 t1 {"M B"}
712 do_fts3query_test 7.$tn.2 t1 {"B D"}
713 do_fts3query_test 7.$tn.3 -deferred B t1 {"M B D"}
716 set sqlite_fts3_enable_parentheses $sfep