📄 shared_err.test
字号:
# 1. If the [sqlite3_step] did not require any IO (required pages in # the cache), then the next row ("002...") may be retrieved # successfully. # # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns # SQLITE_ERROR and [sqlite3_finalize] returns IOERR. # # 3. If, after the initial IO error, SQLite tried to rollback the # active transaction and a second IO error was encountered, then # statement $::STMT will have been aborted. This means [sqlite3_stmt] # returns SQLITE_ABORT, and the statement cursor does not move. i.e. # [sqlite3_column] still returns the current row ("001...") and # [sqlite3_finalize] returns SQLITE_OK. # do_test shared_ioerr-3.$n.cleanup.1 { expr { $::steprc eq "SQLITE_ROW" || $::steprc eq "SQLITE_ERROR" || $::steprc eq "SQLITE_ABORT" } } {1} do_test shared_ioerr-3.$n.cleanup.2 { expr { ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") || ($::steprc eq "SQLITE_ERROR" && $::column eq "") || ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001") } } {1} do_test shared_ioerr-3.$n.cleanup.3 { expr { ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") || ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") || ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK") } } {1}# db2 eval {select * from sqlite_master} db2 close}# This is a repeat of the previous test except that this time we# are doing a reverse-order scan of the table when the cursor is# "saved".# do_ioerr_test shared_ioerr-3rev -tclprep { sqlite3 db2 test.db execsql { PRAGMA read_uncommitted = 1; PRAGMA cache_size = 10; BEGIN; CREATE TABLE t1(a, b, UNIQUE(a, b)); } db2 for {set i 0} {$i < 200} {incr i} { set a [string range [string repeat "[format %03d $i]." 5] 0 end-1] set b [string repeat $i 2000] execsql {INSERT INTO t1 VALUES($a, $b)} db2 } execsql {COMMIT} db2 set ::DB2 [sqlite3_connection_pointer db2] set ::STMT [sqlite3_prepare $::DB2 \ "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY] sqlite3_step $::STMT ;# Cursor points at 199.199.199.199.199 sqlite3_step $::STMT ;# Cursor points at 198.198.198.198.198} -tclbody { execsql { BEGIN; INSERT INTO t1 VALUES('201.201.201.201.201', NULL); UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%'; COMMIT; }} -cleanup { set ::steprc [sqlite3_step $::STMT] set ::column [sqlite3_column_text $::STMT 0] set ::finalrc [sqlite3_finalize $::STMT] # There are three possible outcomes here (assuming persistent IO errors): # # 1. If the [sqlite3_step] did not require any IO (required pages in # the cache), then the next row ("002...") may be retrieved # successfully. # # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns # SQLITE_ERROR and [sqlite3_finalize] returns IOERR. # # 3. If, after the initial IO error, SQLite tried to rollback the # active transaction and a second IO error was encountered, then # statement $::STMT will have been aborted. This means [sqlite3_stmt] # returns SQLITE_ABORT, and the statement cursor does not move. i.e. # [sqlite3_column] still returns the current row ("001...") and # [sqlite3_finalize] returns SQLITE_OK. # do_test shared_ioerr-3rev.$n.cleanup.1 { expr { $::steprc eq "SQLITE_ROW" || $::steprc eq "SQLITE_ERROR" || $::steprc eq "SQLITE_ABORT" } } {1} do_test shared_ioerr-3rev.$n.cleanup.2 { expr { ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") || ($::steprc eq "SQLITE_ERROR" && $::column eq "") || ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198") } } {1} do_test shared_ioerr-3rev.$n.cleanup.3 { expr { ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") || ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") || ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK") } } {1}# db2 eval {select * from sqlite_master} db2 close}# Only run these tests if memory debugging is turned on.#if {[info command sqlite_malloc_stat]==""} { puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..." db close sqlite3_enable_shared_cache $::enable_shared_cache finish_test return}# Provoke a malloc() failure when a cursor position is being saved. This# only happens with index cursors (because they malloc() space to save the# current key value). It does not happen with tables, because an integer# key does not require a malloc() to store. ## The library should return an SQLITE_NOMEM to the caller. The query that# owns the cursor (the one for which the position is not saved) should# continue unaffected.# do_malloc_test 4 -tclprep { sqlite3 db2 test.db execsql { PRAGMA read_uncommitted = 1; BEGIN; CREATE TABLE t1(a, b, UNIQUE(a, b)); } db2 for {set i 0} {$i < 5} {incr i} { set a [string repeat $i 10] set b [string repeat $i 2000] execsql {INSERT INTO t1 VALUES($a, $b)} db2 } execsql {COMMIT} db2 set ::DB2 [sqlite3_connection_pointer db2] set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] sqlite3_step $::STMT ;# Cursor points at 0000000000 sqlite3_step $::STMT ;# Cursor points at 1111111111} -tclbody { execsql { INSERT INTO t1 VALUES(6, NULL); }} -cleanup { do_test shared_malloc-4.$::n.cleanup.1 { set ::rc [sqlite3_step $::STMT] expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ABORT"} } {1} if {$::rc=="SQLITE_ROW"} { do_test shared_malloc-4.$::n.cleanup.2 { sqlite3_column_text $::STMT 0 } {2222222222} } do_test shared_malloc-4.$::n.cleanup.3 { sqlite3_finalize $::STMT } {SQLITE_OK}# db2 eval {select * from sqlite_master} db2 close}do_malloc_test 5 -tclbody { sqlite3 dbX test.db sqlite3 dbY test.db dbX close dbY close} -cleanup { catch {dbX close} catch {dbY close}}do_malloc_test 6 -tclbody { catch {db close} sqlite3_thread_cleanup sqlite3_enable_shared_cache 0} -cleanup { sqlite3_enable_shared_cache 1}do_test shared_misuse-7.1 { sqlite3 db test.db catch { sqlite3_enable_shared_cache 0 } msg set msg} {library routine called out of sequence}# Again provoke a malloc() failure when a cursor position is being saved, # this time during a ROLLBACK operation by some other handle. ## The library should return an SQLITE_NOMEM to the caller. The query that# owns the cursor (the one for which the position is not saved) should# be aborted.# set ::aborted 0do_malloc_test 8 -tclprep { sqlite3 db2 test.db execsql { PRAGMA read_uncommitted = 1; BEGIN; CREATE TABLE t1(a, b, UNIQUE(a, b)); } db2 for {set i 0} {$i < 2} {incr i} { set a [string repeat $i 10] set b [string repeat $i 2000] execsql {INSERT INTO t1 VALUES($a, $b)} db2 } execsql {COMMIT} db2 set ::DB2 [sqlite3_connection_pointer db2] set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] sqlite3_step $::STMT ;# Cursor points at 0000000000 sqlite3_step $::STMT ;# Cursor points at 1111111111} -tclbody { execsql { BEGIN; INSERT INTO t1 VALUES(6, NULL); ROLLBACK; }} -cleanup { do_test shared_malloc-8.$::n.cleanup.1 { lrange [execsql { SELECT a FROM t1; } db2] 0 1 } {0000000000 1111111111} do_test shared_malloc-8.$::n.cleanup.2 { set rc1 [sqlite3_step $::STMT] set rc2 [sqlite3_finalize $::STMT] if {$rc1=="SQLITE_ABORT"} { incr ::aborted } expr { ($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") || ($rc1=="SQLITE_ABORT" && $rc2=="SQLITE_OK") } } {1} db2 close}do_test shared_malloc-8.X { # Test that one or more queries were aborted due to the malloc() failure. expr $::aborted>=1} {1}catch {db close}sqlite3_enable_shared_cache $::enable_shared_cachefinish_test
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -