-C Fail\san\sATTACH\sif\sthe\sauxiliary\sdatabase\sis\slocked.\s\sTicket\s#514.\s(CVS\s1127)
-D 2003-12-06T22:22:36
+C Make\sthe\sVACUUM\scommand\srun\sout\sof\sthe\sVDBE\slike\sall\sother\scommands.\n(Ticket\s#464).\s\sMake\sthe\sVACUUM\scommand\swork\seven\sif\sthere\sare\sVIEWs\nin\sthe\sSQLITE_MASTER\stable\sthat\scome\sbefore\stables\sthey\sreference.\n(Ticket\s#515)\s(CVS\s1128)
+D 2003-12-07T00:24:35
F Makefile.in 5cb273b7d0e945d47ee8b9ad1c2a04ce79927d2d
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/shell.c 3b067edc098c45caca164bcad1fa79192c3ec5ae
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in e6cfff01fafc8a82ce82cd8c932af421dc9adb54
-F src/sqliteInt.h 882aa33ee2aed7685449b899d917a316b9cc2c44
+F src/sqliteInt.h f8549cf426920e43efb105a08484768cdb73c808
F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
F src/tclsqlite.c 3efac6b5861ac149c41251d4d4c420c94be5ba6a
F src/test1.c f9d5816610f7ec4168ab7b098d5207a5708712b6
F src/trigger.c ce83e017b407d046e909d05373d7f8ee70f9f7f9
F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
F src/util.c cc95dd360fac09a059b2ab98e4c333d1a2308db5
-F src/vacuum.c e4724eade07e4cf8897060a8cf632dbd92408eeb
-F src/vdbe.c d61f720a836a7c948356105b87b2512a9484cb3b
+F src/vacuum.c 77485a64a6e4e358170f150fff681c1624a092b0
+F src/vdbe.c b40c2a7002c0c8e5a226666622f487e241dadf36
F src/vdbe.h 3957844e46fea71fd030e78f6a3bd2f7e320fb43
F src/vdbeInt.h 2824bf88895b901b3a8c9e44527c67530e1c0dcb
F src/vdbeaux.c 877ae44ab42f43d38e8cd989087627508a4c98dd
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test c26848402e7ac829e043e1fa5e0eb87032e5d81d
F test/attach2.test d0105f4e8b1debf0ac25ed7df986b5854620e172
-F test/auth.test b7d6bdeffa804b96b7bcac2712e5f71ce014a1b8
+F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
F test/bind.test 56a57043b42c4664ca705f6050e56717a8a6699a
F test/trigger4.test 542afce45774e8f8e1130b96b8675f414d6e4bd8
F test/unique.test 0e38d4cc7affeef2527720d1dafd1f6870f02f2b
F test/update.test 2ef5a6655f2966f0aef733a9f4495b3fe8e16809
-F test/vacuum.test a58776ef529e9bc21980ac120d6859d4ee34b578
+F test/vacuum.test 9447f1d7633b083c9b97f807fa05f9b27ada7503
F test/version.test 605fd0d7e7d571370c32b12dbf395b58953de246
F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53
F test/where.test cb3a2ed062ce4b5f08aff2d08027c6a46d68c47b
F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
-P 656c90387a4a714b4f31040ece9b0e15e30934af
-R 9ba0dba1a5b0b6a0c4f493ffeeb808ce
+P ac428c8d4a731678cc26cf198689814a8a56d141
+R de0e25f496472fda102deb07f0a3f4c2
U drh
-Z 4d2d90a1bb0f4a7af58cf43ec43a116f
+Z da3da18ef1bdac6a224ddd572daad46d
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
-** $Id: vacuum.c,v 1.8 2003/08/15 13:24:52 drh Exp $
+** $Id: vacuum.c,v 1.9 2003/12/07 00:24:35 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
struct vacuumStruct {
sqlite *dbOld; /* Original database */
sqlite *dbNew; /* New database */
- Parse *pParse; /* The parser context */
+ char **pzErrMsg; /* Write errors here */
+ int rc; /* Set to non-zero on an error */
const char *zTable; /* Name of a table being copied */
const char *zPragma; /* Pragma to execute with results */
dynStr s1, s2; /* Two dynamic strings */
/*
** Execute statements of SQL. If an error occurs, write the error
-** message into pParse->zErrMsg and return non-zero.
+** message into *pzErrMsg and return non-zero.
*/
-static int execsql(Parse *pParse, sqlite *db, const char *zSql){
- int rc;
+static int execsql(char **pzErrMsg, sqlite *db, const char *zSql){
char *zErrMsg = 0;
+ int rc;
/* printf("***** executing *****\n%s\n", zSql); */
rc = sqlite_exec(db, zSql, 0, 0, &zErrMsg);
- if( rc ){
- sqliteErrorMsg(pParse, "%s", zErrMsg);
+ if( zErrMsg ){
+ sqliteSetString(pzErrMsg, zErrMsg, (char*)0);
sqlite_freemem(zErrMsg);
}
return rc;
}
}
appendText(&p->s2,")", 1);
- rc = execsql(p->pParse, p->dbNew, p->s2.z);
+ rc = execsql(p->pzErrMsg, p->dbNew, p->s2.z);
return rc;
}
assert( argv[0]!=0 );
assert( argv[1]!=0 );
assert( argv[2]!=0 );
- rc = execsql(p->pParse, p->dbNew, argv[2]);
+ rc = execsql(p->pzErrMsg, p->dbNew, argv[2]);
if( rc==SQLITE_OK && strcmp(argv[0],"table")==0 ){
char *zErrMsg = 0;
p->s1.nUsed = 0;
appendQuoted(&p->s1, argv[1]);
p->zTable = argv[1];
rc = sqlite_exec(p->dbOld, p->s1.z, vacuumCallback2, p, &zErrMsg);
- if( rc && p->pParse->zErrMsg==0 ){
- sqliteErrorMsg(p->pParse, "%s", zErrMsg);
+ if( zErrMsg ){
+ sqliteSetString(p->pzErrMsg, zErrMsg, (char*)0);
+ sqlite_freemem(zErrMsg);
}
}
return rc;
assert( strlen(p->zPragma)<100 );
assert( strlen(argv[0])<30 );
sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
- rc = execsql(p->pParse, p->dbNew, zBuf);
+ rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
return rc;
}
** become a no-op.
*/
void sqliteVacuum(Parse *pParse, Token *pTableName){
+ Vdbe *v = sqliteGetVdbe(pParse);
+ sqliteVdbeAddOp(v, OP_Vacuum, 0, 0);
+ return;
+}
+
+/*
+** This routine implements the OP_Vacuum opcode of the VDBE.
+*/
+int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
const char *zFilename; /* full pathname of the database file */
int nFilename; /* number of characters in zFilename[] */
char *zTemp = 0; /* a temporary file in same directory as zFilename */
sqlite *dbNew = 0; /* The new vacuumed database */
- sqlite *db; /* The original database */
int rc = SQLITE_OK; /* Return code from service routines */
int i; /* Loop counter */
- char *zErrMsg = 0; /* Error messages stored here */
- int safety = 0; /* TRUE if safety is off */
+ char *zErrMsg; /* Error message */
vacuumStruct sVac; /* Information passed to callbacks */
/* These are all of the pragmas that need to be transferred over
/* "default_temp_store", */
};
- /* Initial error checks
- */
- if( pParse->explain ){
- return;
- }
- db = pParse->db;
if( db->flags & SQLITE_InTrans ){
- sqliteErrorMsg(pParse, "cannot VACUUM from within a transaction");
- return;
+ sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction",
+ (char*)0);
+ return SQLITE_ERROR;
}
memset(&sVac, 0, sizeof(sVac));
if( zFilename==0 ){
/* This only happens with the in-memory database. VACUUM is a no-op
** there, so just return */
- return;
+ return SQLITE_OK;
}
nFilename = strlen(zFilename);
zTemp = sqliteMalloc( nFilename+100 );
- if( zTemp==0 ) return;
+ if( zTemp==0 ) return SQLITE_NOMEM;
strcpy(zTemp, zFilename);
for(i=0; i<10; i++){
zTemp[nFilename] = '-';
if( !sqliteOsFileExists(zTemp) ) break;
}
if( i>=10 ){
- sqliteErrorMsg(pParse, "unable to create a temporary database file "
- "in the same directory as the original database");
+ sqliteSetString(pzErrMsg, "unable to create a temporary database file "
+ "in the same directory as the original database", (char*)0);
goto end_of_vacuum;
}
dbNew = sqlite_open(zTemp, 0, &zErrMsg);
if( dbNew==0 ){
- sqliteErrorMsg(pParse, "unable to open a temporary database at %s - %s",
- zTemp, zErrMsg);
- goto end_of_vacuum;
- }
- if( sqliteSafetyOff(db) ){
- sqliteErrorMsg(pParse, "library routines called out of sequence");
+ sqliteSetString(pzErrMsg, "unable to open a temporary database at ",
+ zTemp, " - ", zErrMsg, (char*)0);
goto end_of_vacuum;
}
- safety = 1;
- if( execsql(pParse, db, "BEGIN") ) goto end_of_vacuum;
- if( execsql(pParse, dbNew, "PRAGMA synchronous=off; BEGIN") ){
+ if( execsql(pzErrMsg, db, "BEGIN") ) goto end_of_vacuum;
+ if( execsql(pzErrMsg, dbNew, "PRAGMA synchronous=off; BEGIN") ){
goto end_of_vacuum;
}
+
sVac.dbOld = db;
sVac.dbNew = dbNew;
- sVac.pParse = pParse;
+ sVac.pzErrMsg = pzErrMsg;
for(i=0; rc==SQLITE_OK && i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
char zBuf[200];
assert( strlen(zPragma[i])<100 );
sVac.zPragma = zPragma[i];
rc = sqlite_exec(db, zBuf, vacuumCallback3, &sVac, &zErrMsg);
}
- if( !rc ){
- rc = sqlite_exec(db, "SELECT type, name, sql FROM sqlite_master "
- "WHERE sql NOT NULL", vacuumCallback1, &sVac, &zErrMsg);
+ if( rc==SQLITE_OK ){
+ rc = sqlite_exec(db,
+ "SELECT type, name, sql FROM sqlite_master "
+ "WHERE sql NOT NULL AND type!='view' "
+ "UNION ALL "
+ "SELECT type, name, sql FROM sqlite_master "
+ "WHERE sql NOT NULL AND type=='view'",
+ vacuumCallback1, &sVac, &zErrMsg);
}
- if( !rc ){
+ if( rc==SQLITE_OK ){
rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
sqlite_exec(db, "COMMIT", 0, 0, 0);
- sqlite_exec(db, "ROLLBACK", 0, 0, 0); /* In case the COMMIT failed */
sqliteResetInternalSchema(db, 0);
}
end_of_vacuum:
- if( rc && pParse->zErrMsg==0 && zErrMsg!=0 ){
- sqliteErrorMsg(pParse, "unable to vacuum database - %s", zErrMsg);
- }
- if( safety ) {
- sqlite_exec(db, "COMMIT", 0, 0, 0);
- sqlite_exec(db, "ROLLBACK", 0, 0, 0); /* In case the COMMIT failed */
- sqliteSafetyOn(db);
+ if( rc && zErrMsg!=0 ){
+ sqliteSetString(pzErrMsg, "unable to vacuum database - ",
+ zErrMsg, (char*)0);
}
+ sqlite_exec(db, "ROLLBACK", 0, 0, 0);
if( dbNew ) sqlite_close(dbNew);
sqliteOsDelete(zTemp);
sqliteFree(zTemp);
sqliteFree(sVac.s1.z);
sqliteFree(sVac.s2.z);
if( zErrMsg ) sqlite_freemem(zErrMsg);
- return;
+ if( rc==SQLITE_ABORT ) rc = SQLITE_ERROR;
+ return rc;
#endif
}