]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add some tests for overlapping SELECT, COMMIT and ROLLBACK commands. (CVS 1774)
authordanielk1977 <danielk1977@noemail.net>
Wed, 30 Jun 2004 06:30:25 +0000 (06:30 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Wed, 30 Jun 2004 06:30:25 +0000 (06:30 +0000)
FossilOrigin-Name: d256c14943968e7adf4b73988cac6af941c9b12d

manifest
manifest.uuid
src/vacuum.c
src/vdbe.c
test/capi2.test
test/capi3.test

index 4bbd27432cb7d43fabfc9481c758863a51f69ed9..1b467c4d3d2c47ce8654f85694b151efc34bfe86 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improve\stest\scoverage\sof\sutil.c\s(CVS\s1773)
-D 2004-06-30T04:02:12
+C Add\ssome\stests\sfor\soverlapping\sSELECT,\sCOMMIT\sand\sROLLBACK\scommands.\s(CVS\s1774)
+D 2004-06-30T06:30:26
 F Makefile.in cb7a9889c38723f72b2506c4236ff30a05ff172b
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -72,8 +72,8 @@ F src/trigger.c 6aaf6d79cc2157c70a06031dd1531707d644cfb4
 F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a
 F src/utf.c f03535db72bfa09e24202ccdd245f21d2fc65f0a
 F src/util.c b267d0fe10cffa3301fe9fab6592a6808a38bce6
-F src/vacuum.c 353c7f69dbeb6738434d81798465cc0698844640
-F src/vdbe.c 32039b08701f1c19fcd9b684366cefaa8fabaa72
+F src/vacuum.c 4aede0a7048d8b71a43f45cc15359e16eddc8a2e
+F src/vdbe.c 6950e25d93346b03404d2fc383883ff9fa2e5966
 F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52
 F src/vdbeInt.h d83fd7389838453d8392915c21f432014afc99cf
 F src/vdbeapi.c ba3722f45db3d3c3509bf5d24f4f868f4c64449d
@@ -95,8 +95,8 @@ F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
 F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
 F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
 F test/btree7.test 429b96cfef5b51a7d512cfb4b5b3e453384af293
-F test/capi2.test fe61f341e953f73c29bacfcbdaf688cd7b0e0d38
-F test/capi3.test 3a7f759ce26a300ecdd288be901fcb0727f8773a
+F test/capi2.test 78f2c486689fcc80394a24c2cc32725330ab6299
+F test/capi3.test 85c4445cd9bd1fa0cd9d8af56a4fae361b57c553
 F test/collate1.test 2ee4fa3a47a652ccf56c5ddf65dcc44d9bad82ef
 F test/collate2.test c1a3b41f761b28853c5696037f92de928f93233b
 F test/collate3.test e60b428e07ec945492ba90ff1c895902ee3a8a50
@@ -232,7 +232,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 0c999f28137bd82ba24dd263bab30d22329eed73
-R aac9bef2959b49a3b21126dff36eb51a
-U drh
-Z d9d34e7eed57c4c6a384e0a609787172
+P 68ac32213766c5e83de54373b90030a458538017
+R 744bf93dd2f36513077a290ed8b8aa9f
+U danielk1977
+Z aa9871afb1977e06c76a2d6bc3030445
index c10c079327776476bea5cdf69b591b2fb4221341..c44e0ae3358dd3fbd52e7a25ebc734bbe8325e10 100644 (file)
@@ -1 +1 @@
-68ac32213766c5e83de54373b90030a458538017
\ No newline at end of file
+d256c14943968e7adf4b73988cac6af941c9b12d
\ No newline at end of file
index 8fdf06b5dddbfd6f582c16d1a88e82208ad689ba..e2a26eaf909e3123ed8121db7bb7ebf8a4e5e632 100644 (file)
@@ -14,7 +14,7 @@
 ** Most of the code in this file may be omitted by defining the
 ** SQLITE_OMIT_VACUUM macro.
 **
-** $Id: vacuum.c,v 1.24 2004/06/26 08:38:25 danielk1977 Exp $
+** $Id: vacuum.c,v 1.25 2004/06/30 06:30:26 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -97,9 +97,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
   char *zTemp = 0;        /* a temporary file in same directory as zFilename */
   int i;                  /* Loop counter */
   Btree *pTemp;
-
   char *zSql = 0;
-  sqlite3_stmt *pStmt = 0;
 
   if( !db->autoCommit ){
     sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
@@ -129,8 +127,16 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
     if( !sqlite3OsFileExists(zTemp) ) break;
   }
 
-  /* Attach the temporary database as 'vacuum' */
+  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
+  ** can be set to 'off' for this file, as it is not recovered if a crash
+  ** occurs anyway. The integrity of the database is maintained by a
+  ** (possibly synchronous) transaction opened on the main database before
+  ** sqlite3BtreeCopyFile() is called.
+  **
+  ** An optimisation would be to use a non-journaled pager.
+  */
   zSql = sqlite3MPrintf("ATTACH '%s' AS vacuum_db;", zTemp);
+  execSql(db, "PRAGMA vacuum_db.synchronous = off;");
   if( !zSql ){
     rc = SQLITE_NOMEM;
     goto end_of_vacuum;
@@ -217,14 +223,20 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
   }
 
 end_of_vacuum:
-  execSql(db, "ROLLBACK;");
+  /* Currently there is an SQL level transaction open on the vacuum
+  ** database. No locks are held on any other files (since the main file
+  ** was committed at the btree level). So it safe to end the transaction
+  ** by manually setting the autoCommit flag to true and detaching the
+  ** vacuum database. The vacuum_db journal file is deleted when the pager
+  ** is closed by the DETACH.
+  */
+  db->autoCommit = 1;
   execSql(db, "DETACH vacuum_db;");
   if( zTemp ){
     sqlite3OsDelete(zTemp);
     sqliteFree(zTemp);
   }
   if( zSql ) sqliteFree( zSql );
-  if( pStmt ) sqlite3_finalize( pStmt );
 #endif
   return rc;
 } 
