]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If a NULL pointer is passed to sqlite3session_attach() in place of a table name,...
authordan <dan@noemail.net>
Tue, 22 Mar 2011 15:21:03 +0000 (15:21 +0000)
committerdan <dan@noemail.net>
Tue, 22 Mar 2011 15:21:03 +0000 (15:21 +0000)
FossilOrigin-Name: e9037e4e4ccaa5c633759c4d041b60b631b92c6c

ext/session/session2.test
ext/session/session_common.tcl
ext/session/sqlite3session.c
ext/session/sqlite3session.h
ext/session/test_session.c
manifest
manifest.uuid

index 984559bb12a29b508482defb6457e99765021c41..d0d8fa561714bc39db0fc004492aa7200bf28c8c 100644 (file)
@@ -258,5 +258,29 @@ foreach {tn sql changeset} {
 }
 
 
+#-------------------------------------------------------------------------
+# Test that if NULL is passed to sqlite3session_attach(), all database
+# tables are attached to the session object.
+#
+test_reset
+do_execsql_test 5.0 {
+  CREATE TABLE t1(a PRIMARY KEY);
+  CREATE TABLE t2(x, y PRIMARY KEY);
+}
+
+foreach {tn sql changeset} {
+  1 { INSERT INTO t1 VALUES(35) }     { {INSERT t1 {} {i 35}} }
+  2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 {} {i 36 i 37}} }
+  3 { 
+    DELETE FROM t1 WHERE 1;
+    UPDATE t2 SET x = 34;
+  } { 
+    {UPDATE t2 {i 36 i 37} {i 34 {} {}}}
+    {DELETE t1 {i 35} {}}
+  }
+} {
+  do_iterator_test 5.$tn * $sql $changeset
+}
+
 finish_test
 
