OLD | NEW |
(Empty) | |
| 1 # 2014 June 17 |
| 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 # This file implements regression tests for SQLite library. The |
| 12 # focus of this script is testing the FTS5 module. |
| 13 # |
| 14 |
| 15 source [file join [file dirname [info script]] fts5_common.tcl] |
| 16 source $testdir/malloc_common.tcl |
| 17 set testprefix fts5fault1 |
| 18 |
| 19 # If SQLITE_ENABLE_FTS3 is defined, omit this file. |
| 20 ifcapable !fts5 { |
| 21 finish_test |
| 22 return |
| 23 } |
| 24 |
| 25 # Simple tests: |
| 26 # |
| 27 # 1: CREATE VIRTUAL TABLE |
| 28 # 2: INSERT statement |
| 29 # 3: DELETE statement |
| 30 # 4: MATCH expressions |
| 31 # |
| 32 # |
| 33 |
| 34 faultsim_save_and_close |
| 35 do_faultsim_test 1 -faults ioerr-t* -prep { |
| 36 faultsim_restore_and_reopen |
| 37 } -body { |
| 38 execsql { CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix='1, 2, 3') } |
| 39 } -test { |
| 40 faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} |
| 41 } |
| 42 |
| 43 reset_db |
| 44 do_execsql_test 2.0 { |
| 45 CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix='1, 2, 3'); |
| 46 } |
| 47 faultsim_save_and_close |
| 48 do_faultsim_test 2 -prep { |
| 49 faultsim_restore_and_reopen |
| 50 } -body { |
| 51 execsql { |
| 52 INSERT INTO t1 VALUES('a b c', 'a bc def ghij klmno'); |
| 53 } |
| 54 } -test { |
| 55 faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} |
| 56 } |
| 57 |
| 58 reset_db |
| 59 do_execsql_test 3.0 { |
| 60 CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix='1, 2, 3'); |
| 61 INSERT INTO t1 VALUES('a b c', 'a bc def ghij klmno'); |
| 62 } |
| 63 faultsim_save_and_close |
| 64 do_faultsim_test 3 -prep { |
| 65 faultsim_restore_and_reopen |
| 66 } -body { |
| 67 execsql { DELETE FROM t1 } |
| 68 } -test { |
| 69 faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} |
| 70 } |
| 71 |
| 72 reset_db |
| 73 do_execsql_test 4.0 { |
| 74 CREATE VIRTUAL TABLE t2 USING fts5(a, b); |
| 75 INSERT INTO t2 VALUES('m f a jj th q gi ar', 'hj n h h sg j i m'); |
| 76 INSERT INTO t2 VALUES('nr s t g od j kf h', 'sb h aq rg op rb n nl'); |
| 77 INSERT INTO t2 VALUES('do h h pb p p q fr', 'c rj qs or cr a l i'); |
| 78 INSERT INTO t2 VALUES('lk gp t i lq mq qm p', 'h mr g f op ld aj h'); |
| 79 INSERT INTO t2 VALUES('ct d sq kc qi k f j', 'sn gh c of g s qt q'); |
| 80 INSERT INTO t2 VALUES('d ea d d om mp s ab', 'dm hg l df cm ft pa c'); |
| 81 INSERT INTO t2 VALUES('tc dk c jn n t sr ge', 'a a kn bc n i af h'); |
| 82 INSERT INTO t2 VALUES('ie ii d i b sa qo rf', 'a h m aq i b m fn'); |
| 83 INSERT INTO t2 VALUES('gs r fo a er m h li', 'tm c p gl eb ml q r'); |
| 84 INSERT INTO t2 VALUES('k fe fd rd a gi ho kk', 'ng m c r d ml rm r'); |
| 85 } |
| 86 faultsim_save_and_close |
| 87 |
| 88 foreach {tn expr res} { |
| 89 1 { dk } 7 |
| 90 2 { m f } 1 |
| 91 3 { f* } {1 3 4 5 6 8 9 10} |
| 92 4 { m OR f } {1 4 5 8 9 10} |
| 93 5 { sn + gh } {5} |
| 94 6 { "sn gh" } {5} |
| 95 7 { NEAR(r a, 5) } {9} |
| 96 8 { m* f* } {1 4 6 8 9 10} |
| 97 9 { m* + f* } {1 8} |
| 98 10 { c NOT p } {5 6 7 10} |
| 99 } { |
| 100 do_faultsim_test 4.$tn -prep { |
| 101 faultsim_restore_and_reopen |
| 102 } -body " |
| 103 execsql { SELECT rowid FROM t2 WHERE t2 MATCH '$expr' } |
| 104 " -test " |
| 105 faultsim_test_result {[list 0 $res]} {1 {vtable constructor failed: t2}} |
| 106 " |
| 107 } |
| 108 |
| 109 |
| 110 #------------------------------------------------------------------------- |
| 111 # The following tests use a larger database populated with random data. |
| 112 # |
| 113 # The database page size is set to 512 bytes and the FTS5 page size left |
| 114 # at the default 1000 bytes. This means that reading a node may require |
| 115 # pulling an overflow page from disk, which is an extra opportunity for |
| 116 # an error to occur. |
| 117 # |
| 118 reset_db |
| 119 do_execsql_test 5.0.1 { |
| 120 PRAGMA main.page_size = 512; |
| 121 CREATE VIRTUAL TABLE x1 USING fts5(a, b); |
| 122 PRAGMA main.page_size; |
| 123 } {512} |
| 124 |
| 125 proc rnddoc {n} { |
| 126 set map [list 0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j] |
| 127 set doc [list] |
| 128 for {set i 0} {$i < $n} {incr i} { |
| 129 lappend doc [string map $map [format %.3d [expr int(rand()*1000)]]] |
| 130 } |
| 131 set doc |
| 132 } |
| 133 db func rnddoc rnddoc |
| 134 |
| 135 do_execsql_test 5.0.2 { |
| 136 WITH r(a, b) AS ( |
| 137 SELECT rnddoc(6), rnddoc(6) UNION ALL |
| 138 SELECT rnddoc(6), rnddoc(6) FROM r |
| 139 ) |
| 140 INSERT INTO x1 SELECT * FROM r LIMIT 10000; |
| 141 } |
| 142 |
| 143 set res [db one { |
| 144 SELECT count(*) FROM x1 WHERE x1.a LIKE '%abc%' OR x1.b LIKE '%abc%'} |
| 145 ] |
| 146 |
| 147 do_faultsim_test 5.1 -faults oom* -body { |
| 148 execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abc' } |
| 149 } -test { |
| 150 faultsim_test_result [list 0 $::res] |
| 151 } |
| 152 do_faultsim_test 5.2 -faults oom* -body { |
| 153 execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abcd' } |
| 154 } -test { |
| 155 faultsim_test_result [list 0 0] |
| 156 } |
| 157 |
| 158 proc test_astar {a b} { |
| 159 return [expr { [regexp {a[^ ][^ ]} $a] || [regexp {a[^ ][^ ]} $b] }] |
| 160 } |
| 161 db func test_astar test_astar |
| 162 |
| 163 set res [db one { SELECT count(*) FROM x1 WHERE test_astar(a, b) } ] |
| 164 do_faultsim_test 5.3 -faults oom* -body { |
| 165 execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'a*' } |
| 166 } -test { |
| 167 faultsim_test_result [list 0 $::res] |
| 168 } |
| 169 |
| 170 do_faultsim_test 5.4 -faults oom* -prep { |
| 171 db close |
| 172 sqlite3 db test.db |
| 173 } -body { |
| 174 execsql { INSERT INTO x1 VALUES('a b c d', 'e f g h') } |
| 175 } -test { |
| 176 faultsim_test_result [list 0 {}] |
| 177 } |
| 178 |
| 179 do_faultsim_test 5.5.1 -faults oom* -body { |
| 180 execsql { |
| 181 SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid=1 |
| 182 } |
| 183 } -test { |
| 184 faultsim_test_result [list 0 1] |
| 185 } |
| 186 do_faultsim_test 5.5.2 -faults oom* -body { |
| 187 execsql { |
| 188 SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid=10 |
| 189 } |
| 190 } -test { |
| 191 faultsim_test_result [list 0 1] |
| 192 } |
| 193 do_faultsim_test 5.5.3 -faults oom* -body { |
| 194 execsql { |
| 195 SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid = ( |
| 196 SELECT min(rowid) FROM x1_data WHERE rowid>20 |
| 197 ) |
| 198 } |
| 199 } -test { |
| 200 faultsim_test_result [list 0 1] |
| 201 } |
| 202 do_faultsim_test 5.5.4 -faults oom* -body { |
| 203 execsql { |
| 204 SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid = ( |
| 205 SELECT max(rowid) FROM x1_data |
| 206 ) |
| 207 } |
| 208 } -test { |
| 209 faultsim_test_result [list 0 1] |
| 210 } |
| 211 |
| 212 #------------------------------------------------------------------------- |
| 213 # |
| 214 reset_db |
| 215 do_execsql_test 6.0 { |
| 216 CREATE VIRTUAL TABLE x1 USING fts5(x); |
| 217 INSERT INTO x1(x1, rank) VALUES('automerge', 0); |
| 218 |
| 219 INSERT INTO x1 VALUES('a b c'); -- 1 |
| 220 INSERT INTO x1 VALUES('a b c'); -- 2 |
| 221 INSERT INTO x1 VALUES('a b c'); -- 3 |
| 222 INSERT INTO x1 VALUES('a b c'); -- 4 |
| 223 INSERT INTO x1 VALUES('a b c'); -- 5 |
| 224 INSERT INTO x1 VALUES('a b c'); -- 6 |
| 225 INSERT INTO x1 VALUES('a b c'); -- 7 |
| 226 INSERT INTO x1 VALUES('a b c'); -- 8 |
| 227 INSERT INTO x1 VALUES('a b c'); -- 9 |
| 228 INSERT INTO x1 VALUES('a b c'); -- 10 |
| 229 INSERT INTO x1 VALUES('a b c'); -- 11 |
| 230 INSERT INTO x1 VALUES('a b c'); -- 12 |
| 231 INSERT INTO x1 VALUES('a b c'); -- 13 |
| 232 INSERT INTO x1 VALUES('a b c'); -- 14 |
| 233 INSERT INTO x1 VALUES('a b c'); -- 15 |
| 234 |
| 235 SELECT count(*) FROM x1_data; |
| 236 } {17} |
| 237 |
| 238 faultsim_save_and_close |
| 239 |
| 240 do_faultsim_test 6.1 -faults oom* -prep { |
| 241 faultsim_restore_and_reopen |
| 242 } -body { |
| 243 execsql { INSERT INTO x1 VALUES('d e f') } |
| 244 } -test { |
| 245 faultsim_test_result [list 0 {}] |
| 246 if {$testrc==0} { |
| 247 set nCnt [db one {SELECT count(*) FROM x1_data}] |
| 248 if {$nCnt!=3} { error "expected 3 entries but there are $nCnt" } |
| 249 } |
| 250 } |
| 251 |
| 252 do_faultsim_test 6.2 -faults oom* -prep { |
| 253 faultsim_restore_and_reopen |
| 254 } -body { |
| 255 execsql { INSERT INTO x1(x1, rank) VALUES('pgsz', 32) } |
| 256 } -test { |
| 257 faultsim_test_result [list 0 {}] |
| 258 } |
| 259 |
| 260 do_faultsim_test 6.3 -faults oom-* -prep { |
| 261 faultsim_restore_and_reopen |
| 262 } -body { |
| 263 execsql { INSERT INTO x1(x1) VALUES('integrity-check') } |
| 264 } -test { |
| 265 faultsim_test_result [list 0 {}] |
| 266 } |
| 267 |
| 268 do_faultsim_test 6.4 -faults oom-* -prep { |
| 269 faultsim_restore_and_reopen |
| 270 } -body { |
| 271 execsql { INSERT INTO x1(x1) VALUES('optimize') } |
| 272 } -test { |
| 273 faultsim_test_result [list 0 {}] |
| 274 } |
| 275 |
| 276 #------------------------------------------------------------------------- |
| 277 # |
| 278 do_faultsim_test 7.0 -faults oom* -prep { |
| 279 catch { db close } |
| 280 } -body { |
| 281 sqlite3 db test.db |
| 282 } -test { |
| 283 faultsim_test_result [list 0 {}] {1 {}} {1 {initialization of fts5 failed: }} |
| 284 } |
| 285 |
| 286 #------------------------------------------------------------------------- |
| 287 # A prefix query against a large document set. |
| 288 # |
| 289 proc rnddoc {n} { |
| 290 set map [list 0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j] |
| 291 set doc [list] |
| 292 for {set i 0} {$i < $n} {incr i} { |
| 293 lappend doc "x[string map $map [format %.3d [expr int(rand()*1000)]]]" |
| 294 } |
| 295 set doc |
| 296 } |
| 297 |
| 298 reset_db |
| 299 db func rnddoc rnddoc |
| 300 |
| 301 do_test 8.0 { |
| 302 execsql { CREATE VIRTUAL TABLE x1 USING fts5(a) } |
| 303 set ::res [list] |
| 304 for {set i 1} {$i<100} {incr i 1} { |
| 305 execsql { INSERT INTO x1 VALUES( rnddoc(50) ) } |
| 306 lappend ::res $i |
| 307 } |
| 308 } {} |
| 309 |
| 310 do_faultsim_test 8.1 -faults oom* -prep { |
| 311 } -body { |
| 312 execsql { |
| 313 SELECT rowid FROM x1 WHERE x1 MATCH 'x*' |
| 314 } |
| 315 } -test { |
| 316 faultsim_test_result [list 0 $::res] |
| 317 } |
| 318 |
| 319 #------------------------------------------------------------------------- |
| 320 # Segment promotion. |
| 321 # |
| 322 do_test 9.0 { |
| 323 reset_db |
| 324 db func rnddoc fts5_rnddoc |
| 325 execsql { |
| 326 CREATE VIRTUAL TABLE s2 USING fts5(x); |
| 327 INSERT INTO s2(s2, rank) VALUES('pgsz', 32); |
| 328 INSERT INTO s2(s2, rank) VALUES('automerge', 0); |
| 329 } |
| 330 |
| 331 for {set i 1} {$i <= 16} {incr i} { |
| 332 execsql { INSERT INTO s2 VALUES(rnddoc(5)) } |
| 333 } |
| 334 fts5_level_segs s2 |
| 335 } {0 1} |
| 336 set insert_doc [db one {SELECT rnddoc(160)}] |
| 337 faultsim_save_and_close |
| 338 |
| 339 do_faultsim_test 9.1 -faults oom-* -prep { |
| 340 faultsim_restore_and_reopen |
| 341 } -body { |
| 342 execsql { INSERT INTO s2 VALUES($::insert_doc) } |
| 343 } -test { |
| 344 faultsim_test_result {0 {}} |
| 345 if {$testrc==0} { |
| 346 set ls [fts5_level_segs s2] |
| 347 if {$ls != "2 0"} { error "fts5_level_segs says {$ls}" } |
| 348 } |
| 349 } |
| 350 |
| 351 |
| 352 |
| 353 finish_test |
| 354 |
OLD | NEW |