Add a sqlite3_log() call on anonymous constraint failures.

Fix the output of test cases having to do with improved reprepare reporting.
Fix the VACUUM command to report more helpful error messages when things go
wrong.

FossilOrigin-Name: 69a493182fd77bec91598516ee42c11a6db1d039
This commit is contained in:
drh 2010-02-24 19:23:56 +00:00
parent 7823006011
commit cda455b7ff
5 changed files with 50 additions and 35 deletions

View File

@ -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-----

View File

@ -1 +1 @@
a8c984c1d6cb6e2fc95a07eb32befeea122e8ed3
69a493182fd77bec91598516ee42c11a6db1d039

View File

@ -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"

View File

@ -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 );

View File

@ -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 {}
#-------------------------------------------------------------------------