/ Check-in [e0b71519]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add extra tests and fixes for ota.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | ota-update
Files: files | file ages | folders
SHA1:e0b7151962fedbcac975f2216fd6b33b995a8945
User & Date: dan 2015-02-16 21:13:19
Context
2015-02-17
20:49
Improve test coverage of ota code a bit. check-in: a438fa6c user: dan tags: ota-update
2015-02-16
21:13
Add extra tests and fixes for ota. check-in: e0b71519 user: dan tags: ota-update
11:48
Add further tests and fixes for ota. check-in: 62dc1fff user: dan tags: ota-update
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/ota/ota1.test.

    52     52       INSERT INTO data_t1 VALUES(2, NULL, 5, 1);
    53     53       INSERT INTO data_t1 VALUES(3, 8, 9, 0);
    54     54       INSERT INTO data_t1 VALUES(4, NULL, 11, 1);
    55     55     }
    56     56     ota1 close
    57     57     return $filename
    58     58   }
           59  +#
           60  +# Create a simple OTA database. That expects to write to a table:
           61  +#
           62  +#   CREATE TABLE t1(c, b, '(a)' INTEGER PRIMARY KEY);
           63  +#
           64  +# This OTA includes both insert and delete operations.
           65  +#
           66  +proc create_ota4b {filename} {
           67  +  forcedelete $filename
           68  +  sqlite3 ota1 $filename  
           69  +  ota1 eval {
           70  +    CREATE TABLE data_t1(c, b, '(a)', ota_control);
           71  +    INSERT INTO data_t1 VALUES(3, 2, 1, 0);
           72  +    INSERT INTO data_t1 VALUES(5, NULL, 2, 1);
           73  +    INSERT INTO data_t1 VALUES(9, 8, 3, 0);
           74  +    INSERT INTO data_t1 VALUES(11, NULL, 4, 1);
           75  +  }
           76  +  ota1 close
           77  +  return $filename
           78  +}
    59     79   
    60     80   # Create a simple OTA database. That expects to write to a table:
    61     81   #
    62     82   #   CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
    63     83   #
    64     84   # This OTA includes update statements.
    65     85   #
