xref: /sqlite-3.40.0/test/fts3auto.test (revision db27fc07)
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