]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further coverage tests for the session module.
authordan <dan@noemail.net>
Mon, 18 Apr 2011 07:36:27 +0000 (07:36 +0000)
committerdan <dan@noemail.net>
Mon, 18 Apr 2011 07:36:27 +0000 (07:36 +0000)
FossilOrigin-Name: 69a01c708bf044eacf21a8951fe9e7d9fb4332c5

ext/session/session2.test
ext/session/sessionfault.test
ext/session/sqlite3session.c
manifest
manifest.uuid

index 5c7ea47d5faf5c8f7e78ba3990cb3a0f90b49adb..04be5f0917fa7de42a0ce3006c3577f8867ad8ba 100644 (file)
@@ -390,6 +390,23 @@ do_iterator_test 6.1.7 * {
   {UPDATE t2 0 X. {i 4 t y} {{} {} t new}}
 }
 
+do_iterator_test 6.1.8 * {
+  CREATE TABLE t3(a, b PRIMARY KEY);
+  CREATE TABLE t4(a, b PRIMARY KEY);
+  CREATE TRIGGER t4t AFTER UPDATE ON t4 BEGIN
+    UPDATE t3 SET a = new.a WHERE b = new.b;
+  END;
+
+  SELECT indirect(1);
+  INSERT INTO t3 VALUES('one', 1);
+  INSERT INTO t4 VALUES('one', 1);
+  SELECT indirect(0);
+  UPDATE t4 SET a = 'two' WHERE b = 1;
+} {
+  {INSERT t4 0 .X {} {t two i 1}} 
+  {INSERT t3 1 .X {} {t two i 1}}
+}
+
 sqlite3session S db main
 do_execsql_test 6.2.1 {
   SELECT indirect(0);
index b9800e1f464e2a8ccae63292658d6c7932addbf1..1444a46b369a5fdebc1749f12470af796ed0d40e 100644 (file)
@@ -20,6 +20,8 @@ source $testdir/tester.tcl
 
 set testprefix sessionfault
 
+if 1 {
+
 forcedelete test.db2
 sqlite3 db2 test.db2
 do_common_sql {
@@ -362,7 +364,7 @@ do_faultsim_test 8.2 -faults oom* -body {
 }
 
 faultsim_delete_and_reopen
-do_test 9.prep {
+do_test 9.1.prep {
   execsql { 
     PRAGMA encoding = 'utf16';
     CREATE TABLE t1(a PRIMARY KEY, b);
@@ -370,7 +372,8 @@ do_test 9.prep {
 } {}
 faultsim_save_and_close
 
-do_faultsim_test 9 -faults oom-transient -prep {
+set answers [list {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}}]
+do_faultsim_test 9.1 -faults oom-transient -prep {
   catch { unset ::c }
   faultsim_restore_and_reopen
   sqlite3session S db main
@@ -383,9 +386,48 @@ do_faultsim_test 9 -faults oom-transient -prep {
   set {} {}
 } -test {
   S delete
-  faultsim_test_result {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}}
+  eval faultsim_test_result $::answers
+  if {[info exists ::c]} {
+    set expected [normalize_list {
+      {INSERT t1 0 X. {} {t abcdefghijklmnopqrstuv t ABCDEFGHIJKLMNOPQRSTUV}}
+    }]
+    if { [changeset_to_list $::c] != $expected } {
+      error "changeset mismatch"
+    }
+  }
+}
+
+}
+
+faultsim_delete_and_reopen
+do_test 9.2.prep {
+  execsql { 
+    PRAGMA encoding = 'utf16';
+    CREATE TABLE t1(a PRIMARY KEY, b);
+    INSERT INTO t1 VALUES('abcdefghij', 'ABCDEFGHIJKLMNOPQRSTUV');
+  }
+} {}
+faultsim_save_and_close
+
+set answers [list {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}}]
+do_faultsim_test 9.2 -faults oom-transient -prep {
+  catch { unset ::c }
+  faultsim_restore_and_reopen
+  sqlite3session S db main
+  S attach *
+} -body {
+  execsql {
+    UPDATE t1 SET b = 'xyz';
+  }
+  set ::c [S changeset]
+  set {} {}
+} -test {
+  S delete
+  eval faultsim_test_result $::answers
   if {[info exists ::c]} {
-    set expected "{INSERT t1 0 X. {} {t abcdefghijklmnopqrstuv t ABCDEFGHIJKLMNOPQRSTUV}}"
+    set expected [normalize_list {
+      {UPDATE t1 0 X. {t abcdefghij t ABCDEFGHIJKLMNOPQRSTUV} {{} {} t xyz}}
+    }]
     if { [changeset_to_list $::c] != $expected } {
       error "changeset mismatch"
     }
@@ -393,4 +435,5 @@ do_faultsim_test 9 -faults oom-transient -prep {
 }
 
 
+
 finish_test
index 4f8117062103b3f94d5b560df3f26611d45ef3af..2232d21938ca8554961f169c93f61179ebba858a 100644 (file)
@@ -222,51 +222,68 @@ static int sessionSerializeValue(
   sqlite3_value *pValue,          /* Value to serialize */
   int *pnWrite                    /* IN/OUT: Increment by bytes written */
 ){
-  int eType;                      /* Value type (SQLITE_NULL, TEXT etc.) */
   int nByte;                      /* Size of serialized value in bytes */
 
-  eType = sqlite3_value_type(pValue);
-  if( aBuf ) aBuf[0] = eType;
-
-  switch( eType ){
-    case SQLITE_NULL: 
-      nByte = 1;
-      break;
-
-    case SQLITE_INTEGER: 
-    case SQLITE_FLOAT:
-      if( aBuf ){
-        /* TODO: SQLite does something special to deal with mixed-endian
-        ** floating point values (e.g. ARM7). This code probably should
-        ** too.  */
-        u64 i;
-        if( eType==SQLITE_INTEGER ){
-          i = (u64)sqlite3_value_int64(pValue);
+  if( pValue ){
+    int eType;                    /* Value type (SQLITE_NULL, TEXT etc.) */
+  
+    eType = sqlite3_value_type(pValue);
+    if( aBuf ) aBuf[0] = eType;
+  
+    switch( eType ){
+      case SQLITE_NULL: 
+        nByte = 1;
+        break;
+  
+      case SQLITE_INTEGER: 
+      case SQLITE_FLOAT:
+        if( aBuf ){
+          /* TODO: SQLite does something special to deal with mixed-endian
+          ** floating point values (e.g. ARM7). This code probably should
+          ** too.  */
+          u64 i;
+          if( eType==SQLITE_INTEGER ){
+            i = (u64)sqlite3_value_int64(pValue);
+          }else{
+            double r;
+            assert( sizeof(double)==8 && sizeof(u64)==8 );
+            r = sqlite3_value_double(pValue);
+            memcpy(&i, &r, 8);
+          }
+          sessionPutI64(&aBuf[1], i);
+        }
+        nByte = 9; 
+        break;
+  
+      default: {
+        u8 *z;
+        int n;
+        int nVarint;
+  
+        assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
+        if( eType==SQLITE_TEXT ){
+          z = (u8 *)sqlite3_value_text(pValue);
         }else{
-          double r;
-          assert( sizeof(double)==8 && sizeof(u64)==8 );
-          r = sqlite3_value_double(pValue);
-          memcpy(&i, &r, 8);
+          z = (u8 *)sqlite3_value_blob(pValue);
         }
-        sessionPutI64(&aBuf[1], i);
-      }
-      nByte = 9; 
-      break;
-
-    default: {
-      int n = sqlite3_value_bytes(pValue);
-      int nVarint = sessionVarintLen(n);
-      assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
-      if( aBuf ){
-        sessionVarintPut(&aBuf[1], n);
-        memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? 
-            sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n
-        );
+        if( z==0 ) return SQLITE_NOMEM;
+        n = sqlite3_value_bytes(pValue);
+        nVarint = sessionVarintLen(n);
+  
+        if( aBuf ){
+          sessionVarintPut(&aBuf[1], n);
+          memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? 
+              sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n
+          );
+        }
+  
+        nByte = 1 + nVarint + n;
+        break;
       }
-
-      nByte = 1 + nVarint + n;
-      break;
     }
+  }else{
+    nByte = 1;
+    if( aBuf ) aBuf[0] = '\0';
   }
 
   *pnWrite += nByte;
@@ -851,18 +868,21 @@ static void sessionPreupdateOneChange(
     return;
   }
 
-  /* Search the hash table for an existing entry for rowid=iKey2. If
-  ** one is found, store a pointer to it in pChange and unlink it from
-  ** the hash table. Otherwise, set pChange to NULL.
-  */
+  /* Calculate the hash-key for this change. If the primary key of the row
+  ** includes a NULL value, exit early. Such changes are ignored by the
+  ** session module. */
   rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash, &bNullPk);
-  if( rc==SQLITE_OK && bNullPk==0 ){
+  if( rc!=SQLITE_OK ) goto error_out;
+
+  if( bNullPk==0 ){
+    /* Search the hash table for an existing record for this row. */
     SessionChange *pC;
     for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
       int bEqual;
       sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual);
       if( bEqual ) break;
     }
+
     if( pC==0 ){
       /* Create a new change object containing all the old values (if
       ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
@@ -876,53 +896,57 @@ static void sessionPreupdateOneChange(
   
       /* Figure out how large an allocation is required */
       nByte = sizeof(SessionChange);
-      for(i=0; i<pTab->nCol && rc==SQLITE_OK; i++){
+      for(i=0; i<pTab->nCol; i++){
         sqlite3_value *p = 0;
         if( op!=SQLITE_INSERT ){
-          rc = sqlite3_preupdate_old(pSession->db, i, &p);
-        }else if( 1 || pTab->abPK[i] ){
-          rc = sqlite3_preupdate_new(pSession->db, i, &p);
-        }
-        if( p && rc==SQLITE_OK ){
-          rc = sessionSerializeValue(0, p, &nByte);
+          TESTONLY(int trc = ) sqlite3_preupdate_old(pSession->db, i, &p);
+          assert( trc==SQLITE_OK );
+        }else if( pTab->abPK[i] ){
+          TESTONLY(int trc = ) sqlite3_preupdate_new(pSession->db, i, &p);
+          assert( trc==SQLITE_OK );
         }
+
+        /* This may fail if SQLite value p contains a utf-16 string that must
+        ** be converted to utf-8 and an OOM error occurs while doing so. */
+        rc = sessionSerializeValue(0, p, &nByte);
+        if( rc!=SQLITE_OK ) goto error_out;
       }
   
       /* Allocate the change object */
       pChange = (SessionChange *)sqlite3_malloc(nByte);
       if( !pChange ){
         rc = SQLITE_NOMEM;
+        goto error_out;
       }else{
         memset(pChange, 0, sizeof(SessionChange));
         pChange->aRecord = (u8 *)&pChange[1];
       }
   
-      /* Populate the change object */
+      /* Populate the change object. None of the preupdate_old(),
+      ** preupdate_new() or SerializeValue() calls below may fail as all
+      ** required values and encodings have already been cached in memory.
+      ** It is not possible for an OOM to occur in this block. */
       nByte = 0;
-      for(i=0; i<pTab->nCol && rc==SQLITE_OK; i++){
+      for(i=0; i<pTab->nCol; i++){
         sqlite3_value *p = 0;
         if( op!=SQLITE_INSERT ){
-          rc = sqlite3_preupdate_old(pSession->db, i, &p);
-        }else if( 1 || pTab->abPK[i] ){
-          rc = sqlite3_preupdate_new(pSession->db, i, &p);
-        }
-        if( p && rc==SQLITE_OK ){
-          rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte);
+          sqlite3_preupdate_old(pSession->db, i, &p);
+        }else if( pTab->abPK[i] ){
+          sqlite3_preupdate_new(pSession->db, i, &p);
         }
+        sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte);
       }
-      if( rc==SQLITE_OK ){
-        /* Add the change back to the hash-table */
-        if( pSession->bIndirect || sqlite3_preupdate_depth(pSession->db) ){
-          pChange->bIndirect = 1;
-        }
-        pChange->nRecord = nByte;
-        pChange->bInsert = (op==SQLITE_INSERT);
-        pChange->pNext = pTab->apChange[iHash];
-        pTab->apChange[iHash] = pChange;
-      }else{
-        sqlite3_free(pChange);
+
+      /* Add the change to the hash-table */
+      if( pSession->bIndirect || sqlite3_preupdate_depth(pSession->db) ){
+        pChange->bIndirect = 1;
       }
-    }else if( rc==SQLITE_OK && pC->bIndirect ){
+      pChange->nRecord = nByte;
+      pChange->bInsert = (op==SQLITE_INSERT);
+      pChange->pNext = pTab->apChange[iHash];
+      pTab->apChange[iHash] = pChange;
+
+    }else if( pC->bIndirect ){
       /* If the existing change is considered "indirect", but this current
       ** change is "direct", mark the change object as direct. */
       if( sqlite3_preupdate_depth(pSession->db)==0 && pSession->bIndirect==0 ){
@@ -932,6 +956,7 @@ static void sessionPreupdateOneChange(
   }
 
   /* If an error has occurred, mark the session object as failed. */
+ error_out:
   if( rc!=SQLITE_OK ){
     pSession->rc = rc;
   }
@@ -1125,7 +1150,7 @@ int sqlite3session_attach(
 ** set *pRc to SQLITE_NOMEM and return non-zero.
 */
 static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
-  if( p->nAlloc-p->nBuf<nByte ){
+  if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
     u8 *aNew;
     int nNew = p->nAlloc ? p->nAlloc : 128;
     do {
@@ -1135,12 +1160,12 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
     aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
     if( 0==aNew ){
       *pRc = SQLITE_NOMEM;
-      return 1;
+    }else{
+      p->aBuf = aNew;
+      p->nAlloc = nNew;
     }
-    p->aBuf = aNew;
-    p->nAlloc = nNew;
   }
-  return 0;
+  return (*pRc!=SQLITE_OK);
 }
 
 /*
@@ -1151,7 +1176,7 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
 ** returning.
 */
 static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
-  if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 1, pRc) ){
+  if( 0==sessionBufferGrow(p, 1, pRc) ){
     p->aBuf[p->nBuf++] = v;
   }
 }
@@ -1164,7 +1189,7 @@ static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){
 ** returning.
 */
 static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){
-  if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 9, pRc) ){
+  if( 0==sessionBufferGrow(p, 9, pRc) ){
     p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v);
   }
 }
@@ -1182,7 +1207,7 @@ static void sessionAppendBlob(
   int nBlob, 
   int *pRc
 ){
-  if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nBlob, pRc) ){
+  if( 0==sessionBufferGrow(p, nBlob, pRc) ){
     memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
     p->nBuf += nBlob;
   }
@@ -1202,7 +1227,7 @@ static void sessionAppendStr(
   int *pRc
 ){
   int nStr = sqlite3Strlen30(zStr);
-  if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){
+  if( 0==sessionBufferGrow(p, nStr, pRc) ){
     memcpy(&p->aBuf[p->nBuf], zStr, nStr);
     p->nBuf += nStr;
   }
@@ -1241,7 +1266,7 @@ static void sessionAppendIdent(
   int *pRc                        /* IN/OUT: Error code */
 ){
   int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1;
-  if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){
+  if( 0==sessionBufferGrow(p, nStr, pRc) ){
     char *zOut = (char *)&p->aBuf[p->nBuf];
     const char *zIn = zStr;
     *zOut++ = '"';
@@ -1300,12 +1325,10 @@ static void sessionAppendCol(
 }
 
 /*
-** This function is a no-op if *pRc is other than SQLITE_OK when it is
-** called. 
 **
-** Otherwse, if *pRc is SQLITE_OK, then it appends an update change to
-** the buffer (see the comments under "CHANGESET FORMAT" at the top of the
-** file). An update change consists of:
+** This function appends an update change to the buffer (see the comments 
+** under "CHANGESET FORMAT" at the top of the file). An update change 
+** consists of:
 **
 **   1 byte:  SQLITE_UPDATE (0x17)
 **   n bytes: old.* record (see RECORD FORMAT)
@@ -1323,89 +1346,89 @@ static void sessionAppendCol(
 ** original values of any fields that have been modified. The new.* record 
 ** contains the new values of only those fields that have been modified.
 */ 
-static void sessionAppendUpdate(
+static int sessionAppendUpdate(
   SessionBuffer *pBuf,            /* Buffer to append to */
   sqlite3_stmt *pStmt,            /* Statement handle pointing at new row */
   SessionChange *p,               /* Object containing old values */
-  u8 *abPK,                       /* Boolean array - true for PK columns */
-  int *pRc                        /* IN/OUT: Error code */
+  u8 *abPK                        /* Boolean array - true for PK columns */
 ){
-  if( *pRc==SQLITE_OK ){
-    SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
-    int bNoop = 1;                /* Set to zero if any values are modified */
-    int nRewind = pBuf->nBuf;     /* Set to zero if any values are modified */
-    int i;                        /* Used to iterate through columns */
-    u8 *pCsr = p->aRecord;        /* Used to iterate through old.* values */
-
-    sessionAppendByte(pBuf, SQLITE_UPDATE, pRc);
-    sessionAppendByte(pBuf, p->bIndirect, pRc);
-    for(i=0; i<sqlite3_column_count(pStmt); i++){
-      int bChanged = 0;
-      int nAdvance;
-      int eType = *pCsr;
-      switch( eType ){
-        case SQLITE_NULL:
-          nAdvance = 1;
-          if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
-            bChanged = 1;
-          }
-          break;
-
-        case SQLITE_FLOAT:
-        case SQLITE_INTEGER: {
-          nAdvance = 9;
-          if( eType==sqlite3_column_type(pStmt, i) ){
-            sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
-            if( eType==SQLITE_INTEGER ){
-              if( iVal==sqlite3_column_int64(pStmt, i) ) break;
-            }else{
-              double dVal;
-              memcpy(&dVal, &iVal, 8);
-              if( dVal==sqlite3_column_double(pStmt, i) ) break;
-            }
-          }
+  int rc = SQLITE_OK;
+  SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */
+  int bNoop = 1;                /* Set to zero if any values are modified */
+  int nRewind = pBuf->nBuf;     /* Set to zero if any values are modified */
+  int i;                        /* Used to iterate through columns */
+  u8 *pCsr = p->aRecord;        /* Used to iterate through old.* values */
+
+  sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
+  sessionAppendByte(pBuf, p->bIndirect, &rc);
+  for(i=0; i<sqlite3_column_count(pStmt); i++){
+    int bChanged = 0;
+    int nAdvance;
+    int eType = *pCsr;
+    switch( eType ){
+      case SQLITE_NULL:
+        nAdvance = 1;
+        if( sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
           bChanged = 1;
-          break;
         }
+        break;
 
-        default: {
-          int nByte;
-          int nHdr = 1 + sessionVarintGet(&pCsr[1], &nByte);
-          assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
-          nAdvance = nHdr + nByte;
-          if( eType==sqlite3_column_type(pStmt, i) 
-           && nByte==sqlite3_column_bytes(pStmt, i) 
-           && 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), nByte)
-          ){
-            break;
+      case SQLITE_FLOAT:
+      case SQLITE_INTEGER: {
+        nAdvance = 9;
+        if( eType==sqlite3_column_type(pStmt, i) ){
+          sqlite3_int64 iVal = sessionGetI64(&pCsr[1]);
+          if( eType==SQLITE_INTEGER ){
+            if( iVal==sqlite3_column_int64(pStmt, i) ) break;
+          }else{
+            double dVal;
+            memcpy(&dVal, &iVal, 8);
+            if( dVal==sqlite3_column_double(pStmt, i) ) break;
           }
-          bChanged = 1;
         }
+        bChanged = 1;
+        break;
       }
 
-      if( bChanged || abPK[i] ){
-        sessionAppendBlob(pBuf, pCsr, nAdvance, pRc);
-      }else{
-        sessionAppendByte(pBuf, 0, pRc);
-      }
-
-      if( bChanged ){
-        sessionAppendCol(&buf2, pStmt, i, pRc);
-        bNoop = 0;
-      }else{
-        sessionAppendByte(&buf2, 0, pRc);
+      default: {
+        int nByte;
+        int nHdr = 1 + sessionVarintGet(&pCsr[1], &nByte);
+        assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
+        nAdvance = nHdr + nByte;
+        if( eType==sqlite3_column_type(pStmt, i) 
+         && nByte==sqlite3_column_bytes(pStmt, i) 
+         && 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), nByte)
+        ){
+          break;
+        }
+        bChanged = 1;
       }
+    }
 
-      pCsr += nAdvance;
+    if( bChanged || abPK[i] ){
+      sessionAppendBlob(pBuf, pCsr, nAdvance, &rc);
+    }else{
+      sessionAppendByte(pBuf, 0, &rc);
     }
 
-    if( bNoop ){
-      pBuf->nBuf = nRewind;
+    if( bChanged ){
+      sessionAppendCol(&buf2, pStmt, i, &rc);
+      bNoop = 0;
     }else{
-      sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc);
+      sessionAppendByte(&buf2, 0, &rc);
     }
-    sqlite3_free(buf2.aBuf);
+
+    pCsr += nAdvance;
   }
+
+  if( bNoop ){
+    pBuf->nBuf = nRewind;
+  }else{
+    sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc);
+  }
+  sqlite3_free(buf2.aBuf);
+
+  return rc;
 }
 
 static int sessionSelectStmt(
@@ -1457,6 +1480,7 @@ static int sessionSelectBind(
     int eType = *a++;
 
     switch( eType ){
+      case 0:
       case SQLITE_NULL:
         assert( abPK[i]==0 );
         break;
@@ -1580,6 +1604,7 @@ int sqlite3session_changeset(
 
         for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){
           rc = sessionSelectBind(pSel, nCol, abPK, p);
+          if( rc!=SQLITE_OK ) continue;
           if( sqlite3_step(pSel)==SQLITE_ROW ){
             int iCol;
             if( p->bInsert ){
@@ -1589,7 +1614,7 @@ int sqlite3session_changeset(
                 sessionAppendCol(&buf, pSel, iCol, &rc);
               }
             }else{
-              sessionAppendUpdate(&buf, pSel, p, abPK, &rc);
+              rc = sessionAppendUpdate(&buf, pSel, p, abPK);
             }
           }else if( !p->bInsert ){
             /* A DELETE change */
index 1938e24d5e8a32529637d278a10a5aedf59b62db..c0ef6b6a1369d5d4c3adccc1f57201cddaef21c7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improve\stest\scoverage\sof\ssession\smodule.
-D 2011-04-16T19:23:10.456
+C Further\scoverage\stests\sfor\sthe\ssession\smodule.
+D 2011-04-18T07:36:27.686
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -100,13 +100,13 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
 F ext/session/session1.test f5d9f2e362abe2563181389509822bda956516ee
-F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb
+F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b
 F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01
 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84
 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478
 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5
-F ext/session/sessionfault.test 759060c36ef424919e3900b885b22aa15caf7f39
-F ext/session/sqlite3session.c 3475df4021c5260f795cf66f67233449795c06ea
+F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180
+F ext/session/sqlite3session.c fd43b8cb35d8112fa77a9e9101f9efe7005e5e23
 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf
 F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
@@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 3dfd1d63bddfa9bd9018eb00bee1d496379630b5
-R 57f77b8ed5537ccfd8e7f64bd8d648b6
+P f46d4b641d613c39a80b12106e6a6ac0efc8be83
+R bc07f4a1348864ef3dbdf87527d99ed2
 U dan
-Z 35862238c72a43b8ebb72adec800f600
+Z fcc600b67a0d6c899a275e81c6cbea0f
index 387cde32ce014de1ac40b015e32dfd119e1a840c..4c438b56bbb9d5bc1161c9a2b095d42b869eed8c 100644 (file)
@@ -1 +1 @@
-f46d4b641d613c39a80b12106e6a6ac0efc8be83
\ No newline at end of file
+69a01c708bf044eacf21a8951fe9e7d9fb4332c5
\ No newline at end of file