mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
Handle errors in saving cursor positions during a rollback by aborting all active statements. (CVS 3027)
FossilOrigin-Name: 5df9f022bfb22976f22b996bda169635354b825c
This commit is contained in:
@ -13,7 +13,7 @@
|
||||
# cache context. What happens to connection B if one connection A encounters
|
||||
# an IO-error whilst reading or writing the file-system?
|
||||
#
|
||||
# $Id: shared_err.test,v 1.8 2006/01/24 11:30:27 danielk1977 Exp $
|
||||
# $Id: shared_err.test,v 1.9 2006/01/24 16:37:59 danielk1977 Exp $
|
||||
|
||||
proc skip {args} {}
|
||||
|
||||
@ -311,11 +311,14 @@ do_malloc_test 4 -tclprep {
|
||||
}
|
||||
} -cleanup {
|
||||
do_test shared_malloc-4.$::n.cleanup.1 {
|
||||
sqlite3_step $::STMT
|
||||
} {SQLITE_ROW}
|
||||
do_test shared_malloc-4.$::n.cleanup.2 {
|
||||
sqlite3_column_text $::STMT 0
|
||||
} {2222222222}
|
||||
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}
|
||||
@ -349,6 +352,61 @@ do_test shared_misuse-7.1 {
|
||||
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 0
|
||||
do_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_cache
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user