mirror of https://github.com/sqlite/sqlite
Merge recent enhancements from trunk.
FossilOrigin-Name: b17872363b60edab05a5d382a44038aad91e4d9f
This commit is contained in:
commit
b684fd5c4a
29
manifest
29
manifest
|
@ -1,5 +1,5 @@
|
||||||
C Fix\sa\sSQL\sNULL\shandling\sbug\sin\sthe\svector\sIN\soperator\scode\sgeneration.
|
C Merge\srecent\senhancements\sfrom\strunk.
|
||||||
D 2016-08-18T19:04:57.401
|
D 2016-08-19T15:41:24.228
|
||||||
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
|
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
|
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
|
||||||
|
@ -331,7 +331,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||||
F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46
|
F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46
|
||||||
F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da
|
F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da
|
||||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||||
F src/build.c c38fd92a8d886a5b9397267bf63b76ebad05c4d5
|
F src/build.c d32cacbb59a403b68e1c2ec962ca31b6f3aad4fc
|
||||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||||
F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
|
F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
|
||||||
|
@ -346,7 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
|
||||||
F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36
|
F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36
|
||||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||||
F src/insert.c d5cd8315c0577e86e17dda9239b45cffa81022c0
|
F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30
|
||||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||||
F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec
|
F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec
|
||||||
F src/main.c 8dc7adfeace35ee1f4c489b503ee8fe6bc1fa802
|
F src/main.c 8dc7adfeace35ee1f4c489b503ee8fe6bc1fa802
|
||||||
|
@ -373,23 +373,23 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0
|
||||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||||
F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e
|
F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e
|
||||||
F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d
|
F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d
|
||||||
F src/parse.y d240b1518fa9c5cb02b222e1fac8e07d950c9ed9
|
F src/parse.y 3d02d64f333c4371c4f08fbd79a64964fa27b576
|
||||||
F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df
|
F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df
|
||||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||||
F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812
|
F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812
|
||||||
F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44
|
F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44
|
||||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||||
F src/prepare.c a668988f324961397305b8352cf6bd87776fb347
|
F src/prepare.c 0fcf16eaacc90c1059055519a76b75b516a59a88
|
||||||
F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
|
F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
|
||||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||||
F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219
|
F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219
|
||||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||||
F src/select.c 3a5ddce5d3773c42e4bd96ee93e758c22cbc59ae
|
F src/select.c cf90abce32567023c940ecabf5707c4714c61c92
|
||||||
F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7
|
F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7
|
||||||
F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99
|
F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||||
F src/sqliteInt.h f4079dcc83ec216d34531792626206a1a35463bc
|
F src/sqliteInt.h 02b7f4bd9f945fbc46b05f7914b9c43d89517c59
|
||||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||||
|
@ -449,8 +449,8 @@ F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc
|
||||||
F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802
|
F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802
|
||||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||||
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
|
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
|
||||||
F src/vacuum.c f6f10c88f8af5feb6b3632e5e4133e4482819c4f
|
F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3
|
||||||
F src/vdbe.c 9a1c5a2d1980ca6a111ce8649e06ed8c790ee1fc
|
F src/vdbe.c 766d363ef6520c671eef165098a24c0c6ef36d89
|
||||||
F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10
|
F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10
|
||||||
F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d
|
F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d
|
||||||
F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3
|
F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3
|
||||||
|
@ -655,7 +655,7 @@ F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
|
||||||
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
||||||
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
||||||
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
|
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
|
||||||
F test/e_vacuum.test 120f29ea56bdce4d43279527ece894ab5d1729d3
|
F test/e_vacuum.test 9e5e47e4059a779c777f47e0f560fc82c99336df
|
||||||
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
||||||
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
||||||
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
||||||
|
@ -1334,6 +1334,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
|
||||||
F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
|
F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
|
||||||
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
|
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
|
||||||
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||||
|
F test/vacuum5.test 99d4a0629252f9ef2fc642caefe92436a744db3a
|
||||||
F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764
|
F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764
|
||||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||||
|
@ -1517,7 +1518,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 3b27a5da100037f75a4efc15e0354a6aa94194f8
|
P 936146b12e27784f15a68fe65732c6d92c3a12f3 083f9e6270fa4faa402b91231271da4f3915c79f
|
||||||
R cb7673431cbb14ee2064b1a631b51486
|
R b0cf551e47740f01d348f132bf9f7791
|
||||||
U drh
|
U drh
|
||||||
Z e68c3ca3548a25a2524e065bf2465c19
|
Z 4f11e98ced958b5a8510961832e75233
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
936146b12e27784f15a68fe65732c6d92c3a12f3
|
b17872363b60edab05a5d382a44038aad91e4d9f
|
|
@ -773,7 +773,7 @@ int sqlite3TwoPartName(
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
assert( db->init.iDb==0 || db->init.busy );
|
assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
|
||||||
iDb = db->init.iDb;
|
iDb = db->init.iDb;
|
||||||
*pUnqual = pName1;
|
*pUnqual = pName1;
|
||||||
}
|
}
|
||||||
|
@ -2011,7 +2011,7 @@ void sqlite3EndTable(
|
||||||
/* Check to see if we need to create an sqlite_sequence table for
|
/* Check to see if we need to create an sqlite_sequence table for
|
||||||
** keeping track of autoincrement keys.
|
** keeping track of autoincrement keys.
|
||||||
*/
|
*/
|
||||||
if( p->tabFlags & TF_Autoincrement ){
|
if( (p->tabFlags & TF_Autoincrement)!=0 ){
|
||||||
Db *pDb = &db->aDb[iDb];
|
Db *pDb = &db->aDb[iDb];
|
||||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||||
if( pDb->pSchema->pSeqTab==0 ){
|
if( pDb->pSchema->pSeqTab==0 ){
|
||||||
|
|
|
@ -200,7 +200,9 @@ static int readsTable(Parse *p, int iDb, Table *pTab){
|
||||||
/*
|
/*
|
||||||
** Locate or create an AutoincInfo structure associated with table pTab
|
** Locate or create an AutoincInfo structure associated with table pTab
|
||||||
** which is in database iDb. Return the register number for the register
|
** which is in database iDb. Return the register number for the register
|
||||||
** that holds the maximum rowid.
|
** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT
|
||||||
|
** table. (Also return zero when doing a VACUUM since we do not want to
|
||||||
|
** update the AUTOINCREMENT counters during a VACUUM.)
|
||||||
**
|
**
|
||||||
** There is at most one AutoincInfo structure per table even if the
|
** There is at most one AutoincInfo structure per table even if the
|
||||||
** same table is autoincremented multiple times due to inserts within
|
** same table is autoincremented multiple times due to inserts within
|
||||||
|
@ -223,7 +225,9 @@ static int autoIncBegin(
|
||||||
Table *pTab /* The table we are writing to */
|
Table *pTab /* The table we are writing to */
|
||||||
){
|
){
|
||||||
int memId = 0; /* Register holding maximum rowid */
|
int memId = 0; /* Register holding maximum rowid */
|
||||||
if( pTab->tabFlags & TF_Autoincrement ){
|
if( (pTab->tabFlags & TF_Autoincrement)!=0
|
||||||
|
&& (pParse->db->flags & SQLITE_Vacuum)==0
|
||||||
|
){
|
||||||
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
||||||
AutoincInfo *pInfo;
|
AutoincInfo *pInfo;
|
||||||
|
|
||||||
|
|
|
@ -1293,8 +1293,8 @@ cmd ::= DROP INDEX ifexists(E) fullname(X). {sqlite3DropIndex(pParse, X, E);}
|
||||||
//
|
//
|
||||||
%ifndef SQLITE_OMIT_VACUUM
|
%ifndef SQLITE_OMIT_VACUUM
|
||||||
%ifndef SQLITE_OMIT_ATTACH
|
%ifndef SQLITE_OMIT_ATTACH
|
||||||
cmd ::= VACUUM. {sqlite3Vacuum(pParse);}
|
cmd ::= VACUUM. {sqlite3Vacuum(pParse,0);}
|
||||||
cmd ::= VACUUM nm. {sqlite3Vacuum(pParse);}
|
cmd ::= VACUUM nm(X). {sqlite3Vacuum(pParse,&X);}
|
||||||
%endif SQLITE_OMIT_ATTACH
|
%endif SQLITE_OMIT_ATTACH
|
||||||
%endif SQLITE_OMIT_VACUUM
|
%endif SQLITE_OMIT_VACUUM
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||||
** structures that describe the table, index, or view.
|
** structures that describe the table, index, or view.
|
||||||
*/
|
*/
|
||||||
int rc;
|
int rc;
|
||||||
|
u8 saved_iDb = db->init.iDb;
|
||||||
sqlite3_stmt *pStmt;
|
sqlite3_stmt *pStmt;
|
||||||
TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
|
TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
|
||||||
|
|
||||||
|
@ -83,7 +84,8 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||||
TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
|
TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
|
||||||
rc = db->errCode;
|
rc = db->errCode;
|
||||||
assert( (rc&0xFF)==(rcp&0xFF) );
|
assert( (rc&0xFF)==(rcp&0xFF) );
|
||||||
db->init.iDb = 0;
|
db->init.iDb = saved_iDb;
|
||||||
|
assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
|
||||||
if( SQLITE_OK!=rc ){
|
if( SQLITE_OK!=rc ){
|
||||||
if( db->init.orphanTrigger ){
|
if( db->init.orphanTrigger ){
|
||||||
assert( iDb==1 );
|
assert( iDb==1 );
|
||||||
|
|
|
@ -1441,7 +1441,7 @@ static const char *columnTypeImpl(
|
||||||
zOrigTab = pTab->zName;
|
zOrigTab = pTab->zName;
|
||||||
if( pNC->pParse ){
|
if( pNC->pParse ){
|
||||||
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
|
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
|
||||||
zOrigDb = pNC->pParse->db->aDb[iDb].zName;
|
zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( iCol<0 ){
|
if( iCol<0 ){
|
||||||
|
|
|
@ -3703,8 +3703,8 @@ Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *);
|
||||||
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
|
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
|
||||||
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
|
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
|
||||||
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
|
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
|
||||||
void sqlite3Vacuum(Parse*);
|
void sqlite3Vacuum(Parse*,Token*);
|
||||||
int sqlite3RunVacuum(char**, sqlite3*);
|
int sqlite3RunVacuum(char**, sqlite3*, int);
|
||||||
char *sqlite3NameFromToken(sqlite3*, Token*);
|
char *sqlite3NameFromToken(sqlite3*, Token*);
|
||||||
int sqlite3ExprCompare(Expr*, Expr*, int);
|
int sqlite3ExprCompare(Expr*, Expr*, int);
|
||||||
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
|
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
|
||||||
|
|
186
src/vacuum.c
186
src/vacuum.c
|
@ -18,57 +18,52 @@
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
|
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
|
||||||
/*
|
|
||||||
** Finalize a prepared statement. If there was an error, store the
|
|
||||||
** text of the error message in *pzErrMsg. Return the result code.
|
|
||||||
*/
|
|
||||||
static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
|
|
||||||
int rc;
|
|
||||||
rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
|
|
||||||
if( rc ){
|
|
||||||
sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Execute zSql on database db. Return an error code.
|
** Execute zSql on database db.
|
||||||
|
**
|
||||||
|
** If zSql returns rows, then each row will have exactly one
|
||||||
|
** column. (This will only happen if zSql begins with "SELECT".)
|
||||||
|
** Take each row of result and call execSql() again recursively.
|
||||||
|
**
|
||||||
|
** The execSqlF() routine does the same thing, except it accepts
|
||||||
|
** a format string as its third argument
|
||||||
*/
|
*/
|
||||||
static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
|
static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
|
||||||
sqlite3_stmt *pStmt;
|
|
||||||
VVA_ONLY( int rc; )
|
|
||||||
if( !zSql ){
|
|
||||||
return SQLITE_NOMEM_BKPT;
|
|
||||||
}
|
|
||||||
if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
|
|
||||||
sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
|
|
||||||
return sqlite3_errcode(db);
|
|
||||||
}
|
|
||||||
VVA_ONLY( rc = ) sqlite3_step(pStmt);
|
|
||||||
assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) );
|
|
||||||
return vacuumFinalize(db, pStmt, pzErrMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Execute zSql on database db. The statement returns exactly
|
|
||||||
** one column. Execute this as SQL on the same database.
|
|
||||||
*/
|
|
||||||
static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
|
|
||||||
sqlite3_stmt *pStmt;
|
sqlite3_stmt *pStmt;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
|
/* printf("SQL: [%s]\n", zSql); fflush(stdout); */
|
||||||
|
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
|
||||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
|
||||||
rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
|
assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
|
||||||
if( rc!=SQLITE_OK ){
|
if( zSubSql ){
|
||||||
vacuumFinalize(db, pStmt, pzErrMsg);
|
assert( zSubSql[0]!='S' );
|
||||||
return rc;
|
rc = execSql(db, pzErrMsg, zSubSql);
|
||||||
|
if( rc!=SQLITE_OK ) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert( rc!=SQLITE_ROW );
|
||||||
return vacuumFinalize(db, pStmt, pzErrMsg);
|
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
|
||||||
|
if( rc ){
|
||||||
|
sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
|
||||||
|
}
|
||||||
|
(void)sqlite3_finalize(pStmt);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
|
||||||
|
char *z;
|
||||||
|
va_list ap;
|
||||||
|
int rc;
|
||||||
|
va_start(ap, zSql);
|
||||||
|
z = sqlite3VMPrintf(db, zSql, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if( z==0 ) return SQLITE_NOMEM;
|
||||||
|
rc = execSql(db, pzErrMsg, z);
|
||||||
|
sqlite3DbFree(db, z);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -101,11 +96,12 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
|
||||||
** transient would cause the database file to appear to be deleted
|
** transient would cause the database file to appear to be deleted
|
||||||
** following reboot.
|
** following reboot.
|
||||||
*/
|
*/
|
||||||
void sqlite3Vacuum(Parse *pParse){
|
void sqlite3Vacuum(Parse *pParse, Token *pNm){
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
|
||||||
sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
|
if( v && (iDb>=2 || iDb==0) ){
|
||||||
sqlite3VdbeUsesBtree(v, 0);
|
sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
|
||||||
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -113,11 +109,10 @@ void sqlite3Vacuum(Parse *pParse){
|
||||||
/*
|
/*
|
||||||
** This routine implements the OP_Vacuum opcode of the VDBE.
|
** This routine implements the OP_Vacuum opcode of the VDBE.
|
||||||
*/
|
*/
|
||||||
int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
|
||||||
int rc = SQLITE_OK; /* Return code from service routines */
|
int rc = SQLITE_OK; /* Return code from service routines */
|
||||||
Btree *pMain; /* The database being vacuumed */
|
Btree *pMain; /* The database being vacuumed */
|
||||||
Btree *pTemp; /* The temporary database we vacuum into */
|
Btree *pTemp; /* The temporary database we vacuum into */
|
||||||
char *zSql = 0; /* SQL statements */
|
|
||||||
int saved_flags; /* Saved value of the db->flags */
|
int saved_flags; /* Saved value of the db->flags */
|
||||||
int saved_nChange; /* Saved value of db->nChange */
|
int saved_nChange; /* Saved value of db->nChange */
|
||||||
int saved_nTotalChange; /* Saved value of db->nTotalChange */
|
int saved_nTotalChange; /* Saved value of db->nTotalChange */
|
||||||
|
@ -126,6 +121,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||||
int isMemDb; /* True if vacuuming a :memory: database */
|
int isMemDb; /* True if vacuuming a :memory: database */
|
||||||
int nRes; /* Bytes of reserved space at the end of each page */
|
int nRes; /* Bytes of reserved space at the end of each page */
|
||||||
int nDb; /* Number of attached databases */
|
int nDb; /* Number of attached databases */
|
||||||
|
const char *zDbMain; /* Schema name of database to vacuum */
|
||||||
|
|
||||||
if( !db->autoCommit ){
|
if( !db->autoCommit ){
|
||||||
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
|
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
|
||||||
|
@ -143,11 +139,13 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||||
saved_nChange = db->nChange;
|
saved_nChange = db->nChange;
|
||||||
saved_nTotalChange = db->nTotalChange;
|
saved_nTotalChange = db->nTotalChange;
|
||||||
saved_mTrace = db->mTrace;
|
saved_mTrace = db->mTrace;
|
||||||
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
|
db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
|
||||||
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
|
| SQLITE_PreferBuiltin | SQLITE_Vacuum);
|
||||||
|
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
|
||||||
db->mTrace = 0;
|
db->mTrace = 0;
|
||||||
|
|
||||||
pMain = db->aDb[0].pBt;
|
zDbMain = db->aDb[iDb].zDbSName;
|
||||||
|
pMain = db->aDb[iDb].pBt;
|
||||||
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
|
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
|
||||||
|
|
||||||
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
|
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
|
||||||
|
@ -165,18 +163,12 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||||
** to write the journal header file.
|
** to write the journal header file.
|
||||||
*/
|
*/
|
||||||
nDb = db->nDb;
|
nDb = db->nDb;
|
||||||
if( sqlite3TempInMemory(db) ){
|
rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
|
||||||
zSql = "ATTACH ':memory:' AS vacuum_db;";
|
|
||||||
}else{
|
|
||||||
zSql = "ATTACH '' AS vacuum_db;";
|
|
||||||
}
|
|
||||||
rc = execSql(db, pzErrMsg, zSql);
|
|
||||||
if( db->nDb>nDb ){
|
|
||||||
pDb = &db->aDb[db->nDb-1];
|
|
||||||
assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
|
|
||||||
}
|
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||||
pTemp = db->aDb[db->nDb-1].pBt;
|
assert( (db->nDb-1)==nDb );
|
||||||
|
pDb = &db->aDb[nDb];
|
||||||
|
assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
|
||||||
|
pTemp = pDb->pBt;
|
||||||
|
|
||||||
/* The call to execSql() to attach the temp database has left the file
|
/* The call to execSql() to attach the temp database has left the file
|
||||||
** locked (as there was more than one active statement when the transaction
|
** locked (as there was more than one active statement when the transaction
|
||||||
|
@ -197,16 +189,15 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size);
|
sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
|
||||||
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
|
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
|
||||||
rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
|
sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF);
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
|
||||||
|
|
||||||
/* Begin a transaction and take an exclusive lock on the main database
|
/* Begin a transaction and take an exclusive lock on the main database
|
||||||
** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
|
** 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.
|
** to ensure that we do not try to change the page-size on a WAL database.
|
||||||
*/
|
*/
|
||||||
rc = execSql(db, pzErrMsg, "BEGIN;");
|
rc = execSql(db, pzErrMsg, "BEGIN");
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||||
rc = sqlite3BtreeBeginTrans(pMain, 2);
|
rc = sqlite3BtreeBeginTrans(pMain, 2);
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||||
|
@ -233,64 +224,48 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||||
/* Query the schema of the main database. Create a mirror schema
|
/* Query the schema of the main database. Create a mirror schema
|
||||||
** in the temporary database.
|
** in the temporary database.
|
||||||
*/
|
*/
|
||||||
rc = execExecSql(db, pzErrMsg,
|
db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
|
||||||
"SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
|
rc = execSqlF(db, pzErrMsg,
|
||||||
" FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
|
"SELECT sql FROM \"%w\".sqlite_master"
|
||||||
" AND coalesce(rootpage,1)>0"
|
" WHERE type='table'AND name<>'sqlite_sequence'"
|
||||||
|
" AND coalesce(rootpage,1)>0",
|
||||||
|
zDbMain
|
||||||
);
|
);
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||||
rc = execExecSql(db, pzErrMsg,
|
rc = execSqlF(db, pzErrMsg,
|
||||||
"SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
|
"SELECT sql FROM \"%w\".sqlite_master"
|
||||||
" FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
|
" WHERE type='index' AND length(sql)>10",
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
zDbMain
|
||||||
rc = execExecSql(db, pzErrMsg,
|
);
|
||||||
"SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
|
|
||||||
" FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
|
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||||
|
db->init.iDb = 0;
|
||||||
|
|
||||||
/* Loop through the tables in the main database. For each, do
|
/* Loop through the tables in the main database. For each, do
|
||||||
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
|
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
|
||||||
** the contents to the temporary database.
|
** the contents to the temporary database.
|
||||||
*/
|
*/
|
||||||
assert( (db->flags & SQLITE_Vacuum)==0 );
|
rc = execSqlF(db, pzErrMsg,
|
||||||
db->flags |= SQLITE_Vacuum;
|
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
|
||||||
rc = execExecSql(db, pzErrMsg,
|
"||' SELECT*FROM\"%w\".'||quote(name)"
|
||||||
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
|
"FROM vacuum_db.sqlite_master "
|
||||||
"|| ' SELECT * FROM main.' || quote(name) || ';'"
|
"WHERE type='table'AND coalesce(rootpage,1)>0",
|
||||||
"FROM main.sqlite_master "
|
zDbMain
|
||||||
"WHERE type = 'table' AND name!='sqlite_sequence' "
|
|
||||||
" AND coalesce(rootpage,1)>0"
|
|
||||||
);
|
);
|
||||||
assert( (db->flags & SQLITE_Vacuum)!=0 );
|
assert( (db->flags & SQLITE_Vacuum)!=0 );
|
||||||
db->flags &= ~SQLITE_Vacuum;
|
db->flags &= ~SQLITE_Vacuum;
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||||
|
|
||||||
/* Copy over the sequence table
|
|
||||||
*/
|
|
||||||
rc = execExecSql(db, pzErrMsg,
|
|
||||||
"SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
|
|
||||||
"FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
|
|
||||||
);
|
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
|
||||||
rc = execExecSql(db, pzErrMsg,
|
|
||||||
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
|
|
||||||
"|| ' SELECT * FROM main.' || quote(name) || ';' "
|
|
||||||
"FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
|
|
||||||
);
|
|
||||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
|
||||||
|
|
||||||
|
|
||||||
/* Copy the triggers, views, and virtual tables from the main database
|
/* Copy the triggers, views, and virtual tables from the main database
|
||||||
** over to the temporary database. None of these objects has any
|
** over to the temporary database. None of these objects has any
|
||||||
** associated storage, so all we have to do is copy their entries
|
** associated storage, so all we have to do is copy their entries
|
||||||
** from the SQLITE_MASTER table.
|
** from the SQLITE_MASTER table.
|
||||||
*/
|
*/
|
||||||
rc = execSql(db, pzErrMsg,
|
rc = execSqlF(db, pzErrMsg,
|
||||||
"INSERT INTO vacuum_db.sqlite_master "
|
"INSERT INTO vacuum_db.sqlite_master"
|
||||||
" SELECT type, name, tbl_name, rootpage, sql"
|
" SELECT*FROM \"%w\".sqlite_master"
|
||||||
" FROM main.sqlite_master"
|
" WHERE type IN('view','trigger')"
|
||||||
" WHERE type='view' OR type='trigger'"
|
" OR(type='table'AND rootpage=0)",
|
||||||
" OR (type='table' AND rootpage=0)"
|
zDbMain
|
||||||
);
|
);
|
||||||
if( rc ) goto end_of_vacuum;
|
if( rc ) goto end_of_vacuum;
|
||||||
|
|
||||||
|
@ -344,6 +319,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||||
|
|
||||||
end_of_vacuum:
|
end_of_vacuum:
|
||||||
/* Restore the original value of db->flags */
|
/* Restore the original value of db->flags */
|
||||||
|
db->init.iDb = 0;
|
||||||
db->flags = saved_flags;
|
db->flags = saved_flags;
|
||||||
db->nChange = saved_nChange;
|
db->nChange = saved_nChange;
|
||||||
db->nTotalChange = saved_nTotalChange;
|
db->nTotalChange = saved_nTotalChange;
|
||||||
|
|
|
@ -6298,15 +6298,14 @@ case OP_JournalMode: { /* out2 */
|
||||||
#endif /* SQLITE_OMIT_PRAGMA */
|
#endif /* SQLITE_OMIT_PRAGMA */
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
|
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
|
||||||
/* Opcode: Vacuum * * * * *
|
/* Opcode: Vacuum P1 * * * *
|
||||||
**
|
**
|
||||||
** Vacuum the entire database. This opcode will cause other virtual
|
** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
|
||||||
** machines to be created and run. It may not be called from within
|
** for an attached database. The "temp" database may not be vacuumed.
|
||||||
** a transaction.
|
|
||||||
*/
|
*/
|
||||||
case OP_Vacuum: {
|
case OP_Vacuum: {
|
||||||
assert( p->readOnly==0 );
|
assert( p->readOnly==0 );
|
||||||
rc = sqlite3RunVacuum(&p->zErrMsg, db);
|
rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1);
|
||||||
if( rc ) goto abort_due_to_error;
|
if( rc ) goto abort_due_to_error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,12 +202,8 @@ do_execsql_test e_vacuum-2.1.1 {
|
||||||
} {}
|
} {}
|
||||||
set original_size [file size test.db2]
|
set original_size [file size test.db2]
|
||||||
|
|
||||||
# Try everything we can think of to get the aux database vacuumed:
|
# Vacuuming the main database does not affect aux
|
||||||
do_execsql_test e_vacuum-2.1.3 { VACUUM } {}
|
do_execsql_test e_vacuum-2.1.3 { VACUUM } {}
|
||||||
do_execsql_test e_vacuum-2.1.4 { VACUUM aux } {}
|
|
||||||
do_execsql_test e_vacuum-2.1.5 { VACUUM 'test.db2' } {}
|
|
||||||
|
|
||||||
# Despite our efforts, space in the aux database has not been reclaimed:
|
|
||||||
do_test e_vacuum-2.1.6 { expr {[file size test.db2]==$::original_size} } 1
|
do_test e_vacuum-2.1.6 { expr {[file size test.db2]==$::original_size} } 1
|
||||||
|
|
||||||
# EVIDENCE-OF: R-17495-17419 The VACUUM command may change the ROWIDs of
|
# EVIDENCE-OF: R-17495-17419 The VACUUM command may change the ROWIDs of
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
# 2016-08-19
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# This file implements a test for VACUUM on attached databases.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
# If the VACUUM statement is disabled in the current build, skip all
|
||||||
|
# the tests in this file.
|
||||||
|
#
|
||||||
|
ifcapable !vacuum {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forcedelete test2.db test3.db
|
||||||
|
do_execsql_test vacuum5-1.1 {
|
||||||
|
CREATE TABLE main.t1(a,b);
|
||||||
|
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
|
||||||
|
INSERT INTO t1(a,b) SELECT x, randomblob(1000) FROM c;
|
||||||
|
CREATE TEMP TABLE ttemp(x,y);
|
||||||
|
INSERT INTO ttemp SELECT * FROM t1;
|
||||||
|
ATTACH 'test2.db' AS x2;
|
||||||
|
ATTACH 'test3.db' AS x3;
|
||||||
|
CREATE TABLE x2.t2(c,d);
|
||||||
|
INSERT INTO t2 SELECT * FROM t1;
|
||||||
|
CREATE TABLE x3.t3(e,f);
|
||||||
|
INSERT INTO t3 SELECT * FROM t1;
|
||||||
|
DELETE FROM t1 WHERE (rowid%3)!=0;
|
||||||
|
DELETE FROM t2 WHERE (rowid%4)!=0;
|
||||||
|
DELETE FROM t3 WHERE (rowid%5)!=0;
|
||||||
|
PRAGMA main.integrity_check;
|
||||||
|
PRAGMA x2.integrity_check;
|
||||||
|
PRAGMA x3.integrity_check;
|
||||||
|
} {ok ok ok}
|
||||||
|
set size1 [file size test.db]
|
||||||
|
set size2 [file size test2.db]
|
||||||
|
set size3 [file size test3.db]
|
||||||
|
|
||||||
|
do_execsql_test vacuum5-1.2.1 {
|
||||||
|
VACUUM main;
|
||||||
|
} {}
|
||||||
|
do_test vacuum5-1.2.2 {
|
||||||
|
expr {[file size test.db]<$size1}
|
||||||
|
} {1}
|
||||||
|
do_test vacuum5-1.2.3 {
|
||||||
|
file size test2.db
|
||||||
|
} $size2
|
||||||
|
do_test vacuum5-1.2.4 {
|
||||||
|
file size test3.db
|
||||||
|
} $size3
|
||||||
|
set size1 [file size test.db]
|
||||||
|
do_execsql_test vacuum-1.2.5 {
|
||||||
|
DELETE FROM t1;
|
||||||
|
PRAGMA main.integrity_check;
|
||||||
|
} {ok}
|
||||||
|
|
||||||
|
do_execsql_test vacuum5-1.3.1 {
|
||||||
|
VACUUM x2;
|
||||||
|
} {}
|
||||||
|
do_test vacuum5-1.3.2 {
|
||||||
|
file size test.db
|
||||||
|
} $size1
|
||||||
|
do_test vacuum5-1.3.3 {
|
||||||
|
expr {[file size test2.db]<$size2}
|
||||||
|
} 1
|
||||||
|
do_test vacuum5-1.3.4 {
|
||||||
|
file size test3.db
|
||||||
|
} $size3
|
||||||
|
set size2 [file size test2.db]
|
||||||
|
do_execsql_test vacuum-1.3.5 {
|
||||||
|
DELETE FROM t2;
|
||||||
|
PRAGMA x2.integrity_check;
|
||||||
|
} {ok}
|
||||||
|
|
||||||
|
do_execsql_test vacuum5-1.4.1 {
|
||||||
|
VACUUM x3;
|
||||||
|
} {}
|
||||||
|
do_test vacuum5-1.3.2 {
|
||||||
|
file size test.db
|
||||||
|
} $size1
|
||||||
|
do_test vacuum5-1.3.3 {
|
||||||
|
file size test2.db
|
||||||
|
} $size2
|
||||||
|
do_test vacuum5-1.3.4 {
|
||||||
|
expr {[file size test3.db]<$size3}
|
||||||
|
} 1
|
||||||
|
|
||||||
|
# VACUUM is a no-op on the TEMP table
|
||||||
|
#
|
||||||
|
set sizeTemp [db one {PRAGMA temp.page_count}]
|
||||||
|
do_execsql_test vacuum5-1.4.1 {
|
||||||
|
VACUUM temp;
|
||||||
|
} {}
|
||||||
|
do_execsql_test vacuum5-1.4.2 {
|
||||||
|
PRAGMA temp.page_count;
|
||||||
|
} $sizeTemp
|
||||||
|
|
||||||
|
do_catchsql_test vacuum5-2.0 {
|
||||||
|
VACUUM olaf;
|
||||||
|
} {1 {unknown database olaf}}
|
Loading…
Reference in New Issue