]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix handling of schema changes mid-session.
authordan <dan@noemail.net>
Thu, 24 Mar 2011 16:53:57 +0000 (16:53 +0000)
committerdan <dan@noemail.net>
Thu, 24 Mar 2011 16:53:57 +0000 (16:53 +0000)
FossilOrigin-Name: 76d2d2ad3b2a5171393b7894f35f463ff284e53b

ext/session/session3.test
ext/session/sqlite3session.c
manifest
manifest.uuid

index e07032fccd2d66ae8e7ac6f88dd0b87bd8a78e53..d0d2c31fa401dadedf4637db2f17ff43c0db1f80 100644 (file)
@@ -19,6 +19,7 @@ source $testdir/tester.tcl
 
 set testprefix session3
 
+#-------------------------------------------------------------------------
 # These tests - session3-1.* - verify that the session module behaves
 # correctly when confronted with a schema mismatch when applying a 
 # changeset (in function sqlite3changeset_apply()).
@@ -27,7 +28,6 @@ set testprefix session3
 #   session3-1.2.*: Table has wrong number of columns in target db.
 #   session3-1.3.*: Table has wrong PK columns in target db.
 #
-
 db close
 sqlite3_shutdown
 test_sqlite3_log log
@@ -77,6 +77,96 @@ do_test 1.3.1 {
   set ::log
 } {SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}}
 
+#-------------------------------------------------------------------------
+# These tests - session3-2.* - verify that the session module behaves
+# correctly when the schema of an attached table is modified during the
+# session.
+#
+#   session3-2.1.*: Table is dropped midway through the session.
+#   session3-2.2.*: Table is dropped and recreated with a different # cols.
+#   session3-2.3.*: Table is dropped and recreated with a different PK.
+#
+# In all of these scenarios, the call to sqlite3session_changeset() will
+# return SQLITE_SCHEMA. Also:
+#   
+#   session3-2.4.*: Table is dropped and recreated with an identical schema.
+#                   In this case sqlite3session_changeset() returns SQLITE_OK.
+#
+
+do_test 2.1 {
+  execsql { CREATE TABLE t2(a, b PRIMARY KEY) }
+  sqlite3session S db main
+  S attach t2
+  execsql {
+    INSERT INTO t2 VALUES(1, 2);
+    DROP TABLE t2;
+  }
+  list [catch { S changeset } msg] $msg
+} {1 SQLITE_SCHEMA}
+
+do_test 2.2.1 {
+  S delete
+  sqlite3session S db main
+  execsql { CREATE TABLE t2(a, b PRIMARY KEY, c) }
+  S attach t2
+  execsql {
+    INSERT INTO t2 VALUES(1, 2, 3);
+    DROP TABLE t2;
+    CREATE TABLE t2(a, b PRIMARY KEY);
+  }
+  list [catch { S changeset } msg] $msg
+} {1 SQLITE_SCHEMA}
+
+do_test 2.2.2 {
+  S delete
+  sqlite3session S db main
+  execsql { 
+    DROP TABLE t2;
+    CREATE TABLE t2(a, b PRIMARY KEY, c);
+  }
+  S attach t2
+  execsql {
+    INSERT INTO t2 VALUES(1, 2, 3);
+    DROP TABLE t2;
+    CREATE TABLE t2(a, b PRIMARY KEY, c, d);
+  }
+  list [catch { S changeset } msg] $msg
+} {1 SQLITE_SCHEMA}
+
+do_test 2.3 {
+  S delete
+  sqlite3session S db main
+  execsql { 
+    DROP TABLE t2;
+    CREATE TABLE t2(a, b PRIMARY KEY);
+  }
+  S attach t2
+  execsql {
+    INSERT INTO t2 VALUES(1, 2);
+    DROP TABLE t2;
+    CREATE TABLE t2(a PRIMARY KEY, b, c);
+  }
+  list [catch { S changeset } msg] $msg
+} {1 SQLITE_SCHEMA}
+
+do_test 2.4 {
+  S delete
+  sqlite3session S db main
+  execsql { 
+    DROP TABLE t2;
+    CREATE TABLE t2(a, b PRIMARY KEY);
+  }
+  S attach t2
+  execsql {
+    INSERT INTO t2 VALUES(1, 2);
+    DROP TABLE t2;
+    CREATE TABLE t2(a, b PRIMARY KEY);
+  }
+  list [catch { S changeset } msg] $msg
+} {0 {}}
+
+S delete
+
 
 catch { db close }
 catch { db2 close }
