1# 2015 September 3 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# This file is focused on OOM errors. 13# 14 15source [file join [file dirname [info script]] fts5_common.tcl] 16source $testdir/malloc_common.tcl 17set testprefix fts5fault9 18 19# If SQLITE_ENABLE_FTS3 is defined, omit this file. 20ifcapable !fts5 { 21 finish_test 22 return 23} 24 25foreach_detail_mode $testprefix { 26 27if {"%DETAIL%" != "none"} continue 28 29fts5_aux_test_functions db 30 31do_execsql_test 1.0 { 32 CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%); 33 INSERT INTO t1(t1, rank) VALUES('pgsz', 32); 34 WITH seq(s) AS ( SELECT 1 UNION ALL SELECT s+1 FROM seq WHERE s<50) 35 INSERT INTO t1 SELECT 'x x x y y y', 'a b c d e f' FROM seq; 36} 37 38do_faultsim_test 1 -faults oom-* -body { 39 execsql { SELECT count(*) FROM t1('x AND y') } 40} -test { 41 faultsim_test_result {0 50} 42} 43 44do_execsql_test 2.0 { 45 CREATE VIRTUAL TABLE t2 USING fts5(a, b, detail=%DETAIL%); 46 INSERT INTO t2(t2, rank) VALUES('pgsz', 32); 47 INSERT INTO t2 VALUES('abc cba', 'cba abc'); 48 INSERT INTO t2 VALUES('abc cba', 'cba abc'); 49 INSERT INTO t2 VALUES('abc cba', 'cba abc'); 50 51 INSERT INTO t2 VALUES('axy cyx', 'cyx axy'); 52 INSERT INTO t2 VALUES('axy cyx', 'cyx axy'); 53 INSERT INTO t2 VALUES('axy cyx', 'cyx axy'); 54} 55 56do_faultsim_test 2 -faults oom-* -body { 57 execsql { SELECT count(*) FROM t2('a* AND c*') } 58} -test { 59 faultsim_test_result {0 6} 60} 61 62 63do_execsql_test 3.0 { 64 CREATE VIRTUAL TABLE t3 USING fts5(a, detail=%DETAIL%); 65 INSERT INTO t3 VALUES('a x x a x a a a'); 66 INSERT INTO t3 VALUES('x a a x a x x x'); 67} 68 69do_faultsim_test 3.1 -faults oom-* -body { 70 execsql { SELECT highlight(t3, 0, '[', ']') FROM t3('a') } 71} -test { 72 faultsim_test_result {0 {{[a] x x [a] x [a] [a] [a]} {x [a] [a] x [a] x x x}}} 73} 74 75do_faultsim_test 3.2 -faults oom-t* -body { 76 execsql { SELECT fts5_test_poslist2(t3) FROM t3('x') } 77} -test { 78 faultsim_test_result \ 79 {0 {{0.0.1 0.0.2 0.0.4} {0.0.0 0.0.3 0.0.5 0.0.6 0.0.7}}} \ 80 {1 SQLITE_NOMEM} 81} 82 83#------------------------------------------------------------------------- 84# Test OOM injection with the xPhraseFirstColumn() API and a tokenizer 85# uses query synonyms. 86# 87fts5_tclnum_register db 88do_execsql_test 4.0 { 89 CREATE VIRTUAL TABLE t4 USING fts5(x, y, z, detail=%DETAIL%, tokenize=tclnum); 90 INSERT INTO t4 VALUES('one two three', '1 2 3', 'i ii iii'); 91 INSERT INTO t4 VALUES('1 2 3', 'i ii iii', 'one two three'); 92 INSERT INTO t4 VALUES('i ii iii', 'one two three', 'i ii iii'); 93 94 INSERT INTO t4 VALUES('a1 a2 a3', 'a4 a5 a6', 'a7 a8 a9'); 95 INSERT INTO t4 VALUES('b1 b2 b3', 'b4 b5 b6', 'b7 b8 b9'); 96 INSERT INTO t4 VALUES('c1 c2 c3', 'c4 c5 c6', 'c7 c8 c9'); 97} 98 99do_faultsim_test 4.1 -faults oom-t* -body { 100 execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('2') } 101} -test { 102 faultsim_test_result \ 103 {0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} \ 104 {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}} 105} 106 107do_faultsim_test 4.2 -faults oom-t* -body { 108 execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('a5 OR b5 OR c5') } 109} -test { 110 faultsim_test_result \ 111 {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} \ 112 {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}} 113} 114 115 116#------------------------------------------------------------------------- 117# An OOM within an "ORDER BY rank" query. 118# 119db func rnddoc fts5_rnddoc 120do_execsql_test 5.0 { 121 CREATE VIRTUAL TABLE xx USING fts5(x, y, detail=%DETAIL%); 122 INSERT INTO xx VALUES ('def', 'abc ' || rnddoc(10)); 123 INSERT INTO xx VALUES ('def', 'abc abc' || rnddoc(9)); 124 INSERT INTO xx VALUES ('def', 'abc abc abc' || rnddoc(8)); 125} {} 126faultsim_save_and_close 127 128do_faultsim_test 5 -faults oom-* -prep { 129 faultsim_restore_and_reopen 130 execsql { SELECT * FROM xx } 131} -body { 132 execsql { SELECT rowid FROM xx('abc AND def') ORDER BY rank } 133} -test { 134 faultsim_test_result [list 0 {3 2 1}] 135} 136 137set doc [string repeat "xyz " 500] 138do_execsql_test 6.0 { 139 CREATE VIRTUAL TABLE yy USING fts5(y, detail=%DETAIL%); 140 INSERT INTO yy(yy, rank) VALUES('pgsz', 64); 141 INSERT INTO yy VALUES ($doc); 142 INSERT INTO yy VALUES ('1 2 3'); 143 INSERT INTO yy VALUES ('xyz'); 144 UPDATE yy SET y = y WHERE rowid = 1; 145 UPDATE yy SET y = y WHERE rowid = 1; 146 UPDATE yy SET y = y WHERE rowid = 1; 147 UPDATE yy SET y = y WHERE rowid = 1; 148} {} 149 150do_faultsim_test 6 -faults oom-* -body { 151 execsql { SELECT rowid FROM yy('xyz') } 152} -test { 153 faultsim_test_result [list 0 {1 3}] 154} 155 156 157} ;# foreach_detail_mode... 158 159finish_test 160