................................................................................
   363    383           3 8 9
   364    384           6 hello xyz
   365    385         }
   366    386       
   367    387         do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok
   368    388       }
   369    389     }
          390  +
          391  +  foreach {tn2 cmd} {1 run_ota 2 step_ota} {
          392  +    foreach {tn schema} {
          393  +      1 {
          394  +        CREATE TABLE t1(c, b, '(a)' INTEGER PRIMARY KEY);
          395  +        CREATE INDEX i1 ON t1(c, b);
          396  +      }
          397  +      2 {
          398  +        CREATE TABLE t1(c, b, '(a)' PRIMARY KEY);
          399  +      }
          400  +      3 {
          401  +        CREATE TABLE t1(c, b, '(a)' PRIMARY KEY) WITHOUT ROWID;
          402  +      }
          403  +    } {
          404  +      reset_db
          405  +      execsql $schema
          406  +      execsql {
          407  +        INSERT INTO t1('(a)', b, c) VALUES(2, 'hello', 'world');
          408  +        INSERT INTO t1('(a)', b, c) VALUES(4, 'hello', 'planet');
          409  +        INSERT INTO t1('(a)', b, c) VALUES(6, 'hello', 'xyz');
          410  +      }
          411  +    
          412  +      do_test $tn3.4.$tn2.$tn.1 {
          413  +        create_ota4b ota.db
          414  +        $cmd test.db ota.db
          415  +      } {SQLITE_DONE}
          416  +      
          417  +      do_execsql_test $tn3.4.$tn2.$tn.2 {
          418  +        SELECT * FROM t1 ORDER BY "(a)" ASC;
          419  +      } {
          420  +        3 2 1
          421  +        9 8 3
          422  +        xyz hello 6
          423  +      }
          424  +    
          425  +      do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok
          426  +    }
          427  +  }
   370    428   
   371    429     #-------------------------------------------------------------------------
   372    430     #
   373    431     foreach {tn2 cmd} {1 run_ota 2 step_ota} {
   374    432       foreach {tn schema} {
   375    433         1 {
   376    434           CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
................................................................................
   431    489     #-------------------------------------------------------------------------
   432    490     # Test some error cases:
   433    491     # 
   434    492     #   * A virtual table with no ota_rowid column.
   435    493     #   * A no-PK table with no ota_rowid column.
   436    494     #   * A PK table with an ota_rowid column.
   437    495     #
          496  +  #   6: An update string of the wrong length
          497  +  #
   438    498     ifcapable fts3 {
   439    499       foreach {tn schema error} {
   440    500          1 {
   441    501            CREATE TABLE t1(a, b);
   442    502            CREATE TABLE ota.data_t1(a, b, ota_control);
   443    503          } {SQLITE_ERROR - table data_t1 requires ota_rowid column}
   444    504       
................................................................................
   457    517            CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control);
   458    518          } {SQLITE_ERROR - table data_t1 may not have ota_rowid column}
   459    519       
   460    520          5 {
   461    521            CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID;
   462    522            CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control);
   463    523          } {SQLITE_ERROR - table data_t1 may not have ota_rowid column}
          524  +
          525  +       6 {
          526  +         CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID;
          527  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          528  +         INSERT INTO ota.data_t1 VALUES(1, 2, 'x.x');
          529  +       } {SQLITE_ERROR - invalid ota_control value}
   464    530       
   465    531       } {
   466    532         reset_db
   467    533         forcedelete ota.db
   468    534         execsql { ATTACH 'ota.db' AS ota }
   469    535         execsql $schema
   470    536   

Changes to ext/ota/ota11.test.

    67     67     dbo close
    68     68   
    69     69     db_restore 
    70     70     hexio_write test.db 18 0101
    71     71     file exists test.db-wal
    72     72   } {1}
    73     73   
    74         -breakpoint
    75     74   do_test 2.3 {
    76     75     sqlite3ota ota test.db ota.db
    77     76     ota step
    78     77   } {SQLITE_ERROR}
    79     78   
    80     79   do_test 2.4 {
    81     80     list [catch {ota close} msg] $msg
    82     81   } {1 {SQLITE_ERROR - cannot update wal mode database}}
           82  +
           83  +#--------------------------------------------------------------------
           84  +# Test a constraint violation message with an unusual table name. 
           85  +# Specifically, one for which the first character is a codepoint
           86  +# smaller than 30 (character '0').
           87  +#
           88  +reset_db
           89  +do_execsql_test 3.1 {
           90  +  CREATE TABLE "(t1)"(a PRIMARY KEY, b, c);
           91  +  INSERT INTO "(t1)" VALUES(1, 2, 3);
           92  +  INSERT INTO "(t1)" VALUES(4, 5, 6);
           93  +}
           94  +db close
           95  +
           96  +do_test 3.2 {
           97  +  forcedelete ota.db
           98  +  sqlite3 dbo ota.db
           99  +  dbo eval {
          100  +    CREATE TABLE "data_(t1)"(a, b, c, ota_control);
          101  +    INSERT INTO "data_(t1)" VALUES(4, 8, 9, 0);
          102  +  }
          103  +  dbo close
          104  +
          105  +  sqlite3ota ota test.db ota.db
          106  +  ota step
          107  +  ota step
          108  +} {SQLITE_CONSTRAINT}
          109  +
          110  +do_test 3.3 {
          111  +  list [catch {ota close} msg] $msg
          112  +} {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: (t1).a}}
          113  +
          114  +#--------------------------------------------------------------------
          115  +# Check that once an OTA update has been applied, attempting to apply
          116  +# it a second time is a no-op (as the state stored in the OTA database is
          117  +# "all steps completed").
          118  +#
          119  +reset_db
          120  +do_execsql_test 4.1 {
          121  +  CREATE TABLE "(t1)"(a, b, c, PRIMARY KEY(c, b, a));
          122  +  INSERT INTO "(t1)" VALUES(1, 2, 3);
          123  +  INSERT INTO "(t1)" VALUES(4, 5, 6);
          124  +}
          125  +db close
          126  +
          127  +do_test 4.2 {
          128  +  forcedelete ota.db
          129  +  sqlite3 dbo ota.db
          130  +  dbo eval {
          131  +    CREATE TABLE "data_(t1)"(a, b, c, ota_control);
          132  +    INSERT INTO "data_(t1)" VALUES(7, 8, 9, 0);
          133  +    INSERT INTO "data_(t1)" VALUES(1, 2, 3, 1);
          134  +  }
          135  +  dbo close
          136  +
          137  +  sqlite3ota ota test.db ota.db
          138  +  while {[ota step]=="SQLITE_OK"} { }
          139  +  ota close
          140  +} {SQLITE_DONE}
          141  +
          142  +do_test 4.3 {
          143  +  sqlite3ota ota test.db ota.db
          144  +  ota step
          145  +} {SQLITE_DONE}
          146  +
          147  +do_test 4.4 {
          148  +  ota close
          149  +} {SQLITE_DONE}
          150  +
          151  +# Also, check that an invalid state value in the ota_state table is
          152  +# detected and reported as corruption.
          153  +do_test 4.5 {
          154  +  sqlite3 dbo ota.db
          155  +  dbo eval { UPDATE ota_state SET v = -1 WHERE k = 1 }
          156  +  dbo close
          157  +  sqlite3ota ota test.db ota.db
          158  +  ota step
          159  +} {SQLITE_CORRUPT}
          160  +do_test 4.6 {
          161  +  list [catch {ota close} msg] $msg
          162  +} {1 SQLITE_CORRUPT}
    83    163   
    84    164   finish_test
    85    165   

