diff --git a/manifest b/manifest index 21dc9f5c35..e65efe1116 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\san\sincorrect\sALWAYS()\smacro\sin\svdbeapi.c.\s\sFix\sthe\soutput\sof\sa\sfew\ntest\scases\sthat\schanged\sdue\sto\sbetter\serror\spropagation\sout\sof\sreprepare. -D 2010-02-24T18:40:39 +C Add\sa\ssqlite3_log()\scall\son\sanonymous\sconstraint\sfailures.\nFix\sthe\soutput\sof\stest\scases\shaving\sto\sdo\swith\simproved\sreprepare\sreporting.\nFix\sthe\sVACUUM\scommand\sto\sreport\smore\shelpful\serror\smessages\swhen\sthings\sgo\nwrong. +D 2010-02-24T19:23:56 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -213,8 +213,8 @@ F src/trigger.c 340c9eca0fb24b1197468d96ba059f867c9834c7 F src/update.c c0dc6b75ad28b76b619042d934f337b02acee208 F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052 F src/util.c 57256361d9794ae9b8c7d7d9df8ee239ba7f9b01 -F src/vacuum.c 28ee5a4963d16cf2477075d85966c0f461cd79de -F src/vdbe.c eb8b083191412e89292b864687f86afa28f4dc3f +F src/vacuum.c deb50c41c39849770ab1bf27e8a35ba1036e3962 +F src/vdbe.c 815ec0f55b184be47f7e354790d55e505eb3b8d3 F src/vdbe.h bea1f0cd530775bdb58a340265f3cf3ee920e9b2 F src/vdbeInt.h e276691b6835da5c0008cc5beaaecedcd7bdba8e F src/vdbeapi.c e0398d74af46911033b92088f740582f3c400515 @@ -235,7 +235,7 @@ F test/alter4.test 9386ffd1e9c7245f43eca412b2058d747509cc1f F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/analyze.test ad5329098fe4de4a96852231d53e3e9e6283ad4b F test/analyze2.test a2ad7b0a4e13801ee3968fe70f22aff52326569c -F test/analyze3.test ae06e0f8b3eaae0dd644ac9ac9d617058b5ac131 +F test/analyze3.test 506203875258ffd8ffa879b9c3c5432022d2b6d8 F test/async.test 8c75d31b8330f8b70cf2571b014d4476a063efdb F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6 F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e @@ -794,14 +794,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 8e60d3995a1ea940de9751dd3bbd7ef41b0bb00a -R 6982e34d63d3f7c4c63beeb945356ebf +P a8c984c1d6cb6e2fc95a07eb32befeea122e8ed3 +R 2b722edc5008cbf38737ae2ef5623db4 U drh -Z c4ecc3e66bf0fd4aae2b5b5dd8f1451e +Z 8f72e9f3a584b7bfbd7a9cae96339e61 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFLhXKqoxKgR168RlERAv3oAJ4/CLWQPurMHkYouSQ4hYLZQvLwUACfbzJS -CpVug0wu1S3JGMsgNXNc/uA= -=PJke +iD8DBQFLhXzPoxKgR168RlERAhuKAJ0bK7dYcMKjnA8nUy8KJNd03rqo5gCfbk0E +IcFdGuxfI3OrBOGRpsZhtkE= +=e87x -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 0cd4c7fda6..0b734ae578 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8c984c1d6cb6e2fc95a07eb32befeea122e8ed3 \ No newline at end of file +69a493182fd77bec91598516ee42c11a6db1d039 \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index 9d26da3dae..4975426918 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -18,28 +18,42 @@ #include "vdbeInt.h" #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. */ -static int execSql(sqlite3 *db, 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; } 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 ); - return sqlite3_finalize(pStmt); + 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, const char *zSql){ +static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ sqlite3_stmt *pStmt; int rc; @@ -47,14 +61,14 @@ static int execExecSql(sqlite3 *db, const char *zSql){ if( rc!=SQLITE_OK ) return rc; while( SQLITE_ROW==sqlite3_step(pStmt) ){ - rc = execSql(db, (char*)sqlite3_column_text(pStmt, 0)); + rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0)); if( rc!=SQLITE_OK ){ - sqlite3_finalize(pStmt); + vacuumFinalize(db, pStmt, pzErrMsg); return rc; } } - return sqlite3_finalize(pStmt); + return vacuumFinalize(db, pStmt, pzErrMsg); } /* @@ -125,7 +139,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ** to write the journal header file. */ zSql = "ATTACH '' AS vacuum_db;"; - rc = execSql(db, zSql); + rc = execSql(db, pzErrMsg, zSql); if( rc!=SQLITE_OK ) goto end_of_vacuum; pDb = &db->aDb[db->nDb-1]; assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 ); @@ -157,7 +171,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ rc = SQLITE_NOMEM; goto end_of_vacuum; } - rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF"); + rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); if( rc!=SQLITE_OK ){ goto end_of_vacuum; } @@ -168,23 +182,23 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ #endif /* Begin a transaction */ - rc = execSql(db, "BEGIN EXCLUSIVE;"); + 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, + 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" ); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execExecSql(db, + rc = execExecSql(db, pzErrMsg, "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)" " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' "); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execExecSql(db, + 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; @@ -193,24 +207,23 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy ** the contents to the temporary database. */ - rc = execExecSql(db, + rc = execExecSql(db, pzErrMsg, "SELECT 'INSERT INTO vacuum_db.' || quote(name) " "|| ' SELECT * FROM main.' || quote(name) || ';'" "FROM main.sqlite_master " "WHERE type = 'table' AND name!='sqlite_sequence' " " AND rootpage>0" - ); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Copy over the sequence table */ - rc = execExecSql(db, + 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, + 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';" @@ -223,7 +236,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ** associated storage, so all we have to do is copy their entries ** from the SQLITE_MASTER table. */ - rc = execSql(db, + rc = execSql(db, pzErrMsg, "INSERT INTO vacuum_db.sqlite_master " " SELECT type, name, tbl_name, rootpage, sql" " FROM main.sqlite_master" diff --git a/src/vdbe.c b/src/vdbe.c index 71fa635d09..5fbeaf49e6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -850,6 +850,8 @@ case OP_Halt: { assert( p->rc!=SQLITE_OK ); sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pc, p->zSql, pOp->p4.z); + }else if( p->rc ){ + sqlite3_log(pOp->p1, "constraint failed at %d in [%s]", pc, p->zSql); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); diff --git a/test/analyze3.test b/test/analyze3.test index f623f987a4..438ecd7b2b 100644 --- a/test/analyze3.test +++ b/test/analyze3.test @@ -481,10 +481,10 @@ do_test analyze3-4.1.2 { sqlite3_bind_text $S 2 "abc" 3 execsql { DROP TABLE t1 } sqlite3_step $S -} {SQLITE_SCHEMA} +} {SQLITE_ERROR} do_test analyze3-4.1.3 { sqlite3_finalize $S -} {SQLITE_SCHEMA} +} {SQLITE_ERROR} # Check an authorization error. # @@ -511,10 +511,10 @@ do_test analyze3-4.2.2 { sqlite3_reset $S sqlite3_bind_text $S 2 "abc" 3 sqlite3_step $S -} {SQLITE_SCHEMA} +} {SQLITE_AUTH} do_test analyze3-4.2.4 { sqlite3_finalize $S -} {SQLITE_SCHEMA} +} {SQLITE_AUTH} # Check the effect of an authorization error that occurs in a re-prepare # performed by sqlite3_step() is the same as one that occurs within @@ -526,10 +526,10 @@ do_test analyze3-4.3.1 { execsql { CREATE TABLE t2(d, e, f) } db auth auth sqlite3_step $S -} {SQLITE_SCHEMA} +} {SQLITE_AUTH} do_test analyze3-4.3.2 { sqlite3_finalize $S -} {SQLITE_SCHEMA} +} {SQLITE_AUTH} db auth {} #-------------------------------------------------------------------------