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

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
This commit is contained in:
drh
2013-03-27 03:15:23 +00:00
parent e115ff8171
commit 138eeeb1b0
4 changed files with 93 additions and 19 deletions

View File

@@ -575,6 +575,19 @@ static void btreeClearHasContent(BtShared *pBt){
pBt->pHasContent = 0;
}
/*
** 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);
}
}
}