199ebad90Sdan# 2011 June 10 299ebad90Sdan# 399ebad90Sdan# May you do good and not evil. 499ebad90Sdan# May you find forgiveness for yourself and forgive others. 599ebad90Sdan# May you share freely, never taking more than you give. 699ebad90Sdan# 799ebad90Sdan#*********************************************************************** 899ebad90Sdan# 999ebad90Sdan 1099ebad90Sdanset testdir [file dirname $argv0] 1199ebad90Sdansource $testdir/tester.tcl 1299ebad90Sdan 1399ebad90Sdan# If this build does not include FTS3, skip the tests in this file. 1499ebad90Sdan# 1599ebad90Sdanifcapable !fts3 { finish_test ; return } 1699ebad90Sdansource $testdir/fts3_common.tcl 1799ebad90Sdansource $testdir/malloc_common.tcl 1899ebad90Sdan 193fd65192Sdanset testprefix fts3auto 203fd65192Sdanset sfep $sqlite_fts3_enable_parentheses 213fd65192Sdanset sqlite_fts3_enable_parentheses 1 2299ebad90Sdan 233fd65192Sdan#-------------------------------------------------------------------------- 24653265d9Sdan# Start of Tcl infrastructure used by tests. The entry point is 25653265d9Sdan# [do_fts3query_test] (described below). 2699ebad90Sdan# 27653265d9Sdan 28653265d9Sdan# do_fts3query_test TESTNAME ?OPTIONS? TABLE MATCHEXPR 29653265d9Sdan# 30653265d9Sdan# This proc runs several test cases on FTS3/4 table $TABLE using match 31653265d9Sdan# expression $MATCHEXPR. All documents in $TABLE must be formatted so that 32653265d9Sdan# they can be "tokenized" using the Tcl list commands (llength, lindex etc.). 33653265d9Sdan# The name and column names used by $TABLE must not require any quoting or 34653265d9Sdan# escaping when used in SQL statements. 35653265d9Sdan# 36653265d9Sdan# $MATCHINFO may be any expression accepted by the FTS4 MATCH operator, 37653265d9Sdan# except that the "<column-name>:token" syntax is not supported. Tcl list 38653265d9Sdan# commands are used to tokenize the expression. Any parenthesis must appear 39653265d9Sdan# either as separate list elements, or as the first (for opening) or last 40653265d9Sdan# (for closing) character of a list element. i.e. the expression "(a OR b)c" 41653265d9Sdan# will not be parsed correctly, but "( a OR b) c" will. 42653265d9Sdan# 43*2cf1a1deSdan# Available OPTIONS are: 44*2cf1a1deSdan# 45*2cf1a1deSdan# -deferred TOKENLIST 46*2cf1a1deSdan# 47*2cf1a1deSdan# If the "deferred" option is supplied, it is passed a list of tokens that 48*2cf1a1deSdan# are deferred by FTS and result in the relevant matchinfo() stats being an 49*2cf1a1deSdan# approximation. 50*2cf1a1deSdan# 51653265d9Sdanset sqlite_fts3_enable_parentheses 1 52*2cf1a1deSdanproc do_fts3query_test {tn args} { 53653265d9Sdan 54*2cf1a1deSdan set nArg [llength $args] 55*2cf1a1deSdan if {$nArg < 2 || ($nArg % 2)} { 56*2cf1a1deSdan set cmd do_fts3query_test 57*2cf1a1deSdan error "wrong # args: should be \"$cmd ?-deferred LIST? TABLE MATCHEXPR\"" 58*2cf1a1deSdan } 59*2cf1a1deSdan set tbl [lindex $args [expr $nArg-2]] 60*2cf1a1deSdan set match [lindex $args [expr $nArg-1]] 61*2cf1a1deSdan set deferred [list] 62*2cf1a1deSdan 63*2cf1a1deSdan foreach {k v} [lrange $args 0 [expr $nArg-3]] { 64*2cf1a1deSdan switch -- $k { 65*2cf1a1deSdan -deferred { 66*2cf1a1deSdan set deferred $v 67*2cf1a1deSdan } 68*2cf1a1deSdan default { 69*2cf1a1deSdan error "bad option \"$k\": must be -deferred" 70*2cf1a1deSdan } 71*2cf1a1deSdan } 72*2cf1a1deSdan } 73*2cf1a1deSdan 74*2cf1a1deSdan get_near_results $tbl $match $deferred aMatchinfo 75653265d9Sdan 76653265d9Sdan set matchinfo_asc [list] 77653265d9Sdan foreach docid [lsort -integer -incr [array names aMatchinfo]] { 78653265d9Sdan lappend matchinfo_asc $docid $aMatchinfo($docid) 79653265d9Sdan } 80653265d9Sdan set matchinfo_desc [list] 81653265d9Sdan foreach docid [lsort -integer -decr [array names aMatchinfo]] { 82653265d9Sdan lappend matchinfo_desc $docid $aMatchinfo($docid) 83653265d9Sdan } 84653265d9Sdan 85653265d9Sdan set title "(\"$match\" -> [llength [array names aMatchinfo]] rows)" 86653265d9Sdan 87653265d9Sdan do_execsql_test $tn$title.1 " 88653265d9Sdan SELECT docid FROM $tbl WHERE $tbl MATCH '$match' ORDER BY docid ASC 89653265d9Sdan " [lsort -integer -incr [array names aMatchinfo]] 90653265d9Sdan 91653265d9Sdan do_execsql_test $tn$title.2 " 92653265d9Sdan SELECT docid FROM $tbl WHERE $tbl MATCH '$match' ORDER BY docid DESC 93653265d9Sdan " [lsort -integer -decr [array names aMatchinfo]] 94653265d9Sdan 95653265d9Sdan do_execsql_test $tn$title.3 " 96653265d9Sdan SELECT docid, mit(matchinfo($tbl, 'x')) FROM $tbl 97653265d9Sdan WHERE $tbl MATCH '$match' ORDER BY docid DESC 98653265d9Sdan " $matchinfo_desc 99653265d9Sdan 100653265d9Sdan do_execsql_test $tn$title.4 " 101653265d9Sdan SELECT docid, mit(matchinfo($tbl, 'x')) FROM $tbl 102653265d9Sdan WHERE $tbl MATCH '$match' ORDER BY docid ASC 103653265d9Sdan " $matchinfo_asc 104653265d9Sdan} 105653265d9Sdan 106653265d9Sdan 10799ebad90Sdanproc mit {blob} { 10899ebad90Sdan set scan(littleEndian) i* 10999ebad90Sdan set scan(bigEndian) I* 11099ebad90Sdan binary scan $blob $scan($::tcl_platform(byteOrder)) r 11199ebad90Sdan return $r 11299ebad90Sdan} 11399ebad90Sdandb func mit mit 11499ebad90Sdan 11599ebad90Sdanproc fix_near_expr {expr} { 11699ebad90Sdan set out [list] 11799ebad90Sdan lappend out [lindex $expr 0] 11899ebad90Sdan foreach {a b} [lrange $expr 1 end] { 11999ebad90Sdan if {[string match -nocase near $a]} { set a 10 } 12099ebad90Sdan if {[string match -nocase near/* $a]} { set a [string range $a 5 end] } 12199ebad90Sdan lappend out $a 12299ebad90Sdan lappend out $b 12399ebad90Sdan } 12499ebad90Sdan return $out 12599ebad90Sdan} 12699ebad90Sdan 127*2cf1a1deSdanproc get_single_near_results {tbl expr deferred arrayvar nullvar} { 1283fd65192Sdan upvar $arrayvar aMatchinfo 1293fd65192Sdan upvar $nullvar nullentry 1303fd65192Sdan catch {array unset aMatchinfo} 13199ebad90Sdan 13299ebad90Sdan set expr [fix_near_expr $expr] 13399ebad90Sdan 13499ebad90Sdan # Calculate the expected results using [fts3_near_match]. The following 13599ebad90Sdan # loop populates the "hits" and "counts" arrays as follows: 13699ebad90Sdan # 13799ebad90Sdan # 1. For each document in the table that matches the NEAR expression, 13899ebad90Sdan # hits($docid) is set to 1. The set of docids that match the expression 13999ebad90Sdan # can therefore be found using [array names hits]. 14099ebad90Sdan # 14199ebad90Sdan # 2. For each column of each document in the table, counts($docid,$iCol) 14299ebad90Sdan # is set to the -phrasecountvar output. 14399ebad90Sdan # 14499ebad90Sdan set res [list] 14599ebad90Sdan catch { array unset hits } 14699ebad90Sdan db eval "SELECT docid, * FROM $tbl" d { 14799ebad90Sdan set iCol 0 14899ebad90Sdan foreach col [lrange $d(*) 1 end] { 14999ebad90Sdan set docid $d(docid) 15099ebad90Sdan set hit [fts3_near_match $d($col) $expr -p counts($docid,$iCol)] 15199ebad90Sdan if {$hit} { set hits($docid) 1 } 15299ebad90Sdan incr iCol 15399ebad90Sdan } 15499ebad90Sdan } 15599ebad90Sdan set nPhrase [expr ([llength $expr]+1)/2] 15699ebad90Sdan set nCol $iCol 15799ebad90Sdan 15899ebad90Sdan # This block populates the nHit and nDoc arrays. For each phrase/column 15999ebad90Sdan # in the query/table, array elements are set as follows: 16099ebad90Sdan # 16199ebad90Sdan # nHit($iPhrase,$iCol) - Total number of hits for phrase $iPhrase in 16299ebad90Sdan # column $iCol. 16399ebad90Sdan # 16499ebad90Sdan # nDoc($iPhrase,$iCol) - Number of documents with at least one hit for 16599ebad90Sdan # phrase $iPhrase in column $iCol. 16699ebad90Sdan # 16799ebad90Sdan for {set iPhrase 0} {$iPhrase < $nPhrase} {incr iPhrase} { 16899ebad90Sdan for {set iCol 0} {$iCol < $nCol} {incr iCol} { 16999ebad90Sdan set nHit($iPhrase,$iCol) 0 17099ebad90Sdan set nDoc($iPhrase,$iCol) 0 17199ebad90Sdan } 17299ebad90Sdan } 17399ebad90Sdan foreach key [array names counts] { 17499ebad90Sdan set iCol [lindex [split $key ,] 1] 17599ebad90Sdan set iPhrase 0 17699ebad90Sdan foreach c $counts($key) { 1772f779343Sdan if {$c>0} { incr nDoc($iPhrase,$iCol) 1 } 1782f779343Sdan incr nHit($iPhrase,$iCol) $c 17999ebad90Sdan incr iPhrase 18099ebad90Sdan } 18199ebad90Sdan } 18299ebad90Sdan 183*2cf1a1deSdan if {[llength $deferred] && [llength $expr]==1} { 1842f779343Sdan set phrase [lindex $expr 0] 1852f779343Sdan set rewritten [list] 1862f779343Sdan set partial 0 1872f779343Sdan foreach tok $phrase { 188*2cf1a1deSdan if {[lsearch $deferred $tok]>=0} { 1892f779343Sdan lappend rewritten * 1902f779343Sdan } else { 1912f779343Sdan lappend rewritten $tok 1922f779343Sdan set partial 1 1932f779343Sdan } 1942f779343Sdan } 1952f779343Sdan if {$partial==0} { 1962f779343Sdan set tblsize [db one "SELECT count(*) FROM $tbl"] 1972f779343Sdan for {set iCol 0} {$iCol < $nCol} {incr iCol} { 1982f779343Sdan set nHit(0,$iCol) $tblsize 1992f779343Sdan set nDoc(0,$iCol) $tblsize 2002f779343Sdan } 2012f779343Sdan } elseif {$rewritten != $phrase} { 2022f779343Sdan while {[lindex $rewritten end] == "*"} { 2032f779343Sdan set rewritten [lrange $rewritten 0 end-1] 2042f779343Sdan } 2052f779343Sdan while {[lindex $rewritten 0] == "*"} { 2062f779343Sdan set rewritten [lrange $rewritten 1 end] 2072f779343Sdan } 208*2cf1a1deSdan get_single_near_results $tbl [list $rewritten] {} aRewrite nullentry 2092f779343Sdan foreach docid [array names hits] { 2102f779343Sdan set aMatchinfo($docid) $aRewrite($docid) 2112f779343Sdan } 2122f779343Sdan return 2132f779343Sdan } 2142f779343Sdan } 2152f779343Sdan 21699ebad90Sdan # Set up the aMatchinfo array. For each document, set aMatchinfo($docid) to 21799ebad90Sdan # contain the output of matchinfo('x') for the document. 21899ebad90Sdan # 21999ebad90Sdan foreach docid [array names hits] { 22099ebad90Sdan set mi [list] 22199ebad90Sdan for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} { 22299ebad90Sdan for {set iCol 0} {$iCol<$nCol} {incr iCol} { 22399ebad90Sdan lappend mi [lindex $counts($docid,$iCol) $iPhrase] 22499ebad90Sdan lappend mi $nHit($iPhrase,$iCol) 2252f779343Sdan lappend mi $nDoc($iPhrase,$iCol) 22699ebad90Sdan } 22799ebad90Sdan } 22899ebad90Sdan set aMatchinfo($docid) $mi 22999ebad90Sdan } 23099ebad90Sdan 2313fd65192Sdan # Set up the nullentry output. 2323fd65192Sdan # 2333fd65192Sdan set nullentry [list] 2343fd65192Sdan for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} { 2353fd65192Sdan for {set iCol 0} {$iCol<$nCol} {incr iCol} { 2362f779343Sdan lappend nullentry 0 $nHit($iPhrase,$iCol) $nDoc($iPhrase,$iCol) 2373fd65192Sdan } 2383fd65192Sdan } 2393fd65192Sdan} 2403fd65192Sdan 2413fd65192Sdan 2423fd65192Sdanproc matching_brackets {expr} { 2433fd65192Sdan if {[string range $expr 0 0]!="(" || [string range $expr end end] !=")"} { 2443fd65192Sdan return 0 2453fd65192Sdan } 2463fd65192Sdan 2473fd65192Sdan set iBracket 1 2483fd65192Sdan set nExpr [string length $expr] 2493fd65192Sdan for {set i 1} {$iBracket && $i < $nExpr} {incr i} { 2503fd65192Sdan set c [string range $expr $i $i] 2513fd65192Sdan if {$c == "("} {incr iBracket} 2523fd65192Sdan if {$c == ")"} {incr iBracket -1} 2533fd65192Sdan } 2543fd65192Sdan 2553fd65192Sdan return [expr ($iBracket==0 && $i==$nExpr)] 2563fd65192Sdan} 2573fd65192Sdan 258*2cf1a1deSdanproc get_near_results {tbl expr deferred arrayvar {nullvar ""}} { 2593fd65192Sdan upvar $arrayvar aMatchinfo 2603fd65192Sdan if {$nullvar != ""} { upvar $nullvar nullentry } 2613fd65192Sdan 2623fd65192Sdan set expr [string trim $expr] 2633fd65192Sdan while { [matching_brackets $expr] } { 2643fd65192Sdan set expr [string trim [string range $expr 1 end-1]] 2653fd65192Sdan } 2663fd65192Sdan 2673fd65192Sdan set prec(NOT) 1 2683fd65192Sdan set prec(AND) 2 2693fd65192Sdan set prec(OR) 3 2703fd65192Sdan 2713fd65192Sdan set currentprec 0 2723fd65192Sdan set iBracket 0 2733fd65192Sdan set expr_length [llength $expr] 2743fd65192Sdan for {set i 0} {$i < $expr_length} {incr i} { 2753fd65192Sdan set op [lindex $expr $i] 2763fd65192Sdan if {$iBracket==0 && [info exists prec($op)] && $prec($op)>=$currentprec } { 2773fd65192Sdan set opidx $i 2783fd65192Sdan set currentprec $prec($op) 2793fd65192Sdan } else { 2803fd65192Sdan for {set j 0} {$j < [string length $op]} {incr j} { 2813fd65192Sdan set c [string range $op $j $j] 2823fd65192Sdan if {$c == "("} { incr iBracket +1 } 2833fd65192Sdan if {$c == ")"} { incr iBracket -1 } 2843fd65192Sdan } 2853fd65192Sdan } 2863fd65192Sdan } 2873fd65192Sdan if {$iBracket!=0} { error "mismatched brackets in: $expr" } 2883fd65192Sdan 2893fd65192Sdan if {[info exists opidx]==0} { 290*2cf1a1deSdan get_single_near_results $tbl $expr $deferred aMatchinfo nullentry 2913fd65192Sdan } else { 2923fd65192Sdan set eLeft [lrange $expr 0 [expr $opidx-1]] 2933fd65192Sdan set eRight [lrange $expr [expr $opidx+1] end] 2943fd65192Sdan 295*2cf1a1deSdan get_near_results $tbl $eLeft $deferred aLeft nullleft 296*2cf1a1deSdan get_near_results $tbl $eRight $deferred aRight nullright 2973fd65192Sdan 2983fd65192Sdan switch -- [lindex $expr $opidx] { 2993fd65192Sdan "NOT" { 3003fd65192Sdan foreach hit [array names aLeft] { 3013fd65192Sdan if {0==[info exists aRight($hit)]} { 3023fd65192Sdan set aMatchinfo($hit) $aLeft($hit) 3033fd65192Sdan } 3043fd65192Sdan } 3053fd65192Sdan set nullentry $nullleft 3063fd65192Sdan } 3073fd65192Sdan 3083fd65192Sdan "AND" { 3093fd65192Sdan foreach hit [array names aLeft] { 3103fd65192Sdan if {[info exists aRight($hit)]} { 3113fd65192Sdan set aMatchinfo($hit) [concat $aLeft($hit) $aRight($hit)] 3123fd65192Sdan } 3133fd65192Sdan } 3143fd65192Sdan set nullentry [concat $nullleft $nullright] 3153fd65192Sdan } 3163fd65192Sdan 3173fd65192Sdan "OR" { 3183fd65192Sdan foreach hit [array names aLeft] { 3193fd65192Sdan if {[info exists aRight($hit)]} { 3203fd65192Sdan set aMatchinfo($hit) [concat $aLeft($hit) $aRight($hit)] 3213fd65192Sdan unset aRight($hit) 3223fd65192Sdan } else { 3233fd65192Sdan set aMatchinfo($hit) [concat $aLeft($hit) $nullright] 3243fd65192Sdan } 3253fd65192Sdan } 3263fd65192Sdan foreach hit [array names aRight] { 3273fd65192Sdan set aMatchinfo($hit) [concat $nullleft $aRight($hit)] 3283fd65192Sdan } 3293fd65192Sdan 3303fd65192Sdan set nullentry [concat $nullleft $nullright] 3313fd65192Sdan } 3323fd65192Sdan } 3333fd65192Sdan } 3343fd65192Sdan} 3353fd65192Sdan 3363fd65192Sdan 3373fd65192Sdan# End of test procs. Actual tests are below this line. 3383fd65192Sdan#-------------------------------------------------------------------------- 3393fd65192Sdan 3403fd65192Sdan#-------------------------------------------------------------------------- 3413fd65192Sdan# The following test cases - fts3auto-1.* - focus on testing the Tcl 3423fd65192Sdan# command [fts3_near_match], which is used by other tests in this file. 3433fd65192Sdan# 3443fd65192Sdanproc test_fts3_near_match {tn doc expr res} { 3453fd65192Sdan fts3_near_match $doc $expr -phrasecountvar p 3463fd65192Sdan uplevel do_test [list $tn] [list [list set {} $p]] [list $res] 3473fd65192Sdan} 3483fd65192Sdan 3493fd65192Sdantest_fts3_near_match 1.1.1 {a b c a b} a {2} 3503fd65192Sdantest_fts3_near_match 1.1.2 {a b c a b} {a 5 b 6 c} {2 2 1} 3513fd65192Sdantest_fts3_near_match 1.1.3 {a b c a b} {"a b"} {2} 3523fd65192Sdantest_fts3_near_match 1.1.4 {a b c a b} {"b c"} {1} 3533fd65192Sdantest_fts3_near_match 1.1.5 {a b c a b} {"c c"} {0} 3543fd65192Sdan 3553fd65192Sdantest_fts3_near_match 1.2.1 "a b c d e f g" {b 2 f} {0 0} 3563fd65192Sdantest_fts3_near_match 1.2.2 "a b c d e f g" {b 3 f} {1 1} 3573fd65192Sdantest_fts3_near_match 1.2.3 "a b c d e f g" {f 2 b} {0 0} 3583fd65192Sdantest_fts3_near_match 1.2.4 "a b c d e f g" {f 3 b} {1 1} 3593fd65192Sdantest_fts3_near_match 1.2.5 "a b c d e f g" {"a b" 2 "f g"} {0 0} 3603fd65192Sdantest_fts3_near_match 1.2.6 "a b c d e f g" {"a b" 3 "f g"} {1 1} 3613fd65192Sdan 3623fd65192Sdanset 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" 3633fd65192Sdantest_fts3_near_match 1.3.1 $A {"c d" 5 "i j" 1 "e f"} {0 0 0} 3643fd65192Sdantest_fts3_near_match 1.3.2 $A {"c d" 5 "i j" 2 "e f"} {1 1 1} 3653fd65192Sdan 3663fd65192Sdan#-------------------------------------------------------------------------- 3673fd65192Sdan# Test cases fts3auto-2.* run some simple tests using the 3682f779343Sdan# [do_fts3query_test] proc. 3693fd65192Sdan# 3703fd65192Sdanforeach {tn create} { 3712f779343Sdan 1 "fts4(a, b)" 3722f779343Sdan 2 "fts4(a, b, order=DESC)" 3732f779343Sdan 3 "fts4(a, b, order=ASC)" 3742f779343Sdan 4 "fts4(a, b, prefix=1)" 3752f779343Sdan 5 "fts4(a, b, order=DESC, prefix=1)" 3762f779343Sdan 6 "fts4(a, b, order=ASC, prefix=1)" 3773fd65192Sdan} { 3783fd65192Sdan do_test 2.$tn.1 { 3793fd65192Sdan catchsql { DROP TABLE t1 } 3802f779343Sdan execsql "CREATE VIRTUAL TABLE t1 USING $create" 38199ebad90Sdan for {set i 0} {$i<32} {incr i} { 38299ebad90Sdan set doc [list] 38399ebad90Sdan if {$i&0x01} {lappend doc one} 38499ebad90Sdan if {$i&0x02} {lappend doc two} 38599ebad90Sdan if {$i&0x04} {lappend doc three} 38699ebad90Sdan if {$i&0x08} {lappend doc four} 38799ebad90Sdan if {$i&0x10} {lappend doc five} 38899ebad90Sdan execsql { INSERT INTO t1 VALUES($doc, null) } 38999ebad90Sdan } 39099ebad90Sdan } {} 3912f779343Sdan 3923fd65192Sdan foreach {tn2 expr} { 39399ebad90Sdan 1 {one} 39499ebad90Sdan 2 {one NEAR/1 five} 39599ebad90Sdan 3 {t*} 39699ebad90Sdan 4 {t* NEAR/0 five} 39799ebad90Sdan 5 {o* NEAR/1 f*} 39899ebad90Sdan 6 {one NEAR five NEAR two NEAR four NEAR three} 3993fd65192Sdan 7 {one NEAR xyz} 4003fd65192Sdan 8 {one OR two} 4013fd65192Sdan 9 {one AND two} 4023fd65192Sdan 10 {one NOT two} 4033fd65192Sdan 11 {one AND two OR three} 4043fd65192Sdan 12 {three OR one AND two} 4053fd65192Sdan 13 {(three OR one) AND two} 4063fd65192Sdan 14 {(three OR one) AND two NOT (five NOT four)} 4073fd65192Sdan 15 {"one two"} 4083fd65192Sdan 16 {"one two" NOT "three four"} 40999ebad90Sdan } { 4102f779343Sdan do_fts3query_test 2.$tn.2.$tn2 t1 $expr 4112f779343Sdan } 4122f779343Sdan} 4132f779343Sdan 4142f779343Sdan#-------------------------------------------------------------------------- 4152f779343Sdan# Some test cases involving deferred tokens. 4162f779343Sdan# 4172f779343Sdanproc make_token_deferrable {tbl token} { 4182f779343Sdan set nRow [db one "SELECT count(*) FROM $tbl"] 4192f779343Sdan set pgsz [db one "PRAGMA page_size"] 4202f779343Sdan execsql BEGIN 4212f779343Sdan for {set i 0} {$i < ($nRow * $pgsz * 1.2)/100} {incr i} { 4222f779343Sdan set doc [string repeat "$token " 100] 4232f779343Sdan execsql "INSERT INTO $tbl VALUES(\$doc)" 4242f779343Sdan } 4252f779343Sdan execsql "INSERT INTO $tbl VALUES('aaaaaaa ${token}aaaaa')" 4262f779343Sdan execsql COMMIT 4272f779343Sdan} 4282f779343Sdan 4292f779343Sdanforeach {tn create} { 4302f779343Sdan 1 "fts4(x)" 4312f779343Sdan 2 "fts4(x, order=DESC)" 4322f779343Sdan} { 4332f779343Sdan catchsql { DROP TABLE t1 } 4342f779343Sdan execsql "CREATE VIRTUAL TABLE t1 USING $create" 4352f779343Sdan do_execsql_test 3.$tn.1 { 436653265d9Sdan INSERT INTO t1(docid, x) VALUES(-2, 'a b c d e f g h i j k'); 437653265d9Sdan INSERT INTO t1(docid, x) VALUES(-1, 'b c d e f g h i j k a'); 438653265d9Sdan INSERT INTO t1(docid, x) VALUES(0, 'c d e f g h i j k a b'); 439653265d9Sdan INSERT INTO t1(docid, x) VALUES(1, 'd e f g h i j k a b c'); 440653265d9Sdan INSERT INTO t1(docid, x) VALUES(2, 'e f g h i j k a b c d'); 441653265d9Sdan INSERT INTO t1(docid, x) VALUES(3, 'f g h i j k a b c d e'); 442653265d9Sdan INSERT INTO t1(docid, x) VALUES(4, 'a c e g i k'); 443653265d9Sdan INSERT INTO t1(docid, x) VALUES(5, 'a d g j'); 444653265d9Sdan INSERT INTO t1(docid, x) VALUES(6, 'c a b'); 4452f779343Sdan } 4462f779343Sdan 4472f779343Sdan make_token_deferrable t1 c 4482f779343Sdan 4492f779343Sdan foreach {tn2 expr} { 4502f779343Sdan 1 {a OR c} 4512f779343Sdan } { 4522f779343Sdan do_fts3query_test 3.$tn.2.$tn2 t1 $expr 4532f779343Sdan } 4542f779343Sdan 4552f779343Sdan execsql { 4562f779343Sdan UPDATE t1_segments 4572f779343Sdan SET block = zeroblob(length(block)) 4582f779343Sdan WHERE length(block)>10000 AND 0 4592f779343Sdan } 460*2cf1a1deSdan foreach {tn2 expr def} { 461*2cf1a1deSdan 1 {a NEAR c} {} 462*2cf1a1deSdan 2 {a AND c} c 463*2cf1a1deSdan 3 {"a c"} c 464*2cf1a1deSdan 4 {"c a"} c 465*2cf1a1deSdan 5 {"a c" NEAR/1 g} {} 466*2cf1a1deSdan 6 {"a c" NEAR/0 g} {} 4672f779343Sdan } { 468*2cf1a1deSdan do_fts3query_test 3.$tn.2.$tn2 -deferred $def t1 $expr 469*2cf1a1deSdan } 470*2cf1a1deSdan} 471*2cf1a1deSdan 472*2cf1a1deSdan#-------------------------------------------------------------------------- 473*2cf1a1deSdan# 474*2cf1a1deSdanforeach {tn create} { 475*2cf1a1deSdan 1 "fts4(x, y)" 476*2cf1a1deSdan 2 "fts4(x, y, order=DESC)" 477*2cf1a1deSdan} { 478*2cf1a1deSdan catchsql { DROP TABLE t1 } 479*2cf1a1deSdan execsql "CREATE VIRTUAL TABLE t1 USING $create" 480*2cf1a1deSdan 481*2cf1a1deSdan foreach {x y} { 482*2cf1a1deSdan {one two five four five} {} 483*2cf1a1deSdan {} {one two five four five} 484*2cf1a1deSdan {one two} {five four five} 485*2cf1a1deSdan } { 486*2cf1a1deSdan execsql {INSERT INTO t1 VALUES($x, $y)} 487*2cf1a1deSdan } 488*2cf1a1deSdan 489*2cf1a1deSdan foreach {tn2 expr} { 490*2cf1a1deSdan 1 {one AND five} 491*2cf1a1deSdan 2 {one NEAR five} 492*2cf1a1deSdan 3 {one NEAR/1 five} 493*2cf1a1deSdan 4 {one NEAR/2 five} 494*2cf1a1deSdan 5 {one NEAR/3 five} 495*2cf1a1deSdan } { 496*2cf1a1deSdan do_fts3query_test 4.$tn.2.$tn2 t1 $expr 4973fd65192Sdan } 49899ebad90Sdan} 49999ebad90Sdan 5003fd65192Sdanset sqlite_fts3_enable_parentheses $sfep 50199ebad90Sdanfinish_test 50299ebad90Sdan 503