AryaWu/sqlite
0
1# 2005 December 302#3# The author disclaims copyright to this source code. In place of4# 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# The focus of the tests in this file are IO errors that occur in a shared13# cache context. What happens to connection B if one connection A encounters14# an IO-error whilst reading or writing the file-system?15#16# $Id: shared_err.test,v 1.24 2008/10/12 00:27:54 shane Exp $17 18proc skip {args} {}19 20 21set testdir [file dirname $argv0]22source $testdir/tester.tcl23source $testdir/malloc_common.tcl24db close25 26ifcapable !shared_cache||!subquery {27 finish_test28 return29}30 31set ::enable_shared_cache [sqlite3_enable_shared_cache 1]32 33do_ioerr_test shared_ioerr-1 -tclprep {34 sqlite3 db2 test.db35 execsql {36 PRAGMA read_uncommitted = 1;37 CREATE TABLE t1(a,b,c);38 BEGIN;39 SELECT * FROM sqlite_master;40 } db241} -sqlbody {42 SELECT * FROM sqlite_master;43 INSERT INTO t1 VALUES(1,2,3);44 BEGIN TRANSACTION;45 INSERT INTO t1 VALUES(1,2,3);46 INSERT INTO t1 VALUES(4,5,6);47 ROLLBACK;48 SELECT * FROM t1;49 BEGIN TRANSACTION;50 INSERT INTO t1 VALUES(1,2,3);51 INSERT INTO t1 VALUES(4,5,6);52 COMMIT;53 SELECT * FROM t1;54 DELETE FROM t1 WHERE a<100;55} -cleanup {56 do_test shared_ioerr-1.$n.cleanup.1 {57 set res [catchsql {58 SELECT * FROM t1;59 } db2]60 set possible_results [list \61 "1 {disk I/O error}" \62 "0 {1 2 3}" \63 "0 {1 2 3 1 2 3 4 5 6}" \64 "0 {1 2 3 1 2 3 4 5 6 1 2 3 4 5 6}" \65 "0 {}" \66 "1 {database disk image is malformed}" \67 ]68 set rc [expr [lsearch -exact $possible_results $res] >= 0]69 if {$rc != 1} {70 puts ""71 puts "Result: $res"72 }73 set rc74 } {1}75 76 # The "database disk image is malformed" is a special case that can77 # occur if an IO error occurs during a rollback in the {SELECT * FROM t1}78 # statement above. This test is to make sure there is no real database79 # corruption.80 db2 close81 do_test shared_ioerr-1.$n.cleanup.2 {82 execsql {pragma integrity_check} db83 } {ok}84}85 86do_ioerr_test shared_ioerr-2 -tclprep {87 sqlite3 db2 test.db88 execsql {89 PRAGMA read_uncommitted = 1;90 BEGIN;91 CREATE TABLE t1(a, b);92 INSERT INTO t1(oid) VALUES(NULL);93 INSERT INTO t1(oid) SELECT NULL FROM t1;94 INSERT INTO t1(oid) SELECT NULL FROM t1;95 INSERT INTO t1(oid) SELECT NULL FROM t1;96 INSERT INTO t1(oid) SELECT NULL FROM t1;97 INSERT INTO t1(oid) SELECT NULL FROM t1;98 INSERT INTO t1(oid) SELECT NULL FROM t1;99 INSERT INTO t1(oid) SELECT NULL FROM t1;100 INSERT INTO t1(oid) SELECT NULL FROM t1;101 INSERT INTO t1(oid) SELECT NULL FROM t1;102 INSERT INTO t1(oid) SELECT NULL FROM t1;103 UPDATE t1 set a = oid, b = 'abcdefghijklmnopqrstuvwxyz0123456789';104 CREATE INDEX i1 ON t1(a);105 COMMIT;106 BEGIN;107 SELECT * FROM sqlite_master;108 } db2109} -tclbody {110 set ::residx 0111 execsql {DELETE FROM t1 WHERE 0 = (a % 2);}112 incr ::residx113 114 # When this transaction begins the table contains 512 entries. The115 # two statements together add 512+146 more if it succeeds. 116 # (1024/7==146)117 execsql {BEGIN;}118 execsql {INSERT INTO t1 SELECT a+1, b FROM t1;}119 execsql {INSERT INTO t1 SELECT 'string' || a, b FROM t1 WHERE 0 = (a%7);}120 execsql {COMMIT;}121 122 incr ::residx123} -cleanup {124 catchsql ROLLBACK125 do_test shared_ioerr-2.$n.cleanup.1 {126 set res [catchsql {127 SELECT max(a), min(a), count(*) FROM (SELECT a FROM t1 order by a);128 } db2]129 set possible_results [list \130 {0 {1024 1 1024}} \131 {0 {1023 1 512}} \132 {0 {string994 1 1170}} \133 ]134 set idx [lsearch -exact $possible_results $res]135 set success [expr {$idx==$::residx || $res=="1 {disk I/O error}"}]136 if {!$success} {137 puts ""138 puts "Result: \"$res\" ($::residx)"139 }140 set success141 } {1}142 db2 close143}144 145# This test is designed to provoke an IO error when a cursor position is146# "saved" (because another cursor is going to modify the underlying table). 147# 148do_ioerr_test shared_ioerr-3 -tclprep {149 sqlite3 db2 test.db150 execsql {151 PRAGMA read_uncommitted = 1;152 PRAGMA cache_size = 10;153 BEGIN;154 CREATE TABLE t1(a, b, UNIQUE(a, b));155 } db2156 for {set i 0} {$i < 200} {incr i} {157 set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]158 159 set b [string repeat $i 2000]160 execsql {INSERT INTO t1 VALUES($a, $b)} db2161 }162 execsql {COMMIT} db2163 set ::DB2 [sqlite3_connection_pointer db2]164 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]165 sqlite3_step $::STMT ;# Cursor points at 000.000.000.000166 sqlite3_step $::STMT ;# Cursor points at 001.001.001.001167 168} -tclbody {169 execsql {170 BEGIN;171 INSERT INTO t1 VALUES('201.201.201.201.201', NULL);172 UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';173 COMMIT;174 }175} -cleanup {176 set ::steprc [sqlite3_step $::STMT]177 set ::column [sqlite3_column_text $::STMT 0]178 set ::finalrc [sqlite3_finalize $::STMT]179 180 # There are three possible outcomes here (assuming persistent IO errors):181 #182 # 1. If the [sqlite3_step] did not require any IO (required pages in183 # the cache), then the next row ("002...") may be retrieved 184 # successfully.185 #186 # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns187 # SQLITE_ERROR and [sqlite3_finalize] returns IOERR.188 #189 # 3. If, after the initial IO error, SQLite tried to rollback the190 # active transaction and a second IO error was encountered, then191 # statement $::STMT will have been aborted. This means [sqlite3_stmt]192 # returns SQLITE_ABORT, and the statement cursor does not move. i.e.193 # [sqlite3_column] still returns the current row ("001...") and194 # [sqlite3_finalize] returns SQLITE_OK.195 #196 197 do_test shared_ioerr-3.$n.cleanup.1 {198 expr {199 $::steprc eq "SQLITE_ROW" || 200 $::steprc eq "SQLITE_ERROR" ||201 $::steprc eq "SQLITE_ABORT" 202 }203 } {1}204 do_test shared_ioerr-3.$n.cleanup.2 {205 expr {206 ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") ||207 ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||208 ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001") 209 }210 } {1}211 do_test shared_ioerr-3.$n.cleanup.3 {212 expr {213 ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||214 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||215 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT")216 }217 } {1}218 219# db2 eval {select * from sqlite_master}220 db2 close221}222 223# This is a repeat of the previous test except that this time we224# are doing a reverse-order scan of the table when the cursor is225# "saved".226# 227do_ioerr_test shared_ioerr-3rev -tclprep {228 sqlite3 db2 test.db229 execsql {230 PRAGMA read_uncommitted = 1;231 PRAGMA cache_size = 10;232 BEGIN;233 CREATE TABLE t1(a, b, UNIQUE(a, b));234 } db2235 for {set i 0} {$i < 200} {incr i} {236 set a [string range [string repeat "[format %03d $i]." 5] 0 end-1]237 238 set b [string repeat $i 2000]239 execsql {INSERT INTO t1 VALUES($a, $b)} db2240 }241 execsql {COMMIT} db2242 set ::DB2 [sqlite3_connection_pointer db2]243 set ::STMT [sqlite3_prepare $::DB2 \244 "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY]245 sqlite3_step $::STMT ;# Cursor points at 199.199.199.199.199246 sqlite3_step $::STMT ;# Cursor points at 198.198.198.198.198247 248} -tclbody {249 execsql {250 BEGIN;251 INSERT INTO t1 VALUES('201.201.201.201.201', NULL);252 UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';253 COMMIT;254 }255} -cleanup {256 set ::steprc [sqlite3_step $::STMT]257 set ::column [sqlite3_column_text $::STMT 0]258 set ::finalrc [sqlite3_finalize $::STMT]259 260 # There are three possible outcomes here (assuming persistent IO errors):261 #262 # 1. If the [sqlite3_step] did not require any IO (required pages in263 # the cache), then the next row ("002...") may be retrieved 264 # successfully.265 #266 # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns267 # SQLITE_ERROR and [sqlite3_finalize] returns IOERR.268 #269 # 3. If, after the initial IO error, SQLite tried to rollback the270 # active transaction and a second IO error was encountered, then271 # statement $::STMT will have been aborted. This means [sqlite3_stmt]272 # returns SQLITE_ABORT, and the statement cursor does not move. i.e.273 # [sqlite3_column] still returns the current row ("001...") and274 # [sqlite3_finalize] returns SQLITE_OK.275 #276 277 do_test shared_ioerr-3rev.$n.cleanup.1 {278 expr {279 $::steprc eq "SQLITE_ROW" || 280 $::steprc eq "SQLITE_ERROR" ||281 $::steprc eq "SQLITE_ABORT" 282 }283 } {1}284 do_test shared_ioerr-3rev.$n.cleanup.2 {285 expr {286 ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") ||287 ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||288 ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198") 289 }290 } {1}291 do_test shared_ioerr-3rev.$n.cleanup.3 {292 expr {293 ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||294 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||295 ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT")296 }297 } {1}298 299# db2 eval {select * from sqlite_master}300 db2 close301}302 303# Provoke a malloc() failure when a cursor position is being saved. This304# only happens with index cursors (because they malloc() space to save the305# current key value). It does not happen with tables, because an integer306# key does not require a malloc() to store. 307#308# The library should return an SQLITE_NOMEM to the caller. The query that309# owns the cursor (the one for which the position is not saved) should310# continue unaffected.311# 312do_malloc_test shared_err-4 -tclprep {313 sqlite3 db2 test.db314 execsql {315 PRAGMA read_uncommitted = 1;316 BEGIN;317 CREATE TABLE t1(a, b, UNIQUE(a, b));318 } db2319 for {set i 0} {$i < 5} {incr i} {320 set a [string repeat $i 10]321 set b [string repeat $i 2000]322 execsql {INSERT INTO t1 VALUES($a, $b)} db2323 }324 execsql {COMMIT} db2325 set ::DB2 [sqlite3_connection_pointer db2]326 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]327 sqlite3_step $::STMT ;# Cursor points at 0000000000328 sqlite3_step $::STMT ;# Cursor points at 1111111111329} -tclbody {330 execsql {331 INSERT INTO t1 VALUES(6, NULL);332 }333} -cleanup {334 do_test shared_malloc-4.$::n.cleanup.1 {335 set ::rc [sqlite3_step $::STMT]336 expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ERROR"}337 } {1}338 if {$::rc=="SQLITE_ROW"} {339 do_test shared_malloc-4.$::n.cleanup.2 {340 sqlite3_column_text $::STMT 0341 } {2222222222}342 }343 do_test shared_malloc-4.$::n.cleanup.3 {344 set rc [sqlite3_finalize $::STMT]345 expr {$rc=="SQLITE_OK" || $rc=="SQLITE_ABORT" ||346 $rc=="SQLITE_NOMEM" || $rc=="SQLITE_IOERR"}347 } {1}348# db2 eval {select * from sqlite_master}349 db2 close350}351 352do_malloc_test shared_err-5 -tclbody {353 db close354 sqlite3 dbX test.db355 sqlite3 dbY test.db356 dbX close357 dbY close358} -cleanup {359 catch {dbX close}360 catch {dbY close}361}362 363do_malloc_test shared_err-6 -tclbody {364 catch {db close}365 ifcapable deprecated {366 sqlite3_thread_cleanup367 }368 sqlite3_enable_shared_cache 0369} -cleanup {370 sqlite3_enable_shared_cache 1371}372 373# As of 3.5.0, sqlite3_enable_shared_cache can be called at374# any time and from any thread375#do_test shared_err-misuse-7.1 {376# sqlite3 db test.db377# catch {378# sqlite3_enable_shared_cache 0379# } msg380# set msg381#} {bad parameter or other API misuse}382 383# Again provoke a malloc() failure when a cursor position is being saved, 384# this time during a ROLLBACK operation by some other handle. 385#386# The library should return an SQLITE_NOMEM to the caller. The query that387# owns the cursor (the one for which the position is not saved) should388# be aborted.389# 390set ::aborted 0391do_malloc_test shared_err-8 -tclprep {392 sqlite3 db2 test.db393 execsql {394 PRAGMA read_uncommitted = 1;395 BEGIN;396 CREATE TABLE t1(a, b, UNIQUE(a, b));397 } db2398 for {set i 0} {$i < 2} {incr i} {399 set a [string repeat $i 10]400 set b [string repeat $i 2000]401 execsql {INSERT INTO t1 VALUES($a, $b)} db2402 }403 execsql {COMMIT} db2404 execsql BEGIN405 execsql ROLLBACK406 set ::DB2 [sqlite3_connection_pointer db2]407 set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]408 sqlite3_step $::STMT ;# Cursor points at 0000000000409 sqlite3_step $::STMT ;# Cursor points at 1111111111410} -tclbody {411 execsql {412 BEGIN;413 INSERT INTO t1 VALUES(6, NULL);414 ROLLBACK}415} -cleanup {416 # UPDATE: As of [5668], if the rollback fails SQLITE_CORRUPT is returned. 417 # So these tests have been updated to expect SQLITE_CORRUPT and its418 # associated English language error message.419 #420 do_test shared_malloc-8.$::n.cleanup.1 {421 set res [catchsql {SELECT a FROM t1} db2]422 set ans [lindex $res 1]423 if {[lindex $res 0]} {424 set r [expr {425 $ans=="disk I/O error" ||426 $ans=="out of memory" ||427 $ans=="database disk image is malformed"428 }]429 } else {430 set r [expr {[lrange $ans 0 1]=="0000000000 1111111111"}]431 }432 } {1}433 do_test shared_malloc-8.$::n.cleanup.2 {434 set rc1 [sqlite3_step $::STMT]435 set rc2 [sqlite3_finalize $::STMT]436 if {$rc2=="SQLITE_ABORT"} {437 incr ::aborted438 }439 expr {440 ($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") || 441 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_ABORT") ||442 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_NOMEM") ||443 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_IOERR") ||444 ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_CORRUPT")445 }446 } {1}447 db2 close448}449 450# When this test case was written, OOM errors in write statements would 451# cause transaction rollback, which would trip cursors in other statements,452# aborting them. This no longer happens.453#454do_test shared_malloc-8.X {455 # Test that one or more queries were aborted due to the malloc() failure.456 # expr $::aborted>=1457 expr $::aborted==0458} {1}459 460# This test is designed to catch a specific bug that was present during461# development of 3.5.0. If a malloc() failed while setting the page-size,462# a buffer (Pager.pTmpSpace) was being freed. This could cause a seg-fault463# later if another connection tried to use the pager.464#465# This test will crash 3.4.2.466#467do_malloc_test shared_err-9 -tclprep {468 sqlite3 db2 test.db469} -sqlbody {470 PRAGMA page_size = 4096;471 PRAGMA page_size = 1024;472} -cleanup {473 db2 eval {474 CREATE TABLE abc(a, b, c);475 BEGIN;476 INSERT INTO abc VALUES(1, 2, 3);477 ROLLBACK;478 } 479 db2 close480} 481 482catch {db close}483catch {db2 close}484do_malloc_test shared_err-10 -tclprep {485 sqlite3 db test.db486 sqlite3 db2 test.db487 488 db eval { SELECT * FROM sqlite_master }489 db2 eval { 490 BEGIN;491 CREATE TABLE abc(a, b, c);492 }493} -tclbody {494 catch {db eval {SELECT * FROM sqlite_master}}495 error 1496} -cleanup {497 execsql { SELECT * FROM sqlite_master }498}499 500do_malloc_test shared_err-11 -tclprep {501 sqlite3 db test.db502 sqlite3 db2 test.db503 504 db eval { SELECT * FROM sqlite_master }505 db2 eval { 506 BEGIN;507 CREATE TABLE abc(a, b, c);508 }509} -tclbody {510 catch {db eval {SELECT * FROM sqlite_master}}511 catch {sqlite3_errmsg16 db}512 error 1513} -cleanup {514 execsql { SELECT * FROM sqlite_master }515}516 517catch {db close}518catch {db2 close}519 520do_malloc_test shared_err-12 -sqlbody {521 CREATE TABLE abc(a, b, c);522 INSERT INTO abc VALUES(1, 2, 3);523}524 525catch {db close}526catch {db2 close}527sqlite3_enable_shared_cache $::enable_shared_cache528finish_test529 