/ Check-in [ecc3544e]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 Unified Diffs 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
  ** 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;
    u16 flags = 0;
    for(j=0; j<nNew; j++){
      Pgno iPgno = aPgno[j];
      if( iPgno>iGt && (iMin==0 || iPgno<iMin) ){
        iMin = iPgno;
        flags = aPgFlags[j];
      }
    }
    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;
    }
  }

  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,







|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<







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++){
    int iBest = 0;                /* aPgno[] index of page number to use */
    Pgno pgno;                    /* Page number to use */
    for(j=1; j<nNew; j++){
      if( aPgno[j]<aPgno[iBest] ) iBest = j;
    }
    pgno = aPgno[iBest];
    aPgno[iBest] = 0xffffffff;
    if( iBest!=i ){
      if( iBest>i ){
        sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
      }
      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

/*
** 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){
  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.







|
<
<
<







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 *pPg, Pgno iNew, u16 flags){



  assert( pPg->pgno!=iNew );
  pPg->flags = flags;
  sqlite3PcacheMove(pPg, iNew);
}

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