/ Check-in [ceee03c7]
Login

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

Overview
Comment:Attempt to modify btree.c so that it assumes that calls to sqlite3PagerWrite() will reallocate the page buffer. As there is not good way to test this assumption yet, probably a few spots were missed.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental-pcache
Files: files | file ages | folders
SHA1:ceee03c79a55ea39866758aa76b78b10e5f4246d
User & Date: drh 2011-11-12 23:10:13
References
2011-11-17
11:43
Restore the test for sqlite3OsFullPathname() failure that was mistakenly removed when [ceee03c79a] was backed out by [69ec53fc1c]. check-in: 4d3cf9e1 user: drh tags: trunk
2011-11-16
23:29
Back out the [ceee03c79a] change. check-in: 69ec53fc user: drh tags: trunk
Context
2011-11-13
21:44
Add a version number to the sqlite3_pcache_methods2 object. Other PCACHE2 documentation improvements. Closed-Leaf check-in: 9f839ac0 user: drh tags: experimental-pcache
2011-11-12
23:10
Attempt to modify btree.c so that it assumes that calls to sqlite3PagerWrite() will reallocate the page buffer. As there is not good way to test this assumption yet, probably a few spots were missed. check-in: ceee03c7 user: drh tags: experimental-pcache
2011-11-11
14:12
Pull over all the latest changes from trunk. check-in: 1bbbf857 user: drh tags: experimental-pcache
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  1772   1772         char *zFullPathname = sqlite3Malloc(nFullPathname);
  1773   1773         MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
  1774   1774         p->sharable = 1;
  1775   1775         if( !zFullPathname ){
  1776   1776           sqlite3_free(p);
  1777   1777           return SQLITE_NOMEM;
  1778   1778         }
  1779         -      sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
         1779  +      rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
         1780  +      if( rc ){
         1781  +        sqlite3_free(zFullPathname);
         1782  +        sqlite3_free(p);
         1783  +        return rc;
         1784  +      }
  1780   1785   #if SQLITE_THREADSAFE
  1781   1786         mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
  1782   1787         sqlite3_mutex_enter(mutexOpen);
  1783   1788         mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  1784   1789         sqlite3_mutex_enter(mutexShared);
  1785   1790   #endif
  1786   1791         for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
................................................................................
  2473   2478   
  2474   2479     assert( sqlite3_mutex_held(pBt->mutex) );
  2475   2480     if( pBt->nPage>0 ){
  2476   2481       return SQLITE_OK;
  2477   2482     }
  2478   2483     pP1 = pBt->pPage1;
  2479   2484     assert( pP1!=0 );
  2480         -  data = pP1->aData;
  2481   2485     rc = sqlite3PagerWrite(pP1->pDbPage);
  2482   2486     if( rc ) return rc;
         2487  +  data = pP1->aData;
  2483   2488     memcpy(data, zMagicHeader, sizeof(zMagicHeader));
  2484   2489     assert( sizeof(zMagicHeader)==16 );
  2485   2490     data[16] = (u8)((pBt->pageSize>>8)&0xff);
  2486   2491     data[17] = (u8)((pBt->pageSize>>16)&0xff);
  2487   2492     data[18] = 1;
  2488   2493     data[19] = 1;
  2489   2494     assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
