| | @@ -380,11 +380,11 @@ |
| 380 | 380 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 381 | 381 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 382 | 382 | */ |
| 383 | 383 | #define SQLITE_VERSION "3.15.0" |
| 384 | 384 | #define SQLITE_VERSION_NUMBER 3015000 |
| 385 | | -#define SQLITE_SOURCE_ID "2016-08-18 22:44:22 d6e3d5796c9991ca0af45ed92ce36f55efc02348" |
| 385 | +#define SQLITE_SOURCE_ID "2016-08-19 15:17:51 12d5e38d269ede27cd38a031a395915301fffe56" |
| 386 | 386 | |
| 387 | 387 | /* |
| 388 | 388 | ** CAPI3REF: Run-Time Library Version Numbers |
| 389 | 389 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 390 | 390 | ** |
| | @@ -16308,12 +16308,12 @@ |
| 16308 | 16308 | SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); |
| 16309 | 16309 | SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); |
| 16310 | 16310 | SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); |
| 16311 | 16311 | SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); |
| 16312 | 16312 | SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); |
| 16313 | | -SQLITE_PRIVATE void sqlite3Vacuum(Parse*); |
| 16314 | | -SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*); |
| 16313 | +SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*); |
| 16314 | +SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int); |
| 16315 | 16315 | SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); |
| 16316 | 16316 | SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int); |
| 16317 | 16317 | SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); |
| 16318 | 16318 | SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int); |
| 16319 | 16319 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); |
| | @@ -83421,19 +83421,18 @@ |
| 83421 | 83421 | break; |
| 83422 | 83422 | }; |
| 83423 | 83423 | #endif /* SQLITE_OMIT_PRAGMA */ |
| 83424 | 83424 | |
| 83425 | 83425 | #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) |
| 83426 | | -/* Opcode: Vacuum * * * * * |
| 83426 | +/* Opcode: Vacuum P1 * * * * |
| 83427 | 83427 | ** |
| 83428 | | -** Vacuum the entire database. This opcode will cause other virtual |
| 83429 | | -** machines to be created and run. It may not be called from within |
| 83430 | | -** a transaction. |
| 83428 | +** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more |
| 83429 | +** for an attached database. The "temp" database may not be vacuumed. |
| 83431 | 83430 | */ |
| 83432 | 83431 | case OP_Vacuum: { |
| 83433 | 83432 | assert( p->readOnly==0 ); |
| 83434 | | - rc = sqlite3RunVacuum(&p->zErrMsg, db); |
| 83433 | + rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1); |
| 83435 | 83434 | if( rc ) goto abort_due_to_error; |
| 83436 | 83435 | break; |
| 83437 | 83436 | } |
| 83438 | 83437 | #endif |
| 83439 | 83438 | |
| | @@ -98189,11 +98188,11 @@ |
| 98189 | 98188 | if( iDb<0 ){ |
| 98190 | 98189 | sqlite3ErrorMsg(pParse, "unknown database %T", pName1); |
| 98191 | 98190 | return -1; |
| 98192 | 98191 | } |
| 98193 | 98192 | }else{ |
| 98194 | | - assert( db->init.iDb==0 || db->init.busy ); |
| 98193 | + assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0); |
| 98195 | 98194 | iDb = db->init.iDb; |
| 98196 | 98195 | *pUnqual = pName1; |
| 98197 | 98196 | } |
| 98198 | 98197 | return iDb; |
| 98199 | 98198 | } |
| | @@ -99427,11 +99426,11 @@ |
| 99427 | 99426 | |
| 99428 | 99427 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 99429 | 99428 | /* Check to see if we need to create an sqlite_sequence table for |
| 99430 | 99429 | ** keeping track of autoincrement keys. |
| 99431 | 99430 | */ |
| 99432 | | - if( p->tabFlags & TF_Autoincrement ){ |
| 99431 | + if( (p->tabFlags & TF_Autoincrement)!=0 ){ |
| 99433 | 99432 | Db *pDb = &db->aDb[iDb]; |
| 99434 | 99433 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 99435 | 99434 | if( pDb->pSchema->pSeqTab==0 ){ |
| 99436 | 99435 | sqlite3NestedParse(pParse, |
| 99437 | 99436 | "CREATE TABLE %Q.sqlite_sequence(name,seq)", |
| | @@ -106699,11 +106698,13 @@ |
| 106699 | 106698 | |
| 106700 | 106699 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 106701 | 106700 | /* |
| 106702 | 106701 | ** Locate or create an AutoincInfo structure associated with table pTab |
| 106703 | 106702 | ** which is in database iDb. Return the register number for the register |
| 106704 | | -** that holds the maximum rowid. |
| 106703 | +** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT |
| 106704 | +** table. (Also return zero when doing a VACUUM since we do not want to |
| 106705 | +** update the AUTOINCREMENT counters during a VACUUM.) |
| 106705 | 106706 | ** |
| 106706 | 106707 | ** There is at most one AutoincInfo structure per table even if the |
| 106707 | 106708 | ** same table is autoincremented multiple times due to inserts within |
| 106708 | 106709 | ** triggers. A new AutoincInfo structure is created if this is the |
| 106709 | 106710 | ** first use of table pTab. On 2nd and subsequent uses, the original |
| | @@ -106722,11 +106723,13 @@ |
| 106722 | 106723 | Parse *pParse, /* Parsing context */ |
| 106723 | 106724 | int iDb, /* Index of the database holding pTab */ |
| 106724 | 106725 | Table *pTab /* The table we are writing to */ |
| 106725 | 106726 | ){ |
| 106726 | 106727 | int memId = 0; /* Register holding maximum rowid */ |
| 106727 | | - if( pTab->tabFlags & TF_Autoincrement ){ |
| 106728 | + if( (pTab->tabFlags & TF_Autoincrement)!=0 |
| 106729 | + && (pParse->db->flags & SQLITE_Vacuum)==0 |
| 106730 | + ){ |
| 106728 | 106731 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 106729 | 106732 | AutoincInfo *pInfo; |
| 106730 | 106733 | |
| 106731 | 106734 | pInfo = pToplevel->pAinc; |
| 106732 | 106735 | while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } |
| | @@ -112732,10 +112735,11 @@ |
| 112732 | 112735 | ** But because db->init.busy is set to 1, no VDBE code is generated |
| 112733 | 112736 | ** or executed. All the parser does is build the internal data |
| 112734 | 112737 | ** structures that describe the table, index, or view. |
| 112735 | 112738 | */ |
| 112736 | 112739 | int rc; |
| 112740 | + u8 saved_iDb = db->init.iDb; |
| 112737 | 112741 | sqlite3_stmt *pStmt; |
| 112738 | 112742 | TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ |
| 112739 | 112743 | |
| 112740 | 112744 | assert( db->init.busy ); |
| 112741 | 112745 | db->init.iDb = iDb; |
| | @@ -112742,11 +112746,12 @@ |
| 112742 | 112746 | db->init.newTnum = sqlite3Atoi(argv[1]); |
| 112743 | 112747 | db->init.orphanTrigger = 0; |
| 112744 | 112748 | TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); |
| 112745 | 112749 | rc = db->errCode; |
| 112746 | 112750 | assert( (rc&0xFF)==(rcp&0xFF) ); |
| 112747 | | - db->init.iDb = 0; |
| 112751 | + db->init.iDb = saved_iDb; |
| 112752 | + assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 ); |
| 112748 | 112753 | if( SQLITE_OK!=rc ){ |
| 112749 | 112754 | if( db->init.orphanTrigger ){ |
| 112750 | 112755 | assert( iDb==1 ); |
| 112751 | 112756 | }else{ |
| 112752 | 112757 | pData->rc = rc; |
| | @@ -121385,61 +121390,56 @@ |
| 121385 | 121390 | */ |
| 121386 | 121391 | /* #include "sqliteInt.h" */ |
| 121387 | 121392 | /* #include "vdbeInt.h" */ |
| 121388 | 121393 | |
| 121389 | 121394 | #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) |
| 121390 | | -/* |
| 121391 | | -** Finalize a prepared statement. If there was an error, store the |
| 121392 | | -** text of the error message in *pzErrMsg. Return the result code. |
| 121393 | | -*/ |
| 121394 | | -static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){ |
| 121395 | | - int rc; |
| 121396 | | - rc = sqlite3VdbeFinalize((Vdbe*)pStmt); |
| 121397 | | - if( rc ){ |
| 121398 | | - sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); |
| 121399 | | - } |
| 121400 | | - return rc; |
| 121401 | | -} |
| 121402 | | - |
| 121403 | | -/* |
| 121404 | | -** Execute zSql on database db. Return an error code. |
| 121395 | + |
| 121396 | +/* |
| 121397 | +** Execute zSql on database db. |
| 121398 | +** |
| 121399 | +** If zSql returns rows, then each row will have exactly one |
| 121400 | +** column. (This will only happen if zSql begins with "SELECT".) |
| 121401 | +** Take each row of result and call execSql() again recursively. |
| 121402 | +** |
| 121403 | +** The execSqlF() routine does the same thing, except it accepts |
| 121404 | +** a format string as its third argument |
| 121405 | 121405 | */ |
| 121406 | 121406 | static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ |
| 121407 | 121407 | sqlite3_stmt *pStmt; |
| 121408 | | - VVA_ONLY( int rc; ) |
| 121409 | | - if( !zSql ){ |
| 121410 | | - return SQLITE_NOMEM_BKPT; |
| 121408 | + int rc; |
| 121409 | + |
| 121410 | + /* printf("SQL: [%s]\n", zSql); fflush(stdout); */ |
| 121411 | + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
| 121412 | + if( rc!=SQLITE_OK ) return rc; |
| 121413 | + while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ |
| 121414 | + const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); |
| 121415 | + assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 ); |
| 121416 | + if( zSubSql ){ |
| 121417 | + assert( zSubSql[0]!='S' ); |
| 121418 | + rc = execSql(db, pzErrMsg, zSubSql); |
| 121419 | + if( rc!=SQLITE_OK ) break; |
| 121420 | + } |
| 121411 | 121421 | } |
| 121412 | | - if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){ |
| 121422 | + assert( rc!=SQLITE_ROW ); |
| 121423 | + if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 121424 | + if( rc ){ |
| 121413 | 121425 | sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); |
| 121414 | | - return sqlite3_errcode(db); |
| 121415 | | - } |
| 121416 | | - VVA_ONLY( rc = ) sqlite3_step(pStmt); |
| 121417 | | - assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) ); |
| 121418 | | - return vacuumFinalize(db, pStmt, pzErrMsg); |
| 121419 | | -} |
| 121420 | | - |
| 121421 | | -/* |
| 121422 | | -** Execute zSql on database db. The statement returns exactly |
| 121423 | | -** one column. Execute this as SQL on the same database. |
| 121424 | | -*/ |
| 121425 | | -static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ |
| 121426 | | - sqlite3_stmt *pStmt; |
| 121427 | | - int rc; |
| 121428 | | - |
| 121429 | | - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 121430 | | - if( rc!=SQLITE_OK ) return rc; |
| 121431 | | - |
| 121432 | | - while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 121433 | | - rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0)); |
| 121434 | | - if( rc!=SQLITE_OK ){ |
| 121435 | | - vacuumFinalize(db, pStmt, pzErrMsg); |
| 121436 | | - return rc; |
| 121437 | | - } |
| 121438 | | - } |
| 121439 | | - |
| 121440 | | - return vacuumFinalize(db, pStmt, pzErrMsg); |
| 121426 | + } |
| 121427 | + (void)sqlite3_finalize(pStmt); |
| 121428 | + return rc; |
| 121429 | +} |
| 121430 | +static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){ |
| 121431 | + char *z; |
| 121432 | + va_list ap; |
| 121433 | + int rc; |
| 121434 | + va_start(ap, zSql); |
| 121435 | + z = sqlite3VMPrintf(db, zSql, ap); |
| 121436 | + va_end(ap); |
| 121437 | + if( z==0 ) return SQLITE_NOMEM; |
| 121438 | + rc = execSql(db, pzErrMsg, z); |
| 121439 | + sqlite3DbFree(db, z); |
| 121440 | + return rc; |
| 121441 | 121441 | } |
| 121442 | 121442 | |
| 121443 | 121443 | /* |
| 121444 | 121444 | ** The VACUUM command is used to clean up the database, |
| 121445 | 121445 | ** collapse free space, etc. It is modelled after the VACUUM command |
| | @@ -121468,35 +121468,36 @@ |
| 121468 | 121468 | ** not work if other processes are attached to the original database. |
| 121469 | 121469 | ** And a power loss in between deleting the original and renaming the |
| 121470 | 121470 | ** transient would cause the database file to appear to be deleted |
| 121471 | 121471 | ** following reboot. |
| 121472 | 121472 | */ |
| 121473 | | -SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){ |
| 121473 | +SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){ |
| 121474 | 121474 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 121475 | | - if( v ){ |
| 121476 | | - sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); |
| 121477 | | - sqlite3VdbeUsesBtree(v, 0); |
| 121475 | + int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0; |
| 121476 | + if( v && (iDb>=2 || iDb==0) ){ |
| 121477 | + sqlite3VdbeAddOp1(v, OP_Vacuum, iDb); |
| 121478 | + sqlite3VdbeUsesBtree(v, iDb); |
| 121478 | 121479 | } |
| 121479 | 121480 | return; |
| 121480 | 121481 | } |
| 121481 | 121482 | |
| 121482 | 121483 | /* |
| 121483 | 121484 | ** This routine implements the OP_Vacuum opcode of the VDBE. |
| 121484 | 121485 | */ |
| 121485 | | -SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ |
| 121486 | +SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ |
| 121486 | 121487 | int rc = SQLITE_OK; /* Return code from service routines */ |
| 121487 | 121488 | Btree *pMain; /* The database being vacuumed */ |
| 121488 | 121489 | Btree *pTemp; /* The temporary database we vacuum into */ |
| 121489 | | - char *zSql = 0; /* SQL statements */ |
| 121490 | 121490 | int saved_flags; /* Saved value of the db->flags */ |
| 121491 | 121491 | int saved_nChange; /* Saved value of db->nChange */ |
| 121492 | 121492 | int saved_nTotalChange; /* Saved value of db->nTotalChange */ |
| 121493 | 121493 | u8 saved_mTrace; /* Saved trace settings */ |
| 121494 | 121494 | Db *pDb = 0; /* Database to detach at end of vacuum */ |
| 121495 | 121495 | int isMemDb; /* True if vacuuming a :memory: database */ |
| 121496 | 121496 | int nRes; /* Bytes of reserved space at the end of each page */ |
| 121497 | 121497 | int nDb; /* Number of attached databases */ |
| 121498 | + const char *zDbMain; /* Schema name of database to vacuum */ |
| 121498 | 121499 | |
| 121499 | 121500 | if( !db->autoCommit ){ |
| 121500 | 121501 | sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); |
| 121501 | 121502 | return SQLITE_ERROR; |
| 121502 | 121503 | } |
| | @@ -121510,15 +121511,17 @@ |
| 121510 | 121511 | ** disable CHECK and foreign key constraints. */ |
| 121511 | 121512 | saved_flags = db->flags; |
| 121512 | 121513 | saved_nChange = db->nChange; |
| 121513 | 121514 | saved_nTotalChange = db->nTotalChange; |
| 121514 | 121515 | saved_mTrace = db->mTrace; |
| 121515 | | - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; |
| 121516 | | - db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); |
| 121516 | + db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks |
| 121517 | + | SQLITE_PreferBuiltin | SQLITE_Vacuum); |
| 121518 | + db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows); |
| 121517 | 121519 | db->mTrace = 0; |
| 121518 | 121520 | |
| 121519 | | - pMain = db->aDb[0].pBt; |
| 121521 | + zDbMain = db->aDb[iDb].zDbSName; |
| 121522 | + pMain = db->aDb[iDb].pBt; |
| 121520 | 121523 | isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); |
| 121521 | 121524 | |
| 121522 | 121525 | /* Attach the temporary database as 'vacuum_db'. The synchronous pragma |
| 121523 | 121526 | ** can be set to 'off' for this file, as it is not recovered if a crash |
| 121524 | 121527 | ** occurs anyway. The integrity of the database is maintained by a |
| | @@ -121532,22 +121535,16 @@ |
| 121532 | 121535 | ** empty. Only the journal header is written. Apparently it takes more |
| 121533 | 121536 | ** time to parse and run the PRAGMA to turn journalling off than it does |
| 121534 | 121537 | ** to write the journal header file. |
| 121535 | 121538 | */ |
| 121536 | 121539 | nDb = db->nDb; |
| 121537 | | - if( sqlite3TempInMemory(db) ){ |
| 121538 | | - zSql = "ATTACH ':memory:' AS vacuum_db;"; |
| 121539 | | - }else{ |
| 121540 | | - zSql = "ATTACH '' AS vacuum_db;"; |
| 121541 | | - } |
| 121542 | | - rc = execSql(db, pzErrMsg, zSql); |
| 121543 | | - if( db->nDb>nDb ){ |
| 121544 | | - pDb = &db->aDb[db->nDb-1]; |
| 121545 | | - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); |
| 121546 | | - } |
| 121540 | + rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db"); |
| 121547 | 121541 | if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121548 | | - pTemp = db->aDb[db->nDb-1].pBt; |
| 121542 | + assert( (db->nDb-1)==nDb ); |
| 121543 | + pDb = &db->aDb[nDb]; |
| 121544 | + assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); |
| 121545 | + pTemp = pDb->pBt; |
| 121549 | 121546 | |
| 121550 | 121547 | /* The call to execSql() to attach the temp database has left the file |
| 121551 | 121548 | ** locked (as there was more than one active statement when the transaction |
| 121552 | 121549 | ** to read the schema was concluded. Unlock it here so that this doesn't |
| 121553 | 121550 | ** cause problems for the call to BtreeSetPageSize() below. */ |
| | @@ -121564,20 +121561,19 @@ |
| 121564 | 121561 | sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); |
| 121565 | 121562 | if( nKey ) db->nextPagesize = 0; |
| 121566 | 121563 | } |
| 121567 | 121564 | #endif |
| 121568 | 121565 | |
| 121569 | | - sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size); |
| 121566 | + sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); |
| 121570 | 121567 | sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); |
| 121571 | | - rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); |
| 121572 | | - if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121568 | + sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF); |
| 121573 | 121569 | |
| 121574 | 121570 | /* Begin a transaction and take an exclusive lock on the main database |
| 121575 | 121571 | ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, |
| 121576 | 121572 | ** to ensure that we do not try to change the page-size on a WAL database. |
| 121577 | 121573 | */ |
| 121578 | | - rc = execSql(db, pzErrMsg, "BEGIN;"); |
| 121574 | + rc = execSql(db, pzErrMsg, "BEGIN"); |
| 121579 | 121575 | if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121580 | 121576 | rc = sqlite3BtreeBeginTrans(pMain, 2); |
| 121581 | 121577 | if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121582 | 121578 | |
| 121583 | 121579 | /* Do not attempt to change the page size for a WAL database */ |
| | @@ -121600,68 +121596,52 @@ |
| 121600 | 121596 | #endif |
| 121601 | 121597 | |
| 121602 | 121598 | /* Query the schema of the main database. Create a mirror schema |
| 121603 | 121599 | ** in the temporary database. |
| 121604 | 121600 | */ |
| 121605 | | - rc = execExecSql(db, pzErrMsg, |
| 121606 | | - "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) " |
| 121607 | | - " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'" |
| 121608 | | - " AND coalesce(rootpage,1)>0" |
| 121601 | + db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */ |
| 121602 | + rc = execSqlF(db, pzErrMsg, |
| 121603 | + "SELECT sql FROM \"%w\".sqlite_master" |
| 121604 | + " WHERE type='table'AND name<>'sqlite_sequence'" |
| 121605 | + " AND coalesce(rootpage,1)>0", |
| 121606 | + zDbMain |
| 121607 | + ); |
| 121608 | + if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121609 | + rc = execSqlF(db, pzErrMsg, |
| 121610 | + "SELECT sql FROM \"%w\".sqlite_master" |
| 121611 | + " WHERE type='index' AND length(sql)>10", |
| 121612 | + zDbMain |
| 121609 | 121613 | ); |
| 121610 | 121614 | if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121611 | | - rc = execExecSql(db, pzErrMsg, |
| 121612 | | - "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)" |
| 121613 | | - " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' "); |
| 121614 | | - if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121615 | | - rc = execExecSql(db, pzErrMsg, |
| 121616 | | - "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) " |
| 121617 | | - " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"); |
| 121618 | | - if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121615 | + db->init.iDb = 0; |
| 121619 | 121616 | |
| 121620 | 121617 | /* Loop through the tables in the main database. For each, do |
| 121621 | 121618 | ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy |
| 121622 | 121619 | ** the contents to the temporary database. |
| 121623 | 121620 | */ |
| 121624 | | - assert( (db->flags & SQLITE_Vacuum)==0 ); |
| 121625 | | - db->flags |= SQLITE_Vacuum; |
| 121626 | | - rc = execExecSql(db, pzErrMsg, |
| 121627 | | - "SELECT 'INSERT INTO vacuum_db.' || quote(name) " |
| 121628 | | - "|| ' SELECT * FROM main.' || quote(name) || ';'" |
| 121629 | | - "FROM main.sqlite_master " |
| 121630 | | - "WHERE type = 'table' AND name!='sqlite_sequence' " |
| 121631 | | - " AND coalesce(rootpage,1)>0" |
| 121621 | + rc = execSqlF(db, pzErrMsg, |
| 121622 | + "SELECT'INSERT INTO vacuum_db.'||quote(name)" |
| 121623 | + "||' SELECT*FROM\"%w\".'||quote(name)" |
| 121624 | + "FROM vacuum_db.sqlite_master " |
| 121625 | + "WHERE type='table'AND coalesce(rootpage,1)>0", |
| 121626 | + zDbMain |
| 121632 | 121627 | ); |
| 121633 | 121628 | assert( (db->flags & SQLITE_Vacuum)!=0 ); |
| 121634 | 121629 | db->flags &= ~SQLITE_Vacuum; |
| 121635 | 121630 | if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121636 | | - |
| 121637 | | - /* Copy over the sequence table |
| 121638 | | - */ |
| 121639 | | - rc = execExecSql(db, pzErrMsg, |
| 121640 | | - "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' " |
| 121641 | | - "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' " |
| 121642 | | - ); |
| 121643 | | - if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121644 | | - rc = execExecSql(db, pzErrMsg, |
| 121645 | | - "SELECT 'INSERT INTO vacuum_db.' || quote(name) " |
| 121646 | | - "|| ' SELECT * FROM main.' || quote(name) || ';' " |
| 121647 | | - "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';" |
| 121648 | | - ); |
| 121649 | | - if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 121650 | | - |
| 121651 | 121631 | |
| 121652 | 121632 | /* Copy the triggers, views, and virtual tables from the main database |
| 121653 | 121633 | ** over to the temporary database. None of these objects has any |
| 121654 | 121634 | ** associated storage, so all we have to do is copy their entries |
| 121655 | 121635 | ** from the SQLITE_MASTER table. |
| 121656 | 121636 | */ |
| 121657 | | - rc = execSql(db, pzErrMsg, |
| 121658 | | - "INSERT INTO vacuum_db.sqlite_master " |
| 121659 | | - " SELECT type, name, tbl_name, rootpage, sql" |
| 121660 | | - " FROM main.sqlite_master" |
| 121661 | | - " WHERE type='view' OR type='trigger'" |
| 121662 | | - " OR (type='table' AND rootpage=0)" |
| 121637 | + rc = execSqlF(db, pzErrMsg, |
| 121638 | + "INSERT INTO vacuum_db.sqlite_master" |
| 121639 | + " SELECT*FROM \"%w\".sqlite_master" |
| 121640 | + " WHERE type IN('view','trigger')" |
| 121641 | + " OR(type='table'AND rootpage=0)", |
| 121642 | + zDbMain |
| 121663 | 121643 | ); |
| 121664 | 121644 | if( rc ) goto end_of_vacuum; |
| 121665 | 121645 | |
| 121666 | 121646 | /* At this point, there is a write transaction open on both the |
| 121667 | 121647 | ** vacuum database and the main database. Assuming no error occurs, |
| | @@ -121711,10 +121691,11 @@ |
| 121711 | 121691 | assert( rc==SQLITE_OK ); |
| 121712 | 121692 | rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1); |
| 121713 | 121693 | |
| 121714 | 121694 | end_of_vacuum: |
| 121715 | 121695 | /* Restore the original value of db->flags */ |
| 121696 | + db->init.iDb = 0; |
| 121716 | 121697 | db->flags = saved_flags; |
| 121717 | 121698 | db->nChange = saved_nChange; |
| 121718 | 121699 | db->nTotalChange = saved_nTotalChange; |
| 121719 | 121700 | db->mTrace = saved_mTrace; |
| 121720 | 121701 | sqlite3BtreeSetPageSize(pMain, -1, -1, 1); |
| | @@ -134715,12 +134696,14 @@ |
| 134715 | 134696 | break; |
| 134716 | 134697 | case 213: /* cmd ::= DROP INDEX ifexists fullname */ |
| 134717 | 134698 | {sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);} |
| 134718 | 134699 | break; |
| 134719 | 134700 | case 214: /* cmd ::= VACUUM */ |
| 134720 | | - case 215: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==215); |
| 134721 | | -{sqlite3Vacuum(pParse);} |
| 134701 | +{sqlite3Vacuum(pParse,0);} |
| 134702 | + break; |
| 134703 | + case 215: /* cmd ::= VACUUM nm */ |
| 134704 | +{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);} |
| 134722 | 134705 | break; |
| 134723 | 134706 | case 216: /* cmd ::= PRAGMA nm dbnm */ |
| 134724 | 134707 | {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} |
| 134725 | 134708 | break; |
| 134726 | 134709 | case 217: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ |
| 134727 | 134710 | |