]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge trunk updates with experimental branch.
authordan <dan@noemail.net>
Thu, 17 Jun 2010 10:52:07 +0000 (10:52 +0000)
committerdan <dan@noemail.net>
Thu, 17 Jun 2010 10:52:07 +0000 (10:52 +0000)
FossilOrigin-Name: 9f6ea1de5abab0ca28688e257ddf03c66413cf6e

1  2 
manifest
manifest.uuid
src/pager.c
test/journal2.test

diff --cc manifest
index 0a38a292c6f1969f9153fe2521a9902b1f8181af,18df49f3c99270b3afba212446faaeafbf51d111..3746475123516961c064252e31b3c185efef615a
+++ b/manifest
@@@ -1,5 -1,5 +1,5 @@@
- C Merge\sfix\s[f80c3f922a]\swith\sexperimental\schanges.
- D 2010-06-17T06:19:53
 -C Do\snot\sdelete\sthe\sjournal\sfile\sin\s"PRAGMA\sjournal_mode"\scommands.\sThis\sfixes\s[fc62af4523].
 -D 2010-06-17T10:42:07
++C Merge\strunk\supdates\swith\sexperimental\sbranch.
++D 2010-06-17T10:52:07
  F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
  F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
  F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@@ -156,7 -156,7 +156,7 @@@ F src/os_common.h a8f95b81eca8a1ab8593d
  F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
  F src/os_unix.c ae173c9f6afaa58b2833a1c95c6cd32021755c42
  F src/os_win.c dfde7d33c446e89dd9a277c036f2c4cc564b3138
- F src/pager.c 3b2527d9d65a43880a98546ea84559271bb6d970
 -F src/pager.c b5584c5e75e463b4a136e26858d555e83ca97b44
++F src/pager.c 658e5063d2d1661336a1e269e1cc324dfa8a683a
  F src/pager.h ca1f23c0cf137ac26f8908df2427c8b308361efd
  F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
  F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
@@@ -466,8 -466,7 +466,8 @@@ F test/join4.test 1a352e4e267114444c292
  F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
  F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901
  F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
- F test/journal2.test 0f867f26c7f30bda2b69dc0e6451caa8fed18ef1
- F test/jrnlmode.test 76f94d61528c5ff32102a12f8cf34f4cc36f7849
++F test/journal2.test 92653f42868b32272a9913c767324b0b3992a60b
+ F test/jrnlmode.test cd0c9c5b2555f3d5bb72ed8aa8d0ad16ecf77e7c
  F test/jrnlmode2.test fe79ea1f0375c926b8de0362ddf94f34a64135fd
  F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710
  F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
@@@ -823,7 -823,7 +824,7 @@@ F tool/speedtest2.tcl ee2149167303ba8e9
  F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
  F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
  F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
- P bede8c8a148fb9be5ffbf38df7fa733e35cc68c3 f80c3f922a114e738613955a939db46cf0847038
- R 99e9ca5d85226de77fd66a29f7003e5a
 -P cccd32c692057beb08a994102c6a10126ddeb937
 -R cc967c249a884e7c285bdbc1b3f00097
++P 20133e9ca98f5e6c42051ed3d65e4eb71d5366a5 1ec74591a93e8b27ad3ac739914a48a91972e82c
++R 4f7b82137af7b10bc7d2278f04c82c2f
  U dan
- Z b12621360876a83980ead5d940279e1b
 -Z 4ebb4fa39dfc135851bcdd3d6648050e
++Z 03dc90f484cb38d112214ba72ea54330
diff --cc manifest.uuid
index 8726926b101ba3520c8797a6ee46f6b3fd3ebe69,76b686d8e11ab921551de692b47d44244fb9ad16..200362655a25ea37b4ef8338ef3fd2629c2a7774
@@@ -1,1 -1,1 +1,1 @@@
- 20133e9ca98f5e6c42051ed3d65e4eb71d5366a5
 -1ec74591a93e8b27ad3ac739914a48a91972e82c
