]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove some unreachable code in sqlite3session.c. Add test cases.
authordan <dan@noemail.net>
Mon, 21 Mar 2011 19:41:29 +0000 (19:41 +0000)
committerdan <dan@noemail.net>
Mon, 21 Mar 2011 19:41:29 +0000 (19:41 +0000)
FossilOrigin-Name: 39cdfa5324ae91bfbbac733b1e3e2d33ca883340

ext/session/session1.test
ext/session/session2.test
ext/session/session_common.tcl
ext/session/sessionfault.test
ext/session/sqlite3session.c
manifest
manifest.uuid

index fd09b47cc599e9be5dc205e243af6578510f4722..1d8b1921b9e099d687ea2325a203521a4c565e50 100644 (file)
@@ -188,7 +188,6 @@ proc do_conflict_test {tn args} {
   sqlite3session S db main
   foreach t $O(-tables) { S attach $t }
   execsql $O(-sql)
-
   set ::xConflict [list]
   sqlite3changeset_apply db2 [S changeset] xConflict
 
index 9065df99a0743d515a3586013b3e2fb550e7c7ee..984559bb12a29b508482defb6457e99765021c41 100644 (file)
@@ -150,6 +150,13 @@ set set_of_tests {
     INSERT INTO %T1% SELECT a+8, b+8 FROM %T1%;
     INSERT INTO %T1% SELECT a+256, b+256 FROM %T1%;
   }
+
+  16 {
+    INSERT INTO %T4% VALUES('abc', 'def');
+    INSERT INTO %T4% VALUES('def', 'abc');
+  }
+  17 { UPDATE %T4% SET b = 1 }
+  18 { DELETE FROM %T4% WHERE 1 }
 }
 
 test_reset
@@ -157,9 +164,10 @@ do_common_sql {
   CREATE TABLE t1(a PRIMARY KEY, b);
   CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
   CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
+  CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
 }
 
-foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3} $set_of_tests] {
+foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3 %T4% t4} $set_of_tests] {
   do_then_apply_sql $sql
   do_test 2.$tn { compare_db db db2 } {}
 }
@@ -182,21 +190,23 @@ do_test 3.0 {
     CREATE TABLE aux.t1(a PRIMARY KEY, b);
     CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY);
     CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b));
+    CREATE TABLE aux.t4(a, b, PRIMARY KEY(b, a));
   }
   execsql {
     CREATE TABLE t1(a PRIMARY KEY, b);
     CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
     CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
+    CREATE TABLE t4(a, b, PRIMARY KEY(b, a));
   } db2
 } {}
 
 proc xTrace {args} { puts $args }
 
 foreach {tn sql} [
-  string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3} $set_of_tests
+  string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3 %T4% aux.t4} $set_of_tests
 ] {
   do_then_apply_sql $sql aux
-  do_test 3.$tn { compare_db db3 db2 } {}
+  do_test 3.$tn { compare_db db2 db3 } {}
 }
 catch {db3 close}
 
