1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Make sure the sqlite3BtreePrevious() routine terminates properly if the

table is deleted out from under it.  Ticket #2286.  This bug was discovered
while trying to increase test coverage from 98.5% to 99% - once again
showing the value of full coverage testing. (CVS 3818)

FossilOrigin-Name: bebf8d2f886ed9fe1b96e4cb11ab3de2f2f7d2c8
This commit is contained in:
drh
2007-04-06 01:03:32 +00:00
parent bd08af4871
commit 8c4d3a6b42
4 changed files with 124 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sthe\samalgamation\sso\sthat\sit\sworks\swith\s-DSQLITE_ENABLE_REDEF_IO.\s\sChange\ntclsqlite.c\sso\sthat\sit\scan\sbe\sappended\sto\sthe\samalgamation.\s\sCreate\sa\snew\namalgamation\sof\sheader\sfiles\sfor\suse\sby\sprojects\sthat\swant\sto\sredefine\stheir\nown\sI/O\sinterface\susing\s-DSQLITE_ENABLE_REDEF_IO.\s(CVS\s3817)
D 2007-04-05T21:58:33
C Make\ssure\sthe\ssqlite3BtreePrevious()\sroutine\sterminates\sproperly\sif\sthe\ntable\sis\sdeleted\sout\sfrom\sunder\sit.\s\sTicket\s#2286.\s\sThis\sbug\swas\sdiscovered\nwhile\strying\sto\sincrease\stest\scoverage\sfrom\s98.5%\sto\s99%\s-\sonce\sagain\nshowing\sthe\svalue\sof\sfull\scoverage\stesting.\s(CVS\s3818)
D 2007-04-06T01:03:33
F Makefile.in a9bd493360a2b17e5214b69d8c32dd6cdaceaf55
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -58,7 +58,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
F src/btree.c 48fa58f2d71edeab4a7d08157abe50a0b7a0e489
F src/btree.c 27299eba3ad5aa1fed184c707576d12d0e608e8d
F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf
F src/build.c 7c2efa468f0c404ef5aa648d43c383318390937f
F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
@@ -271,7 +271,7 @@ F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893
F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217
F test/minmax.test 66434d8ee04869fe4c220b665b73748accbb9163
F test/misc1.test 27a6ad11ba6e4b73aeee650ab68053ad7dfd0433
F test/misc2.test 0b45deedcfd6ba857ea2f377c5669d3501a535c7
F test/misc2.test d35faf7df27750d25ab656ca92dceebbd89f7368
F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03
F test/misc4.test b043a05dea037cca5989f3ae09552fa16119bc80
F test/misc5.test c7d2d2a5a20dc37d3605a8067f0df5af2240122e
@@ -451,7 +451,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P 204e7d38aeb40d126b80a869958ca79cd0902d83
R 33250e136d9f0af3693e864db67d12e7
P f2caff870c81c08ec85aae72986c231ee986b251
R 318b6ff1df8c9d65e7de849f673a3ac5
U drh
Z d3104f68e1b1c0abe9a9e14724db1ec1
Z 3ae24a6bd11cbf91ba2afccd5e139cc3

View File

@@ -1 +1 @@
f2caff870c81c08ec85aae72986c231ee986b251
bebf8d2f886ed9fe1b96e4cb11ab3de2f2f7d2c8

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.350 2007/04/02 05:07:47 danielk1977 Exp $
** $Id: btree.c,v 1.351 2007/04/06 01:03:33 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -3520,6 +3520,14 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
if( rc!=SQLITE_OK ){
return rc;
}
#endif
assert( pRes!=0 );
pPage = pCur->pPage;
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_SHARED_CACHE
if( pCur->skip>0 ){
pCur->skip = 0;
*pRes = 0;
@@ -3528,12 +3536,6 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
pCur->skip = 0;
#endif
assert( pRes!=0 );
pPage = pCur->pPage;
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
assert( pPage->isInit );
assert( pCur->idx<pPage->nCell );
@@ -3588,6 +3590,12 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
if( rc!=SQLITE_OK ){
return rc;
}
#endif
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_SHARED_CACHE
if( pCur->skip<0 ){
pCur->skip = 0;
*pRes = 0;
@@ -3596,11 +3604,6 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
pCur->skip = 0;
#endif
if( CURSOR_INVALID==pCur->eState ){
*pRes = 1;
return SQLITE_OK;
}
pPage = pCur->pPage;
assert( pPage->isInit );
assert( pCur->idx>=0 );

View File

@@ -13,7 +13,7 @@
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc2.test,v 1.26 2006/09/29 14:01:07 drh Exp $
# $Id: misc2.test,v 1.27 2007/04/06 01:03:34 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -253,6 +253,106 @@ do_test misc2-7.8 {
execsql {SELECT * FROM t1}
} {1 2 3 4 5 6 7 8 9 10}
# Repeat the tests 7.1 through 7.8 about but this time do the SELECTs
# in reverse order so that we exercise the sqlite3BtreePrev() routine
# instead of sqlite3BtreeNext()
#
do_test misc2-7.11 {
db close
file delete -force test.db
sqlite3 db test.db
execsql {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
SELECT * FROM t1;
}
} {1 2 3}
do_test misc2-7.12 {
set rc [catch {
db eval {SELECT rowid FROM t1 ORDER BY rowid DESC} {} {
db eval "DELETE FROM t1 WHERE rowid=$rowid"
}
} msg]
lappend rc $msg
} {0 {}}
do_test misc2-7.13 {
execsql {SELECT * FROM t1}
} {}
do_test misc2-7.14 {
execsql {
DELETE FROM t1;
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(4);
}
db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
if {$x & 1} {
db eval {DELETE FROM t1 WHERE rowid=$rowid}
}
}
execsql {SELECT * FROM t1}
} {2 4}
do_test misc2-7.15 {
execsql {
DELETE FROM t1;
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(4);
}
db eval {SELECT rowid, x FROM t1} {
if {$x & 1} {
db eval {DELETE FROM t1 WHERE rowid=$rowid+1}
}
}
execsql {SELECT * FROM t1}
} {1 3}
do_test misc2-7.16 {
execsql {
DELETE FROM t1;
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(4);
}
db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
if {$x & 1} {
db eval {DELETE FROM t1}
}
}
execsql {SELECT * FROM t1}
} {}
do_test misc2-7.17 {
execsql {
DELETE FROM t1;
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(4);
}
db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
if {$x & 1} {
db eval {UPDATE t1 SET x=x+100 WHERE rowid=$rowid}
}
}
execsql {SELECT * FROM t1}
} {101 2 103 4}
do_test misc2-7.18 {
execsql {
DELETE FROM t1;
INSERT INTO t1(rowid,x) VALUES(10,10);
}
db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
if {$x>1} {
db eval {INSERT INTO t1(rowid,x) VALUES($x-1,$x-1)}
}
}
execsql {SELECT * FROM t1}
} {1 2 3 4 5 6 7 8 9 10}
db close
file delete -force test.db
sqlite3 db test.db