1*4520Snw141292 2*4520Snw141292#pragma ident "%Z%%M% %I% %E% SMI" 3*4520Snw141292 4*4520Snw141292# 2001 September 15 5*4520Snw141292# 6*4520Snw141292# The author disclaims copyright to this source code. In place of 7*4520Snw141292# a legal notice, here is a blessing: 8*4520Snw141292# 9*4520Snw141292# May you do good and not evil. 10*4520Snw141292# May you find forgiveness for yourself and forgive others. 11*4520Snw141292# May you share freely, never taking more than you give. 12*4520Snw141292# 13*4520Snw141292#*********************************************************************** 14*4520Snw141292# This file attempts to check the library in an out-of-memory situation. 15*4520Snw141292# When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special 16*4520Snw141292# command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This 17*4520Snw141292# special feature is used to see what happens in the library if a malloc 18*4520Snw141292# were to really fail due to an out-of-memory situation. 19*4520Snw141292# 20*4520Snw141292# $Id: malloc.test,v 1.6 2004/02/14 01:39:50 drh Exp $ 21*4520Snw141292 22*4520Snw141292set testdir [file dirname $argv0] 23*4520Snw141292source $testdir/tester.tcl 24*4520Snw141292 25*4520Snw141292# Only run these tests if memory debugging is turned on. 26*4520Snw141292# 27*4520Snw141292if {[info command sqlite_malloc_stat]==""} { 28*4520Snw141292 puts "Skipping malloc tests: not compiled with -DMEMORY_DEBUG..." 29*4520Snw141292 finish_test 30*4520Snw141292 return 31*4520Snw141292} 32*4520Snw141292 33*4520Snw141292for {set go 1; set i 1} {$go} {incr i} { 34*4520Snw141292 do_test malloc-1.$i { 35*4520Snw141292 sqlite_malloc_fail 0 36*4520Snw141292 catch {db close} 37*4520Snw141292 catch {file delete -force test.db} 38*4520Snw141292 catch {file delete -force test.db-journal} 39*4520Snw141292 sqlite_malloc_fail $i 40*4520Snw141292 set v [catch {sqlite db test.db} msg] 41*4520Snw141292 if {$v} { 42*4520Snw141292 set msg "" 43*4520Snw141292 } else { 44*4520Snw141292 set v [catch {execsql { 45*4520Snw141292 CREATE TABLE t1( 46*4520Snw141292 a int, b float, c double, d text, e varchar(20), 47*4520Snw141292 primary key(a,b,c) 48*4520Snw141292 ); 49*4520Snw141292 CREATE INDEX i1 ON t1(a,b); 50*4520Snw141292 INSERT INTO t1 VALUES(1,2.3,4.5,'hi','there'); 51*4520Snw141292 INSERT INTO t1 VALUES(6,7.0,0.8,'hello','out yonder'); 52*4520Snw141292 SELECT * FROM t1; 53*4520Snw141292 SELECT avg(b) FROM t1 GROUP BY a HAVING b>20.0; 54*4520Snw141292 DELETE FROM t1 WHERE a IN (SELECT min(a) FROM t1); 55*4520Snw141292 SELECT count(*) FROM t1; 56*4520Snw141292 }} msg] 57*4520Snw141292 } 58*4520Snw141292 set leftover [lindex [sqlite_malloc_stat] 2] 59*4520Snw141292 if {$leftover>0} { 60*4520Snw141292 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 61*4520Snw141292 set ::go 0 62*4520Snw141292 set v {1 1} 63*4520Snw141292 } else { 64*4520Snw141292 set v2 [expr {$msg=="" || $msg=="out of memory"}] 65*4520Snw141292 if {!$v2} {puts "\nError message returned: $msg"} 66*4520Snw141292 lappend v $v2 67*4520Snw141292 } 68*4520Snw141292 } {1 1} 69*4520Snw141292} 70*4520Snw141292 71*4520Snw141292set fd [open ./data.tmp w] 72*4520Snw141292for {set i 1} {$i<=20} {incr i} { 73*4520Snw141292 puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}] abcdefghijklmnopqrstuvwxyz" 74*4520Snw141292} 75*4520Snw141292close $fd 76*4520Snw141292 77*4520Snw141292for {set go 1; set i 1} {$go} {incr i} { 78*4520Snw141292 do_test malloc-2.$i { 79*4520Snw141292 sqlite_malloc_fail 0 80*4520Snw141292 catch {db close} 81*4520Snw141292 catch {file delete -force test.db} 82*4520Snw141292 catch {file delete -force test.db-journal} 83*4520Snw141292 sqlite_malloc_fail $i 84*4520Snw141292 set v [catch {sqlite db test.db} msg] 85*4520Snw141292 if {$v} { 86*4520Snw141292 set msg "" 87*4520Snw141292 } else { 88*4520Snw141292 set v [catch {execsql { 89*4520Snw141292 CREATE TABLE t1(a int, b int, c int); 90*4520Snw141292 CREATE INDEX i1 ON t1(a,b); 91*4520Snw141292 COPY t1 FROM 'data.tmp'; 92*4520Snw141292 SELECT 'stuff', count(*) as 'other stuff', max(a+10) FROM t1; 93*4520Snw141292 UPDATE t1 SET b=b||b||b||b; 94*4520Snw141292 UPDATE t1 SET b=a WHERE a in (10,12,22); 95*4520Snw141292 INSERT INTO t1(c,b,a) VALUES(20,10,5); 96*4520Snw141292 INSERT INTO t1 SELECT * FROM t1 97*4520Snw141292 WHERE a IN (SELECT a FROM t1 WHERE a<10); 98*4520Snw141292 DELETE FROM t1 WHERE a>=10; 99*4520Snw141292 DROP INDEX i1; 100*4520Snw141292 DELETE FROM t1; 101*4520Snw141292 }} msg] 102*4520Snw141292 } 103*4520Snw141292 set leftover [lindex [sqlite_malloc_stat] 2] 104*4520Snw141292 if {$leftover>0} { 105*4520Snw141292 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 106*4520Snw141292 set ::go 0 107*4520Snw141292 set v {1 1} 108*4520Snw141292 } else { 109*4520Snw141292 set v2 [expr {$msg=="" || $msg=="out of memory"}] 110*4520Snw141292 if {!$v2} {puts "\nError message returned: $msg"} 111*4520Snw141292 lappend v $v2 112*4520Snw141292 } 113*4520Snw141292 } {1 1} 114*4520Snw141292} 115*4520Snw141292 116*4520Snw141292set fd [open ./data.tmp w] 117*4520Snw141292for {set i 1} {$i<=10} {incr i} { 118*4520Snw141292 puts $fd "$i\t[expr {$i*$i}]\t[expr {100-$i}]" 119*4520Snw141292} 120*4520Snw141292close $fd 121*4520Snw141292 122*4520Snw141292for {set go 1; set i 1} {$go} {incr i} { 123*4520Snw141292 do_test malloc-3.$i { 124*4520Snw141292 sqlite_malloc_fail 0 125*4520Snw141292 catch {db close} 126*4520Snw141292 catch {file delete -force test.db} 127*4520Snw141292 catch {file delete -force test.db-journal} 128*4520Snw141292 sqlite_malloc_fail $i 129*4520Snw141292 set v [catch {sqlite db test.db} msg] 130*4520Snw141292 if {$v} { 131*4520Snw141292 set msg "" 132*4520Snw141292 } else { 133*4520Snw141292 set v [catch {execsql { 134*4520Snw141292 BEGIN TRANSACTION; 135*4520Snw141292 CREATE TABLE t1(a int, b int, c int); 136*4520Snw141292 CREATE INDEX i1 ON t1(a,b); 137*4520Snw141292 COPY t1 FROM 'data.tmp'; 138*4520Snw141292 INSERT INTO t1(c,b,a) VALUES(20,10,5); 139*4520Snw141292 DELETE FROM t1 WHERE a>=10; 140*4520Snw141292 DROP INDEX i1; 141*4520Snw141292 DELETE FROM t1; 142*4520Snw141292 ROLLBACK; 143*4520Snw141292 }} msg] 144*4520Snw141292 } 145*4520Snw141292 set leftover [lindex [sqlite_malloc_stat] 2] 146*4520Snw141292 if {$leftover>0} { 147*4520Snw141292 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 148*4520Snw141292 set ::go 0 149*4520Snw141292 set v {1 1} 150*4520Snw141292 } else { 151*4520Snw141292 set v2 [expr {$msg=="" || $msg=="out of memory"}] 152*4520Snw141292 if {!$v2} {puts "\nError message returned: $msg"} 153*4520Snw141292 lappend v $v2 154*4520Snw141292 } 155*4520Snw141292 } {1 1} 156*4520Snw141292} 157*4520Snw141292for {set go 1; set i 1} {$go} {incr i} { 158*4520Snw141292 do_test malloc-4.$i { 159*4520Snw141292 sqlite_malloc_fail 0 160*4520Snw141292 catch {db close} 161*4520Snw141292 catch {file delete -force test.db} 162*4520Snw141292 catch {file delete -force test.db-journal} 163*4520Snw141292 sqlite_malloc_fail $i 164*4520Snw141292 set v [catch {sqlite db test.db} msg] 165*4520Snw141292 if {$v} { 166*4520Snw141292 set msg "" 167*4520Snw141292 } else { 168*4520Snw141292 set v [catch {execsql { 169*4520Snw141292 BEGIN TRANSACTION; 170*4520Snw141292 CREATE TABLE t1(a int, b int, c int); 171*4520Snw141292 CREATE INDEX i1 ON t1(a,b); 172*4520Snw141292 COPY t1 FROM 'data.tmp'; 173*4520Snw141292 UPDATE t1 SET b=a WHERE a in (10,12,22); 174*4520Snw141292 INSERT INTO t1 SELECT * FROM t1 175*4520Snw141292 WHERE a IN (SELECT a FROM t1 WHERE a<10); 176*4520Snw141292 DROP INDEX i1; 177*4520Snw141292 DELETE FROM t1; 178*4520Snw141292 COMMIT; 179*4520Snw141292 }} msg] 180*4520Snw141292 } 181*4520Snw141292 set leftover [lindex [sqlite_malloc_stat] 2] 182*4520Snw141292 if {$leftover>0} { 183*4520Snw141292 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 184*4520Snw141292 set ::go 0 185*4520Snw141292 set v {1 1} 186*4520Snw141292 } else { 187*4520Snw141292 set v2 [expr {$msg=="" || $msg=="out of memory"}] 188*4520Snw141292 if {!$v2} {puts "\nError message returned: $msg"} 189*4520Snw141292 lappend v $v2 190*4520Snw141292 } 191*4520Snw141292 } {1 1} 192*4520Snw141292} 193*4520Snw141292for {set go 1; set i 1} {$go} {incr i} { 194*4520Snw141292 do_test malloc-5.$i { 195*4520Snw141292 sqlite_malloc_fail 0 196*4520Snw141292 catch {db close} 197*4520Snw141292 catch {file delete -force test.db} 198*4520Snw141292 catch {file delete -force test.db-journal} 199*4520Snw141292 sqlite_malloc_fail $i 200*4520Snw141292 set v [catch {sqlite db test.db} msg] 201*4520Snw141292 if {$v} { 202*4520Snw141292 set msg "" 203*4520Snw141292 } else { 204*4520Snw141292 set v [catch {execsql { 205*4520Snw141292 BEGIN TRANSACTION; 206*4520Snw141292 CREATE TABLE t1(a,b); 207*4520Snw141292 CREATE TABLE t2(x,y); 208*4520Snw141292 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 209*4520Snw141292 INSERT INTO t2(x,y) VALUES(new.rowid,1); 210*4520Snw141292 END; 211*4520Snw141292 INSERT INTO t1(a,b) VALUES(2,3); 212*4520Snw141292 COMMIT; 213*4520Snw141292 }} msg] 214*4520Snw141292 } 215*4520Snw141292 set leftover [lindex [sqlite_malloc_stat] 2] 216*4520Snw141292 if {$leftover>0} { 217*4520Snw141292 if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"} 218*4520Snw141292 set ::go 0 219*4520Snw141292 set v {1 1} 220*4520Snw141292 } else { 221*4520Snw141292 set v2 [expr {$msg=="" || $msg=="out of memory"}] 222*4520Snw141292 if {!$v2} {puts "\nError message returned: $msg"} 223*4520Snw141292 lappend v $v2 224*4520Snw141292 } 225*4520Snw141292 } {1 1} 226*4520Snw141292} 227*4520Snw141292sqlite_malloc_fail 0 228*4520Snw141292finish_test 229