index 1b5ebc5b974b1aa0a7e21b9c2bed5c140c051528..c1a644039604cd3611591f995969747cab080bb0 100644 (file)
@@ -83,7 +83,11 @@ proc compare_db {db1 db2} {
   set lot1 [$db1 eval $sql]
   set lot2 [$db2 eval $sql]
 
-  if {$lot1 != $lot2} { error "databases contain different tables" }
+  if {$lot1 != $lot2} { 
+    puts $lot1
+    puts $lot2
+    error "databases contain different tables" 
+  }
 
   foreach tbl $lot1 {
     set col1 [list]
index d6dd361b0024fb5ef741d22b4b150029d2e7616c..8f38fe63e8bb4ab7be0495e866a53b7afc3766c2 100644 (file)
@@ -82,4 +82,56 @@ do_faultsim_test pagerfault-2 -faults oom-* -prep {
   faultsim_integrity_check
 }
 
+catch { db close }
+catch { db2 close }
+forcedelete test.db2 test.db
+sqlite3 db2 test.db2
+sqlite3 db test.db
+
+proc xConflict {op tbl type args} {
+  if { $type=="CONFLICT" || $type=="DATA" } {
+    return "REPLACE"
+  }
+  return "OMIT"
+}
+
+do_test 3.0 {
+  execsql {
+    PRAGMA encoding = 'utf16';
+    CREATE TABLE t1(a PRIMARY KEY, b);
+    INSERT INTO t1 VALUES(5, 32);
+  }
+  execsql {
+    PRAGMA encoding = 'utf16';
+    CREATE TABLE t1(a PRIMARY KEY, b NOT NULL);
+    INSERT INTO t1 VALUES(1, 2);
+    INSERT INTO t1 VALUES(2, 4);
+    INSERT INTO t1 VALUES(4, 16);
+  } db2
+} {}
+
+faultsim_save_and_close
+db2 close
+
+do_faultsim_test pagerfault-3 -faults oom-transient -prep {
+  catch {db2 close}
+  catch {db close}
+  faultsim_restore_and_reopen
+  sqlite3 db2 test.db2
+  sqlite3session S db main
+  S attach t1
+  execsql {
+    INSERT INTO t1 VALUES(1, 45);
+    INSERT INTO t1 VALUES(2, 55);
+    INSERT INTO t1 VALUES(3, 55);
+    UPDATE t1 SET a = 4 WHERE a = 5;
+  }
+} -body {
+  sqlite3changeset_apply db2 [S changeset] xConflict
+} -test {
+  catch { S delete }
+  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
+  if {$testrc==0} { compare_db db db2 }
+}
+
 finish_test
index e6d4675b08b5a95c65de1a1717cc3c0b1b971811..3c6a972961b25b7af4243daffe235ce8f87788bc 100644 (file)
@@ -552,11 +552,10 @@ static int sessionTableInfo(
   int nThis;
   int i;
   u8 *pAlloc;
-  u8 *pFree = 0;
-  char **azCol;
+  char **azCol = 0;
   u8 *abPK;
 
-  assert( pazCol || pabPK );
+  assert( pazCol && pabPK );
 
   nThis = strlen(zThis);
   zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
@@ -584,15 +583,10 @@ static int sessionTableInfo(
     }
   }
   if( rc==SQLITE_OK ){
-    pFree = pAlloc;
-    if( pazCol ){
-      azCol = (char **)pAlloc;
-      pAlloc = (u8 *)&azCol[nCol];
-    }
-    if( pabPK ){
-      abPK = (u8 *)pAlloc;
-      pAlloc = &abPK[nCol];
-    }
+    azCol = (char **)pAlloc;
+    pAlloc = (u8 *)&azCol[nCol];
+    abPK = (u8 *)pAlloc;
+    pAlloc = &abPK[nCol];
     if( pzTab ){
       memcpy(pAlloc, zThis, nThis+1);
       *pzTab = (char *)pAlloc;
@@ -604,12 +598,10 @@ static int sessionTableInfo(
       int nName = sqlite3_column_bytes(pStmt, 1);
       const unsigned char *zName = sqlite3_column_text(pStmt, 1);
       if( zName==0 ) break;
-      if( pazCol ){
-        memcpy(pAlloc, zName, nName+1);
-        azCol[i] = (char *)pAlloc;
-        pAlloc += nName+1;
-      }
-      if( pabPK ) abPK[i] = sqlite3_column_int(pStmt, 5);
+      memcpy(pAlloc, zName, nName+1);
+      azCol[i] = (char *)pAlloc;
+      pAlloc += nName+1;
+      abPK[i] = sqlite3_column_int(pStmt, 5);
       i++;
     }
     rc = sqlite3_reset(pStmt);
@@ -620,13 +612,13 @@ static int sessionTableInfo(
   ** free any allocation made. An error code will be returned in this case.
   */
   if( rc==SQLITE_OK ){
-    if( pazCol ) *pazCol = (const char **)azCol;
-    if( pabPK ) *pabPK = abPK;
+    *pazCol = (const char **)azCol;
+    *pabPK = abPK;
   }else{
-    if( pazCol ) *pazCol = 0;
-    if( pabPK ) *pabPK = 0;
+    *pazCol = 0;
+    *pabPK = 0;
     if( pzTab ) *pzTab = 0;
-    sqlite3_free(pFree);
+    sqlite3_free(azCol);
   }
   sqlite3_finalize(pStmt);
   return rc;
@@ -1785,7 +1777,7 @@ struct SessionApplyCtx {
 **
 ** The DELETE statement looks like this:
 **
-**     DELETE FROM x WHERE a = :1 AND c = :3 AND :5 OR (b IS :2 AND d IS :4)
+**     DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4)
 **
 ** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require
 ** matching b and d values, or 1 otherwise. The second case comes up if the
@@ -1997,6 +1989,41 @@ static int sessionInsertRow(
   return rc;
 }
 
+/*
+** Iterator pIter must point to an SQLITE_INSERT entry. This function 
+** transfers new.* values from the current iterator entry to statement
+** pStmt. The table being inserted into has nCol columns.
+**
+** New.* value $i 0 from the iterator is bound to variable ($i+1) of 
+** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1)
+** are transfered to the statement. Otherwise, if abPK is not NULL, it points
+** to an array nCol elements in size. In this case only those values for 
+** which abPK[$i] is true are read from the iterator and bound to the 
+** statement.
+**
+** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK.
+*/
+static int sessionBindValues(
+  sqlite3_changeset_iter *pIter,  /* Iterator to read values from */
+  int(*xIterValue)(sqlite3_changeset_iter *, int, sqlite3_value **),
+  int nCol,                       /* Number of columns */
+  u8 *abPK,                       /* If not NULL, bind only if true */
+  sqlite3_stmt *pStmt             /* Bind values to this statement */
+){
+  int i;
+  int rc = SQLITE_OK;
+  for(i=0; rc==SQLITE_OK && i<nCol; i++){
+    if( !abPK || abPK[i] ){
+      sqlite3_value *pVal;
+      rc = xIterValue(pIter, i, &pVal);
+      if( rc==SQLITE_OK ){
+        rc = sqlite3_bind_value(pStmt, i+1, pVal);
+      }
+    }
+  }
+  return rc;
+}
+
 /*
 ** SQL statement pSelect is as generated by the sessionSelectRow() function.
 ** This function binds the primary key values from the change that changeset
@@ -2007,10 +2034,8 @@ static int sessionInsertRow(
 ** error occurs, an SQLite error code is returned.
 **
 ** If the iterator currently points to an INSERT record, bind values from the
-** new.* record to the SELECT statement. Or, if it points to a DELETE, bind
-** values from the old.* record. If the changeset iterator points to an
-** UPDATE, bind values from the new.* record, but use old.* values in place
-** of any undefined new.* values.
+** new.* record to the SELECT statement. Or, if it points to a DELETE or
+** UPDATE, bind values from the old.* record. 
 */
 static int sessionSeekToRow(
   sqlite3 *db,                    /* Database handle */
@@ -2019,27 +2044,15 @@ static int sessionSeekToRow(
   sqlite3_stmt *pSelect           /* SELECT statement from sessionSelectRow() */
 ){
   int rc = SQLITE_OK;             /* Return code */
-  int i;                          /* Used to iterate through table columns */
   int nCol;                       /* Number of columns in table */
   int op;                         /* Changset operation (SQLITE_UPDATE etc.) */
   const char *zDummy;             /* Unused */
 
   sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
-
-  for(i=0; rc==SQLITE_OK && i<nCol; i++){
-    if( abPK[i] ){
-      sqlite3_value *pVal = 0;
-      if( op!=SQLITE_DELETE ){
-        rc = sqlite3changeset_new(pIter, i, &pVal);
-      }
-      if( pVal==0 ){
-        rc = sqlite3changeset_old(pIter, i, &pVal);
-      }
-      if( rc==SQLITE_OK ){
-        rc = sqlite3_bind_value(pSelect, i+1, pVal);
-      }
-    }
-  }
+  rc = sessionBindValues(pIter, 
+      op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
+      nCol, abPK, pSelect
+  );
 
   if( rc==SQLITE_OK ){
     rc = sqlite3_step(pSelect);
@@ -2108,7 +2121,7 @@ static int sessionConflictHandler(
   if( pbReplace ){
     rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
   }else{
-    rc = SQLITE_DONE;
+    rc = SQLITE_OK;
   }
 
   if( rc==SQLITE_ROW ){
@@ -2117,7 +2130,7 @@ static int sessionConflictHandler(
     res = xConflict(pCtx, eType, pIter);
     pIter->pConflict = 0;
     rc = sqlite3_reset(p->pSelect);
-  }else{
+  }else if( rc==SQLITE_OK ){
     /* No other row with the new.* primary key. */
     rc = sqlite3_reset(p->pSelect);
     if( rc==SQLITE_OK ){
@@ -2192,16 +2205,9 @@ static int sessionApplyOneOp(
   sqlite3changeset_op(pIter, &zDummy, &nCol, &op);
 
   if( op==SQLITE_DELETE ){
-    int i;
 
     /* Bind values to the DELETE statement. */
-    for(i=0; rc==SQLITE_OK && i<nCol; i++){
-      sqlite3_value *pVal;
-      rc = sqlite3changeset_old(pIter, i, &pVal);
-      if( rc==SQLITE_OK ){
-        rc = sqlite3_bind_value(p->pDelete, i+1, pVal);
-      }
-    }
+    rc = sessionBindValues(pIter, sqlite3changeset_old, nCol, 0, p->pDelete);
     if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){
       rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0);
     }
@@ -2254,44 +2260,20 @@ static int sessionApplyOneOp(
       );
 
     }else if( rc==SQLITE_CONSTRAINT ){
-      /* This may be a CONSTRAINT or CONFLICT error. It is a CONFLICT if
-      ** the only problem is a duplicate PRIMARY KEY, or a CONSTRAINT 
-      ** otherwise. */
-      int bPKChange = 0;
-
-      /* Check if the PK has been modified. */
-      rc = SQLITE_OK;
-      for(i=0; i<nCol && rc==SQLITE_OK; i++){
-        if( p->abPK[i] ){
-          sqlite3_value *pNew;
-          rc = sqlite3changeset_new(pIter, i, &pNew);
-          if( rc==SQLITE_OK && pNew ){
-            bPKChange = 1;
-            break;
-          }
-        }
-      }
-
-      rc = sessionConflictHandler(SQLITE_CHANGESET_CONFLICT, 
-          p, pIter, xConflict, pCtx, (bPKChange ? pbReplace : 0)
+      /* This is always a CONSTRAINT conflict. */
+      rc = sessionConflictHandler(
+          SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
       );
     }
 
   }else{
-    int i;
     assert( op==SQLITE_INSERT );
-    for(i=0; rc==SQLITE_OK && i<nCol; i++){
-      sqlite3_value *pVal;
-      rc = sqlite3changeset_new(pIter, i, &pVal);
-      if( rc==SQLITE_OK ){
-        rc = sqlite3_bind_value(p->pInsert, i+1, pVal);
-      }
-    }
+    rc = sessionBindValues(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
     if( rc!=SQLITE_OK ) return rc;
 
     sqlite3_step(p->pInsert);
     rc = sqlite3_reset(p->pInsert);
-    if( rc==SQLITE_CONSTRAINT && xConflict ){
+    if( rc==SQLITE_CONSTRAINT ){
       rc = sessionConflictHandler(
           SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
       );
@@ -2369,21 +2351,11 @@ int sqlite3changeset_apply(
     }
 
     if( bReplace ){
+      assert( pIter->op==SQLITE_INSERT );
       rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
       if( rc==SQLITE_OK ){
-        int i;
-        for(i=0; i<sApply.nCol; i++){
-          if( sApply.abPK[i] ){
-            sqlite3_value *pVal;
-            rc = sqlite3changeset_new(pIter, i, &pVal);
-            if( rc==SQLITE_OK && pVal==0 ){
-              rc = sqlite3changeset_old(pIter, i, &pVal);
-            }
-            if( rc==SQLITE_OK ){
-              rc = sqlite3_bind_value(sApply.pDelete, i+1, pVal);
-            }
-          }
-        }
+        rc = sessionBindValues(pIter, 
+            sqlite3changeset_new, sApply.nCol, sApply.abPK, sApply.pDelete);
         sqlite3_bind_int(sApply.pDelete, sApply.nCol+1, 1);
       }
       if( rc==SQLITE_OK ){
index 54c5fdee988a758b48fd9e9830089c62065df5c9..90e7ad14b42e29b74e25f528288945c10383d91f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Merge\sin\sthe\ssqlite3_db_config()\senhancements\sfor\senabling\sand\sdisabling\nFKs\sand\striggers\sfrom\strunk.
-D 2011-03-21T17:17:49.766
+C Remove\ssome\sunreachable\scode\sin\ssqlite3session.c.\sAdd\stest\scases.
+D 2011-03-21T19:41:30
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -102,11 +99,11 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
 F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
-F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a
-F ext/session/session2.test 6462c21d3795d9e48ffea2e7550d1b2d6da66dfb
-F ext/session/session_common.tcl 880b554b0bcadcabe1331afb87d58ad1ed2510c4
-F ext/session/sessionfault.test 4190de237b2c76ca7529ef415778a862d7d0fa30
-F ext/session/sqlite3session.c c5a60c2cf21f8892f9ae4850fad2d7859c2c3692
+F ext/session/session1.test 1e8cda2cc8a60171dabc0fbec4124f9f7c943f23
+F ext/session/session2.test 54c3a5ecdc60548a8ab0a86793b136de6f32a255
+F ext/session/session_common.tcl d7bb85c3fd76d53bd9b909da808d5c16f5213111
+F ext/session/sessionfault.test da234166d5d044c91964863174d7171b0561708b
+F ext/session/sqlite3session.c 1ca39db8a10b8bcb973b35a68c0924b6a64c4a97
 F ext/session/sqlite3session.h 2c071ee5925e82c21c7c9c296a0422c039607106
 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
@@ -926,14 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 32e95164d1192b87b1ab019549fd2394642cd3fe 09e167f9c14625924b17bbb1f292f89ac9ddc93a
-R a0add848dadb7db1c3f35ed60dcfc8d8
-U drh
-Z 2f330aa02552b587cf8d8ca729d4e813
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFNh4hAoxKgR168RlERAlZKAJ9kBWPV0idzBc6FhOD1zal2v2X27gCfZtYB
-1RyGCy9Ef7CucSG+WlvrUDU=
-=TZ5z
------END PGP SIGNATURE-----
+P 2b3c8b9d9aa909f64a29ed8167de24c328c50d85
+R c6506b08e053cfdd0bd616ee1b17add6
+U dan
+Z 4cc9deaf80e50ac14cbc33555ec1ddf1
index 347c896eb41cfe8e77be571cab8acaa74c349f55..3a13c2368c0f707f829e000e1712ec46d160c105 100644 (file)
@@ -1 +1 @@
-2b3c8b9d9aa909f64a29ed8167de24c328c50d85
\ No newline at end of file
+39cdfa5324ae91bfbbac733b1e3e2d33ca883340
\ No newline at end of file