1# 2009 October 22 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 contains tests to verify that malloc() errors that occur 13# within the FTS3 module code are handled correctly. 14# 15 16set testdir [file dirname $argv0] 17source $testdir/tester.tcl 18ifcapable !fts3 { finish_test ; return } 19source $testdir/malloc_common.tcl 20 21do_malloc_test fts3_malloc-1.1 -sqlbody { 22 CREATE VIRTUAL TABLE ft USING fts3(a, b, c); 23} 24 25do_malloc_test fts3_malloc-1.2 -sqlprep { 26 CREATE VIRTUAL TABLE ft USING fts3(a, b, c); 27} -sqlbody { 28 DROP TABLE ft; 29} 30 31do_malloc_test fts3_malloc-1.3 -sqlprep { 32 CREATE VIRTUAL TABLE ft USING fts3(content); 33} -sqlbody { 34 INSERT INTO ft VALUES('one two three four'); 35} 36 37do_malloc_test fts3_malloc-1.4 -tclprep { 38 db eval {CREATE VIRTUAL TABLE ft USING fts3(a, b)} 39 for {set i 0} {$i<16} {incr i} { 40 db eval { INSERT INTO ft VALUES('one two', 'three four') } 41 } 42} -sqlbody { 43 INSERT INTO ft VALUES('one two', 'three four'); 44} 45 46proc do_write_test {sql} { 47 uplevel [list db eval $sql] 48} 49 50proc do_read_test {name sql result} { 51 52 if {![info exists ::DO_MALLOC_TEST]} { 53 set ::DO_MALLOC_TEST 1 54 } 55 56 set answers [list [list 0 $result]] 57 if {$::DO_MALLOC_TEST } { 58 set answers [list {1 {out of memory}} [list 0 $result]] 59 set modes [list 100000 transient 1 persistent] 60 } else { 61 set modes [list 0 nofail] 62 } 63 set str [join $answers " OR "] 64 65 foreach {nRepeat zName} $modes { 66 for {set iFail 1} 1 {incr iFail} { 67 if {$::DO_MALLOC_TEST} {sqlite3_memdebug_fail $iFail -repeat $nRepeat} 68 69 set res [catchsql $sql] 70 if {[lsearch $answers $res]>=0} { 71 set res $str 72 } 73 do_test $name.$zName.$iFail [list set {} $res] $str 74 set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign] 75 if {$nFail==0} break 76 } 77 } 78} 79 80proc normal_list {l} { 81 set ret [list] 82 foreach elem $l {lappend ret $elem} 83 set ret 84} 85 86db close 87file delete -force test.db test.db-journal 88sqlite3 db test.db 89sqlite3_db_config_lookaside db 0 0 0 90set sqlite_fts3_enable_parentheses 1 91 92 93do_test fts3_malloc-2.0 { 94 execsql { CREATE VIRTUAL TABLE ft USING fts3(a, b) } 95 for {set ii 1} {$ii < 32} {incr ii} { 96 set a [list] 97 set b [list] 98 if {$ii & 0x01} {lappend a one ; lappend b neung} 99 if {$ii & 0x02} {lappend a two ; lappend b song } 100 if {$ii & 0x04} {lappend a three ; lappend b sahm } 101 if {$ii & 0x08} {lappend a four ; lappend b see } 102 if {$ii & 0x10} {lappend a five ; lappend b hah } 103 execsql { INSERT INTO ft VALUES($a, $b) } 104 } 105} {} 106 107foreach {tn sql result} { 108 1 "SELECT count(*) FROM sqlite_master" {5} 109 2 "SELECT * FROM ft WHERE docid = 1" {one neung} 110 3 "SELECT * FROM ft WHERE docid = 2" {two song} 111 4 "SELECT * FROM ft WHERE docid = 3" {{one two} {neung song}} 112 113 5 "SELECT a FROM ft" { 114 {one} {two} {one two} 115 {three} {one three} {two three} 116 {one two three} {four} {one four} 117 {two four} {one two four} {three four} 118 {one three four} {two three four} {one two three four} 119 {five} {one five} {two five} 120 {one two five} {three five} {one three five} 121 {two three five} {one two three five} {four five} 122 {one four five} {two four five} {one two four five} 123 {three four five} {one three four five} {two three four five} 124 {one two three four five} 125 } 126 127 6 "SELECT a FROM ft WHERE a MATCH 'one'" { 128 {one} {one two} {one three} {one two three} 129 {one four} {one two four} {one three four} {one two three four} 130 {one five} {one two five} {one three five} {one two three five} 131 {one four five} {one two four five} 132 {one three four five} {one two three four five} 133 } 134 135 7 "SELECT a FROM ft WHERE a MATCH 'o*'" { 136 {one} {one two} {one three} {one two three} 137 {one four} {one two four} {one three four} {one two three four} 138 {one five} {one two five} {one three five} {one two three five} 139 {one four five} {one two four five} 140 {one three four five} {one two three four five} 141 } 142 143 8 "SELECT a FROM ft WHERE a MATCH 'o* t*'" { 144 {one two} {one three} {one two three} 145 {one two four} {one three four} {one two three four} 146 {one two five} {one three five} {one two three five} 147 {one two four five} {one three four five} {one two three four five} 148 } 149 150 9 "SELECT a FROM ft WHERE a MATCH '\"o* t*\"'" { 151 {one two} {one three} {one two three} 152 {one two four} {one three four} {one two three four} 153 {one two five} {one three five} {one two three five} 154 {one two four five} {one three four five} {one two three four five} 155 } 156 157 10 {SELECT a FROM ft WHERE a MATCH '"o* f*"'} { 158 {one four} {one five} {one four five} 159 } 160 161 11 {SELECT a FROM ft WHERE a MATCH '"one two three"'} { 162 {one two three} 163 {one two three four} 164 {one two three five} 165 {one two three four five} 166 } 167 168 12 {SELECT a FROM ft WHERE a MATCH '"two three four"'} { 169 {two three four} 170 {one two three four} 171 {two three four five} 172 {one two three four five} 173 } 174 175 12 {SELECT a FROM ft WHERE a MATCH '"two three" five'} { 176 {two three five} {one two three five} 177 {two three four five} {one two three four five} 178 } 179 180 13 {SELECT a FROM ft WHERE ft MATCH '"song sahm" hah'} { 181 {two three five} {one two three five} 182 {two three four five} {one two three four five} 183 } 184 185 14 {SELECT a FROM ft WHERE b MATCH 'neung'} { 186 {one} {one two} 187 {one three} {one two three} 188 {one four} {one two four} 189 {one three four} {one two three four} 190 {one five} {one two five} 191 {one three five} {one two three five} 192 {one four five} {one two four five} 193 {one three four five} {one two three four five} 194 } 195 196 15 {SELECT a FROM ft WHERE b MATCH '"neung song sahm"'} { 197 {one two three} {one two three four} 198 {one two three five} {one two three four five} 199 } 200 201 16 {SELECT a FROM ft WHERE b MATCH 'hah "song sahm"'} { 202 {two three five} {one two three five} 203 {two three four five} {one two three four five} 204 } 205 206 17 {SELECT a FROM ft WHERE b MATCH 'song OR sahm'} { 207 {two} {one two} {three} 208 {one three} {two three} {one two three} 209 {two four} {one two four} {three four} 210 {one three four} {two three four} {one two three four} 211 {two five} {one two five} {three five} 212 {one three five} {two three five} {one two three five} 213 {two four five} {one two four five} {three four five} 214 {one three four five} {two three four five} {one two three four five} 215 } 216 217 18 {SELECT a FROM ft WHERE a MATCH 'three NOT two'} { 218 {three} {one three} {three four} 219 {one three four} {three five} {one three five} 220 {three four five} {one three four five} 221 } 222 223 19 {SELECT a FROM ft WHERE b MATCH 'sahm NOT song'} { 224 {three} {one three} {three four} 225 {one three four} {three five} {one three five} 226 {three four five} {one three four five} 227 } 228 229 20 {SELECT a FROM ft WHERE ft MATCH 'sahm NOT song'} { 230 {three} {one three} {three four} 231 {one three four} {three five} {one three five} 232 {three four five} {one three four five} 233 } 234 235 21 {SELECT a FROM ft WHERE b MATCH 'neung NEAR song NEAR sahm'} { 236 {one two three} {one two three four} 237 {one two three five} {one two three four five} 238 } 239 240} { 241 set result [normal_list $result] 242 do_read_test fts3_malloc-2.$tn $sql $result 243} 244 245do_test fts3_malloc-3.0 { 246 execsql BEGIN 247 for {set ii 32} {$ii < 1024} {incr ii} { 248 set a [list] 249 set b [list] 250 if {$ii & 0x0001} {lappend a one ; lappend b neung } 251 if {$ii & 0x0002} {lappend a two ; lappend b song } 252 if {$ii & 0x0004} {lappend a three ; lappend b sahm } 253 if {$ii & 0x0008} {lappend a four ; lappend b see } 254 if {$ii & 0x0010} {lappend a five ; lappend b hah } 255 if {$ii & 0x0020} {lappend a six ; lappend b hok } 256 if {$ii & 0x0040} {lappend a seven ; lappend b jet } 257 if {$ii & 0x0080} {lappend a eight ; lappend b bairt } 258 if {$ii & 0x0100} {lappend a nine ; lappend b gow } 259 if {$ii & 0x0200} {lappend a ten ; lappend b sip } 260 execsql { INSERT INTO ft VALUES($a, $b) } 261 } 262 execsql COMMIT 263} {} 264foreach {tn sql result} { 265 1 "SELECT count(*) FROM ft" {1023} 266 2 "SELECT a FROM ft WHERE a MATCH 'one two three four five six seven eight'" { 267 {one two three four five six seven eight} 268 {one two three four five six seven eight nine} 269 {one two three four five six seven eight ten} 270 {one two three four five six seven eight nine ten} 271 } 272 273 3 {SELECT count(*), sum(docid) FROM ft WHERE a MATCH 'o*'} {512 262144} 274 4 {SELECT count(*), sum(docid) FROM ft WHERE a MATCH '"two three four"'} { 275 128 66368 276 } 277} { 278#set ::DO_MALLOC_TEST 0 279 set result [normal_list $result] 280 do_read_test fts3_malloc-3.$tn $sql $result 281} 282 283finish_test 284 285