SQLite

Check-in [ecc3544e71]
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
Timelines: family | ancestors | descendants | both | defrag-opt
Files: files | file ages | folders
SHA1: ecc3544e712041736af7c7b4f34864a1f2e30ff7
User & Date: dan 2014-10-24 20:57:03.500
Context
2014-10-25
20:36
Further modifications to new code to better handle corrupt databases. (check-in: 1a8cf0a043 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: ecc3544e71 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: 19736dd9fb user: dan tags: defrag-opt)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/btree.c.
6852
6853
6854
6855
6856
6857
6858
6859
6860


6861
6862
6863


6864
6865
6866
6867
6868







6869
6870
6871
6872
6873
6874
6875
6876
6877


6878
6879
6880
6881
6882
6883
6884
6852
6853
6854
6855
6856
6857
6858


6859
6860



6861
6862





6863
6864
6865
6866
6867
6868
6869









6870
6871
6872
6873
6874
6875
6876
6877
6878







-
-
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+







  ** for large insertions and deletions.
  */
  for(i=0; i<nNew; i++){
    aPgno[i] = apNew[i]->pgno;
    aPgFlags[i] = apNew[i]->pDbPage->flags;
  }
  for(i=0; i<nNew; i++){
    Pgno iGt = (i==0 ? 0 : apNew[i-1]->pgno);
    Pgno iMin = 0;
    int iBest = 0;                /* aPgno[] index of page number to use */
    Pgno pgno;                    /* Page number to use */
    u16 flags = 0;
    for(j=0; j<nNew; j++){
      Pgno iPgno = aPgno[j];
    for(j=1; j<nNew; j++){
      if( aPgno[j]<aPgno[iBest] ) iBest = j;
      if( iPgno>iGt && (iMin==0 || iPgno<iMin) ){
        iMin = iPgno;
        flags = aPgFlags[j];
      }
    }
    }
    pgno = aPgno[iBest];
    aPgno[iBest] = 0xffffffff;
    if( iBest!=i ){
      if( iBest>i ){
        sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
      }
    if( iMin==0 ){
      /* This case can only occur if aPgno[] contains duplicate page 
      ** numbers. Which can only happen if the database is corrupt. */
      assert( CORRUPT_DB );
      rc = SQLITE_CORRUPT_BKPT;
      goto balance_cleanup;
    }else if( apNew[i]->pgno!=iMin ){
      sqlite3PagerRekey(apNew[i]->pDbPage, iMin, flags);
      apNew[i]->pgno = iMin;
      sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]);
      apNew[i]->pgno = pgno;
    }
  }

  TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) "
         "%d(%d nc=%d) %d(%d nc=%d)\n",
    apNew[0]->pgno, szNew[0], cntNew[0],
    nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,
Changes to src/pager.c.
6849
6850
6851
6852
6853
6854
6855
6856

6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6849
6850
6851
6852
6853
6854
6855

6856



6857
6858
6859
6860
6861
6862
6863







-
+
-
-
-








/*
** The page handle passed as the first argument refers to a dirty page 
** with a page number other than iNew. This function changes the page's 
** page number to iNew and sets the value of the PgHdr.flags field to 
** the value passed as the third parameter.
*/
void sqlite3PagerRekey(DbPage *pPage, Pgno iNew, u16 flags){
void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
  PgHdr *pPg = (PgHdr*)pPage;
  assert( (flags & PGHDR_DIRTY) && (pPg->flags & PGHDR_DIRTY) );
  assert( !subjRequiresPage(pPg) );
  assert( pPg->pgno!=iNew );
  pPg->flags = flags;
  sqlite3PcacheMove(pPg, iNew);
}

/*
** Return a pointer to the data for the specified page.