Simplifications to error message processing. Fix a possible problem in error

message formatting when vacuuming a database with a corrupt schema.

FossilOrigin-Name: 56ef98a04765c34c1c2f3ed7a6f03a732f3b886e
This commit is contained in:
drh 2015-05-15 04:13:15 +00:00
parent f922ca497d
commit 22c17b8bf5
11 changed files with 72 additions and 90 deletions

View File

@ -1,5 +1,5 @@
C Increase\sthe\sversion\snumber\sto\s3.8.11.\s\sUpgrade\sautoconf\sfrom\s2.62\sto\s2.69.
D 2015-05-14T15:39:18.685
C Simplifications\sto\serror\smessage\sprocessing.\s\sFix\sa\spossible\sproblem\sin\serror\nmessage\sformatting\swhen\svacuuming\sa\sdatabase\swith\sa\scorrupt\sschema.
D 2015-05-15T04:13:15.980
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in edfc69769e613a6359c42c06ea1d42c3bece1736
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -197,7 +197,7 @@ F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271
F src/main.c bf14bc6a321965e528d8ab30087e9440335f2e4b
F src/malloc.c 5bc15d525811d387b37c29f2e368143460e41e96
F src/malloc.c 908c780fdddd472163c2d1b1820ae4081f01ad20
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
@ -226,8 +226,8 @@ F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
F src/prepare.c 1fffbdcd6f8a0173a8f70d71f22528f4c0e1e3d3
F src/printf.c 54dd6dce95454fadffa3ebf7717c5f6c06250d1d
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
F src/printf.c 13ce37e5574f9b0682fa86dbcf9faf76b9d82a15
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 99eabf7eff0bfa65b75939b46caa82e2b2133f28
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
@ -236,7 +236,7 @@ F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee
F src/sqlite.h.in bf3fe5eba3a5142477b8dae3cfce627c3e971455
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h c9f77bd02f419dcc8c644c5032c42eb29069a545
F src/sqliteInt.h 88738d94a343000e7a5c0e295d111c4cfccb18b0
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@ -287,17 +287,17 @@ F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
F src/tokenize.c b15511a2396641792f386ceb440d1d922972a78e
F src/tokenize.c af8cbbca6db6b664ffecafa236b06629ef6d35c4
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c a6431c92803b975b7322724a7b433e538d243539
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c d437887d02d13d79dc69ac018f788aefac3b3972
F src/vdbe.c 8775967d8ae262f4134a34f539b8747b23421000
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
F src/vdbeInt.h de3291a6688dfef9f61d47705c1bd57008b1185d
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
F src/vdbeaux.c 03591cca98ec50e1493043f0ff7abbece0b9c83d
F src/vdbeaux.c efe1667d31e8648dbe04a441e5aa9b62dbee2f03
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
F src/vdbemem.c 7bfbeef0978a2e1a05d979641fdbf7c189b7ddf4
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
@ -750,7 +750,7 @@ F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
F test/misc1.test 783ba75743b2cf71e0f646bf540a6cef57264811
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
F test/misc4.test 21c3a52354c022d2388a40c5082e9348e041bef7
F test/misc5.test f96428ea95b3820aafc6f1c50cf48a09e4597ee1
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2
@ -1258,7 +1258,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 3428043cd00294457548bb07ada2ad526b6532d6
R c07bb644a4970dea0428c10e9d8b15e9
P be438d049dd9d7aa6b88db8314eaa11bdd7af5b9
R 71064bfce8a81bd8d5b829a20a3cc70a
U drh
Z daab10dd46a6d0c5e5daa86cd7f31c23
Z 79e4b5f5046076a826cf4c89f92e95b1

View File

@ -1 +1 @@
be438d049dd9d7aa6b88db8314eaa11bdd7af5b9
56ef98a04765c34c1c2f3ed7a6f03a732f3b886e

View File

