]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In sqlite3_close_v2(), do not attempt to roll back a transaction if there exist activ...
authordan <dan@noemail.net>
Thu, 16 May 2013 11:57:28 +0000 (11:57 +0000)
committerdan <dan@noemail.net>
Thu, 16 May 2013 11:57:28 +0000 (11:57 +0000)
FossilOrigin-Name: d11e76072a17fe833b87595d9d79f2c4b0b09cb3

manifest
manifest.uuid
src/main.c
src/test1.c
test/close.test [new file with mode: 0644]

index ec49a5a18d01339b2b463e5c253282eb23445750..f3e24afc9ef8400ae83bf03ed5020ae14cdf57c6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Treat\sidentifiers\sin\sthe\sHAVING\sclause\sthe\ssame\sas\sin\sthe\sWHERE\sclause.\nOnly\sconsider\sAS\snames\sfrom\sthe\sresult\sset\sto\smatch\sif\sthere\sare\sno\sother\nmatches.\s\sContinuation\sof\sthe\sfix\sfor\s[2500cdb9be05].\s\sThis\scheck-in\nfixes\sa\sbug\sfound\sby\s[http://www.sqlite.org/sqllogictest/\s|\sSqlLogicTest]\nduring\srelease\stesting\sfor\sversion\s3.7.17.
-D 2013-05-16T01:02:45.632
+C In\ssqlite3_close_v2(),\sdo\snot\sattempt\sto\sroll\sback\sa\stransaction\sif\sthere\sexist\sactive\sstatement\sobjects.\sAny\sopen\stransaction\swill\sbe\srolled\sback\swhen\sthe\slast\sof\sthese\sstatement\sobjects\sis\sfinalized.
+D 2013-05-16T11:57:28.062
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 101fc5d712bfa348313987e5728ead013dc82fba
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -160,7 +160,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
 F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2
-F src/main.c ccbac976228cd21209ede2bdc82bbf22b0ddf197
+F src/main.c c6419ef57392b1aa0cf6ed9c80dfc06b153fe299
 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
@@ -201,7 +201,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c 2ecec9937e69bc17560ad886da35195daa7261b8
-F src/test1.c ab9dd4fc486a2542f57a2ca17d74fc7f28dfd05a
+F src/test1.c 045d45a4f7eeb5d963f8fc150339f1bad279011a
 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
 F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -338,6 +338,7 @@ F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1
 F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde
 F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
 F test/check.test 2eb93611139a7dfaed3be80067c7dc5ceb5fb287
+F test/close.test e37610d60e9c9b9979a981f3f50071d7dff28616
 F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7
 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
 F test/collate1.test fd02c4d8afc71879c4bb952586389961a21fb0ce
@@ -1064,7 +1065,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 7e76889d675e4c646158f7f9188d25f155c18876
-R 734d69ab143a2741580e8434cd6321b1
-U drh
-Z 6441f17ff50e2e08c247bf534d4dc934
+P 9ffff3d05226bbd01a0745dd0a511776358253c0
+R 1a17d95315a3a4d605dc90092cbaec4e
+U dan
+Z 6e4c531756ef5b922f59a9b9e491858b
index b0132386fcfe4203629bdffdb36f78ca3c66f4ef..99b6ba1500ca2f046395fe63bd1cef9554edc4c5 100644 (file)
@@ -1 +1 @@
-9ffff3d05226bbd01a0745dd0a511776358253c0
\ No newline at end of file
+d11e76072a17fe833b87595d9d79f2c4b0b09cb3
\ No newline at end of file
index 763adbfe8eedc24261416e4151e43c4c8d994655..39f60421e681277cc3dba09abe7cf790d528f5c3 100644 (file)
@@ -848,12 +848,6 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
     return SQLITE_BUSY;
   }
 