++9f6ea1de5abab0ca28688e257ddf03c66413cf6e
diff --cc src/pager.c
Simple merge
index 8104299d493619b9cbe7f1a66f6c93725323ea44,0000000000000000000000000000000000000000..ad76a8173fad84aca5db3f14eca49e446a37b968
mode 100644,000000..100644
--- /dev/null
@@@ -1,188 -1,0 +1,229 @@@
 +# 2010 June 16
 +#
 +# 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.
 +#
 +#***********************************************************************
 +# This file implements regression tests for SQLite library.
 +#
 +
 +set testdir [file dirname $argv0]
 +source $testdir/tester.tcl
 +source $testdir/lock_common.tcl
 +source $testdir/malloc_common.tcl
 +db close
 +
 +set a_string_counter 1
 +proc a_string {n} {
 +  global a_string_counter
 +  incr a_string_counter
 +  string range [string repeat "${a_string_counter}." $n] 1 $n
 +}
 +
 +# Create a [testvfs] and install it as the default VFS. Set the device
 +# characteristics flags to "SAFE_DELETE".
 +#
 +testvfs tvfs -default 1
 +tvfs devchar safe_delete
 +
 +# Set up a hook so that each time a journal file is opened, closed or
 +# deleted, the method name ("xOpen", "xClose" or "xDelete") and the final
 +# segment of the journal file-name (i.e. "test.db-journal") are appended to
 +# global list variable $::oplog.
 +#
 +tvfs filter {xOpen xClose xDelete}
 +tvfs script journal_op_catcher
