diff options
author | drh <drh@noemail.net> | 2013-03-27 03:15:23 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2013-03-27 03:15:23 +0000 |
commit | 138eeeb1b0e9d59c0c2ee5caa1463edd1a62ffcc (patch) | |
tree | 9320313f608c986b1979c76fa675ad3a53b328d6 /src/btree.c | |
parent | e115ff8171bb43e56254c9e88e96254d56e3986d (diff) | |
download | sqlite-138eeeb1b0e9d59c0c2ee5caa1463edd1a62ffcc.tar.gz sqlite-138eeeb1b0e9d59c0c2ee5caa1463edd1a62ffcc.zip |
Candidate fix for ticket [6bfb98dfc0c]: Make sure invalid cursors drop all
references to database pages prior to doing any insert or update.
FossilOrigin-Name: 322a5f086d9ee46017f750df81527799a54ae258
Diffstat (limited to 'src/btree.c')
-rw-r--r-- | src/btree.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/btree.c b/src/btree.c index b3549fa69..96140d68c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -576,6 +576,19 @@ static void btreeClearHasContent(BtShared *pBt){ } /* +** Release all of the apPage[] pages for a cursor. +*/ +static void btreeReleaseAllCursorPages(BtCursor *pCur){ + int i; + for(i=0; i<=pCur->iPage; i++){ + releasePage(pCur->apPage[i]); + pCur->apPage[i] = 0; + } + pCur->iPage = -1; +} + + +/* ** Save the current cursor position in the variables BtCursor.nKey ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. ** @@ -614,12 +627,7 @@ static int saveCursorPosition(BtCursor *pCur){ assert( !pCur->apPage[0]->intKey || !pCur->pKey ); if( rc==SQLITE_OK ){ - int i; - for(i=0; i<=pCur->iPage; i++){ - releasePage(pCur->apPage[i]); - pCur->apPage[i] = 0; - } - pCur->iPage = -1; + btreeReleaseAllCursorPages(pCur); pCur->eState = CURSOR_REQUIRESEEK; } @@ -637,11 +645,15 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ assert( sqlite3_mutex_held(pBt->mutex) ); assert( pExcept==0 || pExcept->pBt==pBt ); for(p=pBt->pCursor; p; p=p->pNext){ - if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && - p->eState==CURSOR_VALID ){ - int rc = saveCursorPosition(p); - if( SQLITE_OK!=rc ){ - return rc; + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ + if( p->eState==CURSOR_VALID ){ + int rc = saveCursorPosition(p); + if( SQLITE_OK!=rc ){ + return rc; + } + }else{ + testcase( p->iPage>0 ); + btreeReleaseAllCursorPages(p); } } } |