Fix the saveCursorPosition() routine in btree.c so that it works
correctly for a eState=CURSOR_SKIPNEXT cursor. FossilOrigin-Name: 37866b4d483296ab9b7fcb9f5486695d4c2b8ddd
This commit is contained in:
parent
cbd3349ab9
commit
d2f83139f3
13
manifest
13
manifest
@ -1,5 +1,5 @@
|
|||||||
C Reactivate\san\solder\sassert()\s(adding\san\s"||\sCORRUPT_DB"\sterm)\sand\sadd\sa\nnew\sassert()\sin\sbtree.c.
|
C Fix\sthe\ssaveCursorPosition()\sroutine\sin\sbtree.c\sso\sthat\sit\sworks\ncorrectly\sfor\sa\seState=CURSOR_SKIPNEXT\scursor.
|
||||||
D 2015-03-25T13:06:54.837
|
D 2015-03-25T17:35:01.825
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
|
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
|||||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||||
F src/btree.c 3634c2ee748bbbb2488cdca9dc8fc8c7bdc2f66f
|
F src/btree.c 933ab4ad883546193f5fd55f840299165adb8069
|
||||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||||
F src/btreeInt.h 2bfefc01875d8da066504c233ec259fcb3b2ef72
|
F src/btreeInt.h 2bfefc01875d8da066504c233ec259fcb3b2ef72
|
||||||
F src/build.c 0419bba592c22f6d00e6d57a2ca7136720d02c1a
|
F src/build.c 0419bba592c22f6d00e6d57a2ca7136720d02c1a
|
||||||
@ -384,6 +384,7 @@ F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
|
|||||||
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
|
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
|
||||||
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
||||||
F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
|
F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
|
||||||
|
F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99
|
||||||
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||||
@ -1246,7 +1247,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 42d1793d6516e285a8925bbfd96b3d3375603d15
|
P 1e96520ac1d12ca83f019a60482efa0a074f2f94
|
||||||
R 90535e28cf02760b75aa0324ce2f944c
|
R 0d2b32f8ac05ffe0443a79d106bd4efe
|
||||||
U drh
|
U drh
|
||||||
Z 7ee968129b9c07925188972da6333faa
|
Z 2f58ba8b67469927a3c7d533210b0ef3
|
||||||
|
@ -1 +1 @@
|
|||||||
1e96520ac1d12ca83f019a60482efa0a074f2f94
|
37866b4d483296ab9b7fcb9f5486695d4c2b8ddd
|
17
src/btree.c
17
src/btree.c
@ -600,10 +600,15 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){
|
|||||||
static int saveCursorPosition(BtCursor *pCur){
|
static int saveCursorPosition(BtCursor *pCur){
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert( CURSOR_VALID==pCur->eState );
|
assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState );
|
||||||
assert( 0==pCur->pKey );
|
assert( 0==pCur->pKey );
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
|
|
||||||
|
if( pCur->eState==CURSOR_SKIPNEXT ){
|
||||||
|
pCur->eState = CURSOR_VALID;
|
||||||
|
}else{
|
||||||
|
pCur->skipNext = 0;
|
||||||
|
}
|
||||||
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
|
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
|
||||||
assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
|
assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
|
||||||
|
|
||||||
@ -674,7 +679,7 @@ static int SQLITE_NOINLINE saveCursorsOnList(
|
|||||||
){
|
){
|
||||||
do{
|
do{
|
||||||
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
|
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
|
||||||
if( p->eState==CURSOR_VALID ){
|
if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
|
||||||
int rc = saveCursorPosition(p);
|
int rc = saveCursorPosition(p);
|
||||||
if( SQLITE_OK!=rc ){
|
if( SQLITE_OK!=rc ){
|
||||||
return rc;
|
return rc;
|
||||||
@ -746,17 +751,19 @@ static int btreeMoveto(
|
|||||||
*/
|
*/
|
||||||
static int btreeRestoreCursorPosition(BtCursor *pCur){
|
static int btreeRestoreCursorPosition(BtCursor *pCur){
|
||||||
int rc;
|
int rc;
|
||||||
|
int skipNext;
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( pCur->eState>=CURSOR_REQUIRESEEK );
|
assert( pCur->eState>=CURSOR_REQUIRESEEK );
|
||||||
if( pCur->eState==CURSOR_FAULT ){
|
if( pCur->eState==CURSOR_FAULT ){
|
||||||
return pCur->skipNext;
|
return pCur->skipNext;
|
||||||
}
|
}
|
||||||
pCur->eState = CURSOR_INVALID;
|
pCur->eState = CURSOR_INVALID;
|
||||||
rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
|
rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
sqlite3_free(pCur->pKey);
|
sqlite3_free(pCur->pKey);
|
||||||
pCur->pKey = 0;
|
pCur->pKey = 0;
|
||||||
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
|
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
|
||||||
|
pCur->skipNext |= skipNext;
|
||||||
if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
|
if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
|
||||||
pCur->eState = CURSOR_SKIPNEXT;
|
pCur->eState = CURSOR_SKIPNEXT;
|
||||||
}
|
}
|
||||||
@ -808,7 +815,7 @@ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){
|
|||||||
*pDifferentRow = 1;
|
*pDifferentRow = 1;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
|
if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
|
||||||
*pDifferentRow = 1;
|
*pDifferentRow = 1;
|
||||||
}else{
|
}else{
|
||||||
*pDifferentRow = 0;
|
*pDifferentRow = 0;
|
||||||
@ -3625,7 +3632,7 @@ int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
|
|||||||
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
|
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
|
||||||
int i;
|
int i;
|
||||||
if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
|
if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
|
||||||
if( p->eState==CURSOR_VALID ){
|
if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
|
||||||
rc = saveCursorPosition(p);
|
rc = saveCursorPosition(p);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
(void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
|
(void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
|
||||||
|
52
test/btree02.test
Normal file
52
test/btree02.test
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# 2015-03-25
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library.
|
||||||
|
#
|
||||||
|
# The focus of this script is making multiple calls to saveCursorPosition()
|
||||||
|
# and restoreCursorPosition() when cursors have eState==CURSOR_SKIPNEXT
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
load_static_extension db eval
|
||||||
|
do_execsql_test btree02-100 {
|
||||||
|
CREATE TABLE t1(a TEXT, ax INTEGER, b INT, PRIMARY KEY(a,ax)) WITHOUT ROWID;
|
||||||
|
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
|
||||||
|
INSERT INTO t1(a,ax,b) SELECT printf('%02x',i), random(), i FROM c;
|
||||||
|
CREATE INDEX t1a ON t1(a);
|
||||||
|
CREATE TABLE t2(x,y);
|
||||||
|
CREATE TABLE t3(cnt);
|
||||||
|
WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<4)
|
||||||
|
INSERT INTO t3(cnt) SELECT i FROM c;
|
||||||
|
SELECT count(*) FROM t1;
|
||||||
|
} {10}
|
||||||
|
do_test btree02-110 {
|
||||||
|
db eval BEGIN
|
||||||
|
set i 0
|
||||||
|
db eval {SELECT a, ax, b, cnt FROM t1 CROSS JOIN t3 WHERE b IS NOT NULL} {
|
||||||
|
db eval {INSERT INTO t2(x,y) VALUES($b,$cnt)}
|
||||||
|
# puts "a,b,cnt = ($a,$b,$cnt)"
|
||||||
|
incr i
|
||||||
|
if {$i%2==1} {
|
||||||
|
set bx [expr {$b+1000}]
|
||||||
|
# puts "INSERT ($a),$bx"
|
||||||
|
db eval {INSERT INTO t1(a,ax,b) VALUES(printf('(%s)',$a),random(),$bx)}
|
||||||
|
} else {
|
||||||
|
# puts "DELETE a=$a"
|
||||||
|
db eval {DELETE FROM t1 WHERE a=$a}
|
||||||
|
}
|
||||||
|
db eval {COMMIT; BEGIN}
|
||||||
|
}
|
||||||
|
db one {COMMIT; SELECT count(*) FROM t1;}
|
||||||
|
} {20}
|
||||||
|
|
||||||
|
finish_test
|
Loading…
Reference in New Issue
Block a user