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#-------------------------------------------------------------------------- 24*db27fc07Sdan# Start of Tcl infrastructure used by tests. The entry points are: 25*db27fc07Sdan# 26*db27fc07Sdan# do_fts3query_test 27*db27fc07Sdan# fts3_make_deferrable 28*db27fc07Sdan# fts3_zero_long_segments 2999ebad90Sdan# 30653265d9Sdan 31*db27fc07Sdan# 32653265d9Sdan# do_fts3query_test TESTNAME ?OPTIONS? TABLE MATCHEXPR 33653265d9Sdan# 34653265d9Sdan# This proc runs several test cases on FTS3/4 table $TABLE using match 35653265d9Sdan# expression $MATCHEXPR. All documents in $TABLE must be formatted so that 36653265d9Sdan# they can be "tokenized" using the Tcl list commands (llength, lindex etc.). 37653265d9Sdan# The name and column names used by $TABLE must not require any quoting or 38653265d9Sdan# escaping when used in SQL statements. 39653265d9Sdan# 40653265d9Sdan# $MATCHINFO may be any expression accepted by the FTS4 MATCH operator, 41653265d9Sdan# except that the "<column-name>:token" syntax is not supported. Tcl list 42653265d9Sdan# commands are used to tokenize the expression. Any parenthesis must appear 43653265d9Sdan# either as separate list elements, or as the first (for opening) or last 44653265d9Sdan# (for closing) character of a list element. i.e. the expression "(a OR b)c" 45653265d9Sdan# will not be parsed correctly, but "( a OR b) c" will. 46653265d9Sdan# 472cf1a1deSdan# Available OPTIONS are: 482cf1a1deSdan# 492cf1a1deSdan# -deferred TOKENLIST 502cf1a1deSdan# 512cf1a1deSdan# If the "deferred" option is supplied, it is passed a list of tokens that 522cf1a1deSdan# are deferred by FTS and result in the relevant matchinfo() stats being an 532cf1a1deSdan# approximation. 542cf1a1deSdan# 55653265d9Sdanset sqlite_fts3_enable_parentheses 1 562cf1a1deSdanproc do_fts3query_test {tn args} { 57653265d9Sdan 582cf1a1deSdan set nArg [llength $args] 592cf1a1deSdan if {$nArg < 2 || ($nArg % 2)} { 602cf1a1deSdan set cmd do_fts3query_test 612cf1a1deSdan error "wrong # args: should be \"$cmd ?-deferred LIST? TABLE MATCHEXPR\"" 622cf1a1deSdan } 632cf1a1deSdan set tbl [lindex $args [expr $nArg-2]] 642cf1a1deSdan set match [lindex $args [expr $nArg-1]] 652cf1a1deSdan set deferred [list] 662cf1a1deSdan 672cf1a1deSdan foreach {k v} [lrange $args 0 [expr $nArg-3]] { 682cf1a1deSdan switch -- $k { 692cf1a1deSdan -deferred { 702cf1a1deSdan set deferred $v 712cf1a1deSdan } 722cf1a1deSdan default { 732cf1a1deSdan error "bad option \"$k\": must be -deferred" 742cf1a1deSdan } 752cf1a1deSdan } 762cf1a1deSdan } 772cf1a1deSdan 782cf1a1deSdan get_near_results $tbl $match $deferred aMatchinfo 79653265d9Sdan 80653265d9Sdan set matchinfo_asc [list] 81653265d9Sdan foreach docid [lsort -integer -incr [array names aMatchinfo]] { 82653265d9Sdan lappend matchinfo_asc $docid $aMatchinfo($docid) 83653265d9Sdan } 84653265d9Sdan set matchinfo_desc [list] 85653265d9Sdan foreach docid [lsort -integer -decr [array names aMatchinfo]] { 86653265d9Sdan lappend matchinfo_desc $docid $aMatchinfo($docid) 87653265d9Sdan } 88653265d9Sdan 89653265d9Sdan set title "(\"$match\" -> [llength [array names aMatchinfo]] rows)" 90653265d9Sdan 91653265d9Sdan do_execsql_test $tn$title.1 " 92653265d9Sdan SELECT docid FROM $tbl WHERE $tbl MATCH '$match' ORDER BY docid ASC 93653265d9Sdan " [lsort -integer -incr [array names aMatchinfo]] 94653265d9Sdan 95653265d9Sdan do_execsql_test $tn$title.2 " 96653265d9Sdan SELECT docid FROM $tbl WHERE $tbl MATCH '$match' ORDER BY docid DESC 97653265d9Sdan " [lsort -integer -decr [array names aMatchinfo]] 98653265d9Sdan 99653265d9Sdan do_execsql_test $tn$title.3 " 100653265d9Sdan SELECT docid, mit(matchinfo($tbl, 'x')) FROM $tbl 101653265d9Sdan WHERE $tbl MATCH '$match' ORDER BY docid DESC 102653265d9Sdan " $matchinfo_desc 103653265d9Sdan 104653265d9Sdan do_execsql_test $tn$title.4 " 105653265d9Sdan SELECT docid, mit(matchinfo($tbl, 'x')) FROM $tbl 106653265d9Sdan WHERE $tbl MATCH '$match' ORDER BY docid ASC 107653265d9Sdan " $matchinfo_asc 108653265d9Sdan} 109653265d9Sdan 110*db27fc07Sdan# fts3_make_deferrable TABLE TOKEN 111*db27fc07Sdan# 112*db27fc07Sdanproc fts3_make_deferrable {tbl token} { 113*db27fc07Sdan 114*db27fc07Sdan set stmt [sqlite3_prepare db "SELECT * FROM $tbl" -1 dummy] 115*db27fc07Sdan set name [sqlite3_column_name $stmt 0] 116*db27fc07Sdan sqlite3_finalize $stmt 117*db27fc07Sdan 118*db27fc07Sdan set nRow [db one "SELECT count(*) FROM $tbl"] 119*db27fc07Sdan set pgsz [db one "PRAGMA page_size"] 120*db27fc07Sdan execsql BEGIN 121*db27fc07Sdan for {set i 0} {$i < ($nRow * $pgsz * 1.2)/100} {incr i} { 122*db27fc07Sdan set doc [string repeat "$token " 100] 123*db27fc07Sdan execsql "INSERT INTO $tbl ($name) VALUES(\$doc)" 124*db27fc07Sdan } 125*db27fc07Sdan execsql "INSERT INTO $tbl ($name) VALUES('aaaaaaa ${token}aaaaa')" 126*db27fc07Sdan execsql COMMIT 127*db27fc07Sdan 128*db27fc07Sdan return [expr $nRow*$pgsz] 129*db27fc07Sdan} 130*db27fc07Sdan 131*db27fc07Sdan# fts3_zero_long_segments TABLE ?LIMIT? 132*db27fc07Sdan# 133*db27fc07Sdanproc fts3_zero_long_segments {tbl limit} { 134*db27fc07Sdan execsql " 135*db27fc07Sdan UPDATE ${tbl}_segments 136*db27fc07Sdan SET block = zeroblob(length(block)) 137*db27fc07Sdan WHERE length(block)>$limit 138*db27fc07Sdan " 139*db27fc07Sdan return [db changes] 140*db27fc07Sdan} 141*db27fc07Sdan 142653265d9Sdan 14399ebad90Sdanproc mit {blob} { 14499ebad90Sdan set scan(littleEndian) i* 14599ebad90Sdan set scan(bigEndian) I* 14699ebad90Sdan binary scan $blob $scan($::tcl_platform(byteOrder)) r 14799ebad90Sdan return $r 14899ebad90Sdan} 14999ebad90Sdandb func mit mit 15099ebad90Sdan 15199ebad90Sdanproc fix_near_expr {expr} { 15299ebad90Sdan set out [list] 15399ebad90Sdan lappend out [lindex $expr 0] 15499ebad90Sdan foreach {a b} [lrange $expr 1 end] { 15599ebad90Sdan if {[string match -nocase near $a]} { set a 10 } 15699ebad90Sdan if {[string match -nocase near/* $a]} { set a [string range $a 5 end] } 15799ebad90Sdan lappend out $a 15899ebad90Sdan lappend out $b 15999ebad90Sdan } 16099ebad90Sdan return $out 16199ebad90Sdan} 16299ebad90Sdan 1632cf1a1deSdanproc get_single_near_results {tbl expr deferred arrayvar nullvar} { 1643fd65192Sdan upvar $arrayvar aMatchinfo 1653fd65192Sdan upvar $nullvar nullentry 1663fd65192Sdan catch {array unset aMatchinfo} 16799ebad90Sdan 16899ebad90Sdan set expr [fix_near_expr $expr] 16999ebad90Sdan 17099ebad90Sdan # Calculate the expected results using [fts3_near_match]. The following 17199ebad90Sdan # loop populates the "hits" and "counts" arrays as follows: 17299ebad90Sdan # 17399ebad90Sdan # 1. For each document in the table that matches the NEAR expression, 17499ebad90Sdan # hits($docid) is set to 1. The set of docids that match the expression 17599ebad90Sdan # can therefore be found using [array names hits]. 17699ebad90Sdan # 17799ebad90Sdan # 2. For each column of each document in the table, counts($docid,$iCol) 17899ebad90Sdan # is set to the -phrasecountvar output. 17999ebad90Sdan # 18099ebad90Sdan set res [list] 18199ebad90Sdan catch { array unset hits } 18299ebad90Sdan db eval "SELECT docid, * FROM $tbl" d { 18399ebad90Sdan set iCol 0 18499ebad90Sdan foreach col [lrange $d(*) 1 end] { 18599ebad90Sdan set docid $d(docid) 18699ebad90Sdan set hit [fts3_near_match $d($col) $expr -p counts($docid,$iCol)] 18799ebad90Sdan if {$hit} { set hits($docid) 1 } 18899ebad90Sdan incr iCol 18999ebad90Sdan } 19099ebad90Sdan } 19199ebad90Sdan set nPhrase [expr ([llength $expr]+1)/2] 19299ebad90Sdan set nCol $iCol 19399ebad90Sdan 19499ebad90Sdan # This block populates the nHit and nDoc arrays. For each phrase/column 19599ebad90Sdan # in the query/table, array elements are set as follows: 19699ebad90Sdan # 19799ebad90Sdan # nHit($iPhrase,$iCol) - Total number of hits for phrase $iPhrase in 19899ebad90Sdan # column $iCol. 19999ebad90Sdan # 20099ebad90Sdan # nDoc($iPhrase,$iCol) - Number of documents with at least one hit for 20199ebad90Sdan # phrase $iPhrase in column $iCol. 20299ebad90Sdan # 20399ebad90Sdan for {set iPhrase 0} {$iPhrase < $nPhrase} {incr iPhrase} { 20499ebad90Sdan for {set iCol 0} {$iCol < $nCol} {incr iCol} { 20599ebad90Sdan set nHit($iPhrase,$iCol) 0 20699ebad90Sdan set nDoc($iPhrase,$iCol) 0 20799ebad90Sdan } 20899ebad90Sdan } 20999ebad90Sdan foreach key [array names counts] { 21099ebad90Sdan set iCol [lindex [split $key ,] 1] 21199ebad90Sdan set iPhrase 0 21299ebad90Sdan foreach c $counts($key) { 2132f779343Sdan if {$c>0} { incr nDoc($iPhrase,$iCol) 1 } 2142f779343Sdan incr nHit($iPhrase,$iCol) $c 21599ebad90Sdan incr iPhrase 21699ebad90Sdan } 21799ebad90Sdan } 21899ebad90Sdan 2192cf1a1deSdan if {[llength $deferred] && [llength $expr]==1} { 2202f779343Sdan set phrase [lindex $expr 0] 2212f779343Sdan set rewritten [list] 2222f779343Sdan set partial 0 2232f779343Sdan foreach tok $phrase { 2242cf1a1deSdan if {[lsearch $deferred $tok]>=0} { 2252f779343Sdan lappend rewritten * 2262f779343Sdan } else { 2272f779343Sdan lappend rewritten $tok 2282f779343Sdan set partial 1 2292f779343Sdan } 2302f779343Sdan } 2312f779343Sdan if {$partial==0} { 2322f779343Sdan set tblsize [db one "SELECT count(*) FROM $tbl"] 2332f779343Sdan for {set iCol 0} {$iCol < $nCol} {incr iCol} { 2342f779343Sdan set nHit(0,$iCol) $tblsize 2352f779343Sdan set nDoc(0,$iCol) $tblsize 2362f779343Sdan } 2372f779343Sdan } elseif {$rewritten != $phrase} { 2382f779343Sdan while {[lindex $rewritten end] == "*"} { 2392f779343Sdan set rewritten [lrange $rewritten 0 end-1] 2402f779343Sdan } 2412f779343Sdan while {[lindex $rewritten 0] == "*"} { 2422f779343Sdan set rewritten [lrange $rewritten 1 end] 2432f779343Sdan } 2442cf1a1deSdan get_single_near_results $tbl [list $rewritten] {} aRewrite nullentry 2452f779343Sdan foreach docid [array names hits] { 2462f779343Sdan set aMatchinfo($docid) $aRewrite($docid) 2472f779343Sdan } 2482f779343Sdan return 2492f779343Sdan } 2502f779343Sdan } 2512f779343Sdan 25299ebad90Sdan # Set up the aMatchinfo array. For each document, set aMatchinfo($docid) to 25399ebad90Sdan # contain the output of matchinfo('x') for the document. 25499ebad90Sdan # 25599ebad90Sdan foreach docid [array names hits] { 25699ebad90Sdan set mi [list] 25799ebad90Sdan for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} { 25899ebad90Sdan for {set iCol 0} {$iCol<$nCol} {incr iCol} { 25999ebad90Sdan lappend mi [lindex $counts($docid,$iCol) $iPhrase] 26099ebad90Sdan lappend mi $nHit($iPhrase,$iCol) 2612f779343Sdan lappend mi $nDoc($iPhrase,$iCol) 26299ebad90Sdan } 26399ebad90Sdan } 26499ebad90Sdan set aMatchinfo($docid) $mi 26599ebad90Sdan } 26699ebad90Sdan 2673fd65192Sdan # Set up the nullentry output. 2683fd65192Sdan # 2693fd65192Sdan set nullentry [list] 2703fd65192Sdan for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} { 2713fd65192Sdan for {set iCol 0} {$iCol<$nCol} {incr iCol} { 2722f779343Sdan lappend nullentry 0 $nHit($iPhrase,$iCol) $nDoc($iPhrase,$iCol) 2733fd65192Sdan } 2743fd65192Sdan } 2753fd65192Sdan} 2763fd65192Sdan 2773fd65192Sdan 2783fd65192Sdanproc matching_brackets {expr} { 2793fd65192Sdan if {[string range $expr 0 0]!="(" || [string range $expr end end] !=")"} { 2803fd65192Sdan return 0 2813fd65192Sdan } 2823fd65192Sdan 2833fd65192Sdan set iBracket 1 2843fd65192Sdan set nExpr [string length $expr] 2853fd65192Sdan for {set i 1} {$iBracket && $i < $nExpr} {incr i} { 2863fd65192Sdan set c [string range $expr $i $i] 2873fd65192Sdan if {$c == "("} {incr iBracket} 2883fd65192Sdan if {$c == ")"} {incr iBracket -1} 2893fd65192Sdan } 2903fd65192Sdan 2913fd65192Sdan return [expr ($iBracket==0 && $i==$nExpr)] 2923fd65192Sdan} 2933fd65192Sdan 2942cf1a1deSdanproc get_near_results {tbl expr deferred arrayvar {nullvar ""}} { 2953fd65192Sdan upvar $arrayvar aMatchinfo 2963fd65192Sdan if {$nullvar != ""} { upvar $nullvar nullentry } 2973fd65192Sdan 2983fd65192Sdan set expr [string trim $expr] 2993fd65192Sdan while { [matching_brackets $expr] } { 3003fd65192Sdan set expr [string trim [string range $expr 1 end-1]] 3013fd65192Sdan } 3023fd65192Sdan 3033fd65192Sdan set prec(NOT) 1 3043fd65192Sdan set prec(AND) 2 3053fd65192Sdan set prec(OR) 3 3063fd65192Sdan 3073fd65192Sdan set currentprec 0 3083fd65192Sdan set iBracket 0 3093fd65192Sdan set expr_length [llength $expr] 3103fd65192Sdan for {set i 0} {$i < $expr_length} {incr i} { 3113fd65192Sdan set op [lindex $expr $i] 3123fd65192Sdan if {$iBracket==0 && [info exists prec($op)] && $prec($op)>=$currentprec } { 3133fd65192Sdan set opidx $i 3143fd65192Sdan set currentprec $prec($op) 3153fd65192Sdan } else { 3163fd65192Sdan for {set j 0} {$j < [string length $op]} {incr j} { 3173fd65192Sdan set c [string range $op $j $j] 3183fd65192Sdan if {$c == "("} { incr iBracket +1 } 3193fd65192Sdan if {$c == ")"} { incr iBracket -1 } 3203fd65192Sdan } 3213fd65192Sdan } 3223fd65192Sdan } 3233fd65192Sdan if {$iBracket!=0} { error "mismatched brackets in: $expr" } 3243fd65192Sdan 3253fd65192Sdan if {[info exists opidx]==0} { 3262cf1a1deSdan get_single_near_results $tbl $expr $deferred aMatchinfo nullentry 3273fd65192Sdan } else { 3283fd65192Sdan set eLeft [lrange $expr 0 [expr $opidx-1]] 3293fd65192Sdan set eRight [lrange $expr [expr $opidx+1] end] 3303fd65192Sdan 3312cf1a1deSdan get_near_results $tbl $eLeft $deferred aLeft nullleft 3322cf1a1deSdan get_near_results $tbl $eRight $deferred aRight nullright 3333fd65192Sdan 3343fd65192Sdan switch -- [lindex $expr $opidx] { 3353fd65192Sdan "NOT" { 3363fd65192Sdan foreach hit [array names aLeft] { 3373fd65192Sdan if {0==[info exists aRight($hit)]} { 3383fd65192Sdan set aMatchinfo($hit) $aLeft($hit) 3393fd65192Sdan } 3403fd65192Sdan } 3413fd65192Sdan set nullentry $nullleft 3423fd65192Sdan } 3433fd65192Sdan 3443fd65192Sdan "AND" { 3453fd65192Sdan foreach hit [array names aLeft] { 3463fd65192Sdan if {[info exists aRight($hit)]} { 3473fd65192Sdan set aMatchinfo($hit) [concat $aLeft($hit) $aRight($hit)] 3483fd65192Sdan } 3493fd65192Sdan } 3503fd65192Sdan set nullentry [concat $nullleft $nullright] 3513fd65192Sdan } 3523fd65192Sdan 3533fd65192Sdan "OR" { 3543fd65192Sdan foreach hit [array names aLeft] { 3553fd65192Sdan if {[info exists aRight($hit)]} { 3563fd65192Sdan set aMatchinfo($hit) [concat $aLeft($hit) $aRight($hit)] 3573fd65192Sdan unset aRight($hit) 3583fd65192Sdan } else { 3593fd65192Sdan set aMatchinfo($hit) [concat $aLeft($hit) $nullright] 3603fd65192Sdan } 3613fd65192Sdan } 3623fd65192Sdan foreach hit [array names aRight] { 3633fd65192Sdan set aMatchinfo($hit) [concat $nullleft $aRight($hit)] 3643fd65192Sdan } 3653fd65192Sdan 3663fd65192Sdan set nullentry [concat $nullleft $nullright] 3673fd65192Sdan } 3683fd65192Sdan } 3693fd65192Sdan } 3703fd65192Sdan} 3713fd65192Sdan 3723fd65192Sdan 3733fd65192Sdan# End of test procs. Actual tests are below this line. 3743fd65192Sdan#-------------------------------------------------------------------------- 3753fd65192Sdan 3763fd65192Sdan#-------------------------------------------------------------------------- 3773fd65192Sdan# The following test cases - fts3auto-1.* - focus on testing the Tcl 3783fd65192Sdan# command [fts3_near_match], which is used by other tests in this file. 3793fd65192Sdan# 3803fd65192Sdanproc test_fts3_near_match {tn doc expr res} { 3813fd65192Sdan fts3_near_match $doc $expr -phrasecountvar p 3823fd65192Sdan uplevel do_test [list $tn] [list [list set {} $p]] [list $res] 3833fd65192Sdan} 3843fd65192Sdan 3853fd65192Sdantest_fts3_near_match 1.1.1 {a b c a b} a {2} 3863fd65192Sdantest_fts3_near_match 1.1.2 {a b c a b} {a 5 b 6 c} {2 2 1} 3873fd65192Sdantest_fts3_near_match 1.1.3 {a b c a b} {"a b"} {2} 3883fd65192Sdantest_fts3_near_match 1.1.4 {a b c a b} {"b c"} {1} 3893fd65192Sdantest_fts3_near_match 1.1.5 {a b c a b} {"c c"} {0} 3903fd65192Sdan 3913fd65192Sdantest_fts3_near_match 1.2.1 "a b c d e f g" {b 2 f} {0 0} 3923fd65192Sdantest_fts3_near_match 1.2.2 "a b c d e f g" {b 3 f} {1 1} 3933fd65192Sdantest_fts3_near_match 1.2.3 "a b c d e f g" {f 2 b} {0 0} 3943fd65192Sdantest_fts3_near_match 1.2.4 "a b c d e f g" {f 3 b} {1 1} 3953fd65192Sdantest_fts3_near_match 1.2.5 "a b c d e f g" {"a b" 2 "f g"} {0 0} 3963fd65192Sdantest_fts3_near_match 1.2.6 "a b c d e f g" {"a b" 3 "f g"} {1 1} 3973fd65192Sdan 3983fd65192Sdanset 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" 3993fd65192Sdantest_fts3_near_match 1.3.1 $A {"c d" 5 "i j" 1 "e f"} {0 0 0} 4003fd65192Sdantest_fts3_near_match 1.3.2 $A {"c d" 5 "i j" 2 "e f"} {1 1 1} 4013fd65192Sdan 4023fd65192Sdan#-------------------------------------------------------------------------- 4033fd65192Sdan# Test cases fts3auto-2.* run some simple tests using the 4042f779343Sdan# [do_fts3query_test] proc. 4053fd65192Sdan# 4063fd65192Sdanforeach {tn create} { 4072f779343Sdan 1 "fts4(a, b)" 4082f779343Sdan 2 "fts4(a, b, order=DESC)" 4092f779343Sdan 3 "fts4(a, b, order=ASC)" 4102f779343Sdan 4 "fts4(a, b, prefix=1)" 4112f779343Sdan 5 "fts4(a, b, order=DESC, prefix=1)" 4122f779343Sdan 6 "fts4(a, b, order=ASC, prefix=1)" 4133fd65192Sdan} { 4143fd65192Sdan do_test 2.$tn.1 { 4153fd65192Sdan catchsql { DROP TABLE t1 } 4162f779343Sdan execsql "CREATE VIRTUAL TABLE t1 USING $create" 41799ebad90Sdan for {set i 0} {$i<32} {incr i} { 41899ebad90Sdan set doc [list] 41999ebad90Sdan if {$i&0x01} {lappend doc one} 42099ebad90Sdan if {$i&0x02} {lappend doc two} 42199ebad90Sdan if {$i&0x04} {lappend doc three} 42299ebad90Sdan if {$i&0x08} {lappend doc four} 42399ebad90Sdan if {$i&0x10} {lappend doc five} 42499ebad90Sdan execsql { INSERT INTO t1 VALUES($doc, null) } 42599ebad90Sdan } 42699ebad90Sdan } {} 4272f779343Sdan 4283fd65192Sdan foreach {tn2 expr} { 42999ebad90Sdan 1 {one} 43099ebad90Sdan 2 {one NEAR/1 five} 43199ebad90Sdan 3 {t*} 43299ebad90Sdan 4 {t* NEAR/0 five} 43399ebad90Sdan 5 {o* NEAR/1 f*} 43499ebad90Sdan 6 {one NEAR five NEAR two NEAR four NEAR three} 4353fd65192Sdan 7 {one NEAR xyz} 4363fd65192Sdan 8 {one OR two} 4373fd65192Sdan 9 {one AND two} 4383fd65192Sdan 10 {one NOT two} 4393fd65192Sdan 11 {one AND two OR three} 4403fd65192Sdan 12 {three OR one AND two} 4413fd65192Sdan 13 {(three OR one) AND two} 4423fd65192Sdan 14 {(three OR one) AND two NOT (five NOT four)} 4433fd65192Sdan 15 {"one two"} 4443fd65192Sdan 16 {"one two" NOT "three four"} 44599ebad90Sdan } { 4462f779343Sdan do_fts3query_test 2.$tn.2.$tn2 t1 $expr 4472f779343Sdan } 4482f779343Sdan} 4492f779343Sdan 4502f779343Sdan#-------------------------------------------------------------------------- 4512f779343Sdan# Some test cases involving deferred tokens. 4522f779343Sdan# 4532f779343Sdan 4542f779343Sdanforeach {tn create} { 4552f779343Sdan 1 "fts4(x)" 4562f779343Sdan 2 "fts4(x, order=DESC)" 4572f779343Sdan} { 4582f779343Sdan catchsql { DROP TABLE t1 } 4592f779343Sdan execsql "CREATE VIRTUAL TABLE t1 USING $create" 4602f779343Sdan do_execsql_test 3.$tn.1 { 461653265d9Sdan INSERT INTO t1(docid, x) VALUES(-2, 'a b c d e f g h i j k'); 462653265d9Sdan INSERT INTO t1(docid, x) VALUES(-1, 'b c d e f g h i j k a'); 463653265d9Sdan INSERT INTO t1(docid, x) VALUES(0, 'c d e f g h i j k a b'); 464653265d9Sdan INSERT INTO t1(docid, x) VALUES(1, 'd e f g h i j k a b c'); 465653265d9Sdan INSERT INTO t1(docid, x) VALUES(2, 'e f g h i j k a b c d'); 466653265d9Sdan INSERT INTO t1(docid, x) VALUES(3, 'f g h i j k a b c d e'); 467653265d9Sdan INSERT INTO t1(docid, x) VALUES(4, 'a c e g i k'); 468653265d9Sdan INSERT INTO t1(docid, x) VALUES(5, 'a d g j'); 469653265d9Sdan INSERT INTO t1(docid, x) VALUES(6, 'c a b'); 4702f779343Sdan } 4712f779343Sdan 472*db27fc07Sdan set limit [fts3_make_deferrable t1 c] 4732f779343Sdan 474*db27fc07Sdan do_fts3query_test 3.$tn.2.1 t1 {a OR c} 4752f779343Sdan 476*db27fc07Sdan do_test 3.$tn.3 { 477*db27fc07Sdan fts3_zero_long_segments t1 $limit 478*db27fc07Sdan } {1} 479*db27fc07Sdan 4802cf1a1deSdan foreach {tn2 expr def} { 4812cf1a1deSdan 1 {a NEAR c} {} 4822cf1a1deSdan 2 {a AND c} c 4832cf1a1deSdan 3 {"a c"} c 4842cf1a1deSdan 4 {"c a"} c 4852cf1a1deSdan 5 {"a c" NEAR/1 g} {} 4862cf1a1deSdan 6 {"a c" NEAR/0 g} {} 4872f779343Sdan } { 488*db27fc07Sdan do_fts3query_test 3.$tn.4.$tn2 -deferred $def t1 $expr 4892cf1a1deSdan } 4902cf1a1deSdan} 4912cf1a1deSdan 4922cf1a1deSdan#-------------------------------------------------------------------------- 4932cf1a1deSdan# 4942cf1a1deSdanforeach {tn create} { 4952cf1a1deSdan 1 "fts4(x, y)" 4962cf1a1deSdan 2 "fts4(x, y, order=DESC)" 497*db27fc07Sdan 3 "fts4(x, y, order=DESC, prefix=2)" 4982cf1a1deSdan} { 4992cf1a1deSdan 500*db27fc07Sdan execsql [subst { 501*db27fc07Sdan DROP TABLE t1; 502*db27fc07Sdan CREATE VIRTUAL TABLE t1 USING $create; 503*db27fc07Sdan INSERT INTO t1 VALUES('one two five four five', ''); 504*db27fc07Sdan INSERT INTO t1 VALUES('', 'one two five four five'); 505*db27fc07Sdan INSERT INTO t1 VALUES('one two', 'five four five'); 506*db27fc07Sdan }] 5072cf1a1deSdan 508*db27fc07Sdan do_fts3query_test 4.$tn.1.1 t1 {one AND five} 509*db27fc07Sdan do_fts3query_test 4.$tn.1.2 t1 {one NEAR five} 510*db27fc07Sdan do_fts3query_test 4.$tn.1.3 t1 {one NEAR/1 five} 511*db27fc07Sdan do_fts3query_test 4.$tn.1.4 t1 {one NEAR/2 five} 512*db27fc07Sdan do_fts3query_test 4.$tn.1.5 t1 {one NEAR/3 five} 513*db27fc07Sdan 514*db27fc07Sdan do_test 4.$tn.2 { 515*db27fc07Sdan set limit [fts3_make_deferrable t1 five] 516*db27fc07Sdan execsql { INSERT INTO t1(t1) VALUES('optimize') } 517*db27fc07Sdan expr {[fts3_zero_long_segments t1 $limit]>0} 518*db27fc07Sdan } {1} 519*db27fc07Sdan 520*db27fc07Sdan do_fts3query_test 4.$tn.3.1 -deferred five t1 {one AND five} 521*db27fc07Sdan do_fts3query_test 4.$tn.3.2 -deferred five t1 {one NEAR five} 522*db27fc07Sdan do_fts3query_test 4.$tn.3.3 -deferred five t1 {one NEAR/1 five} 523*db27fc07Sdan do_fts3query_test 4.$tn.3.4 -deferred five t1 {one NEAR/2 five} 524*db27fc07Sdan do_fts3query_test 4.$tn.3.5 -deferred five t1 {one NEAR/3 five} 525*db27fc07Sdan 526*db27fc07Sdan do_fts3query_test 4.$tn.4.1 -deferred fi* t1 {on* AND fi*} 527*db27fc07Sdan do_fts3query_test 4.$tn.4.2 -deferred fi* t1 {on* NEAR fi*} 528*db27fc07Sdan do_fts3query_test 4.$tn.4.3 -deferred fi* t1 {on* NEAR/1 fi*} 529*db27fc07Sdan do_fts3query_test 4.$tn.4.4 -deferred fi* t1 {on* NEAR/2 fi*} 530*db27fc07Sdan do_fts3query_test 4.$tn.4.5 -deferred fi* t1 {on* NEAR/3 fi*} 53199ebad90Sdan} 53299ebad90Sdan 5333fd65192Sdanset sqlite_fts3_enable_parentheses $sfep 53499ebad90Sdanfinish_test 53599ebad90Sdan 536