Index: third_party/sqlite/src/src/backup.c |
diff --git a/third_party/sqlite/src/src/backup.c b/third_party/sqlite/src/src/backup.c |
index 1c282242d7a578822602ab6726409e7acac6fe71..165144d9657454b2dd2cd10727b423e3d1cea016 100644 |
--- a/third_party/sqlite/src/src/backup.c |
+++ b/third_party/sqlite/src/src/backup.c |
@@ -83,22 +83,16 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ |
int i = sqlite3FindDbName(pDb, zDb); |
if( i==1 ){ |
- Parse *pParse; |
+ Parse sParse; |
int rc = 0; |
- pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse)); |
- if( pParse==0 ){ |
- sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory"); |
- rc = SQLITE_NOMEM; |
- }else{ |
- pParse->db = pDb; |
- if( sqlite3OpenTempDatabase(pParse) ){ |
- sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); |
- rc = SQLITE_ERROR; |
- } |
- sqlite3DbFree(pErrorDb, pParse->zErrMsg); |
- sqlite3ParserReset(pParse); |
- sqlite3StackFree(pErrorDb, pParse); |
+ memset(&sParse, 0, sizeof(sParse)); |
+ sParse.db = pDb; |
+ if( sqlite3OpenTempDatabase(&sParse) ){ |
+ sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); |
+ rc = SQLITE_ERROR; |
} |
+ sqlite3DbFree(pErrorDb, sParse.zErrMsg); |
+ sqlite3ParserReset(&sParse); |
if( rc ){ |
return 0; |
} |
@@ -182,7 +176,7 @@ sqlite3_backup *sqlite3_backup_init( |
** sqlite3_backup_finish(). */ |
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); |
if( !p ){ |
- sqlite3Error(pDestDb, SQLITE_NOMEM); |
+ sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); |
} |
} |
@@ -196,7 +190,6 @@ sqlite3_backup *sqlite3_backup_init( |
p->isAttached = 0; |
if( 0==p->pSrc || 0==p->pDest |
- || setDestPgsz(p)==SQLITE_NOMEM |
|| checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK |
){ |
/* One (or both) of the named databases did not exist or an OOM |
@@ -384,14 +377,6 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ |
rc = SQLITE_OK; |
} |
- /* Lock the destination database, if it is not locked already. */ |
- if( SQLITE_OK==rc && p->bDestLocked==0 |
- && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) |
- ){ |
- p->bDestLocked = 1; |
- sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); |
- } |
- |
/* If there is no open read-transaction on the source database, open |
** one now. If a transaction is opened here, then it will be closed |
** before this function exits. |
@@ -401,6 +386,24 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ |
bCloseTrans = 1; |
} |
+ /* If the destination database has not yet been locked (i.e. if this |
+ ** is the first call to backup_step() for the current backup operation), |
+ ** try to set its page size to the same as the source database. This |
+ ** is especially important on ZipVFS systems, as in that case it is |
+ ** not possible to create a database file that uses one page size by |
+ ** writing to it with another. */ |
+ if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){ |
+ rc = SQLITE_NOMEM; |
+ } |
+ |
+ /* Lock the destination database, if it is not locked already. */ |
+ if( SQLITE_OK==rc && p->bDestLocked==0 |
+ && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) |
+ ){ |
+ p->bDestLocked = 1; |
+ sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); |
+ } |
+ |
/* Do not allow backup if the destination database is in WAL mode |
** and the page sizes are different between source and destination */ |
pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); |
@@ -581,7 +584,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ |
} |
if( rc==SQLITE_IOERR_NOMEM ){ |
- rc = SQLITE_NOMEM; |
+ rc = SQLITE_NOMEM_BKPT; |
} |
p->rc = rc; |
} |
@@ -777,10 +780,10 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ |
** sqlite3_backup_step(), we can guarantee that the copy finishes |
** within a single call (unless an error occurs). The assert() statement |
** checks this assumption - (p->rc) should be set to either SQLITE_DONE |
- ** or an error code. |
- */ |
+ ** or an error code. */ |
sqlite3_backup_step(&b, 0x7FFFFFFF); |
assert( b.rc!=SQLITE_OK ); |
+ |
rc = sqlite3_backup_finish(&b); |
if( rc==SQLITE_OK ){ |
pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; |