index 41c80dee82bfbe8ab910a3b30715148b5fe25505..d5c74fba5c837276e82709aa33e5470adf471831 100644 (file)
@@ -77,7 +77,9 @@ proc do_then_apply_sql {sql {dbname main}} {
 
 proc do_iterator_test {tn tbl_list sql res} {
   sqlite3session S db main
+  if {[llength $tbl_list]==0} { S attach * }
   foreach t $tbl_list {S attach $t}
+
   execsql $sql
 
   set r [list]
index 7c7890aed2d1e3e827c245cb56a89ddaa1dde039..2b0e3ac6bb2b6e2af21ff86e39d98da4467979b9 100644 (file)
@@ -19,6 +19,7 @@ struct sqlite3_session {
   sqlite3 *db;                    /* Database handle session is attached to */
   char *zDb;                      /* Name of database session is attached to */
   int bEnable;                    /* True if currently recording */
+  int bAutoAttach;                /* True to auto-attach tables */
   int rc;                         /* Non-zero if an error has occurred */
   sqlite3_session *pNext;         /* Next session object on same db. */
   SessionTable *pTable;           /* List of attached tables */
@@ -775,7 +776,16 @@ static void xPreUpdate(
     if( pSession->rc ) continue;
     if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
 
-    for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
+    for(pTab=pSession->pTable; pTab || pSession->bAutoAttach; pTab=pTab->pNext){
+      if( !pTab ){
+        /* This branch is taken if table zName has not yet been attached to
+        ** this session and the auto-attach flag is set.  */
+        pSession->rc = sqlite3session_attach(pSession,zName);
+        if( pSession->rc ) continue;
+        pTab = pSession->pTable;
+        assert( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) );
+      }
+
       if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){
         sessionPreupdateOneChange(op, pSession, pTab);
         if( op==SQLITE_UPDATE ){
@@ -876,31 +886,35 @@ int sqlite3session_attach(
   sqlite3_session *pSession,      /* Session object */
   const char *zName               /* Table name */
 ){
-  SessionTable *pTab;             /* New table object (if required) */
-  int nName;                      /* Number of bytes in string zName */
   int rc = SQLITE_OK;
-
   sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
 
-  /* First search for an existing entry. If one is found, this call is
-  ** a no-op. Return early. */
-  nName = strlen(zName);
-  for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
-    if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
-  }
+  if( !zName ){
+    pSession->bAutoAttach = 1;
+  }else{
+    SessionTable *pTab;           /* New table object (if required) */
+    int nName;                    /* Number of bytes in string zName */
+
+    /* First search for an existing entry. If one is found, this call is
+    ** a no-op. Return early. */
+    nName = strlen(zName);
+    for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
+      if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
+    }
 
-  if( !pTab ){
-    /* Allocate new SessionTable object. */
-    pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
     if( !pTab ){
-      rc = SQLITE_NOMEM;
-    }else{
-      /* Populate the new SessionTable object and link it into the list. */
-      memset(pTab, 0, sizeof(SessionTable));
-      pTab->zName = (char *)&pTab[1];
-      memcpy(pTab->zName, zName, nName+1);
-      pTab->pNext = pSession->pTable;
-      pSession->pTable = pTab;
+      /* Allocate new SessionTable object. */
+      pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
+      if( !pTab ){
+        rc = SQLITE_NOMEM;
+      }else{
+        /* Populate the new SessionTable object and link it into the list. */
+        memset(pTab, 0, sizeof(SessionTable));
+        pTab->zName = (char *)&pTab[1];
+        memcpy(pTab->zName, zName, nName+1);
+        pTab->pNext = pSession->pTable;
+        pSession->pTable = pTab;
+      }
     }
   }
 
index 8e1767efab4dcec73c00a4fb1b675e89ef997ad1..d9d0ae1f54496e3e6b665dc3ba228bd0935a93a4 100644 (file)
@@ -93,9 +93,15 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
 /*
 ** CAPI3REF: Attach A Table To A Session Object
 **
-** Attach a table to a session. All subsequent changes made to the table
-** while the session object is enabled will be recorded. See documentation
-** for [sqlite3session_changeset()] for further details.
+** If argument zTab is not NULL, then it is the name of a table to attach
+** to the session object passed as the first argument. All subsequent changes 
+** made to the table while the session object is enabled will be recorded. See 
+** documentation for [sqlite3session_changeset()] for further details.
+**
+** Or, if argument zTab is NULL, then changes are recorded for all tables
+** in the database. If additional tables are added to the database (by 
+** executing "CREATE TABLE" statements) after this call is made, changes for 
+** the new tables are also recorded.
 **
 ** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
 ** defined as part of their CREATE TABLE statement. It does not matter if the 
@@ -109,9 +115,8 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
 ** Changes are not recorded for individual rows that have NULL values stored
 ** in one or more of their PRIMARY KEY columns.
 **
-** SQLITE_OK is returned if the table is successfully attached to the session
-** object. Or, if an error occurs, an SQLite error code (e.g. SQLITE_NOMEM)
-** is returned.
+** SQLITE_OK is returned if the call completes without error. Or, if an error 
+** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
 */
 int sqlite3session_attach(
   sqlite3_session *pSession,      /* Session object */
index e3c7f4a216d216959db505032d6217c1c7ef7137..ecc07187d35f1bff80c57fcfa9ddec3ae0c6e3da 100644 (file)
@@ -54,11 +54,14 @@ static int test_session_cmd(
   }
 
   switch( iSub ){
-    case 0:        /* attach */
-      rc = sqlite3session_attach(pSession, Tcl_GetString(objv[2]));
+    case 0: {      /* attach */
+      char *zArg = Tcl_GetString(objv[2]);
+      if( zArg[0]=='*' && zArg[1]=='\0' ) zArg = 0;
+      rc = sqlite3session_attach(pSession, zArg);
       if( rc!=SQLITE_OK ){
         return test_session_error(interp, rc);
       }
+    }
       break;
 
     case 1: {      /* changeset */
index a2a6acaf3dd63f3ddfc2f41a9bcc13afe0200776..1573c82507f1d8c2657b08925860ac68286d7049 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sOOM\stests\sand\srelated\sfixes\sfor\sthe\ssession\smodule.
-D 2011-03-22T12:08:00
+C If\sa\sNULL\spointer\sis\spassed\sto\ssqlite3session_attach()\sin\splace\sof\sa\stable\sname,\sattach\sall\sdatabase\stables\sto\sthe\ssession\sobject.
+D 2011-03-22T15:21:04
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -100,12 +100,12 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
 F ext/session/session1.test 1e8cda2cc8a60171dabc0fbec4124f9f7c943f23
-F ext/session/session2.test 54c3a5ecdc60548a8ab0a86793b136de6f32a255
-F ext/session/session_common.tcl c40e81e86b46adc92b7bcb0182eaa70c8523ad8e
+F ext/session/session2.test f993ee243db15025a7d9b1dae903fe3f82f04229
+F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28
 F ext/session/sessionfault.test 2dcf303379d0c01d8320f3c7d0452e6a0dcebd48
-F ext/session/sqlite3session.c 2fd432583cc79928b6d31792fc4cb8bfc3e50588
-F ext/session/sqlite3session.h 2b7b2b983bba8f7a299922056884912084b32c68
-F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
+F ext/session/sqlite3session.c c2cc2149e682af9d2ddaab09152ef578c8f97864
+F ext/session/sqlite3session.h 5055e21ca0cb6ddacd46b773a15d90bc0298b0a2
+F ext/session/test_session.c d31fbf5902d0cff5e5495a5ce62efda77b596f2b
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7
@@ -923,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 510198f171b9f77a4ad49c06c978c5fbb3a5b7f9
-R 64f2c206ae40e85e14ca00143e665617
+P 06048a68b351e3eb15a890cb54db8a1d4b345fbc
+R aba670c08b10d639853d25c358b85571
 U dan
-Z 4313381608751ccada39ab0745df4a8f
+Z 48e2e8d1a1883a86d400f9c1e1c32110
index 58da30c0cdab6c4710f404aa57f303a09861b694..f56d01fe0f7a3ac94e7df97cc4249fe22084b8b7 100644 (file)
@@ -1 +1 @@
-06048a68b351e3eb15a890cb54db8a1d4b345fbc
\ No newline at end of file
+e9037e4e4ccaa5c633759c4d041b60b631b92c6c
\ No newline at end of file