Changes to ext/ota/otafault.test.

    16     16   source $testdir/tester.tcl
    17     17   source $testdir/malloc_common.tcl
    18     18   set ::testprefix otafault
    19     19   
    20     20   do_test 1.1 {
    21     21     forcedelete ota.db
    22     22     execsql {
           23  +    PRAGMA encoding = utf16;
    23     24       CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
    24     25       CREATE INDEX t1cb ON t1(c, b);
    25     26       INSERT INTO t1 VALUES(1, 1, 1);
    26     27       INSERT INTO t1 VALUES(2, 2, 2);
    27     28       INSERT INTO t1 VALUES(3, 3, 3);
    28     29       CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
    29     30       CREATE INDEX t2cb ON t1(c, b);
................................................................................
    45     46     }
    46     47     db close
    47     48   
    48     49     forcecopy test.db test.db.bak
    49     50     forcecopy ota.db ota.db.bak
    50     51   } {}
    51     52   
    52         -do_faultsim_test 2 -faults oom-trans* -prep {
    53         -  catch { db close }
    54         -  forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
    55         -  forcecopy test.db.bak test.db
    56         -  forcecopy ota.db.bak  ota.db
    57         -} -body {
    58         -  sqlite3ota ota test.db ota.db
    59         -  while {[ota step]=="SQLITE_OK"} {}
    60         -  ota close
    61         -} -test {
    62         -  faultsim_test_result {0 SQLITE_DONE} \
    63         -                       {1 {SQLITE_NOMEM - out of memory}} \
    64         -                       {1 SQLITE_NOMEM} \
    65         -                       {1 SQLITE_IOERR_NOMEM} \
    66         -                       {1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}}
    67         -  if {$testrc==0} {
    68         -    sqlite3 db test.db
    69         -    faultsim_integrity_check
    70         -    set res [db eval {
    71         -      SELECT * FROM t1 UNION ALL SELECT * FROM t2;
    72         -    }]
    73         -    set expected [list {*}{
    74         -      1 1 1   3 three 3   4 4 4
    75         -      a a a   c see c     d d d
    76         -    }]
    77         -
    78         -    if {$res != $expected} {
    79         -      puts ""
    80         -      puts "res: $res"
    81         -      puts "exp: $expected"
    82         -      error "data not as expected!"
           53  +sqlite3_shutdown
           54  +set lookaside_config [sqlite3_config_lookaside 0 0]
           55  +sqlite3_initialize
           56  +autoinstall_test_functions
           57  +
           58  +foreach {tn f reslist} {
           59  +  1 oom-tra*  {
           60  +    {0 SQLITE_DONE} 
           61  +    {1 {SQLITE_NOMEM - out of memory}} 
           62  +    {1 SQLITE_NOMEM} 
           63  +    {1 SQLITE_IOERR_NOMEM} 
           64  +    {1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}}
           65  +  }
           66  +  2 ioerr-*  {
           67  +    {0 SQLITE_DONE} 
           68  +    {1 {SQLITE_IOERR - disk I/O error}}
           69  +    {1 SQLITE_IOERR}
           70  +    {1 SQLITE_IOERR_WRITE}
           71  +    {1 SQLITE_IOERR_READ}
           72  +    {1 SQLITE_IOERR_FSYNC}
           73  +    {1 {SQLITE_ERROR - SQL logic error or missing database}}
           74  +    {1 {SQLITE_ERROR - unable to open database: ota.db}}
           75  +    {1 {SQLITE_IOERR - unable to open database: ota.db}}
           76  +  }
           77  +} {
           78  +  do_faultsim_test 2 -faults $::f -prep {
           79  +    catch { db close }
           80  +    forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
           81  +    forcecopy test.db.bak test.db
           82  +    forcecopy ota.db.bak  ota.db
           83  +  } -body {
           84  +    sqlite3ota ota test.db ota.db
           85  +    while {[ota step]=="SQLITE_OK"} {}
           86  +    ota close
           87  +  } -test {
           88  +    faultsim_test_result {*}$::reslist
           89  +    if {$testrc==0} {
           90  +      sqlite3 db test.db
           91  +      faultsim_integrity_check
           92  +      set res [db eval {
           93  +        SELECT * FROM t1 UNION ALL SELECT * FROM t2;
           94  +      }]
           95  +      set expected [list {*}{
           96  +        1 1 1   3 three 3   4 4 4
           97  +        a a a   c see c     d d d
           98  +      }]
           99  +  
          100  +      if {$res != $expected} {
          101  +        puts ""
          102  +        puts "res: $res"
          103  +        puts "exp: $expected"
          104  +        error "data not as expected!"
          105  +      }
    83    106       }
    84    107     }
    85    108   }
    86    109   
          110  +catch {db close}
          111  +sqlite3_shutdown
          112  +sqlite3_config_lookaside {*}$lookaside_config
          113  +sqlite3_initialize
          114  +autoinstall_test_functions
          115  +
    87    116   proc copy_if_exists {src target} {
    88    117     if {[file exists $src]} {
    89    118       forcecopy $src $target
    90    119     } else {
    91    120       forcedelete $target
    92    121     }
    93    122   }

Changes to ext/ota/sqlite3ota.c.

   390    390           rc = sqlite3_step(pIter->pTblIter);
   391    391           if( rc!=SQLITE_ROW ){
   392    392             rc = sqlite3_reset(pIter->pTblIter);
   393    393             pIter->zTbl = 0;
   394    394           }else{
   395    395             pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
   396    396             pIter->iTnum = sqlite3_column_int(pIter->pTblIter, 1);
   397         -          rc = SQLITE_OK;
          397  +          rc = pIter->zTbl ? SQLITE_OK : SQLITE_NOMEM;
   398    398           }
   399    399         }else{
   400    400           if( pIter->zIdx==0 ){
   401         -          sqlite3_bind_text(pIter->pIdxIter, 1, pIter->zTbl, -1, SQLITE_STATIC);
          401  +          sqlite3_stmt *pIdx = pIter->pIdxIter;
          402  +          rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC);
   402    403           }
   403         -        rc = sqlite3_step(pIter->pIdxIter);
   404         -        if( rc!=SQLITE_ROW ){
   405         -          rc = sqlite3_reset(pIter->pIdxIter);
   406         -          pIter->bCleanup = 1;
   407         -          pIter->zIdx = 0;
   408         -        }else{
   409         -          pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0);
   410         -          pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1);
   411         -          pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2);
   412         -          rc = SQLITE_OK;
          404  +        if( rc==SQLITE_OK ){
          405  +          rc = sqlite3_step(pIter->pIdxIter);
          406  +          if( rc!=SQLITE_ROW ){
          407  +            rc = sqlite3_reset(pIter->pIdxIter);
          408  +            pIter->bCleanup = 1;
          409  +            pIter->zIdx = 0;
          410  +          }else{
          411  +            pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0);
          412  +            pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1);
          413  +            pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2);
          414  +            rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM;
          415  +          }
   413    416           }
   414    417         }
   415    418       }
   416    419     }
   417    420   
   418    421     if( rc!=SQLITE_OK ){
   419    422       otaObjIterFinalize(pIter);
................................................................................
   721    724       if( p->rc==SQLITE_OK ){
   722    725         p->rc = prepareFreeAndCollectError(p->db, &pStmt, &p->zErrmsg, 
   723    726             sqlite3_mprintf("PRAGMA main.table_info(%Q)", pIter->zTbl)
   724    727         );
   725    728       }
   726    729       while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
   727    730         const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
          731  +      if( zName==0 ) break;  /* An OOM - finalize() below returns S_NOMEM */
   728    732         for(i=iOrder; i<pIter->nTblCol; i++){
   729    733           if( 0==strcmp(zName, pIter->azTblCol[i]) ) break;
   730    734         }
   731    735         if( i==pIter->nTblCol ){
   732    736           p->rc = SQLITE_ERROR;
   733    737           p->zErrmsg = sqlite3_mprintf("column missing from data_%q: %s",
   734    738               pIter->zTbl, zName
................................................................................
   859    863       const char *zType;
   860    864   
   861    865       if( iCid<0 ){
   862    866         /* An integer primary key. If the table has an explicit IPK, use
   863    867         ** its name. Otherwise, use "ota_rowid".  */
   864    868         if( pIter->eType==OTA_PK_IPK ){
   865    869           int i;
   866         -        for(i=0; i<pIter->nTblCol && pIter->abTblPk[i]==0; i++);
          870  +        for(i=0; pIter->abTblPk[i]==0; i++);
   867    871           assert( i<pIter->nTblCol );
   868    872           zCol = pIter->azTblCol[i];
   869    873         }else{
   870    874           zCol = "ota_rowid";
   871    875         }
   872    876         zType = "INTEGER";
   873    877       }else{
................................................................................
  1003   1007   ** (p->objiter.pSelect) currently points to a valid row. However, there
  1004   1008   ** is something wrong with the ota_control value in the ota_control value
  1005   1009   ** stored in the (p->nCol+1)'th column. Set the error code and error message
  1006   1010   ** of the OTA handle to something reflecting this.
  1007   1011   */
  1008   1012   static void otaBadControlError(sqlite3ota *p){
  1009   1013     p->rc = SQLITE_ERROR;
  1010         -  p->zErrmsg = sqlite3_mprintf("Invalid ota_control value");
         1014  +  p->zErrmsg = sqlite3_mprintf("invalid ota_control value");
  1011   1015   }
  1012   1016   
  1013   1017   
  1014   1018   static char *otaObjIterGetSetlist(
  1015   1019     sqlite3ota *p,
  1016   1020     OtaObjIter *pIter,
  1017   1021     const char *zMask
................................................................................
  1082   1086   
  1083   1087      
  1084   1088       p->rc = prepareFreeAndCollectError(p->db, &pXList, &p->zErrmsg,
  1085   1089           sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
  1086   1090       );
  1087   1091       while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){
  1088   1092         const char *zOrig = (const char*)sqlite3_column_text(pXList,3);
  1089         -      if( zOrig && strcmp(zOrig,"pk")==0 ){
  1090         -        p->rc = prepareFreeAndCollectError(p->db, &pXInfo, &p->zErrmsg,
  1091         -          sqlite3_mprintf("PRAGMA main.index_xinfo = %Q",
  1092         -                           sqlite3_column_text(pXList,1))
  1093         -        );
         1093  +      if( zOrig && strcmp(zOrig, "pk")==0 ){
         1094  +        const char *zIdx = (const char*)sqlite3_column_text(pXList,1);
         1095  +        if( zIdx ){
         1096  +          p->rc = prepareFreeAndCollectError(p->db, &pXInfo, &p->zErrmsg,
         1097  +              sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
         1098  +          );
         1099  +        }
  1094   1100           break;
  1095   1101         }
  1096   1102       }
  1097         -    sqlite3_finalize(pXList);
         1103  +    rc = sqlite3_finalize(pXList);
         1104  +    if( p->rc==SQLITE_OK ) p->rc = rc;
         1105  +
  1098   1106       while( p->rc==SQLITE_OK && pXInfo && SQLITE_ROW==sqlite3_step(pXInfo) ){
  1099   1107         if( sqlite3_column_int(pXInfo, 5) ){
  1100   1108           /* int iCid = sqlite3_column_int(pXInfo, 0); */
  1101   1109           const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2);
  1102   1110           const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : "";
  1103   1111           z = otaMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc);
  1104   1112           zSep = ", ";
  1105   1113         }
  1106   1114       }
  1107   1115       z = otaMPrintf(p, "%z)", z);
  1108         -
  1109   1116       rc = sqlite3_finalize(pXInfo);
  1110   1117       if( p->rc==SQLITE_OK ) p->rc = rc;
  1111   1118     }
  1112   1119     return z;
  1113   1120   }
  1114   1121   
  1115   1122   static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){
................................................................................
  1726   1733           res = OTA_IDX_DELETE;
  1727   1734         }else if( iVal==3 ){
  1728   1735           res = OTA_IDX_INSERT;
  1729   1736         }
  1730   1737         break;
  1731   1738       }
  1732   1739   
  1733         -    case SQLITE_TEXT:
  1734         -      *pzMask = (const char*)sqlite3_column_text(p->objiter.pSelect, iCol);
         1740  +    case SQLITE_TEXT: {
         1741  +      const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol);
         1742  +      if( z==0 ){
         1743  +        p->rc = SQLITE_NOMEM;
         1744  +      }else{
         1745  +        *pzMask = (const char*)z;
         1746  +      }
  1735   1747         res = OTA_UPDATE;
         1748  +
  1736   1749         break;
         1750  +    }
  1737   1751   
  1738   1752       default:
  1739   1753         break;
  1740   1754     }
  1741   1755   
  1742   1756     if( res==0 ){
  1743   1757       otaBadControlError(p);
................................................................................
  1809   1823           }
  1810   1824   
  1811   1825           if( eType==SQLITE_DELETE && pIter->zIdx==0 && pIter->abTblPk[i]==0 ){
  1812   1826             continue;
  1813   1827           }
  1814   1828   
  1815   1829           pVal = sqlite3_column_value(pIter->pSelect, i);
  1816         -        sqlite3_bind_value(pWriter, i+1, pVal);
         1830  +        p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
         1831  +        if( p->rc==SQLITE_RANGE ) p->rc = SQLITE_OK;
         1832  +        if( p->rc ) goto step_out;
  1817   1833         }
  1818   1834         if( pIter->zIdx==0
  1819   1835          && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE) 
  1820   1836         ){
  1821   1837           /* For a virtual table, or a table with no primary key, the 
  1822   1838           ** SELECT statement is:
  1823   1839           **
  1824   1840           **   SELECT <cols>, ota_control, ota_rowid FROM ....
  1825   1841           **
  1826   1842           ** Hence column_value(pIter->nCol+1).
  1827   1843           */
  1828   1844           assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
  1829   1845           pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
  1830         -        sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
         1846  +        p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
  1831   1847         }
  1832         -      sqlite3_step(pWriter);
  1833         -      p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
         1848  +      if( p->rc==SQLITE_OK ){
         1849  +        sqlite3_step(pWriter);
         1850  +        p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
         1851  +      }
  1834   1852       }else if( eType==OTA_UPDATE ){
  1835   1853         sqlite3_value *pVal;
  1836   1854         sqlite3_stmt *pUpdate = 0;
  1837   1855         otaGetUpdateStmt(p, pIter, zMask, &pUpdate);
  1838   1856         if( pUpdate ){
  1839   1857           for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
         1858  +          char c = zMask[pIter->aiSrcOrder[i]];
  1840   1859             pVal = sqlite3_column_value(pIter->pSelect, i);
  1841         -          sqlite3_bind_value(pUpdate, i+1, pVal);
         1860  +          if( pIter->abTblPk[i] || c=='x' || c=='d' ){
         1861  +            p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
         1862  +          }
  1842   1863           }
  1843         -        if( pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE ){
         1864  +        if( p->rc==SQLITE_OK 
         1865  +         && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE) 
         1866  +        ){
  1844   1867             /* Bind the ota_rowid value to column _rowid_ */
  1845   1868             assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
  1846   1869             pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
  1847         -          sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
         1870  +          p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
  1848   1871           }
  1849         -        sqlite3_step(pUpdate);
  1850         -        p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
         1872  +        if( p->rc==SQLITE_OK ){
         1873  +          sqlite3_step(pUpdate);
         1874  +          p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
         1875  +        }
  1851   1876         }
  1852   1877       }else{
  1853   1878         /* no-op */
  1854   1879         assert( eType==OTA_DELETE && pIter->zIdx );
  1855   1880       }
  1856   1881     }
  1857   1882   