@ -771,19 +771,11 @@ char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
}
/*
** Create a string from the zFromat argument and the va_list that follows.
** Store the string in memory obtained from sqliteMalloc() and make *pz
** point to that string.
** Free any prior content in *pz and replace it with a copy of zNew.
*/
void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
va_list ap;
char *z;
va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
sqlite3DbFree(db, *pz);
*pz = z;
*pz = sqlite3DbStrDup(db, zNew);
}
/*

View File

@ -26,13 +26,13 @@ static void corruptSchema(
){
sqlite3 *db = pData->db;
if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
char *z;
if( zObj==0 ) zObj = "?";
sqlite3SetString(pData->pzErrMsg, db,
"malformed database schema (%s)", zObj);
if( zExtra ){
*pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
"%s - %s", *pData->pzErrMsg, zExtra);
}
z = sqlite3_mprintf("malformed database schema (%s)", zObj);
if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra);
sqlite3DbFree(db, *pData->pzErrMsg);
*pData->pzErrMsg = z;
if( z==0 ) db->mallocFailed = 1;
}
pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
}
@ -224,7 +224,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
if( rc!=SQLITE_OK ){
sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
goto initone_error_out;
}
openedTransaction = 1;

View File

@ -931,24 +931,6 @@ char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
return z;
}
/*
** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
** the string and before returning. This routine is intended to be used
** to modify an existing string. For example:
**
** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
**
*/
char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
va_list ap;
char *z;
va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
sqlite3DbFree(db, zStr);
return z;
}
/*
** Print into memory obtained from sqlite3_malloc(). Omit the internal
** %-conversion extensions.

View File

@ -3151,7 +3151,6 @@ void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
char *sqlite3MPrintf(sqlite3*,const char*, ...);
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
void sqlite3DebugPrintf(const char*, ...);
#endif
@ -3170,7 +3169,7 @@ char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
#endif
void sqlite3SetString(char **, sqlite3*, const char*, ...);
void sqlite3SetString(char **, sqlite3*, const char*);
void sqlite3ErrorMsg(Parse*, const char*, ...);
int sqlite3Dequote(char*);
int sqlite3KeywordCode(const unsigned char*, int);

View File

@ -472,7 +472,7 @@ abort_parse:
pParse->rc = SQLITE_NOMEM;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
}
assert( pzErrMsg!=0 );
if( pParse->zErrMsg ){

View File

@ -967,12 +967,11 @@ case OP_Halt: {
assert( zType!=0 || pOp->p4.z!=0 );
zLogFmt = "abort at %d in [%s]: %s";
if( zType && pOp->p4.z ){
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
zType, pOp->p4.z);
sqlite3VdbeError(p, "%s constraint failed: %s", zType, pOp->p4.z);
}else if( pOp->p4.z ){
sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
sqlite3VdbeError(p, "%s", pOp->p4.z);
}else{
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
sqlite3VdbeError(p, "%s constraint failed", zType);
}
sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
}
@ -1604,7 +1603,7 @@ case OP_Function: {
/* If the function returned an error, throw an exception */
if( ctx.fErrorOrAux ){
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
sqlite3VdbeError(p, "%s", sqlite3_value_text(ctx.pOut));
rc = ctx.isError;
}
sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
@ -2791,8 +2790,7 @@ case OP_Savepoint: {
/* A new savepoint cannot be created if there are active write
** statements (i.e. open read/write incremental blob handles).
*/
sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
"SQL statements in progress");
sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress");
rc = SQLITE_BUSY;
}else{
nName = sqlite3Strlen30(zName);
@ -2843,15 +2841,14 @@ case OP_Savepoint: {
iSavepoint++;
}
if( !pSavepoint ){
sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
sqlite3VdbeError(p, "no such savepoint: %s", zName);
rc = SQLITE_ERROR;
}else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
/* It is not possible to release (commit) a savepoint if there are
** active write statements.
*/
sqlite3SetString(&p->zErrMsg, db,
"cannot release savepoint - SQL statements in progress"
);
sqlite3VdbeError(p, "cannot release savepoint - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else{
@ -2957,23 +2954,12 @@ case OP_AutoCommit: {
assert( db->nVdbeActive>0 ); /* At least this one VM is active */
assert( p->bIsReader );
#if 0
if( turnOnAC && iRollback && db->nVdbeActive>1 ){
/* If this instruction implements a ROLLBACK and other VMs are
** still running, and a transaction is active, return an error indicating
** that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else
#endif
if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
"SQL statements in progress");
sqlite3VdbeError(p, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else if( desiredAutoCommit!=db->autoCommit ){
if( iRollback ){
@ -3000,7 +2986,7 @@ case OP_AutoCommit: {
}
goto vdbe_return;
}else{
sqlite3SetString(&p->zErrMsg, db,
sqlite3VdbeError(p,
(!desiredAutoCommit)?"cannot start a transaction within a transaction":(
(iRollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
@ -5433,7 +5419,7 @@ case OP_Program: { /* jump */
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
sqlite3VdbeError(p, "too many levels of trigger recursion");
break;
}
@ -5736,7 +5722,7 @@ case OP_AggStep: {
ctx.skipFlag = 0;
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
rc = ctx.isError;
}
if( ctx.skipFlag ){
@ -5768,7 +5754,7 @@ case OP_AggFinal: {
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
if( rc ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
}
sqlite3VdbeChangeEncoding(pMem, encoding);
UPDATE_MAX_BLOBSIZE(pMem);
@ -5873,7 +5859,7 @@ case OP_JournalMode: { /* out2 */
){
if( !db->autoCommit || db->nVdbeRead>1 ){
rc = SQLITE_ERROR;
sqlite3SetString(&p->zErrMsg, db,
sqlite3VdbeError(p,
"cannot change %s wal mode from within a transaction",
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
@ -6004,7 +5990,7 @@ case OP_TableLock: {
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
if( (rc&0xFF)==SQLITE_LOCKED ){
const char *z = pOp->p4.z;
sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
sqlite3VdbeError(p, "database table is locked: %s", z);
}
}
break;
@ -6552,7 +6538,7 @@ vdbe_return:
** is encountered.
*/
too_big:
sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
sqlite3VdbeError(p, "string or blob too big");
rc = SQLITE_TOOBIG;
goto vdbe_error_halt;
@ -6560,7 +6546,7 @@ too_big:
*/
no_mem:
db->mallocFailed = 1;
sqlite3SetString(&p->zErrMsg, db, "out of memory");
sqlite3VdbeError(p, "out of memory");
rc = SQLITE_NOMEM;
goto vdbe_error_halt;
@ -6571,7 +6557,7 @@ abort_due_to_error:
assert( p->zErrMsg==0 );
if( db->mallocFailed ) rc = SQLITE_NOMEM;
if( rc!=SQLITE_IOERR_NOMEM ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
}
goto vdbe_error_halt;
@ -6582,6 +6568,6 @@ abort_due_to_interrupt:
assert( db->u1.isInterrupted );
rc = SQLITE_INTERRUPT;
p->rc = rc;
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
goto vdbe_error_halt;
}

View File

@ -391,6 +391,7 @@ struct Vdbe {
/*
** Function prototypes
*/
void sqlite3VdbeError(Vdbe*, const char *, ...);
void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(VdbeCursor*);

View File

@ -38,6 +38,17 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){
return p;
}
/*
** Change the error string stored in Vdbe.zErrMsg
*/
void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
va_list ap;
sqlite3DbFree(p->db, p->zErrMsg);
va_start(ap, zFormat);
p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap);
va_end(ap);
}
/*
** Remember the SQL string for a prepared statement.
*/
@ -1394,7 +1405,7 @@ int sqlite3VdbeList(
}else if( db->u1.isInterrupted ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
}else{
char *zP4;
Op *pOp;
@ -2297,7 +2308,7 @@ int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
){
p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
p->errorAction = OE_Abort;
sqlite3SetString(&p->zErrMsg, db, "FOREIGN KEY constraint failed");
sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
return SQLITE_ERROR;
}
return SQLITE_OK;

View File

@ -208,4 +208,15 @@ do_test misc4-6.2 {
}
} {1}
# 2015-05-15. Error message formatting problem.
#
db close
sqlite3 db :memory:
do_catchsql_test misc4-7.1 {
CREATE TABLE t7(x);
PRAGMA writable_schema=ON;
UPDATE sqlite_master SET sql='CREATE TABLE [M%s%s%s%s%s%s%s%s%s%s%s%s%s';
VACUUM;
} {1 {unrecognized token: "[M%s%s%s%s%s%s%s%s%s%s%s%s%s"}}
finish_test