summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/btree.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/btree.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/btree.c34
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);
}