From: dan Date: Tue, 24 Mar 2015 18:03:29 +0000 (+0000) Subject: When the OTA module updates or deletes a row, save only those fields that are part... X-Git-Tag: version-3.8.11~252^2~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f37120a416aee4703f5305e68c7535927678cc87;p=thirdparty%2Fsqlite.git When the OTA module updates or deletes a row, save only those fields that are part of an index or primary key to the ota update database. FossilOrigin-Name: 6326fd3249bee267da0172f8afd1e7b3f71521b9 --- diff --git a/ext/ota/sqlite3ota.c b/ext/ota/sqlite3ota.c index 4728069991..6d0e899117 100644 --- a/ext/ota/sqlite3ota.c +++ b/ext/ota/sqlite3ota.c @@ -203,6 +203,13 @@ struct OtaState { ** * the table itself, ** * each index of the table (zero or more points to visit), and ** * a special "cleanup table" state. +** +** abIndexed: +** If the table has no indexes on it, abIndexed is set to NULL. Otherwise, +** it points to an array of flags nTblCol elements in size. The flag is +** set for each column that is either a part of the PK or a part of an +** index. Or clear otherwise. +** */ struct OtaObjIter { sqlite3_stmt *pTblIter; /* Iterate through tables */ @@ -213,6 +220,7 @@ struct OtaObjIter { int *aiSrcOrder; /* src table col -> target table col */ u8 *abTblPk; /* Array of flags, set on target PK columns */ u8 *abNotNull; /* Array of flags, set on NOT NULL columns */ + u8 *abIndexed; /* Array of flags, set on indexed & PK cols */ int eType; /* Table type - an OTA_PK_XXX value */ /* Output variables. zTbl==0 implies EOF. */ @@ -638,7 +646,7 @@ static void *otaMalloc(sqlite3ota *p, int nByte){ ** error code in the OTA handle passed as the first argument. */ static void otaAllocateIterArrays(sqlite3ota *p, OtaObjIter *pIter, int nCol){ - int nByte = (2*sizeof(char*) + sizeof(int) + 2*sizeof(u8)) * nCol; + int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol; char **azNew; azNew = (char**)otaMalloc(p, nByte); @@ -648,6 +656,7 @@ static void otaAllocateIterArrays(sqlite3ota *p, OtaObjIter *pIter, int nCol){ pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol]; pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol]; pIter->abNotNull = (u8*)&pIter->abTblPk[nCol]; + pIter->abIndexed = (u8*)&pIter->abNotNull[nCol]; } } @@ -813,6 +822,40 @@ otaTableType_end: { } } +/* +** This is a helper function for otaObjIterCacheTableInfo(). It populates +** the pIter->abIndexed[] array. +*/ +static void otaObjIterCacheIndexedCols(sqlite3ota *p, OtaObjIter *pIter){ + sqlite3_stmt *pList = 0; + int bIndex = 0; + + if( p->rc==SQLITE_OK ){ + memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol); + p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) + ); + } + + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ + const char *zIdx = (const char*)sqlite3_column_text(pList, 1); + sqlite3_stmt *pXInfo = 0; + if( zIdx==0 ) break; + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + if( iCid>=0 ) pIter->abIndexed[iCid] = 1; + } + otaFinalize(p, pXInfo); + bIndex = 1; + } + + otaFinalize(p, pList); + if( bIndex==0 ) pIter->abIndexed = 0; +} + /* ** If they are not already populated, populate the pIter->azTblCol[], @@ -918,6 +961,8 @@ static int otaObjIterCacheTableInfo(sqlite3ota *p, OtaObjIter *pIter){ } otaFinalize(p, pStmt); + otaObjIterCacheIndexedCols(p, pIter); + assert( pIter->eType!=OTA_PK_VTAB || pIter->abIndexed==0 ); } return p->rc; @@ -946,10 +991,10 @@ static char *otaObjIterGetCollist( /* ** This function is used to create a SELECT list (the list of SQL ** expressions that follows a SELECT keyword) for a SELECT statement -** used to read from an ota_xxx table while updating the index object -** currently indicated by the iterator object passed as the second -** argument. A "PRAGMA index_xinfo = " statement is used to -** obtain the required information. +** used to read from an data_xxx or ota_tmp_xxx table while updating the +** index object currently indicated by the iterator object passed as the +** second argument. A "PRAGMA index_xinfo = " statement is used +** to obtain the required information. ** ** If the index is of the following form: ** @@ -1075,12 +1120,16 @@ static char *otaObjIterGetOldlist( const char *zObj ){ char *zList = 0; - if( p->rc==SQLITE_OK ){ + if( p->rc==SQLITE_OK && pIter->abIndexed ){ const char *zS = ""; int i; for(i=0; inTblCol; i++){ - const char *zCol = pIter->azTblCol[i]; - zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol); + if( pIter->abIndexed[i] ){ + const char *zCol = pIter->azTblCol[i]; + zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol); + }else{ + zList = sqlite3_mprintf("%z%sNULL", zList, zS); + } zS = ", "; if( zList==0 ){ p->rc = SQLITE_NOMEM; @@ -1612,7 +1661,7 @@ static int otaObjIterPrepareAll( ); } - if( pIter->eType!=OTA_PK_VTAB ){ + if( pIter->abIndexed ){ const char *zOtaRowid = ""; if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){ zOtaRowid = ", ota_rowid"; @@ -2283,7 +2332,7 @@ int sqlite3ota_step(sqlite3ota *p){ /* Clean up the ota_tmp_xxx table for the previous table. It ** cannot be dropped as there are currently active SQL statements. ** But the contents can be deleted. */ - if( pIter->eType!=OTA_PK_VTAB ){ + if( pIter->abIndexed ){ const char *zTbl = pIter->zTbl; otaMPrintfExec(p, p->dbOta, "DELETE FROM 'ota_tmp_%q'", zTbl); } diff --git a/manifest b/manifest index 79b5a921e7..f5a7bb25c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbroken\sassert()\sin\sthe\sota\smodule. -D 2015-03-23T17:10:51.066 +C When\sthe\sOTA\smodule\supdates\sor\sdeletes\sa\srow,\ssave\sonly\sthose\sfields\sthat\sare\spart\sof\san\sindex\sor\sprimary\skey\sto\sthe\sota\supdate\sdatabase. +D 2015-03-24T18:03:29.870 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -138,7 +138,7 @@ F ext/ota/otaA.test ef4bfa8cfd4ed814ae86f7457b64aa2f18c90171 F ext/ota/otacrash.test a078d34e2edbcedac5f894e3e7d08d452a327007 F ext/ota/otafault.test 8c43586c2b96ca16bbce00b5d7e7d67316126db8 F ext/ota/otafault2.test fa202a98ca221faec318f3e5c5f39485b1256561 -F ext/ota/sqlite3ota.c 1d3b605c27622efdc288a3ac94ab199d1c8b5ea0 +F ext/ota/sqlite3ota.c 9c16cd3bf99d2591a8a0b56b114ebbf839d42399 F ext/ota/sqlite3ota.h f1a9dd98b00fa622c7e2eb68e580ee02e194c4d6 F ext/ota/test_ota.c e34c801c665d64b4b9e00b71f1acf8c652404b2b F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1261,7 +1261,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 52e73eeca063bb30092ce600068bf487641399a0 -R a9aebe9b51af54f1535cb011847cd5d2 +P 858de8a5e7925bd96d7b9c0f00bc16358cf3b295 +R 8b55a1f50bfcaf2003b1038217883d03 U dan -Z 141e2fc0ed2825bfcd2784386daf5cbd +Z 9f88de65f5585dc798e54fceff613e97 diff --git a/manifest.uuid b/manifest.uuid index 429e676afd..c8d380d77e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -858de8a5e7925bd96d7b9c0f00bc16358cf3b295 \ No newline at end of file +6326fd3249bee267da0172f8afd1e7b3f71521b9 \ No newline at end of file