# 2009 October 22 # # 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 contains tests to verify that malloc() errors that occur # within the FTS3 module code are handled correctly. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !fts3 { finish_test ; return } source $testdir/malloc_common.tcl do_malloc_test fts3_malloc-1.1 -sqlbody { CREATE VIRTUAL TABLE ft USING fts3(a, b, c); } do_malloc_test fts3_malloc-1.2 -sqlprep { CREATE VIRTUAL TABLE ft USING fts3(a, b, c); } -sqlbody { DROP TABLE ft; } do_malloc_test fts3_malloc-1.3 -sqlprep { CREATE VIRTUAL TABLE ft USING fts3(content); } -sqlbody { INSERT INTO ft VALUES('one two three four'); } do_malloc_test fts3_malloc-1.4 -tclprep { db eval {CREATE VIRTUAL TABLE ft USING fts3(a, b)} for {set i 0} {$i<16} {incr i} { db eval { INSERT INTO ft VALUES('one two', 'three four') } } } -sqlbody { INSERT INTO ft VALUES('one two', 'three four'); } proc do_write_test {sql} { uplevel [list db eval $sql] } proc do_read_test {name sql result} { if {![info exists ::DO_MALLOC_TEST]} { set ::DO_MALLOC_TEST 1 } set answers [list [list 0 $result]] if {$::DO_MALLOC_TEST } { set answers [list {1 {out of memory}} [list 0 $result]] set modes [list 100000 transient 1 persistent] } else { set modes [list 0 nofail] } set str [join $answers " OR "] foreach {nRepeat zName} $modes { for {set iFail 1} 1 {incr iFail} { if {$::DO_MALLOC_TEST} {sqlite3_memdebug_fail $iFail -repeat $nRepeat} set res [catchsql $sql] if {[lsearch $answers $res]>=0} { set res $str } do_test $name.$zName.$iFail [list set {} $res] $str set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign] if {$nFail==0} break } } } proc normal_list {l} { set ret [list] foreach elem $l {lappend ret $elem} set ret } db close file delete -force test.db test.db-journal sqlite3 db test.db sqlite3_db_config_lookaside db 0 0 0 set sqlite_fts3_enable_parentheses 1 do_test fts3_malloc-2.0 { execsql { CREATE VIRTUAL TABLE ft USING fts3(a, b) } for {set ii 1} {$ii < 32} {incr ii} { set a [list] set b [list] if {$ii & 0x01} {lappend a one ; lappend b neung} if {$ii & 0x02} {lappend a two ; lappend b song } if {$ii & 0x04} {lappend a three ; lappend b sahm } if {$ii & 0x08} {lappend a four ; lappend b see } if {$ii & 0x10} {lappend a five ; lappend b hah } execsql { INSERT INTO ft VALUES($a, $b) } } } {} foreach {tn sql result} { 1 "SELECT count(*) FROM sqlite_master" {5} 2 "SELECT * FROM ft WHERE docid = 1" {one neung} 3 "SELECT * FROM ft WHERE docid = 2" {two song} 4 "SELECT * FROM ft WHERE docid = 3" {{one two} {neung song}} 5 "SELECT a FROM ft" { {one} {two} {one two} {three} {one three} {two three} {one two three} {four} {one four} {two four} {one two four} {three four} {one three four} {two three four} {one two three four} {five} {one five} {two five} {one two five} {three five} {one three five} {two three five} {one two three five} {four five} {one four five} {two four five} {one two four five} {three four five} {one three four five} {two three four five} {one two three four five} } 6 "SELECT a FROM ft WHERE a MATCH 'one'" { {one} {one two} {one three} {one two three} {one four} {one two four} {one three four} {one two three four} {one five} {one two five} {one three five} {one two three five} {one four five} {one two four five} {one three four five} {one two three four five} } 7 "SELECT a FROM ft WHERE a MATCH 'o*'" { {one} {one two} {one three} {one two three} {one four} {one two four} {one three four} {one two three four} {one five} {one two five} {one three five} {one two three five} {one four five} {one two four five} {one three four five} {one two three four five} } 8 "SELECT a FROM ft WHERE a MATCH 'o* t*'" { {one two} {one three} {one two three} {one two four} {one three four} {one two three four} {one two five} {one three five} {one two three five} {one two four five} {one three four five} {one two three four five} } 9 "SELECT a FROM ft WHERE a MATCH '\"o* t*\"'" { {one two} {one three} {one two three} {one two four} {one three four} {one two three four} {one two five} {one three five} {one two three five} {one two four five} {one three four five} {one two three four five} } 10 {SELECT a FROM ft WHERE a MATCH '"o* f*"'} { {one four} {one five} {one four five} } 11 {SELECT a FROM ft WHERE a MATCH '"one two three"'} { {one two three} {one two three four} {one two three five} {one two three four five} } 12 {SELECT a FROM ft WHERE a MATCH '"two three four"'} { {two three four} {one two three four} {two three four five} {one two three four five} } 12 {SELECT a FROM ft WHERE a MATCH '"two three" five'} { {two three five} {one two three five} {two three four five} {one two three four five} } 13 {SELECT a FROM ft WHERE ft MATCH '"song sahm" hah'} { {two three five} {one two three five} {two three four five} {one two three four five} } 14 {SELECT a FROM ft WHERE b MATCH 'neung'} { {one} {one two} {one three} {one two three} {one four} {one two four} {one three four} {one two three four} {one five} {one two five} {one three five} {one two three five} {one four five} {one two four five} {one three four five} {one two three four five} } 15 {SELECT a FROM ft WHERE b MATCH '"neung song sahm"'} { {one two three} {one two three four} {one two three five} {one two three four five} } 16 {SELECT a FROM ft WHERE b MATCH 'hah "song sahm"'} { {two three five} {one two three five} {two three four five} {one two three four five} } 17 {SELECT a FROM ft WHERE b MATCH 'song OR sahm'} { {two} {one two} {three} {one three} {two three} {one two three} {two four} {one two four} {three four} {one three four} {two three four} {one two three four} {two five} {one two five} {three five} {one three five} {two three five} {one two three five} {two four five} {one two four five} {three four five} {one three four five} {two three four five} {one two three four five} } 18 {SELECT a FROM ft WHERE a MATCH 'three NOT two'} { {three} {one three} {three four} {one three four} {three five} {one three five} {three four five} {one three four five} } 19 {SELECT a FROM ft WHERE b MATCH 'sahm NOT song'} { {three} {one three} {three four} {one three four} {three five} {one three five} {three four five} {one three four five} } 20 {SELECT a FROM ft WHERE ft MATCH 'sahm NOT song'} { {three} {one three} {three four} {one three four} {three five} {one three five} {three four five} {one three four five} } 21 {SELECT a FROM ft WHERE b MATCH 'neung NEAR song NEAR sahm'} { {one two three} {one two three four} {one two three five} {one two three four five} } } { set result [normal_list $result] do_read_test fts3_malloc-2.$tn $sql $result } do_test fts3_malloc-3.0 { execsql BEGIN for {set ii 32} {$ii < 1024} {incr ii} { set a [list] set b [list] if {$ii & 0x0001} {lappend a one ; lappend b neung } if {$ii & 0x0002} {lappend a two ; lappend b song } if {$ii & 0x0004} {lappend a three ; lappend b sahm } if {$ii & 0x0008} {lappend a four ; lappend b see } if {$ii & 0x0010} {lappend a five ; lappend b hah } if {$ii & 0x0020} {lappend a six ; lappend b hok } if {$ii & 0x0040} {lappend a seven ; lappend b jet } if {$ii & 0x0080} {lappend a eight ; lappend b bairt } if {$ii & 0x0100} {lappend a nine ; lappend b gow } if {$ii & 0x0200} {lappend a ten ; lappend b sip } execsql { INSERT INTO ft VALUES($a, $b) } } execsql COMMIT } {} foreach {tn sql result} { 1 "SELECT count(*) FROM ft" {1023} 2 "SELECT a FROM ft WHERE a MATCH 'one two three four five six seven eight'" { {one two three four five six seven eight} {one two three four five six seven eight nine} {one two three four five six seven eight ten} {one two three four five six seven eight nine ten} } 3 {SELECT count(*), sum(docid) FROM ft WHERE a MATCH 'o*'} {512 262144} 4 {SELECT count(*), sum(docid) FROM ft WHERE a MATCH '"two three four"'} { 128 66368 } } { #set ::DO_MALLOC_TEST 0 set result [normal_list $result] do_read_test fts3_malloc-3.$tn $sql $result } finish_test