| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 # 2007 April 26 | 
|  | 2 # | 
|  | 3 # The author disclaims copyright to this source code. | 
|  | 4 # | 
|  | 5 #************************************************************************* | 
|  | 6 # This file implements tests for prefix-searching in the fts2 | 
|  | 7 # component of the SQLite library. | 
|  | 8 # | 
|  | 9 # $Id: fts2n.test,v 1.2 2007/12/13 21:54:11 drh Exp $ | 
|  | 10 # | 
|  | 11 | 
|  | 12 set testdir [file dirname $argv0] | 
|  | 13 source $testdir/tester.tcl | 
|  | 14 | 
|  | 15 # If SQLITE_ENABLE_FTS2 is defined, omit this file. | 
|  | 16 ifcapable !fts2 { | 
|  | 17   finish_test | 
|  | 18   return | 
|  | 19 } | 
|  | 20 | 
|  | 21 # A large string to prime the pump with. | 
|  | 22 set text { | 
|  | 23   Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas | 
|  | 24   iaculis mollis ipsum. Praesent rhoncus placerat justo. Duis non quam | 
|  | 25   sed turpis posuere placerat. Curabitur et lorem in lorem porttitor | 
|  | 26   aliquet. Pellentesque bibendum tincidunt diam. Vestibulum blandit | 
|  | 27   ante nec elit. In sapien diam, facilisis eget, dictum sed, viverra | 
|  | 28   at, felis. Vestibulum magna. Sed magna dolor, vestibulum rhoncus, | 
|  | 29   ornare vel, vulputate sit amet, felis. Integer malesuada, tellus at | 
|  | 30   luctus gravida, diam nunc porta nibh, nec imperdiet massa metus eu | 
|  | 31   lectus. Aliquam nisi. Nunc fringilla nulla at lectus. Suspendisse | 
|  | 32   potenti. Cum sociis natoque penatibus et magnis dis parturient | 
|  | 33   montes, nascetur ridiculus mus. Pellentesque odio nulla, feugiat eu, | 
|  | 34   suscipit nec, consequat quis, risus. | 
|  | 35 } | 
|  | 36 | 
|  | 37 db eval { | 
|  | 38   CREATE VIRTUAL TABLE t1 USING fts2(c); | 
|  | 39 | 
|  | 40   INSERT INTO t1(rowid, c) VALUES(1, $text); | 
|  | 41   INSERT INTO t1(rowid, c) VALUES(2, 'Another lovely row'); | 
|  | 42 } | 
|  | 43 | 
|  | 44 # Exact match | 
|  | 45 do_test fts2n-1.1 { | 
|  | 46   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lorem'" | 
|  | 47 } {1} | 
|  | 48 | 
|  | 49 # And a prefix | 
|  | 50 do_test fts2n-1.2 { | 
|  | 51   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lore*'" | 
|  | 52 } {1} | 
|  | 53 | 
|  | 54 # Prefix includes exact match | 
|  | 55 do_test fts2n-1.3 { | 
|  | 56   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lorem*'" | 
|  | 57 } {1} | 
|  | 58 | 
|  | 59 # Make certain everything isn't considered a prefix! | 
|  | 60 do_test fts2n-1.4 { | 
|  | 61   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lore'" | 
|  | 62 } {} | 
|  | 63 | 
|  | 64 # Prefix across multiple rows. | 
|  | 65 do_test fts2n-1.5 { | 
|  | 66   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lo*'" | 
|  | 67 } {1 2} | 
|  | 68 | 
|  | 69 # Likewise, with multiple hits in one document. | 
|  | 70 do_test fts2n-1.6 { | 
|  | 71   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'l*'" | 
|  | 72 } {1 2} | 
|  | 73 | 
|  | 74 # Prefix which should only hit one document. | 
|  | 75 do_test fts2n-1.7 { | 
|  | 76   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lov*'" | 
|  | 77 } {2} | 
|  | 78 | 
|  | 79 # * not at end is dropped. | 
|  | 80 do_test fts2n-1.8 { | 
|  | 81   execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lo *'" | 
|  | 82 } {} | 
|  | 83 | 
|  | 84 # Stand-alone * is dropped. | 
|  | 85 do_test fts2n-1.9 { | 
|  | 86   execsql "SELECT rowid FROM t1 WHERE t1 MATCH '*'" | 
|  | 87 } {} | 
|  | 88 | 
|  | 89 # Phrase-query prefix. | 
|  | 90 do_test fts2n-1.10 { | 
|  | 91   execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"lovely r*\"'" | 
|  | 92 } {2} | 
|  | 93 do_test fts2n-1.11 { | 
|  | 94   execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"lovely r\"'" | 
|  | 95 } {} | 
|  | 96 | 
|  | 97 # Phrase query with multiple prefix matches. | 
|  | 98 do_test fts2n-1.12 { | 
|  | 99   execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"a* l*\"'" | 
|  | 100 } {1 2} | 
|  | 101 | 
|  | 102 # Phrase query with multiple prefix matches. | 
|  | 103 do_test fts2n-1.13 { | 
|  | 104   execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"a* l* row\"'" | 
|  | 105 } {2} | 
|  | 106 | 
|  | 107 | 
|  | 108 | 
|  | 109 | 
|  | 110 # Test across updates (and, by implication, deletes). | 
|  | 111 | 
|  | 112 # Version of text without "lorem". | 
|  | 113 regsub -all {[Ll]orem} $text '' ntext | 
|  | 114 | 
|  | 115 db eval { | 
|  | 116   CREATE VIRTUAL TABLE t2 USING fts2(c); | 
|  | 117 | 
|  | 118   INSERT INTO t2(rowid, c) VALUES(1, $text); | 
|  | 119   INSERT INTO t2(rowid, c) VALUES(2, 'Another lovely row'); | 
|  | 120   UPDATE t2 SET c = $ntext WHERE rowid = 1; | 
|  | 121 } | 
|  | 122 | 
|  | 123 # Can't see lorem as an exact match. | 
|  | 124 do_test fts2n-2.1 { | 
|  | 125   execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lorem'" | 
|  | 126 } {} | 
|  | 127 | 
|  | 128 # Can't see a prefix of lorem, either. | 
|  | 129 do_test fts2n-2.2 { | 
|  | 130   execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lore*'" | 
|  | 131 } {} | 
|  | 132 | 
|  | 133 # Can see lovely in the other document. | 
|  | 134 do_test fts2n-2.3 { | 
|  | 135   execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lo*'" | 
|  | 136 } {2} | 
|  | 137 | 
|  | 138 # Can still see other hits. | 
|  | 139 do_test fts2n-2.4 { | 
|  | 140   execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'l*'" | 
|  | 141 } {1 2} | 
|  | 142 | 
|  | 143 # Prefix which should only hit one document. | 
|  | 144 do_test fts2n-2.5 { | 
|  | 145   execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lov*'" | 
|  | 146 } {2} | 
|  | 147 | 
|  | 148 | 
|  | 149 | 
|  | 150 # Test with a segment which will have multiple levels in the tree. | 
|  | 151 | 
|  | 152 # Build a big document with lots of unique terms. | 
|  | 153 set bigtext $text | 
|  | 154 foreach c {a b c d e} { | 
|  | 155   regsub -all {[A-Za-z]+} $bigtext "&$c" t | 
|  | 156   append bigtext $t | 
|  | 157 } | 
|  | 158 | 
|  | 159 # Populate a table with many copies of the big document, so that we | 
|  | 160 # can test the number of hits found.  Populate $ret with the expected | 
|  | 161 # hit counts for each row.  offsets() returns 4 elements for every | 
|  | 162 # hit.  We'll have 6 hits for row 1, 1 for row 2, and 6*(2^5)==192 for | 
|  | 163 # $bigtext. | 
|  | 164 set ret {6 1} | 
|  | 165 db eval { | 
|  | 166   BEGIN; | 
|  | 167   CREATE VIRTUAL TABLE t3 USING fts2(c); | 
|  | 168 | 
|  | 169   INSERT INTO t3(rowid, c) VALUES(1, $text); | 
|  | 170   INSERT INTO t3(rowid, c) VALUES(2, 'Another lovely row'); | 
|  | 171 } | 
|  | 172 for {set i 0} {$i<100} {incr i} { | 
|  | 173   db eval {INSERT INTO t3(rowid, c) VALUES(3+$i, $bigtext)} | 
|  | 174   lappend ret 192 | 
|  | 175 } | 
|  | 176 db eval {COMMIT;} | 
|  | 177 | 
|  | 178 # Test that we get the expected number of hits. | 
|  | 179 do_test fts2n-3.1 { | 
|  | 180   set t {} | 
|  | 181   db eval {SELECT offsets(t3) as o FROM t3 WHERE t3 MATCH 'l*'} { | 
|  | 182     set l [llength $o] | 
|  | 183     lappend t [expr {$l/4}] | 
|  | 184   } | 
|  | 185   set t | 
|  | 186 } $ret | 
|  | 187 | 
|  | 188 # TODO(shess) It would be useful to test a couple edge cases, but I | 
|  | 189 # don't know if we have the precision to manage it from here at this | 
|  | 190 # time.  Prefix hits can cross leaves, which the code above _should_ | 
|  | 191 # hit by virtue of size.  There are two variations on this.  If the | 
|  | 192 # tree is 2 levels high, the code will find the leaf-node extent | 
|  | 193 # directly, but if its higher, the code will have to follow two | 
|  | 194 # separate interior branches down the tree.  Both should be tested. | 
|  | 195 | 
|  | 196 finish_test | 
| OLD | NEW | 
|---|