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:
14
manifest
14
manifest
@@ -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)
|
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-05T21:58:33
|
D 2007-04-06T01:03:33
|
||||||
F Makefile.in a9bd493360a2b17e5214b69d8c32dd6cdaceaf55
|
F Makefile.in a9bd493360a2b17e5214b69d8c32dd6cdaceaf55
|
||||||
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -58,7 +58,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
|
|||||||
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
|
F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
|
||||||
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
|
||||||
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
|
||||||
F src/btree.c 48fa58f2d71edeab4a7d08157abe50a0b7a0e489
|
F src/btree.c 27299eba3ad5aa1fed184c707576d12d0e608e8d
|
||||||
F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf
|
F src/btree.h 9b2cc0d113c0bc2d37d244b9a394d56948c9acbf
|
||||||
F src/build.c 7c2efa468f0c404ef5aa648d43c383318390937f
|
F src/build.c 7c2efa468f0c404ef5aa648d43c383318390937f
|
||||||
F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
|
F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
|
||||||
@@ -271,7 +271,7 @@ F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893
|
|||||||
F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217
|
F test/memleak.test d2d2a1ff7105d32dc3fdf691458cf6cba58c7217
|
||||||
F test/minmax.test 66434d8ee04869fe4c220b665b73748accbb9163
|
F test/minmax.test 66434d8ee04869fe4c220b665b73748accbb9163
|
||||||
F test/misc1.test 27a6ad11ba6e4b73aeee650ab68053ad7dfd0433
|
F test/misc1.test 27a6ad11ba6e4b73aeee650ab68053ad7dfd0433
|
||||||
F test/misc2.test 0b45deedcfd6ba857ea2f377c5669d3501a535c7
|
F test/misc2.test d35faf7df27750d25ab656ca92dceebbd89f7368
|
||||||
F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03
|
F test/misc3.test 7bd937e2c62bcc6be71939faf068d506467b1e03
|
||||||
F test/misc4.test b043a05dea037cca5989f3ae09552fa16119bc80
|
F test/misc4.test b043a05dea037cca5989f3ae09552fa16119bc80
|
||||||
F test/misc5.test c7d2d2a5a20dc37d3605a8067f0df5af2240122e
|
F test/misc5.test c7d2d2a5a20dc37d3605a8067f0df5af2240122e
|
||||||
@@ -451,7 +451,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 204e7d38aeb40d126b80a869958ca79cd0902d83
|
P f2caff870c81c08ec85aae72986c231ee986b251
|
||||||
R 33250e136d9f0af3693e864db67d12e7
|
R 318b6ff1df8c9d65e7de849f673a3ac5
|
||||||
U drh
|
U drh
|
||||||
Z d3104f68e1b1c0abe9a9e14724db1ec1
|
Z 3ae24a6bd11cbf91ba2afccd5e139cc3
|
||||||
|
@@ -1 +1 @@
|
|||||||
f2caff870c81c08ec85aae72986c231ee986b251
|
bebf8d2f886ed9fe1b96e4cb11ab3de2f2f7d2c8
|
27
src/btree.c
27
src/btree.c
@@ -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.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.
|
** 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
|
||||||
@@ -3520,6 +3520,14 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
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 ){
|
if( pCur->skip>0 ){
|
||||||
pCur->skip = 0;
|
pCur->skip = 0;
|
||||||
*pRes = 0;
|
*pRes = 0;
|
||||||
@@ -3528,12 +3536,6 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
|||||||
pCur->skip = 0;
|
pCur->skip = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert( pRes!=0 );
|
|
||||||
pPage = pCur->pPage;
|
|
||||||
if( CURSOR_INVALID==pCur->eState ){
|
|
||||||
*pRes = 1;
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
assert( pPage->isInit );
|
assert( pPage->isInit );
|
||||||
assert( pCur->idx<pPage->nCell );
|
assert( pCur->idx<pPage->nCell );
|
||||||
|
|
||||||
@@ -3588,6 +3590,12 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if( CURSOR_INVALID==pCur->eState ){
|
||||||
|
*pRes = 1;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
if( pCur->skip<0 ){
|
if( pCur->skip<0 ){
|
||||||
pCur->skip = 0;
|
pCur->skip = 0;
|
||||||
*pRes = 0;
|
*pRes = 0;
|
||||||
@@ -3596,11 +3604,6 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
|||||||
pCur->skip = 0;
|
pCur->skip = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( CURSOR_INVALID==pCur->eState ){
|
|
||||||
*pRes = 1;
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
pPage = pCur->pPage;
|
pPage = pCur->pPage;
|
||||||
assert( pPage->isInit );
|
assert( pPage->isInit );
|
||||||
assert( pCur->idx>=0 );
|
assert( pCur->idx>=0 );
|
||||||
|
102
test/misc2.test
102
test/misc2.test
@@ -13,7 +13,7 @@
|
|||||||
# This file implements tests for miscellanous features that were
|
# This file implements tests for miscellanous features that were
|
||||||
# left out of other test files.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -253,6 +253,106 @@ do_test misc2-7.8 {
|
|||||||
execsql {SELECT * FROM t1}
|
execsql {SELECT * FROM t1}
|
||||||
} {1 2 3 4 5 6 7 8 9 10}
|
} {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
|
db close
|
||||||
file delete -force test.db
|
file delete -force test.db
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
|
Reference in New Issue
Block a user