diff --git a/manifest b/manifest index 5e593a552c..081f76e2f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sdocumentation\supdates.\s(CVS\s2401) -D 2005-03-19T15:10:45 +C Tentative\sfix\sfor\sticket\s#1171.\s\sMore\sresearch\sand\stesting\sneeded.\s(CVS\s2402) +D 2005-03-20T19:10:12 F Makefile.in 5c00d0037104de2a50ac7647a5f12769795957a3 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 @@ -52,7 +52,7 @@ F src/os_unix.c fba0167576f09e242afd4c4978e1d2944b1da8b5 F src/os_unix.h 40b2fd1d02cfa45d6c3dea25316fd019cf9fcb0c F src/os_win.c bddeae1c3299be0fbe47077dd4e98b786a067f71 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c 26a642c1238615bdea53d458ab6a4df7ca070a08 +F src/pager.c bac21a13353a91cf8342e3c5ee7bd89a50e46917 F src/pager.h 70d496f372163abb6340f474288c4bb9ea962cf7 F src/parse.y 10c0ace9efce31d5a06e03488a4284b9d97abc56 F src/pragma.c 4b20dbc0f4b97f412dc511853d3d0c2e0d4adedc @@ -115,7 +115,7 @@ F test/collate3.test 51362bdfb43a72bd2b087d90b2623b0695538e7a F test/collate4.test b8668612691c4dcf90f67a8df1eeb1544e7fdaf8 F test/collate5.test 581775b94604b7435dc6a5c6e72fbbf7d69e3830 F test/collate6.test 6c9470d1606ee3e564675b229653e320c49ec638 -F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87 +F test/conflict.test 3c4ef047070ce495e15d7d267a7d791d6f4ffef5 F test/corrupt.test 18c7a995b1af76a8c8600b996257f2c7b7bff083 F test/corrupt2.test 88342570828f2b8cbbd8369eff3891f5c0bdd5ba F test/crash.test f38b980a0508655d08c957a6dd27d66bca776504 @@ -277,7 +277,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b -P 90a00e90663749e5d1f8e28709dfbe981f8afc8b -R b87c30888e4a9264bec8715ac90b8e35 +P f065b6102db838d48f1a1a9ed68b2a09cd440cf8 +R 2d3ac9a5328361b0e3fa76626887a5ca U drh -Z b19b05f5c3b18978c53300f98dffca49 +Z 040f462f187d8ccdb87f470324a49732 diff --git a/manifest.uuid b/manifest.uuid index ad5c5f3695..f736004c88 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f065b6102db838d48f1a1a9ed68b2a09cd440cf8 \ No newline at end of file +f0a39cee78472b93cce5304fc255285ddea7d2bf \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 19c9eb5326..0f3eff11bb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.194 2005/03/15 17:09:30 drh Exp $ +** @(#) $Id: pager.c,v 1.195 2005/03/20 19:10:12 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -973,7 +973,8 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ pPg = pager_lookup(pPager, pgno); assert( pPager->state>=PAGER_EXCLUSIVE || pPg ); TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno); - if( pPager->state>=PAGER_EXCLUSIVE ){ + assert( jfd == (useCksum ? &pPager->jfd : &pPager->stfd) ); + if( pPager->state>=PAGER_EXCLUSIVE && (useCksum || !pPg || !pPg->needSync) ){ sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize); } diff --git a/test/conflict.test b/test/conflict.test index 1369b773a6..7470f04320 100644 --- a/test/conflict.test +++ b/test/conflict.test @@ -13,7 +13,7 @@ # This file implements tests for the conflict resolution extension # to SQLite. # -# $Id: conflict.test,v 1.22 2004/06/21 06:50:29 danielk1977 Exp $ +# $Id: conflict.test,v 1.23 2005/03/20 19:10:13 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -637,6 +637,121 @@ do_test conflict-10.2 { execsql {SELECT * FROM t4} } {} -integrity_check conflict-99.0 +# Ticket #1171. Make sure statement rollbacks do not +# damage the database. +# +do_test conflict-11.1 { + execsql { + -- Create a database object (pages 2, 3 of the file) + BEGIN; + CREATE TABLE abc(a UNIQUE, b, c); + INSERT INTO abc VALUES(1, 2, 3); + INSERT INTO abc VALUES(4, 5, 6); + INSERT INTO abc VALUES(7, 8, 9); + COMMIT; + } + + + # Set a small cache size so that changes will spill into + # the database file. + execsql { + PRAGMA cache_size = 10; + } + + # Make lots of changes. Because of the small cache, some + # (most?) of these changes will spill into the disk file. + # In other words, some of the changes will not be held in + # cache. + # + execsql { + BEGIN; + -- Make sure the pager is in EXCLUSIVE state. + CREATE TABLE def(d, e, f); + INSERT INTO def VALUES + ('xxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyy', 'zzzzzzzzzzzzzzzz'); + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + DELETE FROM abc WHERE a = 4; + } + + # Execute a statement that does a statement rollback due to + # a constraint failure. + # + catchsql { + INSERT INTO abc SELECT 10, 20, 30 FROM def; + } + + # Rollback the database. Verify that the state of the ABC table + # is unchanged from the beginning of the transaction. In other words, + # make sure the DELETE on table ABC that occurred within the transaction + # had no effect. + # + execsql { + ROLLBACK; + SELECT * FROM abc; + } +} {1 2 3 4 5 6 7 8 9} +integrity_check conflict-11.2 + +# Repeat test conflict-11.1 but this time commit. +# +do_test conflict-11.3 { + execsql { + BEGIN; + -- Make sure the pager is in EXCLUSIVE state. + UPDATE abc SET a=a+1; + CREATE TABLE def(d, e, f); + INSERT INTO def VALUES + ('xxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyy', 'zzzzzzzzzzzzzzzz'); + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + DELETE FROM abc WHERE a = 4; + } + catchsql { + INSERT INTO abc SELECT 10, 20, 30 FROM def; + } + execsql { + ROLLBACK; + SELECT * FROM abc; + } +} {1 2 3 4 5 6 7 8 9} +# Repeat test conflict-11.1 but this time commit. +# +do_test conflict-11.5 { + execsql { + BEGIN; + -- Make sure the pager is in EXCLUSIVE state. + CREATE TABLE def(d, e, f); + INSERT INTO def VALUES + ('xxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyy', 'zzzzzzzzzzzzzzzz'); + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + INSERT INTO def SELECT * FROM def; + DELETE FROM abc WHERE a = 4; + } + catchsql { + INSERT INTO abc SELECT 10, 20, 30 FROM def; + } + execsql { + COMMIT; + SELECT * FROM abc; + } +} {1 2 3 7 8 9} +integrity_check conflict-11.6 + finish_test