1
0
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:
danielk1977
2006-01-20 16:32:04 +00:00
parent 90669c1dca
commit 97a227c996
8 changed files with 110 additions and 43 deletions

View File

@ -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) C Fix\sanother\scouple\sof\sIO\sor\smalloc()\sfailure\sproblems\sin\sa\sshared-cache\scontext.\s(CVS\s2982)
D 2006-01-20T15:45:36 D 2006-01-20T16:32:04
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967 F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -34,7 +34,7 @@ F src/alter.c 90b779cf00489535cab6490df6dc050f40e4e874
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
F src/attach.c 0081040e9a5d13669b6712e947688c10f030bfc1 F src/attach.c 0081040e9a5d13669b6712e947688c10f030bfc1
F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2 F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
F src/btree.c e8ff8d76a412299cad1c9a2c4e1fd15ad48bae27 F src/btree.c 8b890e64b0ad7c510635244b75d65a97ee9f26ad
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184 F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
F src/build.c 15224e2fd348ad32b9044aaa5bdc912e4067da15 F src/build.c 15224e2fd348ad32b9044aaa5bdc912e4067da15
F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2 F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2
@ -59,7 +59,7 @@ F src/os_unix.c a242a9458b08f01fa11d42b23bcdb89a3fbf2a68
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
F src/os_win.c 98e4e38db7d4a00647b2bb1c60d28b7ca5034c03 F src/os_win.c 98e4e38db7d4a00647b2bb1c60d28b7ca5034c03
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c 49fab8c32de2419cb549220d285c6399bc0d899e F src/pager.c 39bf1957f8531c9056c8659048a4cdd949439d66
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c
F src/pragma.c 4496cc77dc35824e1c978c3d1413b8a5a4c777d3 F src/pragma.c 4496cc77dc35824e1c978c3d1413b8a5a4c777d3
@ -90,8 +90,8 @@ F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b
F src/vdbe.c 9eceb866b8197d25d07f700e16b1a50638d4bd6e F src/vdbe.c 9eceb866b8197d25d07f700e16b1a50638d4bd6e
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
F src/vdbeInt.h eb3f86ab08ef11635bc78eb88c3ff13f923c233b F src/vdbeInt.h eb3f86ab08ef11635bc78eb88c3ff13f923c233b
F src/vdbeapi.c b5a3eacce266a657cdc0fc740b60ba480fb88649 F src/vdbeapi.c 75eabedc09b3b2a6f2d256f85704b8b0cc0f50fa
F src/vdbeaux.c d9a757ed4e3eefc54408226cb781694059fe2b39 F src/vdbeaux.c 9d92640082c632ab2a48fa0b1763390a78573607
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
F src/vdbemem.c 2034e93b32c14bda6e306bb54e3a8e930b963027 F src/vdbemem.c 2034e93b32c14bda6e306bb54e3a8e930b963027
F src/where.c 5215507b232e718606e0014f999912d53de32a70 F src/where.c 5215507b232e718606e0014f999912d53de32a70
@ -189,7 +189,7 @@ F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79 F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79
F test/malloc.test ce6d1e7e79f9db967b51e1975b50760af66db90d F test/malloc.test ce6d1e7e79f9db967b51e1975b50760af66db90d
F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e
F test/malloc3.test 1cf2376c9495973608c021efaefb25e71bd6e21f F test/malloc3.test 5494b3fac35a2362584c97dc5655c2c3227c798a
F test/malloc4.test 2e29d155eb4b4808019ef47eeedfcbe9e09e0f05 F test/malloc4.test 2e29d155eb4b4808019ef47eeedfcbe9e09e0f05
F test/malloc5.test 7425272e263325fda7d32cb55706e52b5c09e7e0 F test/malloc5.test 7425272e263325fda7d32cb55706e52b5c09e7e0
F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8 F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8
@ -228,7 +228,7 @@ F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6
F test/server1.test e328b8e641ba8fe9273132cfef497383185dc1f5 F test/server1.test e328b8e641ba8fe9273132cfef497383185dc1f5
F test/shared.test 9982a65ccf3f4eee844a19f3ab0bcd7a158a76e5 F test/shared.test 9982a65ccf3f4eee844a19f3ab0bcd7a158a76e5
F test/shared2.test 909fc0f0277684ed29cc1b36c8e159188aec7f28 F test/shared2.test 909fc0f0277684ed29cc1b36c8e159188aec7f28
F test/shared_err.test dea32ad1ce72c1aa88a4671b5de3900961f6c687 F test/shared_err.test f72c9fbe1802500f0d97e768f947ae5c703c0152
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797 F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797
F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2 F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2
@ -344,7 +344,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P 97491d4eb5fc24d8f5cc7605db844359ecc6a818 P fd4a6bb1ac94d085dda247799c0a5c64aaeec046
R 0ac1c3b7951d8503eabc2e4f37bf1aac R bde9ce22812627a378f8978bb7879372
U drh U danielk1977
Z 64f4b8a9886c6294a59c365b44cd61fd Z c8dd5ea23e29760f9b39f58f5d5d0fb8

