/ Check-in [ecc3544e]
Login

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

Overview
Comment:Ensure that the "Any prior cache entry associated with newKey is guaranteed not to be pinned" guarantee made to xRekey implementations is not violated.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | defrag-opt
Files: files | file ages | folders
SHA1: ecc3544e712041736af7c7b4f34864a1f2e30ff7
User & Date: dan 2014-10-24 20:57:03
Context
2014-10-25
20:36
Further modifications to new code to better handle corrupt databases. check-in: 1a8cf0a0 user: dan tags: defrag-opt
2014-10-24
20:57
Ensure that the "Any prior cache entry associated with newKey is guaranteed not to be pinned" guarantee made to xRekey implementations is not violated. check-in: ecc3544e user: dan tags: defrag-opt
18:43
Fix some issues in the new code on this branch related to the handling of corrupt databases. check-in: 19736dd9 user: dan tags: defrag-opt
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  6852   6852     ** for large insertions and deletions.
  6853   6853     */
  6854   6854     for(i=0; i<nNew; i++){
  6855   6855       aPgno[i] = apNew[i]->pgno;
  6856   6856       aPgFlags[i] = apNew[i]->pDbPage->flags;
  6857   6857     }
  6858   6858     for(i=0; i<nNew; i++){
  6859         -    Pgno iGt = (i==0 ? 0 : apNew[i-1]->pgno);
  6860         -    Pgno iMin = 0;
  6861         -    u16 flags = 0;
  6862         -    for(j=0; j<nNew; j++){
  6863         -      Pgno iPgno = aPgno[j];
  6864         -      if( iPgno>iGt && (iMin==0 || iPgno<iMin) ){
  6865         -        iMin = iPgno;
  6866         -        flags = aPgFlags[j];
         6859  +    int iBest = 0;                /* aPgno[] index of page number to use */
         6860  +    Pgno pgno;                    /* Page number to use */
         6861  +    for(j=1; j<nNew; j++){
         6862  +      if( aPgno[j]<aPgno[iBest] ) iBest = j;
         6863  +    }
         6864  +    pgno = aPgno[iBest];
         6865  +    aPgno[iBest] = 0xffffffff;
         6866  +    if( iBest!=i ){
         6867  +      if( iBest>i ){
         6868  +        sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
  6867   6869         }
  6868         -    }
  6869         -    if( iMin==0 ){
  6870         -      /* This case can only occur if aPgno[] contains duplicate page 
  6871         -      ** numbers. Which can only happen if the database is corrupt. */
  6872         -      assert( CORRUPT_DB );
  6873         -      rc = SQLITE_CORRUPT_BKPT;
  6874         -      goto balance_cleanup;
  6875         -    }else if( apNew[i]->pgno!=iMin ){
  6876         -      sqlite3PagerRekey(apNew[i]->pDbPage, iMin, flags);
  6877         -      apNew[i]->pgno = iMin;
         6870  +      sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]);
         6871  +      apNew[i]->pgno = pgno;
  6878   6872       }
  6879   6873     }
  6880   6874   
  6881   6875     TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) "
  6882   6876            "%d(%d nc=%d) %d(%d nc=%d)\n",
  6883   6877       apNew[0]->pgno, szNew[0], cntNew[0],
  6884   6878       nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,

Changes to src/pager.c.

  6849   6849   
  6850   6850   /*
  6851   6851   ** The page handle passed as the first argument refers to a dirty page 
  6852   6852   ** with a page number other than iNew. This function changes the page's 
  6853   6853   ** page number to iNew and sets the value of the PgHdr.flags field to 
  6854   6854   ** the value passed as the third parameter.
  6855   6855   */
  6856         -void sqlite3PagerRekey(DbPage *pPage, Pgno iNew, u16 flags){
  6857         -  PgHdr *pPg = (PgHdr*)pPage;
  6858         -  assert( (flags & PGHDR_DIRTY) && (pPg->flags & PGHDR_DIRTY) );
  6859         -  assert( !subjRequiresPage(pPg) );
         6856  +void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
  6860   6857     assert( pPg->pgno!=iNew );
  6861   6858     pPg->flags = flags;
  6862   6859     sqlite3PcacheMove(pPg, iNew);
  6863   6860   }
  6864   6861   
  6865   6862   /*
  6866   6863   ** Return a pointer to the data for the specified page.