diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/btree.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/src/btree.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/btree.c b/ext/pdo_sqlite/sqlite/src/btree.c index c1d9844f5b..3df2a3b01d 100644 --- a/ext/pdo_sqlite/sqlite/src/btree.c +++ b/ext/pdo_sqlite/sqlite/src/btree.c @@ -1396,13 +1396,20 @@ static void zeroPage(MemPage *pPage, int flags){ /* ** Get a page from the pager. Initialize the MemPage.pBt and ** MemPage.aData elements if needed. +** +** If the noContent flag is set, it means that we do not care about +** the content of the page at this time. So do not go to the disk +** to fetch the content. Just fill in the content with zeros for now. +** If in the future we call sqlite3PagerWrite() on this page, that +** means we have started to be concerned about content and the disk +** read should occur at that point. */ -static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage, int clrFlag){ +static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage, int noContent){ int rc; MemPage *pPage; DbPage *pDbPage; - rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, clrFlag); + rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent); if( rc ) return rc; pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage); pPage->aData = sqlite3PagerGetData(pDbPage); @@ -1411,9 +1418,6 @@ static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage, int clrFlag){ pPage->pgno = pgno; pPage->hdrOffset = pPage->pgno==1 ? 100 : 0; *ppPage = pPage; - if( clrFlag ){ - sqlite3PagerDontRollback(pPage->pDbPage); - } return SQLITE_OK; } @@ -3830,6 +3834,7 @@ static int allocateBtreePage( put4byte(&aData[4], k-1); rc = getPage(pBt, *pPgno, ppPage, 1); if( rc==SQLITE_OK ){ + sqlite3PagerDontRollback((*ppPage)->pDbPage); rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ releasePage(*ppPage); @@ -3948,7 +3953,7 @@ static int freePage(MemPage *pPage){ put4byte(&pTrunk->aData[4], k+1); put4byte(&pTrunk->aData[8+k*4], pPage->pgno); #ifndef SQLITE_SECURE_DELETE - sqlite3PagerDontWrite(pBt->pPager, pPage->pgno); + sqlite3PagerDontWrite(pPage->pDbPage); #endif } TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); @@ -3982,7 +3987,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ if( ovflPgno==0 || ovflPgno>sqlite3PagerPagecount(pBt->pPager) ){ return SQLITE_CORRUPT_BKPT; } - rc = getPage(pBt, ovflPgno, &pOvfl, 0); + rc = getPage(pBt, ovflPgno, &pOvfl, nOvfl==0); if( rc ) return rc; if( nOvfl ){ ovflPgno = get4byte(pOvfl->aData); @@ -6561,18 +6566,31 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ rc = sqlite3PagerOverwrite(pBtTo->pPager, i, sqlite3PagerGetData(pDbPage)); sqlite3PagerUnref(pDbPage); } + + /* If the file is shrinking, journal the pages that are being truncated + ** so that they can be rolled back if the commit fails. + */ for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){ DbPage *pDbPage; if( i==iSkip ) continue; rc = sqlite3PagerGet(pBtTo->pPager, i, &pDbPage); if( rc ) break; rc = sqlite3PagerWrite(pDbPage); + sqlite3PagerDontWrite(pDbPage); + /* Yeah. It seems wierd to call DontWrite() right after Write(). But + ** that is because the names of those procedures do not exactly + ** represent what they do. Write() really means "put this page in the + ** rollback journal and mark it as dirty so that it will be written + ** to the database file later." DontWrite() undoes the second part of + ** that and prevents the page from being written to the database. The + ** page is still on the rollback journal, though. And that is the whole + ** point of this loop: to put pages on the rollback journal. */ sqlite3PagerUnref(pDbPage); - sqlite3PagerDontWrite(pBtTo->pPager, i); } if( !rc && nPage<nToPage ){ rc = sqlite3PagerTruncate(pBtTo->pPager, nPage); } + if( rc ){ sqlite3BtreeRollback(pTo); } |