................................................................................
  3773   3778       *ppPage = pPage;
  3774   3779     }else{
  3775   3780       releasePage(pPage);
  3776   3781     }
  3777   3782     return (rc==SQLITE_DONE ? SQLITE_OK : rc);
  3778   3783   }
  3779   3784   
  3780         -/*
  3781         -** Copy data from a buffer to a page, or from a page to a buffer.
  3782         -**
  3783         -** pPayload is a pointer to data stored on database page pDbPage.
  3784         -** If argument eOp is false, then nByte bytes of data are copied
  3785         -** from pPayload to the buffer pointed at by pBuf. If eOp is true,
  3786         -** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
  3787         -** of data are copied from the buffer pBuf to pPayload.
  3788         -**
  3789         -** SQLITE_OK is returned on success, otherwise an error code.
  3790         -*/
  3791         -static int copyPayload(
  3792         -  void *pPayload,           /* Pointer to page data */
  3793         -  void *pBuf,               /* Pointer to buffer */
  3794         -  int nByte,                /* Number of bytes to copy */
  3795         -  int eOp,                  /* 0 -> copy from page, 1 -> copy to page */
  3796         -  DbPage *pDbPage           /* Page containing pPayload */
  3797         -){
  3798         -  if( eOp ){
  3799         -    /* Copy data from buffer to page (a write operation) */
  3800         -    int rc = sqlite3PagerWrite(pDbPage);
  3801         -    if( rc!=SQLITE_OK ){
  3802         -      return rc;
  3803         -    }
  3804         -    memcpy(pPayload, pBuf, nByte);
  3805         -  }else{
  3806         -    /* Copy data from page to buffer (a read operation) */
  3807         -    memcpy(pBuf, pPayload, nByte);
  3808         -  }
  3809         -  return SQLITE_OK;
  3810         -}
  3811         -
  3812   3785   /*
  3813   3786   ** This function is used to read or overwrite payload information
  3814   3787   ** for the entry that the pCur cursor is pointing to. If the eOp
  3815   3788   ** parameter is 0, this is a read operation (data copied into
  3816   3789   ** buffer pBuf). If it is non-zero, a write (data copied from
  3817   3790   ** buffer pBuf).
  3818   3791   **
................................................................................
  3851   3824     MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
  3852   3825     BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
  3853   3826   
  3854   3827     assert( pPage );
  3855   3828     assert( pCur->eState==CURSOR_VALID );
  3856   3829     assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
  3857   3830     assert( cursorHoldsMutex(pCur) );
         3831  +
  3858   3832   
  3859   3833     getCellInfo(pCur);
  3860   3834     aPayload = pCur->info.pCell + pCur->info.nHeader;
  3861   3835     nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
  3862   3836   
  3863   3837     if( NEVER(offset+amt > nKey+pCur->info.nData) 
  3864   3838      || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
................................................................................
  3869   3843   
  3870   3844     /* Check if data must be read/written to/from the btree page itself. */
  3871   3845     if( offset<pCur->info.nLocal ){
  3872   3846       int a = amt;
  3873   3847       if( a+offset>pCur->info.nLocal ){
  3874   3848         a = pCur->info.nLocal - offset;
  3875   3849       }
  3876         -    rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
         3850  +    if( eOp ){
         3851  +      if( (rc = sqlite3PagerWrite(pPage->pDbPage))!=SQLITE_OK ) return rc;
         3852  +      getCellInfo(pCur);
         3853  +      aPayload = pCur->info.pCell + pCur->info.nHeader;
         3854  +      memcpy(aPayload+offset, pBuf, a);
         3855  +    }else{
         3856  +      memcpy(pBuf, aPayload+offset, a);
         3857  +    }
  3877   3858       offset = 0;
  3878   3859       pBuf += a;
  3879   3860       amt -= a;
  3880   3861     }else{
  3881   3862       offset -= pCur->info.nLocal;
  3882   3863     }
  3883   3864   
................................................................................
  3980   3961           }else
  3981   3962   #endif
  3982   3963   
  3983   3964           {
  3984   3965             DbPage *pDbPage;
  3985   3966             rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
  3986   3967             if( rc==SQLITE_OK ){
         3968  +            if( eOp && (rc = sqlite3PagerWrite(pDbPage))!=SQLITE_OK ){
         3969  +              sqlite3PagerUnref(pDbPage);
         3970  +              return rc;
         3971  +            }
  3987   3972               aPayload = sqlite3PagerGetData(pDbPage);
  3988   3973               nextPage = get4byte(aPayload);
  3989         -            rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
         3974  +            if( eOp ){
         3975  +              memcpy(&aPayload[offset+4], pBuf, a);
         3976  +            }else{
         3977  +              memcpy(pBuf, &aPayload[offset+4], a);
         3978  +            }
  3990   3979               sqlite3PagerUnref(pDbPage);
  3991   3980               offset = 0;
  3992   3981             }
  3993   3982           }
  3994   3983           amt -= a;
  3995   3984           pBuf += a;
  3996   3985         }
................................................................................
  7381   7370   
  7382   7371   /*
  7383   7372   ** Write meta-information back into the database.  Meta[0] is
  7384   7373   ** read-only and may not be written.
  7385   7374   */
  7386   7375   int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
  7387   7376     BtShared *pBt = p->pBt;
  7388         -  unsigned char *pP1;
  7389   7377     int rc;
  7390   7378     assert( idx>=1 && idx<=15 );
  7391   7379     sqlite3BtreeEnter(p);
  7392   7380     assert( p->inTrans==TRANS_WRITE );
  7393   7381     assert( pBt->pPage1!=0 );
  7394         -  pP1 = pBt->pPage1->aData;
  7395   7382     rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  7396   7383     if( rc==SQLITE_OK ){
  7397         -    put4byte(&pP1[36 + idx*4], iMeta);
         7384  +    put4byte(&pBt->pPage1->aData[36 + idx*4], iMeta);
  7398   7385   #ifndef SQLITE_OMIT_AUTOVACUUM
  7399   7386       if( idx==BTREE_INCR_VACUUM ){
  7400   7387         assert( pBt->autoVacuum || iMeta==0 );
  7401   7388         assert( iMeta==0 || iMeta==1 );
  7402   7389         pBt->incrVacuum = (u8)iMeta;
  7403   7390       }
  7404   7391   #endif
................................................................................
  8219   8206     if( rc==SQLITE_OK ){
  8220   8207       u8 *aData = pBt->pPage1->aData;
  8221   8208       if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
  8222   8209         rc = sqlite3BtreeBeginTrans(pBtree, 2);
  8223   8210         if( rc==SQLITE_OK ){
  8224   8211           rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  8225   8212           if( rc==SQLITE_OK ){
         8213  +          aData = pBt->pPage1->aData;
  8226   8214             aData[18] = (u8)iVersion;
  8227   8215             aData[19] = (u8)iVersion;
  8228   8216           }
  8229   8217         }
  8230   8218       }
  8231   8219     }
  8232   8220   
  8233   8221     pBt->doNotUseWAL = 0;
  8234   8222     return rc;
  8235   8223   }