]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When the OTA module updates or deletes a row, save only those fields that are part...
authordan <dan@noemail.net>
Tue, 24 Mar 2015 18:03:29 +0000 (18:03 +0000)
committerdan <dan@noemail.net>
Tue, 24 Mar 2015 18:03:29 +0000 (18:03 +0000)
FossilOrigin-Name: 6326fd3249bee267da0172f8afd1e7b3f71521b9

ext/ota/sqlite3ota.c
manifest
manifest.uuid

index 4728069991b5b218a87ece9ba77fe4ce039d4b20..6d0e899117083ab7816fb0dfc74cc2a23d4f7cf7 100644 (file)
@@ -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 = <idxname>" 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 = <idxname>" 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; i<pIter->nTblCol; 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);
             }
index 79b5a921e7ce0e4506fbae9db1a601f1cb5e483a..f5a7bb25c86ee67306032fe638b128b9f701727d 100644 (file)
--- 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
index 429e676afd42a8cf43b688e6ccc107f79cc794e8..c8d380d77e17f336960fb01d85fb67f1997c3271 100644 (file)
@@ -1 +1 @@
-858de8a5e7925bd96d7b9c0f00bc16358cf3b295
\ No newline at end of file
+6326fd3249bee267da0172f8afd1e7b3f71521b9
\ No newline at end of file