From: dan Date: Thu, 17 Jun 2010 10:52:07 +0000 (+0000) Subject: Merge trunk updates with experimental branch. X-Git-Tag: version-3.7.2~256^2~14 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=24827d0c0f1424888a30ae7456f0c00190198c6f;p=thirdparty%2Fsqlite.git Merge trunk updates with experimental branch. FossilOrigin-Name: 9f6ea1de5abab0ca28688e257ddf03c66413cf6e --- 24827d0c0f1424888a30ae7456f0c00190198c6f diff --cc manifest index 0a38a292c6,18df49f3c9..3746475123 --- a/manifest +++ 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 8726926b10,76b686d8e1..200362655a --- a/manifest.uuid +++ b/manifest.uuid @@@ -1,1 -1,1 +1,1 @@@ - 20133e9ca98f5e6c42051ed3d65e4eb71d5366a5 -1ec74591a93e8b27ad3ac739914a48a91972e82c ++9f6ea1de5abab0ca28688e257ddf03c66413cf6e diff --cc test/journal2.test index 8104299d49,0000000000..ad76a8173f mode 100644,000000..100644 --- a/test/journal2.test +++ b/test/journal2.test @@@ -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 - +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 {$method == "xDelete" || $method == "xWrite" || $method == "xTruncate"} { ++ if {[lsearch {xDelete xWrite xTruncate} $method]>=0} { + return SQLITE_IOERR + } + return SQLITE_OK + } + - if {[string match *journal* $filename]==0} return - ++ # 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 { - xOpen { - incr ::open_journals($f) +1 - } - xClose { - incr ::open_journals($f) -1 - } - xDelete { - if {$::open_journals($f)>0} { return SQLITE_IOERR } - } ++ xOpen { incr ::open_journals($f) +1 } ++ xClose { incr ::open_journals($f) -1 } ++ xDelete { if {$::open_journals($f)>0} { puts EEE;return SQLITE_IOERR } } + } + - return ++ 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. 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). ++# 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 +