| Index: third_party/sqlite/src/src/vacuum.c | 
| diff --git a/third_party/sqlite/src/src/vacuum.c b/third_party/sqlite/src/src/vacuum.c | 
| index 5a4ed32052c52ce6b0a24f70926440e77637c4b1..4d0c0976a182a01a0195b047dc5289bca1095cb4 100644 | 
| --- a/third_party/sqlite/src/src/vacuum.c | 
| +++ b/third_party/sqlite/src/src/vacuum.c | 
| @@ -45,7 +45,7 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ | 
| return sqlite3_errcode(db); | 
| } | 
| VVA_ONLY( rc = ) sqlite3_step(pStmt); | 
| -  assert( rc!=SQLITE_ROW ); | 
| +  assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) ); | 
| return vacuumFinalize(db, pStmt, pzErrMsg); | 
| } | 
|  | 
| @@ -72,19 +72,40 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ | 
| } | 
|  | 
| /* | 
| -** The non-standard VACUUM command is used to clean up the database, | 
| +** The VACUUM command is used to clean up the database, | 
| ** collapse free space, etc.  It is modelled after the VACUUM command | 
| -** in PostgreSQL. | 
| +** in PostgreSQL.  The VACUUM command works as follows: | 
| ** | 
| -** In version 1.0.x of SQLite, the VACUUM command would call | 
| -** gdbm_reorganize() on all the database tables.  But beginning | 
| -** with 2.0.0, SQLite no longer uses GDBM so this command has | 
| -** become a no-op. | 
| +**   (1)  Create a new transient database file | 
| +**   (2)  Copy all content from the database being vacuumed into | 
| +**        the new transient database file | 
| +**   (3)  Copy content from the transient database back into the | 
| +**        original database. | 
| +** | 
| +** The transient database requires temporary disk space approximately | 
| +** equal to the size of the original database.  The copy operation of | 
| +** step (3) requires additional temporary disk space approximately equal | 
| +** to the size of the original database for the rollback journal. | 
| +** Hence, temporary disk space that is approximately 2x the size of the | 
| +** original database is required.  Every page of the database is written | 
| +** approximately 3 times:  Once for step (2) and twice for step (3). | 
| +** Two writes per page are required in step (3) because the original | 
| +** database content must be written into the rollback journal prior to | 
| +** overwriting the database with the vacuumed content. | 
| +** | 
| +** Only 1x temporary space and only 1x writes would be required if | 
| +** the copy of step (3) were replace by deleting the original database | 
| +** and renaming the transient database as the original.  But that will | 
| +** not work if other processes are attached to the original database. | 
| +** And a power loss in between deleting the original and renaming the | 
| +** transient would cause the database file to appear to be deleted | 
| +** following reboot. | 
| */ | 
| void sqlite3Vacuum(Parse *pParse){ | 
| Vdbe *v = sqlite3GetVdbe(pParse); | 
| if( v ){ | 
| sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); | 
| +    sqlite3VdbeUsesBtree(v, 0); | 
| } | 
| return; | 
| } | 
| @@ -110,7 +131,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ | 
| sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); | 
| return SQLITE_ERROR; | 
| } | 
| -  if( db->activeVdbeCnt>1 ){ | 
| +  if( db->nVdbeActive>1 ){ | 
| sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); | 
| return SQLITE_ERROR; | 
| } | 
| @@ -176,6 +197,18 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ | 
| } | 
| #endif | 
|  | 
| +  rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); | 
| +  if( rc!=SQLITE_OK ) goto end_of_vacuum; | 
| + | 
| +  /* Begin a transaction and take an exclusive lock on the main database | 
| +  ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, | 
| +  ** to ensure that we do not try to change the page-size on a WAL database. | 
| +  */ | 
| +  rc = execSql(db, pzErrMsg, "BEGIN;"); | 
| +  if( rc!=SQLITE_OK ) goto end_of_vacuum; | 
| +  rc = sqlite3BtreeBeginTrans(pMain, 2); | 
| +  if( rc!=SQLITE_OK ) goto end_of_vacuum; | 
| + | 
| /* Do not attempt to change the page size for a WAL database */ | 
| if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) | 
| ==PAGER_JOURNALMODE_WAL ){ | 
| @@ -189,27 +222,19 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ | 
| rc = SQLITE_NOMEM; | 
| goto end_of_vacuum; | 
| } | 
| -  rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); | 
| -  if( rc!=SQLITE_OK ){ | 
| -    goto end_of_vacuum; | 
| -  } | 
|  | 
| #ifndef SQLITE_OMIT_AUTOVACUUM | 
| sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : | 
| sqlite3BtreeGetAutoVacuum(pMain)); | 
| #endif | 
|  | 
| -  /* Begin a transaction */ | 
| -  rc = execSql(db, pzErrMsg, "BEGIN EXCLUSIVE;"); | 
| -  if( rc!=SQLITE_OK ) goto end_of_vacuum; | 
| - | 
| /* Query the schema of the main database. Create a mirror schema | 
| ** in the temporary database. | 
| */ | 
| rc = execExecSql(db, pzErrMsg, | 
| "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) " | 
| "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'" | 
| -      "   AND rootpage>0" | 
| +      "   AND coalesce(rootpage,1)>0" | 
| ); | 
| if( rc!=SQLITE_OK ) goto end_of_vacuum; | 
| rc = execExecSql(db, pzErrMsg, | 
| @@ -230,7 +255,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ | 
| "|| ' SELECT * FROM main.' || quote(name) || ';'" | 
| "FROM main.sqlite_master " | 
| "WHERE type = 'table' AND name!='sqlite_sequence' " | 
| -      "  AND rootpage>0" | 
| +      "  AND coalesce(rootpage,1)>0" | 
| ); | 
| if( rc!=SQLITE_OK ) goto end_of_vacuum; | 
|  | 
| @@ -263,13 +288,11 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ | 
| ); | 
| if( rc ) goto end_of_vacuum; | 
|  | 
| -  /* At this point, unless the main db was completely empty, there is now a | 
| -  ** transaction open on the vacuum database, but not on the main database. | 
| -  ** Open a btree level transaction on the main database. This allows a | 
| -  ** call to sqlite3BtreeCopyFile(). The main database btree level | 
| -  ** transaction is then committed, so the SQL level never knows it was | 
| -  ** opened for writing. This way, the SQL transaction used to create the | 
| -  ** temporary database never needs to be committed. | 
| +  /* At this point, there is a write transaction open on both the | 
| +  ** vacuum database and the main database. Assuming no error occurs, | 
| +  ** both transactions are closed by this block - the main database | 
| +  ** transaction by sqlite3BtreeCopyFile() and the other by an explicit | 
| +  ** call to sqlite3BtreeCommit(). | 
| */ | 
| { | 
| u32 meta; | 
| @@ -286,6 +309,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ | 
| BTREE_DEFAULT_CACHE_SIZE, 0,  /* Preserve the default page cache size */ | 
| BTREE_TEXT_ENCODING,      0,  /* Preserve the text encoding */ | 
| BTREE_USER_VERSION,       0,  /* Preserve the user version */ | 
| +       BTREE_APPLICATION_ID,     0,  /* Preserve the application id */ | 
| }; | 
|  | 
| assert( 1==sqlite3BtreeIsInTrans(pTemp) ); | 
| @@ -337,7 +361,7 @@ end_of_vacuum: | 
|  | 
| /* This both clears the schemas and reduces the size of the db->aDb[] | 
| ** array. */ | 
| -  sqlite3ResetInternalSchema(db, -1); | 
| +  sqlite3ResetAllSchemasOfConnection(db); | 
|  | 
| return rc; | 
| } | 
|  |