................................................................................
  2175   2200       }
  2176   2201   
  2177   2202       /* If it has not already been created, create the ota_state table */
  2178   2203       if( p->rc==SQLITE_OK ){
  2179   2204         p->rc = sqlite3_exec(p->db, OTA_CREATE_STATE, 0, 0, &p->zErrmsg);
  2180   2205       }
  2181   2206   
  2182         -    /* Check that this is not a wal mode database. If it is, it cannot be
  2183         -    ** updated. There is also a check for a live *-wal file in otaVfsAccess()
  2184         -    ** function, on the off chance that the target is a wal database for
  2185         -    ** which the first page of the db file has been overwritten by garbage
  2186         -    ** during an earlier failed checkpoint.  */
  2187         -#if 0
  2188         -    if( p->rc==SQLITE_OK && p->pTargetFd->iWriteVer>1 ){
  2189         -      p->rc = SQLITE_ERROR;
  2190         -      p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
  2191         -    }
  2192         -#endif
  2193         -
  2194   2207       if( p->rc==SQLITE_OK ){
  2195   2208         pState = otaLoadState(p);
  2196   2209         assert( pState || p->rc!=SQLITE_OK );
  2197   2210         if( p->rc==SQLITE_OK ){
  2198   2211   
  2199   2212           if( pState->eStage==0 ){ 
  2200   2213             otaDeleteOalFile(p);
................................................................................
  2205   2218           p->nProgress = pState->nProgress;
  2206   2219         }
  2207   2220       }
  2208   2221       assert( p->rc!=SQLITE_OK || p->eStage!=0 );
  2209   2222   
  2210   2223       if( p->rc==SQLITE_OK ){
  2211   2224         if( p->eStage==OTA_STAGE_OAL ){
         2225  +
         2226  +        /* Check that this is not a wal mode database. If it is, it cannot 
         2227  +        ** be updated.  */
  2212   2228           if( p->pTargetFd->pWalFd ){
  2213   2229             p->rc = SQLITE_ERROR;
  2214   2230             p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
  2215   2231           }
  2216   2232   
  2217   2233           /* At this point (pTargetFd->iCookie) contains the value of the
  2218   2234           ** change-counter cookie (the thing that gets incremented when a 
................................................................................
  2239   2255             otaLoadTransactionState(p, pState);
  2240   2256           }
  2241   2257         }else if( p->eStage==OTA_STAGE_CKPT ){
  2242   2258           otaSetupCheckpoint(p, pState);
  2243   2259           p->nStep = pState->nRow;
  2244   2260         }else if( p->eStage==OTA_STAGE_DONE ){
  2245   2261           p->rc = SQLITE_DONE;
         2262  +      }else{
         2263  +        p->rc = SQLITE_CORRUPT;
  2246   2264         }
  2247   2265       }
  2248   2266   
  2249   2267       otaFreeState(pState);
  2250   2268     }
  2251   2269   
  2252   2270     return p;
................................................................................
  2414   2432     void *zBuf, 
  2415   2433     int iAmt, 
  2416   2434     sqlite_int64 iOfst
  2417   2435   ){
  2418   2436     ota_file *p = (ota_file*)pFile;
  2419   2437     int rc;
  2420   2438   
  2421         -  if( p->pOta 
  2422         -   && p->pOta->eStage==OTA_STAGE_CAPTURE
  2423         -   && (p->openFlags & SQLITE_OPEN_WAL) 
  2424         -  ){
         2439  +  if( p->pOta && p->pOta->eStage==OTA_STAGE_CAPTURE ){
         2440  +    assert( p->openFlags & SQLITE_OPEN_WAL );
  2425   2441       rc = otaCaptureWalRead(p->pOta, iOfst, iAmt);
  2426   2442     }else{
  2427   2443       rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
  2428   2444       if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
  2429   2445         /* These look like magic numbers. But they are stable, as they are part
  2430   2446          ** of the definition of the SQLite file format, which may not change. */
  2431   2447         u8 *pBuf = (u8*)zBuf;
................................................................................
  2443   2459     sqlite3_file *pFile, 
  2444   2460     const void *zBuf, 
  2445   2461     int iAmt, 
  2446   2462     sqlite_int64 iOfst
  2447   2463   ){
  2448   2464     ota_file *p = (ota_file*)pFile;
  2449   2465     int rc;
  2450         -  if( p->pOta 
  2451         -   && p->pOta->eStage==OTA_STAGE_CAPTURE
  2452         -   && (p->openFlags & SQLITE_OPEN_MAIN_DB)
  2453         -  ){
         2466  +  if( p->pOta && p->pOta->eStage==OTA_STAGE_CAPTURE ){
         2467  +    assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
  2454   2468       rc = otaCaptureDbWrite(p->pOta, iOfst);
  2455   2469     }else{
  2456   2470       rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
  2457   2471       if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
  2458   2472         /* These look like magic numbers. But they are stable, as they are part
  2459   2473         ** of the definition of the SQLite file format, which may not change. */
  2460   2474         u8 *pBuf = (u8*)zBuf;