aboutsummaryrefslogtreecommitdiff
path: root/src/btree.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2013-03-27 03:15:23 +0000
committerdrh <drh@noemail.net>2013-03-27 03:15:23 +0000
commit138eeeb1b0e9d59c0c2ee5caa1463edd1a62ffcc (patch)
tree9320313f608c986b1979c76fa675ad3a53b328d6 /src/btree.c
parente115ff8171bb43e56254c9e88e96254d56e3986d (diff)
downloadsqlite-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.c34
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);
}
}
}