From: dan Date: Wed, 4 Feb 2015 19:20:42 +0000 (+0000) Subject: Fix the error messages returned by ota if an update violates a unique constraint. X-Git-Tag: version-3.8.11~252^2~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06c97225641821330871db5efdd964a5e2793087;p=thirdparty%2Fsqlite.git Fix the error messages returned by ota if an update violates a unique constraint. FossilOrigin-Name: c4845a3b591723ff60b7b1da198f44908c12bdfc --- diff --git a/ext/ota/sqlite3ota.c b/ext/ota/sqlite3ota.c index 6c7437d5e1..e6882d855d 100644 --- a/ext/ota/sqlite3ota.c +++ b/ext/ota/sqlite3ota.c @@ -674,12 +674,16 @@ static char *otaObjIterGetIndexCols( zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate); if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){ const char *zOrder = (bDesc ? " DESC" : ""); - zImpPK = sqlite3_mprintf("%z%sc%d%s", zImpPK, zCom, nBind, zOrder); + zImpPK = sqlite3_mprintf("%z%s\"ota_imp_%d%w\"%s", + zImpPK, zCom, nBind, zCol, zOrder + ); } - zImpCols = sqlite3_mprintf( - "%z%sc%d %s COLLATE %Q", zImpCols, zCom, nBind, zType, zCollate + zImpCols = sqlite3_mprintf("%z%s\"ota_imp_%d%w\" %s COLLATE %Q", + zImpCols, zCom, nBind, zCol, zType, zCollate + ); + zWhere = sqlite3_mprintf( + "%z%s\"ota_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol ); - zWhere = sqlite3_mprintf("%z%sc%d IS ?", zWhere, zAnd, nBind); if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM; zCom = ", "; zAnd = " AND "; @@ -1028,8 +1032,9 @@ static void otaCreateImposterTable(sqlite3ota *p, OtaObjIter *pIter){ } } - zSql = otaMPrintf(p, "CREATE TABLE ota_imposter(%z)%s", - zSql, (pIter->eType==OTA_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") + zSql = otaMPrintf(p, "CREATE TABLE \"ota_imp_%w\"(%z)%s", + pIter->zTbl, zSql, + (pIter->eType==OTA_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") ); if( p->rc==SQLITE_OK ){ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); @@ -1064,6 +1069,7 @@ static int otaObjIterPrepareAll( } if( zIdx ){ + const char *zTbl = pIter->zTbl; char *zImposterCols = 0; /* Columns for imposter table */ char *zImposterPK = 0; /* Primary key declaration for imposter */ char *zWhere = 0; /* WHERE clause on PK columns */ @@ -1080,8 +1086,8 @@ static int otaObjIterPrepareAll( sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); otaMPrintfExec(p, - "CREATE TABLE ota_imposter( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", - zImposterCols, zImposterPK + "CREATE TABLE \"ota_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", + zTbl, zImposterCols, zImposterPK ); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); @@ -1089,14 +1095,14 @@ static int otaObjIterPrepareAll( pIter->nCol = nBind; if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->db, &pIter->pInsert, &p->zErrmsg, - sqlite3_mprintf("INSERT INTO ota_imposter VALUES(%s)", zBind) + sqlite3_mprintf("INSERT INTO \"ota_imp_%w\" VALUES(%s)", zTbl, zBind) ); } /* And to delete index entries */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->db, &pIter->pDelete, &p->zErrmsg, - sqlite3_mprintf("DELETE FROM ota_imposter WHERE %s", zWhere) + sqlite3_mprintf("DELETE FROM \"ota_imp_%w\" WHERE %s", zTbl, zWhere) ); } @@ -1154,14 +1160,14 @@ static int otaObjIterPrepareAll( /* Create the imposter table or tables (if required). */ otaCreateImposterTable(p, pIter); otaCreateImposterTable2(p, pIter); - zWrite = (pIter->eType==OTA_PK_VTAB ? zTbl : "ota_imposter"); + zWrite = (pIter->eType==OTA_PK_VTAB ? "" : "ota_imp_"); /* Create the INSERT statement to write to the target PK b-tree */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->db, &pIter->pInsert, pz, sqlite3_mprintf( - "INSERT INTO main.%Q(%s%s) VALUES(%s)", - zWrite, zCollist, (bOtaRowid ? ", _rowid_" : ""), zBindings + "INSERT INTO main.\"%s%w\"(%s%s) VALUES(%s)", + zWrite, zTbl, zCollist, (bOtaRowid ? ", _rowid_" : ""), zBindings ) ); } @@ -1170,7 +1176,7 @@ static int otaObjIterPrepareAll( if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->db, &pIter->pDelete, pz, sqlite3_mprintf( - "DELETE FROM main.%Q WHERE %s", zWrite, zWhere + "DELETE FROM main.\"%s%w\" WHERE %s", zWrite, zTbl, zWhere ) ); } @@ -1183,42 +1189,39 @@ static int otaObjIterPrepareAll( /* Create the ota_tmp_xxx table and the triggers to populate it. */ otaMPrintfExec(p, - "PRAGMA ota_mode = 1;" "CREATE TABLE IF NOT EXISTS ota.'ota_tmp_%q' AS " "SELECT *%s FROM ota.'data_%q' WHERE 0;" - "CREATE TEMP TRIGGER ota_delete_tr BEFORE DELETE ON ota_imposter " + "CREATE TEMP TRIGGER ota_delete_tr BEFORE DELETE ON \"%s%w\" " "BEGIN " " INSERT INTO 'ota_tmp_%q'(ota_control, %s%s) VALUES(2, %s);" "END;" - "CREATE TEMP TRIGGER ota_update1_tr BEFORE UPDATE ON ota_imposter " + "CREATE TEMP TRIGGER ota_update1_tr BEFORE UPDATE ON \"%s%w\" " "BEGIN " " INSERT INTO 'ota_tmp_%q'(ota_control, %s%s) VALUES(2, %s);" "END;" - "CREATE TEMP TRIGGER ota_update2_tr AFTER UPDATE ON ota_imposter " + "CREATE TEMP TRIGGER ota_update2_tr AFTER UPDATE ON \"%s%w\" " "BEGIN " " INSERT INTO 'ota_tmp_%q'(ota_control, %s%s) VALUES(3, %s);" "END;" , zTbl, (pIter->eType==OTA_PK_EXTERNAL ? ", 0 AS ota_rowid" : "") , zTbl, - zTbl, zCollist, zOtaRowid, zOldlist, - zTbl, zCollist, zOtaRowid, zOldlist, - zTbl, zCollist, zOtaRowid, zNewlist + zWrite, zTbl, zTbl, zCollist, zOtaRowid, zOldlist, + zWrite, zTbl, zTbl, zCollist, zOtaRowid, zOldlist, + zWrite, zTbl, zTbl, zCollist, zOtaRowid, zNewlist ); if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){ otaMPrintfExec(p, - "CREATE TEMP TRIGGER ota_insert_tr AFTER INSERT ON ota_imposter " + "CREATE TEMP TRIGGER ota_insert_tr AFTER INSERT ON \"%s%w\" " "BEGIN " " INSERT INTO 'ota_tmp_%q'(ota_control, %s, ota_rowid)" " VALUES(0, %s);" - "END;" - , zTbl, zCollist, zNewlist + "END;", + zWrite, zTbl, zTbl, zCollist, zNewlist ); } - }else if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->db, "PRAGMA ota_mode = 0", 0, 0, &p->zErrmsg); } /* Allocate space required for the zMask field. */ @@ -1265,9 +1268,11 @@ static int otaGetUpdateStmt( sqlite3_finalize(pIter->pUpdate); pIter->pUpdate = 0; if( p->rc==SQLITE_OK ){ - zUpdate = sqlite3_mprintf("UPDATE \"%w\" SET %s WHERE %s", - (pIter->eType==OTA_PK_VTAB ? pIter->zTbl : "ota_imposter"), - zSet, zWhere + const char *zPrefix = ""; + + if( pIter->eType!=OTA_PK_VTAB ) zPrefix = "ota_imp_"; + zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", + zPrefix, pIter->zTbl, zSet, zWhere ); p->rc = prepareFreeAndCollectError( p->db, &pIter->pUpdate, &p->zErrmsg, zUpdate @@ -1852,7 +1857,6 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){ const char *zScript = "PRAGMA journal_mode=off;" "PRAGMA pager_ota_mode=1;" - "PRAGMA ota_mode=1;" "BEGIN IMMEDIATE;" ; p->rc = sqlite3_exec(p->db, zScript, 0, 0, &p->zErrmsg); @@ -1891,6 +1895,27 @@ sqlite3 *sqlite3ota_db(sqlite3ota *pOta){ return (pOta ? pOta->db : 0); } + +/* +** If the error code currently stored in the OTA handle is SQLITE_CONSTRAINT, +** then edit any error message string so as to remove all occurrences of +** the pattern "ota_imp_[0-9]*". +*/ +static void otaEditErrmsg(sqlite3ota *p){ + if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){ + int i; + int nErrmsg = strlen(p->zErrmsg); + for(i=0; i<(nErrmsg-8); i++){ + if( memcmp(&p->zErrmsg[i], "ota_imp_", 8)==0 ){ + int nDel = 8; + while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++; + memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel); + nErrmsg -= nDel; + } + } + } +} + /* ** Close the OTA handle. */ @@ -1923,6 +1948,7 @@ int sqlite3ota_close(sqlite3ota *p, char **pzErrmsg){ if( p->pCkpt ) sqlite3_ckpt_close(p->pCkpt, 0, 0); sqlite3_close(p->db); + otaEditErrmsg(p); rc = p->rc; *pzErrmsg = p->zErrmsg; sqlite3_free(p); diff --git a/manifest b/manifest index b19a7886de..bbae196aaa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\slinear\sscan\sof\sthe\sentire\stable\swhen\sota\supdates\sor\sdeletes\sa\srow\sfrom\sa\stable\swith\san\sexternal\sprimary\skey\sindex. -D 2015-02-04T16:32:47.267 +C Fix\sthe\serror\smessages\sreturned\sby\sota\sif\san\supdate\sviolates\sa\sunique\sconstraint. +D 2015-02-04T19:20:42.631 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5407a688f4d77a05c18a8142be8ae5a2829dd610 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -136,7 +136,7 @@ F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b F ext/ota/otafault.test 508ba87c83d632670ac0f94371a465d4bb4d49dd -F ext/ota/sqlite3ota.c 8d1f7f1643b85bd442cc99a919b1bbbac5b1d785 +F ext/ota/sqlite3ota.c 41df903106a0107aa70068090b263c93a502da72 F ext/ota/sqlite3ota.h ce378c0c503f625611713133f9c79704ea4ee7a4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 14e6239434d4e3f65d3e90320713f26aa24e167f @@ -1254,7 +1254,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 0d5415f26427d0af89663c5a3e944e488143b648 -R f9a2d13b5d717bd34c88d8b13812d5f5 +P 1db198ccca1e5c5a922cefe3daeff8d2e5d3a7f7 +R d14aafac71cb07666d32346674c8200d U dan -Z 54797f4495fbc966460447f60ea02156 +Z f2b3565f17adbd359615b6fecd58bae9 diff --git a/manifest.uuid b/manifest.uuid index e98583da50..a3e199e74c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1db198ccca1e5c5a922cefe3daeff8d2e5d3a7f7 \ No newline at end of file +c4845a3b591723ff60b7b1da198f44908c12bdfc \ No newline at end of file