]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix problems related to savepoint rollback and fts3.
authordan <dan@noemail.net>
Wed, 27 Apr 2011 12:08:04 +0000 (12:08 +0000)
committerdan <dan@noemail.net>
Wed, 27 Apr 2011 12:08:04 +0000 (12:08 +0000)
FossilOrigin-Name: ff69f823f23e6fb6e8b2857c4576d9c0732d9572

manifest
manifest.uuid
src/sqliteInt.h
src/test1.c
src/vdbe.c
src/vtab.c
test/fts3conf.test

index e810ed1767bedf26d0f459182908de765273be27..525bcf35db1e6745988036efa6c6f0637e468095 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Extra\stests\sfor\sfts3.\sAnd\sfixes\sfor\sconflict-handling\srelated\sproblems\sin\sfts3.
-D 2011-04-26T19:21:34.191
+C Fix\sproblems\srelated\sto\ssavepoint\srollback\sand\sfts3.
+D 2011-04-27T12:08:04.566
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -181,12 +181,12 @@ F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff
 F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79
 F src/sqlite.h.in 3dc514ef85adfdb6377abee4fb780b420fc43f5e
 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
-F src/sqliteInt.h 1ec9fa7b728c486e526ec012f73fdfb244238dfc
+F src/sqliteInt.h e70a03bb66d209e279b3edeb57d4fdc42a1d9fda
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c 501c9a200fd998a268be475be5858febc90b725b
-F src/test1.c 9ca440e80e16e53920904a0a5ac7feffb9b2c9a1
+F src/test1.c e0e4af306b678da05334c2ccaf0377ae8f06e911
 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc
 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
@@ -236,7 +236,7 @@ F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f
 F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60
 F src/util.c 465fe10aabf0ca7d7826a156dab919b0b65c525a
 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
-F src/vdbe.c b6396cb75bead0d163577b834cbcf4dcd0cea231
+F src/vdbe.c 672ec2f41b95a6f35b5bbfe555689457dea4789e
 F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797
 F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae
 F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1
@@ -244,7 +244,7 @@ F src/vdbeaux.c 5c4cd4be10b8247061f97b77fa2b0a23728d43ed
 F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562
 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
-F src/vtab.c bcfd5a8b0a4951a60658cdd887a929f6c3816fdf
+F src/vtab.c 59db0620d682d34abb96860020429e77bb2b8ced
 F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794
 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
@@ -456,7 +456,7 @@ F test/fts3aux1.test 0b02743955d56fc0d4d66236a26177bd1b726de0
 F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
-F test/fts3conf.test 03e5baecc3a1c82fc50fc75789bc1e13861f47fe
+F test/fts3conf.test 7b71b8a5f21481dfae43b9f7a26f2506fc2f9e70
 F test/fts3corrupt.test 7890cc202406858386ddf390a879dcf80bc10abf
 F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
 F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
@@ -932,7 +932,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 6d2633a6d0a9bb88fb1a6adac0827dc51df2d4d2
-R 3d729f606d16bb9d30fc86b95bfd6047
+P fb4a355871d9482ccb28b6ba03b842b3cc87b696
+R 7aaab6bc74b8e2e016b6645549f49c48
 U dan
-Z dd1f59cf11e82349f934a1bcc8d1254a
+Z e77f5258c98bca31cf26e41c03abebcf
index 923ce0ed9668689224f26f0071d85876e8d0a9ae..c29bc677d91a103489774ca00b35b452a3372115 100644 (file)
@@ -1 +1 @@
-fb4a355871d9482ccb28b6ba03b842b3cc87b696
\ No newline at end of file
+ff69f823f23e6fb6e8b2857c4576d9c0732d9572
\ No newline at end of file
index 71cb368cc6a618a8452dbef4f51b41e785a5cbf9..9c1bda7a76fd7adcb25072c37c88641432d955a2 100644 (file)
@@ -871,9 +871,6 @@ struct sqlite3 {
 #endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   Hash aModule;                 /* populated by sqlite3_create_module() */
-#if 0
-  Table *pVTab;                 /* vtab with active Connect/Create method */
-#endif
   VtabCtx *pVtabCtx;            /* Context for active vtab connect/create */
   VTable **aVTrans;             /* Virtual tables with open transactions */
   int nVTrans;                  /* Allocated size of aVTrans */
index 8a0d09a7164752018c497f0e957345118593260a..b79bbd08269f2f43cbd03c2bf158970be3e2f1fb 100644 (file)
@@ -14,6 +14,7 @@
 ** testing of the SQLite library.
 */
 #include "sqliteInt.h"
+#include "vdbeInt.h"
 #include "tcl.h"
 #include <stdlib.h>
 #include <string.h>
@@ -2326,6 +2327,32 @@ static int test_stmt_readonly(
   return TCL_OK;
 }
 
+/*
+** Usage:  uses_stmt_journal  STMT
+**
+** Return true if STMT uses a statement journal.
+*/
+static int uses_stmt_journal(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3_stmt *pStmt;
+  int rc;
+
+  if( objc!=2 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"",
+        Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
+    return TCL_ERROR;
+  }
+
+  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+  rc = sqlite3_stmt_readonly(pStmt);
+  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(((Vdbe *)pStmt)->usesStmtJournal));
+  return TCL_OK;
+}
+
 
 /*
 ** Usage:  sqlite3_reset  STMT 
@@ -5583,6 +5610,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_sql",                   test_sql           ,0 },
      { "sqlite3_next_stmt",             test_next_stmt     ,0 },
      { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
+     { "uses_stmt_journal",             uses_stmt_journal ,0 },
 
      { "sqlite3_release_memory",        test_release_memory,     0},
      { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
index b348a397f46051c88361b30278ea22ab29c97401..996c649f88e8bfb00b1a20592befd918bc33a6c1 100644 (file)
@@ -2580,6 +2580,14 @@ case OP_Savepoint: {
     }else{
       nName = sqlite3Strlen30(zName);
 
+      /* This call is Ok even if this savepoint is actually a transaction
+      ** savepoint (and therefore should not prompt xSavepoint()) callbacks.
+      ** If this is a transaction savepoint being opened, it is guaranteed
+      ** that the db->aVTrans[] array is empty.  */
+      assert( db->autoCommit==0 || db->nVTrans==0 );
+      rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement);
+      if( rc!=SQLITE_OK ) goto abort_due_to_error;
+
       /* Create a new savepoint structure. */
       pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1);
       if( pNew ){
@@ -2686,6 +2694,11 @@ case OP_Savepoint: {
       }else{
         db->nDeferredCons = pSavepoint->nDeferredCons;
       }
+
+      if( !isTransaction ){
+        rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
+        if( rc!=SQLITE_OK ) goto abort_due_to_error;
+      }
     }
   }
 