index 442e396ae517e53ad164ef00d31cd6482d7eef4d..4fe0fe984206813328e3286f4cdd8eacac3081ee 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.396 2004/06/30 02:43:38 danielk1977 Exp $
+** $Id: vdbe.c,v 1.397 2004/06/30 06:30:26 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -2212,7 +2212,8 @@ case OP_Statement: {
 /* Opcode: AutoCommit P1 P2 *
 **
 ** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
-** back any currently active btree transactions.
+** back any currently active btree transactions. If there are any active
+** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
 */
 case OP_AutoCommit: {
   u8 i = pOp->p1;
@@ -2221,7 +2222,17 @@ case OP_AutoCommit: {
   assert( i==1 || i==0 );
   assert( i==1 || rollback==0 );
 
-  if( i!=db->autoCommit ){
+  assert( db->activeVdbeCnt>0 );
+
+  if( db->activeVdbeCnt>1 && i && !db->autoCommit ){
+    /* If this instruction implements a COMMIT or ROLLBACK, other VMs are
+    ** still running, and a transaction is active, return an error indicating
+    ** that the other VMs must complete first. 
+    */
+    sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit", 
+        " transaction - SQL statements in progress", 0);
+    rc = SQLITE_ERROR;
+  }else if( i!=db->autoCommit ){
     db->autoCommit = i;
     p->autoCommitOn |= i;
     if( pOp->p2 ){
index a4265c9a16a68b4b8e12cb242f935c0c733fadb8..6af1989dcc093f68c5a1196c3bb36f576e6a503d 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script testing the callback-free C/C++ API.
 #
-# $Id: capi2.test,v 1.17 2004/06/26 09:50:12 danielk1977 Exp $
+# $Id: capi2.test,v 1.18 2004/06/30 06:30:26 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -484,18 +484,18 @@ do_test capi2-6.20 {
        [get_row_values $VM1] \
        [get_column_names $VM1]
 } {SQLITE_ROW 1 9 {x counter}}
-do_test capi2-6.21 {
-  execsql {ROLLBACK; SELECT * FROM t1}
-} {1 2 3}
+#do_test capi2-6.21 {
+#  execsql {ROLLBACK; SELECT * FROM t1}
+#} {1 2 3}
 do_test capi2-6.22 {
   list [sqlite3_step $VM1] \
        [sqlite3_column_count $VM1] \
        [get_row_values $VM1] \
        [get_column_names $VM1]
 } {SQLITE_ROW 1 10 {x counter}}
-do_test capi2-6.23 {
-  execsql {BEGIN TRANSACTION;}
-} {}
+#do_test capi2-6.23 {
+#  execsql {BEGIN TRANSACTION;}
+#} {}
 do_test capi2-6.24 {
   list [sqlite3_step $VM1] \
        [sqlite3_column_count $VM1] \
@@ -507,7 +507,7 @@ do_test capi2-6.25 {
     INSERT INTO t1 VALUES(2,3,4);
     SELECT * FROM t1;
   }
-} {1 2 3 2 3 4}
+} {1 3 3 2 3 4}
 do_test capi2-6.26 {
   list [sqlite3_step $VM1] \
        [sqlite3_column_count $VM1] \
index 7dce3722df0ead5a439ed54a18e5420d8367aee9..a595bff52acf0b11ac5c2a41e5dc6cce0097b666 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script testing the callback-free C/C++ API.
 #
-# $Id: capi3.test,v 1.18 2004/06/30 02:35:51 danielk1977 Exp $
+# $Id: capi3.test,v 1.19 2004/06/30 06:30:26 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -498,7 +498,7 @@ do_test capi3-8.2 {
 
   # Build a 5-field row record consisting of 5 null records. This is
   # officially black magic.
-  unset data
+  catch {unset data}
   set data [binary format c6 {6 0 0 0 0 0}]
   btree_insert $::bc 5 $data
 
@@ -601,7 +601,164 @@ db close
 sqlite_malloc_fail 0
 }
 
-finish_test
+# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK
+# statement issued while there are still outstanding VMs that are part of
+# the transaction fails.
+set DB [sqlite3 db test.db]
+sqlite_register_test_function $DB func
+do_test capi3-11.1 {
+  execsql {
+    BEGIN;
+    CREATE TABLE t1(a, b);
+    INSERT INTO t1 VALUES(1, 'int');
+    INSERT INTO t1 VALUES(2, 'notatype');
+  }
+} {}
+do_test capi3-11.2 {
+  set STMT [sqlite3_prepare $DB "SELECT func(b, a) FROM t1" -1 TAIL]
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3-11.3 {
+  catchsql {
+    COMMIT;
+  }
+} {1 {cannot commit transaction - SQL statements in progress}}
+do_test capi3-11.4 {
+  sqlite3_step $STMT
+} {SQLITE_ERROR}
+do_test capi3-11.5 {
+  sqlite3_finalize $STMT
+} {SQLITE_ERROR}
+do_test capi3-11.6 {
+  catchsql {
+    SELECT * FROM t1;
+  }
+} {0 {1 int 2 notatype}}
+do_test capi3-11.7 {
+  catchsql {
+    COMMIT;
+  }
+} {0 {}}
+do_test capi3-11.8 {
+  execsql {
+    CREATE TABLE t2(a);
+    INSERT INTO t2 VALUES(1);
+    INSERT INTO t2 VALUES(2);
+    BEGIN;
+    INSERT INTO t2 VALUES(3);
+  }
+} {}
+do_test capi3-11.9 {
+  set STMT [sqlite3_prepare $DB "SELECT a FROM t2" -1 TAIL]
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3-11.3 {
+  catchsql {
+    ROLLBACK;
+  }
+} {1 {cannot rollback transaction - SQL statements in progress}}
+do_test capi3-11.10 {
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3-11.11 {
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3-11.12 {
+  sqlite3_step $STMT
+} {SQLITE_DONE}
+do_test capi3-11.13 {
+  sqlite3_finalize $STMT
+} {SQLITE_OK}
+do_test capi3-11.14 {
+  execsql {
+    SELECT a FROM t2;
+  }
+} {1 2 3}
+do_test capi3-11.15 {
+  catchsql {
+    ROLLBACK;
+  }
+} {0 {}}
+do_test capi3-11.16 {
+  execsql {
+    SELECT a FROM t2;
+  }
+} {1 2}
+
+# Sanity check on the definition of 'outstanding VM'. This means any VM
+# that has had sqlite3_step() called more recently than sqlite3_finalize() or
+# sqlite3_reset(). So a VM that has just been prepared or reset does not
+# count as an active VM.
+do_test capi3-11.17 {
+  execsql {
+    BEGIN;
+  }
+} {}
+do_test capi3-11.18 {
+  set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL]
+  catchsql {
+    COMMIT;
+  }
+} {0 {}}
+do_test capi3-11.19 {
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3-11.20 {
+  catchsql {
+    BEGIN;
+    COMMIT;
+  }
+} {1 {cannot commit transaction - SQL statements in progress}}
+do_test capi3-11.20 {
+  sqlite3_reset $STMT
+  catchsql {
+    COMMIT;
+  }
+} {0 {}}
+do_test capi3-11.21 {
+  sqlite3_finalize $STMT
+} {SQLITE_OK}
 
+# The following tests - capi3-12.* - check that it's Ok to start a
+# transaction while other VMs are active, and that it's Ok to execute
+# atomic updates in the same situation (so long as they are on a different
+# table).
+do_test capi3-12.1 {
+  set STMT [sqlite3_prepare $DB "SELECT a FROM t2" -1 TAIL]
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3-12.2 {
+  catchsql {
+    INSERT INTO t1 VALUES(3, NULL);
+  }
+} {0 {}}
+do_test capi3-12.3 {
+  catchsql {
+    INSERT INTO t2 VALUES(4);
+  }
+} {1 {database table is locked}}
+do_test capi3-12.4 {
+  catchsql {
+    BEGIN;
+    INSERT INTO t1 VALUES(4, NULL);
+  }
+} {0 {}}
+do_test capi3-12.5 {
+  sqlite3_step $STMT
+} {SQLITE_ROW}
+do_test capi3-12.6 {
+  sqlite3_step $STMT
+} {SQLITE_DONE}
+do_test capi3-12.7 {
+  sqlite3_finalize $STMT
+} {SQLITE_OK}
+do_test capi3-12.8 {
+  execsql {
+    COMMIT;
+    SELECT a FROM t1;
+  }
+} {1 2 3 4}
 
 
+finish_test
+