Tentative fix for ticket . More research and testing needed. (CVS 2402)

FossilOrigin-Name: f0a39cee78472b93cce5304fc255285ddea7d2bf
This commit is contained in:
drh 2005-03-20 19:10:12 +00:00
parent c2cb4c10c8
commit 41712ef171
4 changed files with 128 additions and 12 deletions

@ -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

@ -1 +1 @@
f065b6102db838d48f1a1a9ed68b2a09cd440cf8
f0a39cee78472b93cce5304fc255285ddea7d2bf

@ -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);
}

@ -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