index 51ff9fd91094b6d54a8f2ce20f3242de07b3973c..811d2e1640bf422214f5fbf2b615057871adcdcc 100644 (file)
@@ -656,8 +656,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
   char *zErr = 0;
 
   sqlite3_mutex_enter(db->mutex);
-  pTab = db->pVtabCtx->pTab;
-  if( !pTab ){
+  if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
     sqlite3Error(db, SQLITE_MISUSE, 0);
     sqlite3_mutex_leave(db->mutex);
     return SQLITE_MISUSE_BKPT;
@@ -852,26 +851,43 @@ int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
   return rc;
 }
 
+/*
+** Invoke either the xSavepoint, xRollbackTo or xRelease method of all
+** virtual tables that currently have an open transaction. Pass iSavepoint
+** as the second argument to the virtual table method invoked.
+**
+** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is
+** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is 
+** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with
+** an open transaction is invoked.
+**
+** If any virtual table method returns an error code other than SQLITE_OK, 
+** processing is abandoned and the error returned to the caller of this
+** function immediately. If all calls to virtual table methods are successful,
+** SQLITE_OK is returned.
+*/
 int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
-  int i;
   int rc = SQLITE_OK;
 
   assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
-
-  for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
-    sqlite3_vtab *pVtab = db->aVTrans[i]->pVtab;
-    sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule;
-    if( pMod->iVersion>=1 ){
-      switch( op ){
-        case SAVEPOINT_BEGIN:
-          rc = pMod->xSavepoint(pVtab, iSavepoint);
-          break;
-        case SAVEPOINT_ROLLBACK:
-          rc = pMod->xRollbackTo(pVtab, iSavepoint);
-          break;
-        default:
-          rc = pMod->xRelease(pVtab, iSavepoint);
-          break;
+  if( db->aVTrans ){
+    int i;
+    for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
+      const sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule;
+      if( pMod->iVersion>=1 ){
+        int (*xMethod)(sqlite3_vtab *, int);
+        switch( op ){
+          case SAVEPOINT_BEGIN:
+            xMethod = pMod->xSavepoint;
+            break;
+          case SAVEPOINT_ROLLBACK:
+            xMethod = pMod->xRollbackTo;
+            break;
+          default:
+            xMethod = pMod->xRelease;
+            break;
+        }
+        if( xMethod ) rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint);
       }
     }
   }
index 7bcf66ef53be8a4168a705da0374a687acebd91e..7557e963232f200cc69a8004daf8c4e595fad6cc 100644 (file)
@@ -56,6 +56,14 @@ proc fts3_integrity {tn db tbl} {
   uplevel [list do_test $tn [list set {} $m1] $m2]
 }
 