-  /* If a transaction is open, roll it back. This also ensures that if
-  ** any database schemas have been modified by the current transaction
-  ** they are reset. And that the required b-tree mutex is held to make
-  ** the the pager rollback and schema reset an atomic operation. */
-  sqlite3RollbackAll(db, SQLITE_OK);
-
 #ifdef SQLITE_ENABLE_SQLLOG
   if( sqlite3GlobalConfig.xSqllog ){
     /* Closing the handle. Fourth parameter is passed the value 2. */
@@ -908,6 +902,12 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
   ** go ahead and free all resources.
   */
 
+  /* If a transaction is open, roll it back. This also ensures that if
+  ** any database schemas have been modified by an uncommitted transaction
+  ** they are reset. And that the required b-tree mutex is held to make
+  ** the pager rollback and schema reset an atomic operation. */
+  sqlite3RollbackAll(db, SQLITE_OK);
+
   /* Free any outstanding Savepoint structures. */
   sqlite3CloseSavepoints(db);
 
@@ -1008,7 +1008,15 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
   int inTrans = 0;
   assert( sqlite3_mutex_held(db->mutex) );
   sqlite3BeginBenignMalloc();
+
+  /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). 
+  ** This is important in case the transaction being rolled back has
+  ** modified the database schema. If the b-tree mutexes are not taken
+  ** here, then another shared-cache connection might sneak in between
+  ** the database rollback and schema reset, which can cause false
+  ** corruption reports in some cases.  */
   sqlite3BtreeEnterAll(db);
+
   for(i=0; i<db->nDb; i++){
     Btree *p = db->aDb[i].pBt;
     if( p ){
index 59de1db8e5e9a7d119cfba8e82a92541c3c6e31e..a638e480addf14439cdfa4ee164dc31b79f8bcac 100644 (file)
@@ -681,6 +681,30 @@ static int sqlite_test_close(
   return TCL_OK;
 }
 
+/*
+** Usage:  sqlite3_close_v2 DB
+**
+** Closes the database opened by sqlite3_open.
+*/
+static int sqlite_test_close_v2(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  char **argv            /* Text of each argument */
+){
+  sqlite3 *db;
+  int rc;
+  if( argc!=2 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " FILENAME\"", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
+  rc = sqlite3_close_v2(db);
+  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
+  return TCL_OK;
+}
+
 /*
 ** Implementation of the x_coalesce() function.
 ** Return the first argument non-NULL argument.
@@ -6077,6 +6101,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
 #endif
      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
+     { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
      { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
      { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
diff --git a/test/close.test b/test/close.test
new file mode 100644 (file)
index 0000000..355a886
--- /dev/null
@@ -0,0 +1,79 @@
+# 2013 May 14
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# Test some specific circumstances to do with shared cache mode.
+#
+
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix close
+
+do_execsql_test 1.0 {
+  CREATE TABLE t1(x);
+  INSERT INTO t1 VALUES('one');
+  INSERT INTO t1 VALUES('two');
+  INSERT INTO t1 VALUES('three');
+}
+db close
+
+do_test 1.1 {
+  set DB [sqlite3_open test.db]
+  sqlite3_close_v2 $DB
+} {SQLITE_OK}
+
+do_test 1.2.1 {
+  set DB [sqlite3_open test.db]
+  set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy]
+  sqlite3_close_v2 $DB
+} {SQLITE_OK}
+do_test 1.2.2 {
+  sqlite3_finalize $STMT
+} {SQLITE_OK}
+
+do_test 1.3.1 {
+  set DB [sqlite3_open test.db]
+  set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy]
+  sqlite3_step $STMT
+  sqlite3_close_v2 $DB
+} {SQLITE_OK}
+
+do_test 1.3.2 {
+  sqlite3_column_text $STMT 0
+} {one}
+
+do_test 1.3.3 {
+  sqlite3_finalize $STMT
+} {SQLITE_OK}
+
+do_test 1.4.1 {
+  set DB [sqlite3_open test.db]
+  set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy]
+  sqlite3_step $STMT
+  sqlite3_close_v2 $DB
+} {SQLITE_OK}
+
+do_test 1.4.2 {
+  list [sqlite3_step $STMT] [sqlite3_column_text $STMT 0]
+} {SQLITE_ROW two}
+
+do_test 1.4.3 {
+  list [catch {
+    sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 dummy
+  } msg] $msg
+} {1 {(21) library routine called out of sequence}}
+
+do_test 1.4.4 {
+  sqlite3_finalize $STMT
+} {SQLITE_OK}
+
+finish_test
+