-C Add\sfurther\spager\stests.
-D 2010-06-21T07:45:47
+C Change\sthings\sso\sthat\sjournal2.test\sworks\swith\sENABLE_ATOMIC_WRITE.
+D 2010-06-21T12:34:30
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
F src/os_unix.c 5231a75a3799872b1250bc70c0e6a1a5960bc865
F src/os_win.c 73608839342de32280cb378d3c2fc85a5dd80bd2
-F src/pager.c 6ebb43239ad4ae2c0b0720bbd88a6a84a301bc8a
+F src/pager.c 9f138b79b47090c1e31efe3d9ea191cc92981643
F src/pager.h ca1f23c0cf137ac26f8908df2427c8b308361efd
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
F test/mallocI.test e3ea401904d010cb7c1e4b2ee8803f4a9f5b999d
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9
-F test/malloc_common.tcl 4981dd86adf0d3f25c755ac3a425d6208fda6362
+F test/malloc_common.tcl 58caffc4be307b56c5b1438b5eba3eb278bd81f5
F test/manydb.test b3d3bc4c25657e7f68d157f031eb4db7b3df0d3c
F test/memdb.test 0825155b2290e900264daaaf0334b6dfe69ea498
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
-F test/pager1.test e086d98a5312a7395d579117a1211d9110faffcc
+F test/pager1.test 86d034bf3ffe4e99648714443776440d0555f705
F test/pager2.test ad062a51030dc1e2749f506528db4cc5bae6474c
F test/pagerfault.test e67e9c18bf7b4bb8cc8d458d3a5ecc980f18a225
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P f6d26e07b70965e332b1589804ca938593a5f432
-R 57527134db79eb4730ccc85bc2c2f806
+P 4104b175a8c3560a7680f3d2b54416821bb2e19d
+R aa81338105a8066f92038016780c9df7
U dan
-Z 286faa52a0364bba3d1b0d11286b24cb
+Z 4c6c5e973462d689a9ddf24faae3aa9f
-4104b175a8c3560a7680f3d2b54416821bb2e19d
\ No newline at end of file
+a64d96db09ef2b7651fa4e98d3c7bf3ae5d3fe96
\ No newline at end of file
u8 tempFile; /* zFilename is a temporary file */
u8 readOnly; /* True for a read-only database */
u8 memDb; /* True to inhibit all file I/O */
- u8 safeJrnlHandle; /* True if jrnl may be held open with no lock */
/* The following block contains those class members that are dynamically
** modified during normal operations. The other variables in this structure
static void pager_unlock(Pager *pPager){
if( !pPager->exclusiveMode ){
int rc = SQLITE_OK; /* Return code */
+ int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
/* Always close the journal file when dropping the database lock.
** Otherwise, another connection with journal_mode=delete might
** delete the file out from under us.
*/
- if( pPager->safeJrnlHandle==0
- || (pPager->journalMode!=PAGER_JOURNALMODE_TRUNCATE
- && pPager->journalMode!=PAGER_JOURNALMODE_PERSIST)
+ assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 );
+ assert( (PAGER_JOURNALMODE_OFF & 5)!=1 );
+ assert( (PAGER_JOURNALMODE_WAL & 5)!=1 );
+ assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 );
+ assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
+ assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
+ if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
+ || 1!=(pPager->journalMode & 5)
){
sqlite3OsClose(pPager->jfd);
}
sqlite3BeginBenignMalloc();
pPager->errCode = 0;
pPager->exclusiveMode = 0;
- pPager->safeJrnlHandle = 0;
#ifndef SQLITE_OMIT_WAL
sqlite3WalClose(pPager->pWal,
(pPager->noSync ? 0 : pPager->sync_flags),
enable_simulated_io_errors();
PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
IOTRACE(("CLOSE %p\n", pPager))
+ sqlite3OsClose(pPager->jfd);
sqlite3OsClose(pPager->fd);
sqlite3PageFree(pTmp);
sqlite3PcacheClose(pPager->pPCache);
);
#else
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
- if( rc==SQLITE_OK ){
- int iDc = sqlite3OsDeviceCharacteristics(pPager->jfd);
- pPager->safeJrnlHandle = (iDc&SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)!=0;
- }
#endif
}
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
catch { db close }
return ""
}
-proc faultsim_restore_and_reopen {} {
+proc faultsim_restore_and_reopen {{dbfile test.db}} {
catch { db close }
foreach f [glob -nocomplain test.db*] { file delete -force $f }
foreach f2 [glob -nocomplain sv_test.db*] {
set f [string range $f2 3 end]
file copy -force $f2 $f
}
- sqlite3 db test.db
+ sqlite3 db $dbfile
sqlite3_extended_result_codes db 1
sqlite3_db_config_lookaside db 0 0 0
}
proc faultsim_delete_and_reopen {{file test.db}} {
catch { db close }
foreach f [glob -nocomplain test.db*] { file delete -force $f }
- sqlite3 db test.db
+ sqlite3 db $file
}
# pager1.4.3.*: Test that the contents of a hot-journal are ignored if the
# page-size or sector-size in the journal header appear to
# be invalid (too large, too small or not a power of 2).
+#
+# pager1.4.4.*: Test hot-journal rollback of journal file with a master
+# journal pointer generated in various "PRAGMA synchronous"
+# modes.
+#
+# pager1.4.5.*: Test that hot-journal rollback stops if it encounters a
+# journal-record for which the checksum fails.
#
do_test pager1.4.1.1 {
faultsim_delete_and_reopen
}
db close
+# Set up a VFS that snapshots the file-system just before a master journal
+# file is deleted to commit a multi-file transaction. Specifically, the
+# file-system is saved just before the xDelete() call to remove the
+# master journal file from the file-system.
+#
+testvfs tv -default 1
+tv script copy_on_mj_delete
+set ::mj_filename_length 0
+proc copy_on_mj_delete {method filename args} {
+ if {[string match *mj* [file tail $filename]]} {
+ set ::mj_filename_length [string length $filename]
+ faultsim_save
+ }
+ return SQLITE_OK
+}
+
+set pwd [pwd]
+foreach {tn1 tcl} {
+ 1 { set prefix "test.db" }
+ 2 {
+ # This test depends on the underlying VFS being able to open paths
+ # 512 bytes in length. The idea is to create a hot-journal file that
+ # contains a master-journal pointer so large that it could contain
+ # a valid page record (if the file page-size is 512 bytes). So as to
+ # make sure SQLite doesn't get confused by this.
+ #
+ set nPadding [expr 511 - $::mj_filename_length]
+
+ # We cannot just create a really long database file name to open, as
+ # Linux limits a single component of a path to 255 bytes by default
+ # (and presumably other systems have limits too). So create a directory
+ # hierarchy to work in.
+ #
+ set dirname "d123456789012345678901234567890/"
+ set nDir [expr $nPadding / 32]
+ if { $nDir } {
+ set p [string repeat $dirname $nDir]
+ file mkdir $p
+ cd $p
+ }
+
+ set padding [string repeat x [expr $nPadding %32]]
+ set prefix "test.db${padding}"
+ }
+} {
+ eval $tcl
+ foreach {tn2 sql} {
+ o {
+ PRAGMA main.synchronous=OFF;
+ PRAGMA aux.synchronous=OFF;
+ }
+ o512 {
+ PRAGMA main.synchronous=OFF;
+ PRAGMA aux.synchronous=OFF;
+ PRAGMA main.page_size = 512;
+ PRAGMA aux.page_size = 512;
+ }
+ n {
+ PRAGMA main.synchronous=NORMAL;
+ PRAGMA aux.synchronous=NORMAL;
+ }
+ f {
+ PRAGMA main.synchronous=FULL;
+ PRAGMA aux.synchronous=FULL;
+ }
+ } {
+
+ set tn "${tn1}.${tn2}"
+
+ # Set up a connection to have two databases, test.db (main) and
+ # test.db2 (aux). Then run a multi-file transaction on them. The
+ # VFS will snapshot the file-system just before the master-journal
+ # file is deleted to commit the transaction.
+ #
+ tv filter xDelete
+ do_test pager1-4.4.$tn.1 {
+ faultsim_delete_and_reopen $prefix
+ execsql "
+ ATTACH '${prefix}2' AS aux;
+ $sql
+ CREATE TABLE a(x);
+ CREATE TABLE aux.b(x);
+ INSERT INTO a VALUES('double-you');
+ INSERT INTO a VALUES('why');
+ INSERT INTO a VALUES('zed');
+ INSERT INTO b VALUES('won');
+ INSERT INTO b VALUES('too');
+ INSERT INTO b VALUES('free');
+ "
+ execsql {
+ BEGIN;
+ INSERT INTO a SELECT * FROM b WHERE rowid<=3;
+ INSERT INTO b SELECT * FROM a WHERE rowid<=3;
+ COMMIT;
+ }
+ } {}
+ tv filter {}
+
+ # Check that the transaction was committed successfully.
+ #
+ do_execsql_test pager1-4.4.$tn.2 {
+ SELECT * FROM a
+ } {double-you why zed won too free}
+ do_execsql_test pager1-4.4.$tn.3 {
+ SELECT * FROM b
+ } {won too free double-you why zed}
+
+ # Restore the file-system and reopen the databases. Check that it now
+ # appears that the transaction was not committed (because the file-system
+ # was restored to the state where it had not been).
+ #
+ do_test pager1-4.4.$tn.4 {
+ faultsim_restore_and_reopen $prefix
+ execsql "ATTACH '${prefix}2' AS aux"
+ } {}
+ do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
+ do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
+
+ # Restore the file-system again. This time, before reopening the databases,
+ # delete the master-journal file from the file-system. It now appears that
+ # the transaction was committed (no master-journal file == no rollback).
+ #
+ do_test pager1-4.4.$tn.7 {
+ faultsim_restore_and_reopen $prefix
+ foreach f [glob ${prefix}-mj*] { file delete -force $f }
+ execsql "ATTACH '${prefix}2' AS aux"
+ } {}
+ do_execsql_test pager1-4.4.$tn.8 {
+ SELECT * FROM a
+ } {double-you why zed won too free}
+ do_execsql_test pager1-4.4.$tn.9 {
+ SELECT * FROM b
+ } {won too free double-you why zed}
+ }
+
+ cd $pwd
+}
+db close
+tv delete
+
#-------------------------------------------------------------------------
# The following tests deal with multi-file commits.
#
# name does not lie on the same sector as the last journal file
# record.
#
-# pager1-5.5.*:
+# pager1-5.5.*: Check that in journal_mode=PERSIST mode, a journal file is
+# truncated to zero bytes when a multi-file transaction is
+# committed (instead of the first couple of bytes being zeroed).
+#
#
do_test pager1-5.1.1 {
faultsim_delete_and_reopen