+proc sql_uses_stmt {db sql} {
+  set stmt [sqlite3_prepare db $sql -1 dummy]
+  set uses [uses_stmt_journal $stmt]
+  sqlite3_finalize $stmt
+  return $uses
+}
+
+
 
 
 do_execsql_test 1.0.1 {
@@ -75,30 +83,30 @@ set T2 "INTO t1(rowid, x) SELECT * FROM source"
 set T3 "t1 SET docid = 2 WHERE docid = 1"
 set T4 "t1 SET docid = CASE WHEN docid = 1 THEN 4 ELSE 3 END WHERE docid <=2"
 
-foreach {tn sql constraint data} [subst {
-  1    "INSERT OR ROLLBACK $T1"   1 {{a b c d} {e f g h}}
-  2    "INSERT OR ABORT    $T1"   1 {{a b c d} {e f g h} {i j k l}}
-  3    "INSERT OR FAIL     $T1"   1 {{a b c d} {e f g h} {i j k l}}
-  4    "INSERT OR IGNORE   $T1"   0 {{a b c d} {e f g h} {i j k l}}
-  5    "INSERT OR REPLACE  $T1"   0 {x {e f g h} {i j k l}}
-
-  6    "INSERT OR ROLLBACK $T2"   1 {{a b c d} {e f g h}}
-  7    "INSERT OR ABORT    $T2"   1 {{a b c d} {e f g h} {i j k l}}
-  8    "INSERT OR FAIL     $T2"   1 {{a b c d} {e f g h} {i j k l} z}
-  9    "INSERT OR IGNORE   $T2"   0 {{a b c d} {e f g h} {i j k l} z}
-  10   "INSERT OR REPLACE  $T2"   0 {{a b c d} y {i j k l} z}
-
-  11   "UPDATE OR ROLLBACK $T3"   1 {{a b c d} {e f g h}}
-  12   "UPDATE OR ABORT    $T3"   1 {{a b c d} {e f g h} {i j k l}}
-  13   "UPDATE OR FAIL     $T3"   1 {{a b c d} {e f g h} {i j k l}}
-  14   "UPDATE OR IGNORE   $T3"   0 {{a b c d} {e f g h} {i j k l}}
-  15   "UPDATE OR REPLACE  $T3"   0 {{a b c d} {i j k l}}
-
-  16   "UPDATE OR ROLLBACK $T4"   1 {{a b c d} {e f g h}}
-  17   "UPDATE OR ABORT    $T4"   1 {{a b c d} {e f g h} {i j k l}}
-  18   "UPDATE OR FAIL     $T4"   1 {{e f g h} {i j k l} {a b c d}}
-  19   "UPDATE OR IGNORE   $T4"   0 {{e f g h} {i j k l} {a b c d}}
-  20   "UPDATE OR REPLACE  $T4"   0 {{e f g h} {a b c d}}
+foreach {tn sql uses constraint data} [subst {
+  1    "INSERT OR ROLLBACK $T1"   1 {{a b c d} {e f g h}}
+  2    "INSERT OR ABORT    $T1"   1 {{a b c d} {e f g h} {i j k l}}
+  3    "INSERT OR FAIL     $T1"   1 {{a b c d} {e f g h} {i j k l}}
+  4    "INSERT OR IGNORE   $T1"   0 {{a b c d} {e f g h} {i j k l}}
+  5    "INSERT OR REPLACE  $T1"   0 {x {e f g h} {i j k l}}
+
+  6    "INSERT OR ROLLBACK $T2"   1 {{a b c d} {e f g h}}
+  7    "INSERT OR ABORT    $T2"   1 {{a b c d} {e f g h} {i j k l}}
+  8    "INSERT OR FAIL     $T2"   1 {{a b c d} {e f g h} {i j k l} z}
+  9    "INSERT OR IGNORE   $T2"   0 {{a b c d} {e f g h} {i j k l} z}
+  10   "INSERT OR REPLACE  $T2"   0 {{a b c d} y {i j k l} z}
+
+  11   "UPDATE OR ROLLBACK $T3"   1 {{a b c d} {e f g h}}
+  12   "UPDATE OR ABORT    $T3"   1 {{a b c d} {e f g h} {i j k l}}
+  13   "UPDATE OR FAIL     $T3"   1 {{a b c d} {e f g h} {i j k l}}
+  14   "UPDATE OR IGNORE   $T3"   0 {{a b c d} {e f g h} {i j k l}}
+  15   "UPDATE OR REPLACE  $T3"   0 {{a b c d} {i j k l}}
+
+  16   "UPDATE OR ROLLBACK $T4"   1 {{a b c d} {e f g h}}
+  17   "UPDATE OR ABORT    $T4"   1 {{a b c d} {e f g h} {i j k l}}
+  18   "UPDATE OR FAIL     $T4"   1 {{e f g h} {i j k l} {a b c d}}
+  19   "UPDATE OR IGNORE   $T4"   0 {{e f g h} {i j k l} {a b c d}}
+  20   "UPDATE OR REPLACE  $T4"   0 {{e f g h} {a b c d}}
 }] {
   db_restore_and_reopen
   execsql { 
@@ -112,7 +120,20 @@ foreach {tn sql constraint data} [subst {
   catchsql COMMIT
 
   fts3_integrity 1.$tn.3 db t1
+
+  do_test 1.$tn.4 [list sql_uses_stmt db $sql] $uses
+}
+
+do_execsql_test 2.1.1 {
+  DELETE FROM t1;
+  BEGIN;
+    INSERT INTO t1 VALUES('a b c');
+    SAVEPOINT a;
+      INSERT INTO t1 VALUES('x y z');
+    ROLLBACK TO a;
+  COMMIT;
 }
+fts3_integrity 2.1.2 db t1
 
 
 finish_test