/ Check-in [49ba54e2]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Optimizations associated with error handling in btree cursors.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 49ba54e26731ed371745d4bdd9dd1dfeb73357b6d206c85a4252ec866be971d0
User & Date: drh 2017-08-02 15:50:09
Context
2017-08-02
18:27
Minor optimization on clearCell() check-in: f3c39c29 user: drh tags: trunk
15:50
Optimizations associated with error handling in btree cursors. check-in: 49ba54e2 user: drh tags: trunk
12:38
Remove unused token codes. check-in: c45078c0 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

   727    727       if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
   728    728         if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
   729    729           int rc = saveCursorPosition(p);
   730    730           if( SQLITE_OK!=rc ){
   731    731             return rc;
   732    732           }
   733    733         }else{
   734         -        testcase( p->iPage>0 );
          734  +        testcase( p->iPage>=0 );
   735    735           btreeReleaseAllCursorPages(p);
   736    736         }
   737    737       }
   738    738       p = p->pNext;
   739    739     }while( p );
   740    740     return SQLITE_OK;
   741    741   }
................................................................................
  3977   3977     BtCursor *p;
  3978   3978     int rc = SQLITE_OK;
  3979   3979   
  3980   3980     assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 );
  3981   3981     if( pBtree ){
  3982   3982       sqlite3BtreeEnter(pBtree);
  3983   3983       for(p=pBtree->pBt->pCursor; p; p=p->pNext){
  3984         -      int i;
  3985   3984         if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
  3986   3985           if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
  3987   3986             rc = saveCursorPosition(p);
  3988   3987             if( rc!=SQLITE_OK ){
  3989   3988               (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
  3990   3989               break;
  3991   3990             }
  3992   3991           }
  3993   3992         }else{
  3994   3993           sqlite3BtreeClearCursor(p);
  3995   3994           p->eState = CURSOR_FAULT;
  3996   3995           p->skipNext = errCode;
  3997   3996         }
  3998         -      for(i=0; i<=p->iPage; i++){
  3999         -        releasePage(p->apPage[i]);
  4000         -        p->apPage[i] = 0;
  4001         -      }
         3997  +      btreeReleaseAllCursorPages(p);
  4002   3998       }
  4003   3999       sqlite3BtreeLeave(pBtree);
  4004   4000     }
  4005   4001     return rc;
  4006   4002   }
  4007   4003   
  4008   4004   /*
................................................................................
  4311   4307             pPrev->pNext = pCur->pNext;
  4312   4308             break;
  4313   4309           }
  4314   4310           pPrev = pPrev->pNext;
  4315   4311         }while( ALWAYS(pPrev) );
  4316   4312       }
  4317   4313       for(i=0; i<=pCur->iPage; i++){
  4318         -      releasePage(pCur->apPage[i]);
         4314  +      releasePageNotNull(pCur->apPage[i]);
  4319   4315       }
  4320   4316       unlockBtreeIfUnused(pBt);
  4321   4317       sqlite3_free(pCur->aOverflow);
  4322   4318       /* sqlite3_free(pCur); */
  4323   4319       sqlite3BtreeLeave(pBtree);
  4324   4320     }
  4325   4321     return SQLITE_OK;
................................................................................
  4934   4930     MemPage *pRoot;
  4935   4931     int rc = SQLITE_OK;
  4936   4932   
  4937   4933     assert( cursorOwnsBtShared(pCur) );
  4938   4934     assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
  4939   4935     assert( CURSOR_VALID   < CURSOR_REQUIRESEEK );
  4940   4936     assert( CURSOR_FAULT   > CURSOR_REQUIRESEEK );
  4941         -  if( pCur->eState>=CURSOR_REQUIRESEEK ){
  4942         -    if( pCur->eState==CURSOR_FAULT ){
  4943         -      assert( pCur->skipNext!=SQLITE_OK );
  4944         -      return pCur->skipNext;
  4945         -    }
  4946         -    sqlite3BtreeClearCursor(pCur);
  4947         -  }
         4937  +  assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 );
  4948   4938   
  4949   4939     if( pCur->iPage>=0 ){
  4950   4940       if( pCur->iPage ){
  4951   4941         do{
  4952   4942           assert( pCur->apPage[pCur->iPage]!=0 );
  4953   4943           releasePageNotNull(pCur->apPage[pCur->iPage--]);
  4954   4944         }while( pCur->iPage);
................................................................................
  4955   4945         goto skip_init;
  4956   4946       }
  4957   4947     }else if( pCur->pgnoRoot==0 ){
  4958   4948       pCur->eState = CURSOR_INVALID;
  4959   4949       return SQLITE_OK;
  4960   4950     }else{
  4961   4951       assert( pCur->iPage==(-1) );
         4952  +    if( pCur->eState>=CURSOR_REQUIRESEEK ){
         4953  +      if( pCur->eState==CURSOR_FAULT ){
         4954  +        assert( pCur->skipNext!=SQLITE_OK );
         4955  +        return pCur->skipNext;
         4956  +      }
         4957  +      sqlite3BtreeClearCursor(pCur);
         4958  +    }
  4962   4959       rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
  4963   4960                           0, pCur->curPagerFlags);
  4964   4961       if( rc!=SQLITE_OK ){
  4965   4962         pCur->eState = CURSOR_INVALID;
  4966   4963          return rc;
  4967   4964       }
  4968   4965       pCur->iPage = 0;
................................................................................
  8250   8247       /* Must make sure nOverflow is reset to zero even if the balance()
  8251   8248       ** fails. Internal data structure corruption will result otherwise. 
  8252   8249       ** Also, set the cursor state to invalid. This stops saveCursorPosition()
  8253   8250       ** from trying to save the current position of the cursor.  */
  8254   8251       pCur->apPage[pCur->iPage]->nOverflow = 0;
  8255   8252       pCur->eState = CURSOR_INVALID;
  8256   8253       if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){
  8257         -      rc = moveToRoot(pCur);
         8254  +      btreeReleaseAllCursorPages(pCur);
  8258   8255         if( pCur->pKeyInfo ){
  8259   8256           assert( pCur->pKey==0 );
  8260   8257           pCur->pKey = sqlite3Malloc( pX->nKey );
  8261   8258           if( pCur->pKey==0 ){
  8262   8259             rc = SQLITE_NOMEM;
  8263   8260           }else{
  8264   8261             memcpy(pCur->pKey, pX->pKey, pX->nKey);
  8265   8262           }
  8266   8263         }
  8267   8264         pCur->eState = CURSOR_REQUIRESEEK;
  8268   8265         pCur->nKey = pX->nKey;
  8269   8266       }
  8270   8267     }
  8271         -  assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
         8268  +  assert( pCur->iPage<0 || pCur->apPage[pCur->iPage]->nOverflow==0 );
  8272   8269   
  8273   8270   end_insert:
  8274   8271     return rc;
  8275   8272   }
  8276   8273   
  8277   8274   /*
  8278   8275   ** Delete the entry that the cursor is pointing to. 
................................................................................
  8434   8431           pCur->ix = pPage->nCell-1;
  8435   8432         }else{
  8436   8433           pCur->skipNext = 1;
  8437   8434         }
  8438   8435       }else{
  8439   8436         rc = moveToRoot(pCur);
  8440   8437         if( bPreserve ){
         8438  +        btreeReleaseAllCursorPages(pCur);
  8441   8439           pCur->eState = CURSOR_REQUIRESEEK;
  8442   8440         }
  8443   8441       }
  8444   8442     }
  8445   8443     return rc;
  8446   8444   }
  8447   8445