View File

@ -1 +1 @@
fd4a6bb1ac94d085dda247799c0a5c64aaeec046 7e34163a65a5842ecc50a14a9d60601e7c9d3249

View File

@ -9,7 +9,7 @@
** May you share freely, never taking more than you give. ** 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. ** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to ** For a detailed discussion of BTrees, refer to
@ -506,6 +506,8 @@ struct BtLock {
#else #else
static void releasePage(MemPage *pPage);
/* /*
** Save the current cursor position in the variables BtCursor.nKey ** Save the current cursor position in the variables BtCursor.nKey
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. ** 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 ); assert( !pCur->pPage->intKey || !pCur->pKey );
/* Todo: Should we drop the reference to pCur->pPage here? */ /* Todo: Should we drop the reference to pCur->pPage here? */
releasePage(pCur->pPage);
pCur->pPage = 0;
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
pCur->eState = CURSOR_REQUIRESEEK; pCur->eState = CURSOR_REQUIRESEEK;
@ -2617,12 +2621,15 @@ int sqlite3BtreeCommitStmt(Btree *p){
** will result in an error. ** will result in an error.
*/ */
int sqlite3BtreeRollbackStmt(Btree *p){ int sqlite3BtreeRollbackStmt(Btree *p){
int rc; int rc = SQLITE_OK;
BtShared *pBt = p->pBt; BtShared *pBt = p->pBt;
if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK; sqlite3MallocDisallow();
rc = sqlite3pager_stmt_rollback(pBt->pPager); if( pBt->inStmt && !pBt->readOnly ){
assert( countWriteCursors(pBt)==0 ); rc = sqlite3pager_stmt_rollback(pBt->pPager);
pBt->inStmt = 0; assert( countWriteCursors(pBt)==0 );
pBt->inStmt = 0;
}
sqlite3MallocAllow();
return rc; return rc;
} }
@ -3174,9 +3181,8 @@ static int moveToRoot(BtCursor *pCur){
BtShared *pBt = pCur->pBtree->pBt; BtShared *pBt = pCur->pBtree->pBt;
restoreOrClearCursorPosition(pCur, 0); restoreOrClearCursorPosition(pCur, 0);
assert( pCur->pPage );
pRoot = pCur->pPage; pRoot = pCur->pPage;
if( pRoot->pgno==pCur->pgnoRoot ){ if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
assert( pRoot->isInit ); assert( pRoot->isInit );
}else{ }else{
if( if(
@ -3443,7 +3449,7 @@ int sqlite3BtreeEof(BtCursor *pCur){
*/ */
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
int rc; int rc;
MemPage *pPage = pCur->pPage; MemPage *pPage;
#ifndef SQLITE_OMIT_SHARED_CACHE #ifndef SQLITE_OMIT_SHARED_CACHE
rc = restoreOrClearCursorPosition(pCur, 1); rc = restoreOrClearCursorPosition(pCur, 1);
@ -3456,9 +3462,10 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
return SQLITE_OK; return SQLITE_OK;
} }
pCur->skip = 0; pCur->skip = 0;
#endif #endif
assert( pRes!=0 ); assert( pRes!=0 );
pPage = pCur->pPage;
if( CURSOR_INVALID==pCur->eState ){ if( CURSOR_INVALID==pCur->eState ){
*pRes = 1; *pRes = 1;
return SQLITE_OK; return SQLITE_OK;

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while ** file simultaneously, or one process from reading the database while
** another is writing. ** 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 #ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h" #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); CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
i64 fileSize; i64 fileSize;
if( sqlite3OsFileSize(pPager->fd,&fileSize)!=SQLITE_OK int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
|| fileSize>=pgno*pPager->pageSize ){ 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)); sqlite3pager_unref(PGHDR_TO_DATA(pPg));
return pager_error(pPager, rc); pPg->pgno = 0;
return rc;
}else{ }else{
clear_simulated_io_error(); clear_simulated_io_error();
memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);

View File

@ -241,7 +241,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
} }
#endif #endif
sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); sqlite3Error(p->db, rc, 0);
p->rc = sqlite3ApiExit(p->db, p->rc); p->rc = sqlite3ApiExit(p->db, p->rc);
return rc; return rc;
} }

