gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/fts3snippet.test (about)

     1  # 2010 January 07
     2  #
     3  # The author disclaims copyright to this source code.  In place of
     4  # a legal notice, here is a blessing:
     5  #
     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.
     9  #
    10  #*************************************************************************
    11  #
    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.
    15  #
    16  
    17  set testdir [file dirname $argv0]
    18  source $testdir/tester.tcl
    19  set testprefix fts3snippet
    20  
    21  # If SQLITE_ENABLE_FTS3 is not defined, omit this file.
    22  ifcapable !fts3 { finish_test ; return }
    23  source $testdir/fts3_common.tcl
    24  
    25  set sqlite_fts3_enable_parentheses 1
    26  set DO_MALLOC_TEST 0
    27  
    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].
    30  #
    31  proc normalize {L} {
    32    set ret [list]
    33    foreach l $L {lappend ret $l}
    34    return $ret
    35  }
    36  
    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
    45  }
    46    
    47  # Document text used by a few tests. Contains the English names of all
    48  # integers between 1 and 300.
    49  #
    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
   126  }]
   127  
   128  foreach {DO_MALLOC_TEST enc} {
   129    0 utf8
   130    1 utf8
   131    1 utf16
   132  } {
   133  
   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\""
   139  
   140    # Set variable $T to the test name prefix for this iteration of the loop.
   141    #
   142    set T "fts3snippet-1.$enc"
   143  
   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    }
   168  
   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    } {}
   178  
   179    set off [string first "twohundred " $numbers]
   180    do_offsets_test $T.2.1 {twohundred} [list 1 0 $off 10]
   181  
   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]
   185  
   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    }
   313  
   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    }
   331  
   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}
   383  
   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}
   400  
   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}
   405  
   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}
   410  
   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}
   414  
   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 }
   419  
   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 }
   424  
   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    }]
   436  
   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}
   462  }
   463  
   464  #-------------------------------------------------------------------------
   465  # Test an interaction between the snippet() function and OR clauses.
   466  #
   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');
   474  }
   475  
   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]}
   484  }
   485  
   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}
   496  }
   497  
   498  do_execsql_test 2.4 {
   499    INSERT INTO t2 VALUES('six');
   500  }
   501  
   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]}
   510  }
   511  
   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}
   522  }
   523  
   524  #-------------------------------------------------------------------------
   525  do_execsql_test 3 {
   526    CREATE VIRTUAL TABLE t3 USING fts4;
   527    INSERT INTO t3 VALUES('[one two three]');
   528  }
   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>]}}
   541  
   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  } {{}}
   549  
   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}
   557  
   558  do_test 4.3 {
   559    llength [db one {
   560      SELECT snippet(t4, '', '', '', 0, 150) FROM t4 WHERE t4 MATCH 'E'
   561    }]
   562  } {64}
   563  
   564  
   565  #-------------------------------------------------------------------------
   566  # Request a snippet from a query with more than 64 phrases.
   567  #
   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');
   573  }
   574  
   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]}
   589  }
   590  
   591  set sqlite_fts3_enable_parentheses 0
   592  finish_test