Index: third_party/sqlite/sqlite-src-3170000/ext/fts5/test/fts5fault1.test |
diff --git a/third_party/sqlite/sqlite-src-3170000/ext/fts5/test/fts5fault1.test b/third_party/sqlite/sqlite-src-3170000/ext/fts5/test/fts5fault1.test |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9d63a1175f20e644bea70850b593ceb70f257f3b |
--- /dev/null |
+++ b/third_party/sqlite/sqlite-src-3170000/ext/fts5/test/fts5fault1.test |
@@ -0,0 +1,354 @@ |
+# 2014 June 17 |
+# |
+# The author disclaims copyright to this source code. In place of |
+# a legal notice, here is a blessing: |
+# |
+# May you do good and not evil. |
+# May you find forgiveness for yourself and forgive others. |
+# May you share freely, never taking more than you give. |
+# |
+#************************************************************************* |
+# This file implements regression tests for SQLite library. The |
+# focus of this script is testing the FTS5 module. |
+# |
+ |
+source [file join [file dirname [info script]] fts5_common.tcl] |
+source $testdir/malloc_common.tcl |
+set testprefix fts5fault1 |
+ |
+# If SQLITE_ENABLE_FTS3 is defined, omit this file. |
+ifcapable !fts5 { |
+ finish_test |
+ return |
+} |
+ |
+# Simple tests: |
+# |
+# 1: CREATE VIRTUAL TABLE |
+# 2: INSERT statement |
+# 3: DELETE statement |
+# 4: MATCH expressions |
+# |
+# |
+ |
+faultsim_save_and_close |
+do_faultsim_test 1 -faults ioerr-t* -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix='1, 2, 3') } |
+} -test { |
+ faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} |
+} |
+ |
+reset_db |
+do_execsql_test 2.0 { |
+ CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix='1, 2, 3'); |
+} |
+faultsim_save_and_close |
+do_faultsim_test 2 -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { |
+ INSERT INTO t1 VALUES('a b c', 'a bc def ghij klmno'); |
+ } |
+} -test { |
+ faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} |
+} |
+ |
+reset_db |
+do_execsql_test 3.0 { |
+ CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix='1, 2, 3'); |
+ INSERT INTO t1 VALUES('a b c', 'a bc def ghij klmno'); |
+} |
+faultsim_save_and_close |
+do_faultsim_test 3 -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { DELETE FROM t1 } |
+} -test { |
+ faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} |
+} |
+ |
+reset_db |
+do_execsql_test 4.0 { |
+ CREATE VIRTUAL TABLE t2 USING fts5(a, b); |
+ INSERT INTO t2 VALUES('m f a jj th q gi ar', 'hj n h h sg j i m'); |
+ INSERT INTO t2 VALUES('nr s t g od j kf h', 'sb h aq rg op rb n nl'); |
+ INSERT INTO t2 VALUES('do h h pb p p q fr', 'c rj qs or cr a l i'); |
+ INSERT INTO t2 VALUES('lk gp t i lq mq qm p', 'h mr g f op ld aj h'); |
+ INSERT INTO t2 VALUES('ct d sq kc qi k f j', 'sn gh c of g s qt q'); |
+ INSERT INTO t2 VALUES('d ea d d om mp s ab', 'dm hg l df cm ft pa c'); |
+ INSERT INTO t2 VALUES('tc dk c jn n t sr ge', 'a a kn bc n i af h'); |
+ INSERT INTO t2 VALUES('ie ii d i b sa qo rf', 'a h m aq i b m fn'); |
+ INSERT INTO t2 VALUES('gs r fo a er m h li', 'tm c p gl eb ml q r'); |
+ INSERT INTO t2 VALUES('k fe fd rd a gi ho kk', 'ng m c r d ml rm r'); |
+} |
+faultsim_save_and_close |
+ |
+foreach {tn expr res} { |
+ 1 { dk } 7 |
+ 2 { m f } 1 |
+ 3 { f* } {1 3 4 5 6 8 9 10} |
+ 4 { m OR f } {1 4 5 8 9 10} |
+ 5 { sn + gh } {5} |
+ 6 { "sn gh" } {5} |
+ 7 { NEAR(r a, 5) } {9} |
+ 8 { m* f* } {1 4 6 8 9 10} |
+ 9 { m* + f* } {1 8} |
+ 10 { c NOT p } {5 6 7 10} |
+} { |
+ do_faultsim_test 4.$tn -prep { |
+ faultsim_restore_and_reopen |
+ } -body " |
+ execsql { SELECT rowid FROM t2 WHERE t2 MATCH '$expr' } |
+ " -test " |
+ faultsim_test_result {[list 0 $res]} {1 {vtable constructor failed: t2}} |
+ " |
+} |
+ |
+ |
+#------------------------------------------------------------------------- |
+# The following tests use a larger database populated with random data. |
+# |
+# The database page size is set to 512 bytes and the FTS5 page size left |
+# at the default 1000 bytes. This means that reading a node may require |
+# pulling an overflow page from disk, which is an extra opportunity for |
+# an error to occur. |
+# |
+reset_db |
+do_execsql_test 5.0.1 { |
+ PRAGMA main.page_size = 512; |
+ CREATE VIRTUAL TABLE x1 USING fts5(a, b); |
+ PRAGMA main.page_size; |
+} {512} |
+ |
+proc rnddoc {n} { |
+ set map [list 0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j] |
+ set doc [list] |
+ for {set i 0} {$i < $n} {incr i} { |
+ lappend doc [string map $map [format %.3d [expr int(rand()*1000)]]] |
+ } |
+ set doc |
+} |
+db func rnddoc rnddoc |
+ |
+do_execsql_test 5.0.2 { |
+ WITH r(a, b) AS ( |
+ SELECT rnddoc(6), rnddoc(6) UNION ALL |
+ SELECT rnddoc(6), rnddoc(6) FROM r |
+ ) |
+ INSERT INTO x1 SELECT * FROM r LIMIT 10000; |
+} |
+ |
+set res [db one { |
+ SELECT count(*) FROM x1 WHERE x1.a LIKE '%abc%' OR x1.b LIKE '%abc%'} |
+] |
+ |
+do_faultsim_test 5.1 -faults oom* -body { |
+ execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abc' } |
+} -test { |
+ faultsim_test_result [list 0 $::res] |
+} |
+do_faultsim_test 5.2 -faults oom* -body { |
+ execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abcd' } |
+} -test { |
+ faultsim_test_result [list 0 0] |
+} |
+ |
+proc test_astar {a b} { |
+ return [expr { [regexp {a[^ ][^ ]} $a] || [regexp {a[^ ][^ ]} $b] }] |
+} |
+db func test_astar test_astar |
+ |
+set res [db one { SELECT count(*) FROM x1 WHERE test_astar(a, b) } ] |
+do_faultsim_test 5.3 -faults oom* -body { |
+ execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'a*' } |
+} -test { |
+ faultsim_test_result [list 0 $::res] |
+} |
+ |
+do_faultsim_test 5.4 -faults oom* -prep { |
+ db close |
+ sqlite3 db test.db |
+} -body { |
+ execsql { INSERT INTO x1 VALUES('a b c d', 'e f g h') } |
+} -test { |
+ faultsim_test_result [list 0 {}] |
+} |
+ |
+do_faultsim_test 5.5.1 -faults oom* -body { |
+ execsql { |
+ SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid=1 |
+ } |
+} -test { |
+ faultsim_test_result [list 0 1] |
+} |
+do_faultsim_test 5.5.2 -faults oom* -body { |
+ execsql { |
+ SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid=10 |
+ } |
+} -test { |
+ faultsim_test_result [list 0 1] |
+} |
+do_faultsim_test 5.5.3 -faults oom* -body { |
+ execsql { |
+ SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid = ( |
+ SELECT min(rowid) FROM x1_data WHERE rowid>20 |
+ ) |
+ } |
+} -test { |
+ faultsim_test_result [list 0 1] |
+} |
+do_faultsim_test 5.5.4 -faults oom* -body { |
+ execsql { |
+ SELECT count(fts5_decode(rowid, block)) FROM x1_data WHERE rowid = ( |
+ SELECT max(rowid) FROM x1_data |
+ ) |
+ } |
+} -test { |
+ faultsim_test_result [list 0 1] |
+} |
+ |
+#------------------------------------------------------------------------- |
+# |
+reset_db |
+do_execsql_test 6.0 { |
+ CREATE VIRTUAL TABLE x1 USING fts5(x); |
+ INSERT INTO x1(x1, rank) VALUES('automerge', 0); |
+ |
+ INSERT INTO x1 VALUES('a b c'); -- 1 |
+ INSERT INTO x1 VALUES('a b c'); -- 2 |
+ INSERT INTO x1 VALUES('a b c'); -- 3 |
+ INSERT INTO x1 VALUES('a b c'); -- 4 |
+ INSERT INTO x1 VALUES('a b c'); -- 5 |
+ INSERT INTO x1 VALUES('a b c'); -- 6 |
+ INSERT INTO x1 VALUES('a b c'); -- 7 |
+ INSERT INTO x1 VALUES('a b c'); -- 8 |
+ INSERT INTO x1 VALUES('a b c'); -- 9 |
+ INSERT INTO x1 VALUES('a b c'); -- 10 |
+ INSERT INTO x1 VALUES('a b c'); -- 11 |
+ INSERT INTO x1 VALUES('a b c'); -- 12 |
+ INSERT INTO x1 VALUES('a b c'); -- 13 |
+ INSERT INTO x1 VALUES('a b c'); -- 14 |
+ INSERT INTO x1 VALUES('a b c'); -- 15 |
+ |
+ SELECT count(*) FROM x1_data; |
+} {17} |
+ |
+faultsim_save_and_close |
+ |
+do_faultsim_test 6.1 -faults oom* -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { INSERT INTO x1 VALUES('d e f') } |
+} -test { |
+ faultsim_test_result [list 0 {}] |
+ if {$testrc==0} { |
+ set nCnt [db one {SELECT count(*) FROM x1_data}] |
+ if {$nCnt!=3} { error "expected 3 entries but there are $nCnt" } |
+ } |
+} |
+ |
+do_faultsim_test 6.2 -faults oom* -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { INSERT INTO x1(x1, rank) VALUES('pgsz', 32) } |
+} -test { |
+ faultsim_test_result [list 0 {}] |
+} |
+ |
+do_faultsim_test 6.3 -faults oom-* -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { INSERT INTO x1(x1) VALUES('integrity-check') } |
+} -test { |
+ faultsim_test_result [list 0 {}] |
+} |
+ |
+do_faultsim_test 6.4 -faults oom-* -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { INSERT INTO x1(x1) VALUES('optimize') } |
+} -test { |
+ faultsim_test_result [list 0 {}] |
+} |
+ |
+#------------------------------------------------------------------------- |
+# |
+do_faultsim_test 7.0 -faults oom* -prep { |
+ catch { db close } |
+} -body { |
+ sqlite3 db test.db |
+} -test { |
+ faultsim_test_result [list 0 {}] {1 {}} {1 {initialization of fts5 failed: }} |
+} |
+ |
+#------------------------------------------------------------------------- |
+# A prefix query against a large document set. |
+# |
+proc rnddoc {n} { |
+ set map [list 0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j] |
+ set doc [list] |
+ for {set i 0} {$i < $n} {incr i} { |
+ lappend doc "x[string map $map [format %.3d [expr int(rand()*1000)]]]" |
+ } |
+ set doc |
+} |
+ |
+reset_db |
+db func rnddoc rnddoc |
+ |
+do_test 8.0 { |
+ execsql { CREATE VIRTUAL TABLE x1 USING fts5(a) } |
+ set ::res [list] |
+ for {set i 1} {$i<100} {incr i 1} { |
+ execsql { INSERT INTO x1 VALUES( rnddoc(50) ) } |
+ lappend ::res $i |
+ } |
+} {} |
+ |
+do_faultsim_test 8.1 -faults oom* -prep { |
+} -body { |
+ execsql { |
+ SELECT rowid FROM x1 WHERE x1 MATCH 'x*' |
+ } |
+} -test { |
+ faultsim_test_result [list 0 $::res] |
+} |
+ |
+#------------------------------------------------------------------------- |
+# Segment promotion. |
+# |
+do_test 9.0 { |
+ reset_db |
+ db func rnddoc fts5_rnddoc |
+ execsql { |
+ CREATE VIRTUAL TABLE s2 USING fts5(x); |
+ INSERT INTO s2(s2, rank) VALUES('pgsz', 32); |
+ INSERT INTO s2(s2, rank) VALUES('automerge', 0); |
+ } |
+ |
+ for {set i 1} {$i <= 16} {incr i} { |
+ execsql { INSERT INTO s2 VALUES(rnddoc(5)) } |
+ } |
+ fts5_level_segs s2 |
+} {0 1} |
+set insert_doc [db one {SELECT rnddoc(160)}] |
+faultsim_save_and_close |
+ |
+do_faultsim_test 9.1 -faults oom-* -prep { |
+ faultsim_restore_and_reopen |
+} -body { |
+ execsql { INSERT INTO s2 VALUES($::insert_doc) } |
+} -test { |
+ faultsim_test_result {0 {}} |
+ if {$testrc==0} { |
+ set ls [fts5_level_segs s2] |
+ if {$ls != "2 0"} { error "fts5_level_segs says {$ls}" } |
+ } |
+} |
+ |
+ |
+ |
+finish_test |
+ |