index c64f567f90ecea8de793de14ce464bf9fe68a425..ffc2e13f5e5aa19b6a97126561555c78a9696b54 100644 (file)
@@ -1349,13 +1349,20 @@ int sqlite3session_changeset(
   for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
     if( pTab->nEntry ){
       const char *zName = pTab->zName;
-      int nCol = pTab->nCol;      /* Local copy of member variable */
-      u8 *abPK = pTab->abPK;      /* Local copy of member variable */
+      int nCol;                   /* Number of columns in table */
+      u8 *abPK;                   /* Primary key array */
+      const char **azCol = 0;     /* Table columns */
       int i;                      /* Used to iterate through hash buckets */
       sqlite3_stmt *pSel = 0;     /* SELECT statement to query table pTab */
       int nRewind = buf.nBuf;     /* Initial size of write buffer */
       int nNoop;                  /* Size of buffer after writing tbl header */
 
+      /* Check the table schema is still Ok. */
+      rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK);
+      if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
+        rc = SQLITE_SCHEMA;
+      }
+
       /* Write a table header */
       sessionAppendByte(&buf, 'T', &rc);
       sessionAppendVarint(&buf, nCol, &rc);
@@ -1365,7 +1372,7 @@ int sqlite3session_changeset(
       /* Build and compile a statement to execute: */
       if( rc==SQLITE_OK ){
         rc = sessionSelectStmt(
-            db, pSession->zDb, zName, nCol, pTab->azCol, abPK, &pSel);
+            db, pSession->zDb, zName, nCol, azCol, abPK, &pSel);
       }
 
       if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){
@@ -1407,6 +1414,7 @@ int sqlite3session_changeset(
       if( buf.nBuf==nNoop ){
         buf.nBuf = nRewind;
       }
+      sqlite3_free(azCol);
     }
   }
 
index e59c27fb7534c65b2e3b82d3a24d6b91e20fe097..1f7e7a7bdd4de6488e77b00b6f940e6d6fed76be 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\shandling\sof\sschema\smismatches\sin\ssqlite3session.c\sso\sthat\sit\smatches\sthe\sdocs\sin\ssqlite3session.h.
-D 2011-03-24T16:04:55
+C Fix\shandling\sof\sschema\schanges\smid-session.
+D 2011-03-24T16:53:57
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -101,10 +101,10 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
 F ext/session/session1.test b2da15b9d727d7f4e5fe95599b32b92d93b5a970
 F ext/session/session2.test 8da094318ac88953478c43d0bfb0aa723ee0e379
-F ext/session/session3.test b8b9ff7efcb19234892c406dba8bd56792560efe
+F ext/session/session3.test c58ebb3273a23da9b5f4eb202d522aa759530a4c
 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28
 F ext/session/sessionfault.test d7e6154a30e85622d0733b1a1e3c63e9b8b7004b
-F ext/session/sqlite3session.c cf91fe0efb0728c219c8bc2b2174a49758fbd3f8
+F ext/session/sqlite3session.c 33a5d4be9c22099aed8e7f6c80b63540953e84c2
 F ext/session/sqlite3session.h 900d900bb6a827f84754fc252a05638e0f413a6e
 F ext/session/test_session.c e0f500ec5e20478afc2c7998133e8acea7ec5104
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
@@ -924,7 +924,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 54298ee5ed183d1f1c49524f25e8ae1407f3d4b5
-R 73cd0f1e5ce098769e9cee2c7d1f1ebc
+P 506a0d7a710e1ff2f367821e73f5080fcf63fbc5
+R 3234ab73592ecae31c60c0a6f501bbfd
 U dan
-Z 8a40e5171d2567a1ae6ca1b697973f9a
+Z 29af2cd6e2d7044fdb214ebc342ad1ba
index e8475cfcd081f4b4ecee413be0018aa6b97efdf3..5f9877e0ed2ca0fec5cc1383c1856b17f435b67d 100644 (file)
@@ -1 +1 @@
-506a0d7a710e1ff2f367821e73f5080fcf63fbc5
\ No newline at end of file
+76d2d2ad3b2a5171393b7894f35f463ff284e53b
\ No newline at end of file