View File

@ -1242,6 +1242,8 @@ int sqlite3VdbeHalt(Vdbe *p){
/* We are forced to roll back the active transaction. Before doing /* We are forced to roll back the active transaction. Before doing
** so, abort any other statements this handle currently has active. ** so, abort any other statements this handle currently has active.
*/ */
abortOtherActiveVdbes(p);
sqlite3RollbackAll(db);
db->autoCommit = 1; db->autoCommit = 1;
} }
} }
@ -1264,12 +1266,12 @@ int sqlite3VdbeHalt(Vdbe *p){
return SQLITE_BUSY; return SQLITE_BUSY;
}else if( rc!=SQLITE_OK ){ }else if( rc!=SQLITE_OK ){
p->rc = rc; p->rc = rc;
rollbackAll(db, p); sqlite3RollbackAll(db);
}else{ }else{
sqlite3CommitInternalChanges(db); sqlite3CommitInternalChanges(db);
} }
}else{ }else{
rollbackAll(db, p); sqlite3RollbackAll(db);
} }
}else if( !xFunc ){ }else if( !xFunc ){
if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
@ -1277,7 +1279,8 @@ int sqlite3VdbeHalt(Vdbe *p){
}else if( p->errorAction==OE_Abort ){ }else if( p->errorAction==OE_Abort ){
xFunc = sqlite3BtreeRollbackStmt; xFunc = sqlite3BtreeRollbackStmt;
}else{ }else{
rollbackAll(db, p); abortOtherActiveVdbes(p);
sqlite3RollbackAll(db);
db->autoCommit = 1; db->autoCommit = 1;
} }
} }
@ -1359,8 +1362,9 @@ int sqlite3VdbeReset(Vdbe *p){
*/ */
if( p->pc>=0 ){ if( p->pc>=0 ){
if( p->zErrMsg ){ if( p->zErrMsg ){
sqlite3Error(p->db, p->rc, "%s", p->zErrMsg); sqlite3* db = p->db;
sqliteFree(p->zErrMsg); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX);
db->errCode = p->rc;
p->zErrMsg = 0; p->zErrMsg = 0;
}else if( p->rc ){ }else if( p->rc ){
sqlite3Error(p->db, p->rc, 0); sqlite3Error(p->db, p->rc, 0);

View File

@ -13,7 +13,7 @@
# correctly. The emphasis of these tests are the _prepare(), _step() and # correctly. The emphasis of these tests are the _prepare(), _step() and
# _finalize() calls. # _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] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -492,13 +492,27 @@ TEST 32 {
sqlite3_step $::STMT32 sqlite3_step $::STMT32
} {SQLITE_ROW} } {SQLITE_ROW}
} }
puts [execsql {SELECT * FROM ghi}]
} }
SQL { SQL BEGIN
BEGIN; TEST 33 {
INSERT INTO ghi SELECT * FROM ghi; do_test $testid {
COMMIT; 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 # 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. # Turn of the Tcl interface's prepared statement caching facility.
db cache size 0 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 # run_test [lrange $::run_test_script 0 3] 0 63
sqlite_malloc_fail 0 sqlite_malloc_fail 0
db close db close

View File

@ -13,7 +13,7 @@
# cache context. What happens to connection B if one connection A encounters # cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system? # 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} {} proc skip {args} {}
@ -28,7 +28,6 @@ ifcapable !shared_cache||!subquery {
} }
set ::enable_shared_cache [sqlite3_enable_shared_cache 1] set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
skip \
do_ioerr_test shared_ioerr-1 -tclprep { do_ioerr_test shared_ioerr-1 -tclprep {
sqlite3 db2 test.db sqlite3 db2 test.db
execsql { execsql {
@ -52,7 +51,7 @@ do_ioerr_test shared_ioerr-1 -tclprep {
SELECT * FROM t1; SELECT * FROM t1;
DELETE FROM t1 WHERE a<100; DELETE FROM t1 WHERE a<100;
} -cleanup { } -cleanup {
do_test shared_ioerr-$n.cleanup.1 { do_test shared_ioerr-1.$n.cleanup.1 {
set res [catchsql { set res [catchsql {
SELECT * FROM t1; SELECT * FROM t1;
} db2] } db2]
@ -131,6 +130,44 @@ do_ioerr_test shared_ioerr-2 -tclprep {
db2 close 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} catch {db close}
sqlite3_enable_shared_cache $::enable_shared_cache sqlite3_enable_shared_cache $::enable_shared_cache
finish_test finish_test