-     if {$method == "xDelete" || $method == "xWrite" || $method == "xTruncate"} {
 +proc journal_op_catcher {method filename args} {
 +
 +  # If global variable ::tvfs_error_on_write is defined, then return an
 +  # IO error to every attempt to modify the file-system. Otherwise, return
 +  # SQLITE_OK.
 +  #
 +  if {[info exists ::tvfs_error_on_write]} {
-   if {[string match *journal* $filename]==0} return
++    if {[lsearch {xDelete xWrite xTruncate} $method]>=0} {
 +      return SQLITE_IOERR 
 +    }
 +    return SQLITE_OK
 +  }
 +
-     xOpen {
-       incr ::open_journals($f) +1
-     }
-     xClose {
-       incr ::open_journals($f) -1
-     }
-     xDelete {
-       if {$::open_journals($f)>0} { return SQLITE_IOERR }
-     }
++  # The rest of this command only deals with xOpen(), xClose() and xDelete()
++  # operations on journal files. If this invocation does not represent such
++  # an operation, return with no further ado.
++  #
 +  set f [file tail $filename]
++  if {[string match *journal $f]==0} return
++  if {[lsearch {xOpen xDelete xClose} $method]<0} return
++
++  # Append a record of this operation to global list variable $::oplog.
++  #
 +  lappend ::oplog $method $f
 +
++  # If this is an attempt to delete a journal file for which there exists
++  # one ore more open handles, return an error. The code in test_vfs.c
++  # will not invoke the xDelete method of the "real" VFS in this case.
++  #
 +  if {[info exists ::open_journals($f)]==0} { set ::open_journals($f) 0 }
 +  switch -- $method {
-   return
++    xOpen   { incr ::open_journals($f) +1 }
++    xClose  { incr ::open_journals($f) -1 }
++    xDelete { if {$::open_journals($f)>0} { puts EEE;return SQLITE_IOERR } }
 +  }
 +
- # Grow the database until it is reasonably large. Then, from a 
- # journal_mode=DELETE connection, attempt to commit a large transaction (one
- # that involves upgrading to an exclusive lock and writing the database
- # before the transaction is committed).
++  return ""
 +}
 +
 +
 +do_test journal2-1.1 {
 +  set ::oplog [list]
 +  sqlite3 db test.db
 +  execsql { CREATE TABLE t1(a, b) }
 +  set ::oplog
 +} {xOpen test.db-journal xClose test.db-journal xDelete test.db-journal}
 +do_test journal2-1.2 {
 +  set ::oplog [list]
 +  execsql { 
 +    PRAGMA journal_mode = truncate;
 +    INSERT INTO t1 VALUES(1, 2);
 +  }
 +  set ::oplog
 +} {xOpen test.db-journal}
 +do_test journal2-1.3 {
 +  set ::oplog [list]
 +  execsql { INSERT INTO t1 VALUES(3, 4) }
 +  set ::oplog
 +} {}
 +do_test journal2-1.4 { execsql { SELECT * FROM t1 } } {1 2 3 4}
 +
 +# Add a second connection. This connection attempts to commit data in
 +# journal_mode=DELETE mode. When it tries to delete the journal file,
 +# the VFS layer returns an IO error.
 +#
 +do_test journal2-1.5 {
 +  set ::oplog [list]
 +  sqlite3 db2 test.db
 +  execsql  { PRAGMA journal_mode = delete } db2
 +  catchsql { INSERT INTO t1 VALUES(5, 6)  } db2
 +} {1 {disk I/O error}}
 +do_test journal2-1.6 { file exists test.db-journal } 1
 +do_test journal2-1.7 { execsql { SELECT * FROM t1 } } {1 2 3 4}
 +do_test journal2-1.8 {
 +  execsql { PRAGMA journal_mode = truncate } db2
 +  execsql { INSERT INTO t1 VALUES(5, 6)  } db2
 +} {}
 +do_test journal2-1.9 { execsql { SELECT * FROM t1 } } {1 2 3 4 5 6}
 +
++# Grow the database until it is reasonably large.
 +#
 +do_test journal2-1.10 {
 +  db2 close
 +  db func a_string a_string
 +  execsql {
 +    CREATE TABLE t2(a UNIQUE, b UNIQUE);
 +    INSERT INTO t2 VALUES(a_string(200), a_string(300));
 +    INSERT INTO t2 SELECT a_string(200), a_string(300) FROM t2;  --  2
 +    INSERT INTO t2 SELECT a_string(200), a_string(300) FROM t2;  --  4
 +    INSERT INTO t2 SELECT a_string(200), a_string(300) FROM t2;  --  8
 +    INSERT INTO t2 SELECT a_string(200), a_string(300) FROM t2;  -- 16
 +    INSERT INTO t2 SELECT a_string(200), a_string(300) FROM t2;  -- 32
 +    INSERT INTO t2 SELECT a_string(200), a_string(300) FROM t2;  -- 64
 +  }
 +  file size test.db-journal
 +} {0}
 +do_test journal2-1.11 {
 +  set sz [expr [file size test.db] / 1024]
 +  expr {$sz>120 && $sz<200}
 +} 1
 +
++# Using new connection [db2] (with journal_mode=DELETE), write a lot of
++# data to the database. So that many pages within the database file are
++# modified before the transaction is committed.
++#
++# Then, enable simulated IO errors in all calls to xDelete, xWrite
++# and xTruncate before committing the transaction and closing the 
++# database file. From the point of view of other file-system users, it
++# appears as if the process hosting [db2] unexpectedly exited.
++# 
 +do_test journal2-1.12 {
 +  sqlite3 db2 test.db
 +  execsql {
 +    PRAGMA cache_size = 10;
 +    BEGIN;
 +      INSERT INTO t2 SELECT randomblob(200), randomblob(300) FROM t2;  -- 128
 +  } db2
 +} {}
 +do_test journal2-1.13 {
 +  tvfs filter {xOpen xClose xDelete xWrite xTruncate}
 +  set ::tvfs_error_on_write 1
 +  catchsql { COMMIT } db2
 +} {1 {disk I/O error}}
 +db2 close
 +unset ::tvfs_error_on_write
 +file copy -force test.db testX.db
 +
 +do_test journal2-1.14 { file exists test.db-journal } 1
 +do_test journal2-1.15 {
 +  execsql {
 +    SELECT count(*) FROM t2;
 +    PRAGMA integrity_check;
 +  }
 +} {64 ok}
 +
 +# This block checks that in the test case above, connection [db2] really
 +# did begin writing to the database file before it hit IO errors. If
 +# this is true, then the copy of the database file made before [db]
 +# rolled back the hot journal should fail the integrity-check.
 +#
 +do_test journal2-1.16 {
 +  set sz [expr [file size testX.db] / 1024]
 +  expr {$sz>240 && $sz<400}
 +} 1
 +do_test journal2-1.17 {
 +  expr {[catchsql { PRAGMA integrity_check } db] == "0 ok"}
 +} {1}
 +do_test journal2-1.20 {
 +  sqlite3 db2 testX.db
 +  expr {[catchsql { PRAGMA integrity_check } db2] == "0 ok"}
 +} {0}
 +do_test journal2-1.21 {
 +  db2 close
 +} {}
 +db close
++
++#-------------------------------------------------------------------------
++# Test that it is possible to switch from journal_mode=truncate to
++# journal_mode=WAL on a SAFE_DELETE file-system. SQLite should close and
++# delete the journal file when committing the transaction that switches
++# the system to WAL mode.
++#
++ifcapable wal {
++  do_test journal2-2.1 {
++    faultsim_delete_and_reopen
++    set ::oplog [list]
++    execsql { PRAGMA journal_mode = persist }
++    set ::oplog
++  } {}
++  do_test journal2-2.2 {
++    execsql { 
++      CREATE TABLE t1(x);
++      INSERT INTO t1 VALUES(3.14159);
++    }
++    set ::oplog
++  } {xOpen test.db-journal}
++  do_test journal2-2.3 {
++    expr {[file size test.db-journal] > 512}
++  } {1}
++  do_test journal2-2.3 {
++    set ::oplog [list]
++    execsql { PRAGMA journal_mode = WAL }
++    set ::oplog
++  } {xClose test.db-journal xDelete test.db-journal}
++  db close
++}
++
 +tvfs delete
 +finish_test
 +