mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Fix another couple of IO or malloc() failure problems in a shared-cache context. (CVS 2982)
FossilOrigin-Name: 7e34163a65a5842ecc50a14a9d60601e7c9d3249
This commit is contained in:
24
manifest
24
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sand\stest\sthe\sprocessing\sof\ssqlite3_result_error()\swithing\saggregate\nfunctions.\s\sAllow\serrors\sto\scome\sfrom\sthe\sstep\sfunction\s(a\snew\ncapability).\s\sTicket\s#1632.\s(CVS\s2981)
|
||||
D 2006-01-20T15:45:36
|
||||
C Fix\sanother\scouple\sof\sIO\sor\smalloc()\sfailure\sproblems\sin\sa\sshared-cache\scontext.\s(CVS\s2982)
|
||||
D 2006-01-20T16:32:04
|
||||
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
|
||||
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -34,7 +34,7 @@ F src/alter.c 90b779cf00489535cab6490df6dc050f40e4e874
|
||||
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
|
||||
F src/attach.c 0081040e9a5d13669b6712e947688c10f030bfc1
|
||||
F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
|
||||
F src/btree.c e8ff8d76a412299cad1c9a2c4e1fd15ad48bae27
|
||||
F src/btree.c 8b890e64b0ad7c510635244b75d65a97ee9f26ad
|
||||
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
|
||||
F src/build.c 15224e2fd348ad32b9044aaa5bdc912e4067da15
|
||||
F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2
|
||||
@ -59,7 +59,7 @@ F src/os_unix.c a242a9458b08f01fa11d42b23bcdb89a3fbf2a68
|
||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||
F src/os_win.c 98e4e38db7d4a00647b2bb1c60d28b7ca5034c03
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c 49fab8c32de2419cb549220d285c6399bc0d899e
|
||||
F src/pager.c 39bf1957f8531c9056c8659048a4cdd949439d66
|
||||
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
|
||||
F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c
|
||||
F src/pragma.c 4496cc77dc35824e1c978c3d1413b8a5a4c777d3
|
||||
@ -90,8 +90,8 @@ F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b
|
||||
F src/vdbe.c 9eceb866b8197d25d07f700e16b1a50638d4bd6e
|
||||
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
||||
F src/vdbeInt.h eb3f86ab08ef11635bc78eb88c3ff13f923c233b
|
||||
F src/vdbeapi.c b5a3eacce266a657cdc0fc740b60ba480fb88649
|
||||
F src/vdbeaux.c d9a757ed4e3eefc54408226cb781694059fe2b39
|
||||
F src/vdbeapi.c 75eabedc09b3b2a6f2d256f85704b8b0cc0f50fa
|
||||
F src/vdbeaux.c 9d92640082c632ab2a48fa0b1763390a78573607
|
||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||
F src/vdbemem.c 2034e93b32c14bda6e306bb54e3a8e930b963027
|
||||
F src/where.c 5215507b232e718606e0014f999912d53de32a70
|
||||
@ -189,7 +189,7 @@ F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
||||
F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79
|
||||
F test/malloc.test ce6d1e7e79f9db967b51e1975b50760af66db90d
|
||||
F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e
|
||||
F test/malloc3.test 1cf2376c9495973608c021efaefb25e71bd6e21f
|
||||
F test/malloc3.test 5494b3fac35a2362584c97dc5655c2c3227c798a
|
||||
F test/malloc4.test 2e29d155eb4b4808019ef47eeedfcbe9e09e0f05
|
||||
F test/malloc5.test 7425272e263325fda7d32cb55706e52b5c09e7e0
|
||||
F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
|
||||
@ -228,7 +228,7 @@ F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6
|
||||
F test/server1.test e328b8e641ba8fe9273132cfef497383185dc1f5
|
||||
F test/shared.test 9982a65ccf3f4eee844a19f3ab0bcd7a158a76e5
|
||||
F test/shared2.test 909fc0f0277684ed29cc1b36c8e159188aec7f28
|
||||
F test/shared_err.test dea32ad1ce72c1aa88a4671b5de3900961f6c687
|
||||
F test/shared_err.test f72c9fbe1802500f0d97e768f947ae5c703c0152
|
||||
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
|
||||
F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797
|
||||
F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2
|
||||
@ -344,7 +344,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 97491d4eb5fc24d8f5cc7605db844359ecc6a818
|
||||
R 0ac1c3b7951d8503eabc2e4f37bf1aac
|
||||
U drh
|
||||
Z 64f4b8a9886c6294a59c365b44cd61fd
|
||||
P fd4a6bb1ac94d085dda247799c0a5c64aaeec046
|
||||
R bde9ce22812627a378f8978bb7879372
|
||||
U danielk1977
|
||||
Z c8dd5ea23e29760f9b39f58f5d5d0fb8
|
||||
|
@ -1 +1 @@
|
||||
fd4a6bb1ac94d085dda247799c0a5c64aaeec046
|
||||
7e34163a65a5842ecc50a14a9d60601e7c9d3249
|
27
src/btree.c
27
src/btree.c
@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.303 2006/01/20 10:55:05 danielk1977 Exp $
|
||||
** $Id: btree.c,v 1.304 2006/01/20 16:32:04 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** For a detailed discussion of BTrees, refer to
|
||||
@ -506,6 +506,8 @@ struct BtLock {
|
||||
|
||||
#else
|
||||
|
||||
static void releasePage(MemPage *pPage);
|
||||
|
||||
/*
|
||||
** Save the current cursor position in the variables BtCursor.nKey
|
||||
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
|
||||
@ -540,6 +542,8 @@ static int saveCursorPosition(BtCursor *pCur){
|
||||
assert( !pCur->pPage->intKey || !pCur->pKey );
|
||||
|
||||
/* Todo: Should we drop the reference to pCur->pPage here? */
|
||||
releasePage(pCur->pPage);
|
||||
pCur->pPage = 0;
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
pCur->eState = CURSOR_REQUIRESEEK;
|
||||
@ -2617,12 +2621,15 @@ int sqlite3BtreeCommitStmt(Btree *p){
|
||||
** will result in an error.
|
||||
*/
|
||||
int sqlite3BtreeRollbackStmt(Btree *p){
|
||||
int rc;
|
||||
int rc = SQLITE_OK;
|
||||
BtShared *pBt = p->pBt;
|
||||
if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
|
||||
rc = sqlite3pager_stmt_rollback(pBt->pPager);
|
||||
assert( countWriteCursors(pBt)==0 );
|
||||
pBt->inStmt = 0;
|
||||
sqlite3MallocDisallow();
|
||||
if( pBt->inStmt && !pBt->readOnly ){
|
||||
rc = sqlite3pager_stmt_rollback(pBt->pPager);
|
||||
assert( countWriteCursors(pBt)==0 );
|
||||
pBt->inStmt = 0;
|
||||
}
|
||||
sqlite3MallocAllow();
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -3174,9 +3181,8 @@ static int moveToRoot(BtCursor *pCur){
|
||||
BtShared *pBt = pCur->pBtree->pBt;
|
||||
|
||||
restoreOrClearCursorPosition(pCur, 0);
|
||||
assert( pCur->pPage );
|
||||
pRoot = pCur->pPage;
|
||||
if( pRoot->pgno==pCur->pgnoRoot ){
|
||||
if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
|
||||
assert( pRoot->isInit );
|
||||
}else{
|
||||
if(
|
||||
@ -3443,7 +3449,7 @@ int sqlite3BtreeEof(BtCursor *pCur){
|
||||
*/
|
||||
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
MemPage *pPage = pCur->pPage;
|
||||
MemPage *pPage;
|
||||
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
rc = restoreOrClearCursorPosition(pCur, 1);
|
||||
@ -3456,9 +3462,10 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
pCur->skip = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
assert( pRes!=0 );
|
||||
pPage = pCur->pPage;
|
||||
if( CURSOR_INVALID==pCur->eState ){
|
||||
*pRes = 1;
|
||||
return SQLITE_OK;
|
||||
|
13
src/pager.c
13
src/pager.c
@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.246 2006/01/20 10:55:05 danielk1977 Exp $
|
||||
** @(#) $Id: pager.c,v 1.247 2006/01/20 16:32:04 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
@ -2693,10 +2693,15 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
|
||||
if( rc!=SQLITE_OK ){
|
||||
i64 fileSize;
|
||||
if( sqlite3OsFileSize(pPager->fd,&fileSize)!=SQLITE_OK
|
||||
|| fileSize>=pgno*pPager->pageSize ){
|
||||
int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
|
||||
if( rc2!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){
|
||||
/* An IO error occured in one of the the sqlite3OsSeek() or
|
||||
** sqlite3OsRead() calls above. Unreference the page and then
|
||||
** set it's page number to 0 (0 means "not a page").
|
||||
*/
|
||||
sqlite3pager_unref(PGHDR_TO_DATA(pPg));
|
||||
return pager_error(pPager, rc);
|
||||
pPg->pgno = 0;
|
||||
return rc;
|
||||
}else{
|
||||
clear_simulated_io_error();
|
||||
memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
|
||||
|
@ -241,7 +241,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
|
||||
}
|
||||
#endif
|
||||
|
||||
sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
|
||||
sqlite3Error(p->db, rc, 0);
|
||||
p->rc = sqlite3ApiExit(p->db, p->rc);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1242,6 +1242,8 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
/* We are forced to roll back the active transaction. Before doing
|
||||
** so, abort any other statements this handle currently has active.
|
||||
*/
|
||||
abortOtherActiveVdbes(p);
|
||||
sqlite3RollbackAll(db);
|
||||
db->autoCommit = 1;
|
||||
}
|
||||
}
|
||||
@ -1264,12 +1266,12 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
return SQLITE_BUSY;
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
p->rc = rc;
|
||||
rollbackAll(db, p);
|
||||
sqlite3RollbackAll(db);
|
||||
}else{
|
||||
sqlite3CommitInternalChanges(db);
|
||||
}
|
||||
}else{
|
||||
rollbackAll(db, p);
|
||||
sqlite3RollbackAll(db);
|
||||
}
|
||||
}else if( !xFunc ){
|
||||
if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
|
||||
@ -1277,7 +1279,8 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
}else if( p->errorAction==OE_Abort ){
|
||||
xFunc = sqlite3BtreeRollbackStmt;
|
||||
}else{
|
||||
rollbackAll(db, p);
|
||||
abortOtherActiveVdbes(p);
|
||||
sqlite3RollbackAll(db);
|
||||
db->autoCommit = 1;
|
||||
}
|
||||
}
|
||||
@ -1359,8 +1362,9 @@ int sqlite3VdbeReset(Vdbe *p){
|
||||
*/
|
||||
if( p->pc>=0 ){
|
||||
if( p->zErrMsg ){
|
||||
sqlite3Error(p->db, p->rc, "%s", p->zErrMsg);
|
||||
sqliteFree(p->zErrMsg);
|
||||
sqlite3* db = p->db;
|
||||
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX);
|
||||
db->errCode = p->rc;
|
||||
p->zErrMsg = 0;
|
||||
}else if( p->rc ){
|
||||
sqlite3Error(p->db, p->rc, 0);
|
||||
|
@ -13,7 +13,7 @@
|
||||
# correctly. The emphasis of these tests are the _prepare(), _step() and
|
||||
# _finalize() calls.
|
||||
#
|
||||
# $Id: malloc3.test,v 1.7 2006/01/20 10:55:05 danielk1977 Exp $
|
||||
# $Id: malloc3.test,v 1.8 2006/01/20 16:32:04 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -492,13 +492,27 @@ TEST 32 {
|
||||
sqlite3_step $::STMT32
|
||||
} {SQLITE_ROW}
|
||||
}
|
||||
puts [execsql {SELECT * FROM ghi}]
|
||||
}
|
||||
SQL {
|
||||
BEGIN;
|
||||
INSERT INTO ghi SELECT * FROM ghi;
|
||||
COMMIT;
|
||||
SQL BEGIN
|
||||
TEST 33 {
|
||||
do_test $testid {
|
||||
execsql {SELECT * FROM ghi}
|
||||
} {a b c 1 2 3}
|
||||
}
|
||||
SQL -norollback {
|
||||
-- There is a unique index on ghi(g), so this statement may not cause
|
||||
-- an automatic ROLLBACK. Hence the "-norollback" switch.
|
||||
INSERT INTO ghi SELECT '2'||g, h, i FROM ghi;
|
||||
}
|
||||
TEST 34 {
|
||||
if {[info exists ::STMT32]} {
|
||||
do_test $testid {
|
||||
sqlite3_finalize $::STMT32
|
||||
} {SQLITE_OK}
|
||||
unset ::STMT32
|
||||
}
|
||||
}
|
||||
SQL COMMIT
|
||||
|
||||
#
|
||||
# End of test program declaration
|
||||
@ -630,7 +644,7 @@ proc run_test {arglist {pcstart 0} {iFailStart 1}} {
|
||||
# Turn of the Tcl interface's prepared statement caching facility.
|
||||
db cache size 0
|
||||
|
||||
run_test $::run_test_script 76 6
|
||||
run_test $::run_test_script
|
||||
# run_test [lrange $::run_test_script 0 3] 0 63
|
||||
sqlite_malloc_fail 0
|
||||
db close
|
||||
|
@ -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.1 2006/01/20 10:55:05 danielk1977 Exp $
|
||||
# $Id: shared_err.test,v 1.2 2006/01/20 16:32:05 danielk1977 Exp $
|
||||
|
||||
proc skip {args} {}
|
||||
|
||||
@ -28,7 +28,6 @@ ifcapable !shared_cache||!subquery {
|
||||
}
|
||||
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
|
||||
|
||||
skip \
|
||||
do_ioerr_test shared_ioerr-1 -tclprep {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
@ -52,7 +51,7 @@ do_ioerr_test shared_ioerr-1 -tclprep {
|
||||
SELECT * FROM t1;
|
||||
DELETE FROM t1 WHERE a<100;
|
||||
} -cleanup {
|
||||
do_test shared_ioerr-$n.cleanup.1 {
|
||||
do_test shared_ioerr-1.$n.cleanup.1 {
|
||||
set res [catchsql {
|
||||
SELECT * FROM t1;
|
||||
} db2]
|
||||
@ -131,6 +130,44 @@ do_ioerr_test shared_ioerr-2 -tclprep {
|
||||
db2 close
|
||||
}
|
||||
|
||||
# This test is designed to provoke an IO error when a cursor position is
|
||||
# "saved" (because another cursor is going to modify the underlying table).
|
||||
#
|
||||
do_ioerr_test shared_ioerr-3 -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_ioerr-3.$n.cleanup.1 {
|
||||
sqlite3_step $::STMT
|
||||
} {SQLITE_ROW}
|
||||
do_test shared_ioerr-3.$n.cleanup.2 {
|
||||
sqlite3_column_text $::STMT 0
|
||||
} {2222222222}
|
||||
do_test shared_ioerr-3.$n.cleanup.3 {
|
||||
sqlite3_finalize $::STMT
|
||||
} {SQLITE_OK}
|
||||
# db2 eval {select * from sqlite_master}
|
||||
db2 close
|
||||
}
|
||||
|
||||
catch {db close}
|
||||
sqlite3_enable_shared_cache $::enable_shared_cache
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user