From: drh Date: Tue, 31 Mar 2009 02:54:40 +0000 (+0000) Subject: Make sure a ROLLBACK that follows an incremental vacuum works. Ticket #3761. (CVS... X-Git-Tag: version-3.6.15~334 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=86655a1d2a16a82ee8f6547273ca529279002124;p=thirdparty%2Fsqlite.git Make sure a ROLLBACK that follows an incremental vacuum works. Ticket #3761. (CVS 6416) FossilOrigin-Name: 8c1d0c6ad9646816eb8ca15b7df4e79b9b1b59ee --- diff --git a/manifest b/manifest index 38f8db3ec4..ceb35cfc13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\stwo\sunused\slines\sfrom\spcache.c.\s(CVS\s6415) -D 2009-03-31T01:32:18 +C Make\ssure\sa\sROLLBACK\sthat\sfollows\san\sincremental\svacuum\sworks.\s\sTicket\s#3761.\s(CVS\s6416) +D 2009-03-31T02:54:40 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -143,7 +143,7 @@ F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5 F src/os_unix.c 5d667f24615043c937a138faaed5f3e93b8619b0 F src/os_win.c e655b2a640ed0481940161ddf811ddcc16d94783 -F src/pager.c 7a2b4b118708de09e580de66d46e51c1b655f76a +F src/pager.c 34aeb87dc8177901d49dd02207828a2121064c25 F src/pager.h 0c9f3520c00d8a3b8e792ca56c9a11b6b02b4b0f F src/parse.y b9ba0946a13e9f32a96044e64a3e8780269b08b0 F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d @@ -632,6 +632,7 @@ F test/tkt3630.test 929f64852103054125200bc825c316d5f75d42f7 F test/tkt3718.test 3ee5e25702f3f5a31340b2766d7a7fac2b5ce99c F test/tkt3731.test 8a6e3732f5a8a24eb875a6faf287ef77bb8c0579 F test/tkt3757.test 8f2208930655bbd4f92c14e19e72303a43e098ef +F test/tkt3761.test b95ea9c98f21cf91325f18a984887e62caceab33 F test/tkt3762.test 2a9f3b03df44ec49ec0cfa8d5da6574c2a7853df F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/trace.test 951cd0f5f571e7f36bf7bfe04be70f90fb16fb00 @@ -712,7 +713,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 7f40576dd76cb67f5248739a0ef1fbe496a3b42a -R 305c3d13be621708afe81bccb171a961 +P d5cab05c9ecbc5cb5e9ed658a55c35434717e969 +R 2bd28920ec005b7244d3e2d73df16d8f U drh -Z 65bf898e0430a485ca348d13359df387 +Z 01a279d64c0fdf6f17549621a13916ca diff --git a/manifest.uuid b/manifest.uuid index 2367b28925..f8c72136c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5cab05c9ecbc5cb5e9ed658a55c35434717e969 \ No newline at end of file +8c1d0c6ad9646816eb8ca15b7df4e79b9b1b59ee \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 9e2ae675b5..86a1790abf 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.575 2009/03/28 10:54:23 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.576 2009/03/31 02:54:40 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1499,6 +1499,7 @@ static int pager_playback_one_page( ** Do not attempt to write if database file has never been opened. */ pPg = pager_lookup(pPager, pgno); + assert( pPg || !MEMDB ); PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData), (isMainJrnl?"main-journal":"sub-journal") @@ -5016,6 +5017,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ PgHdr *pPgOld; /* The page being overwritten. */ Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */ int rc; /* Return code */ + Pgno origPgno; /* The original page number */ assert( pPg->nRef>0 ); @@ -5074,6 +5076,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); } + origPgno = pPg->pgno; sqlite3PcacheMove(pPg, pgno); if( pPgOld ){ sqlite3PcacheDrop(pPgOld); @@ -5116,6 +5119,19 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ sqlite3PagerUnref(pPgHdr); } + /* + ** For an in-memory database, make sure the original page continues + ** to exist, in case the transaction needs to roll back. We allocate + ** the page now, instead of at rollback, because we can better deal + ** with an out-of-memory error now. Ticket #3761. + */ + if( MEMDB ){ + DbPage *pNew; + rc = sqlite3PagerAcquire(pPager, origPgno, &pNew, 1); + if( rc!=SQLITE_OK ) return rc; + sqlite3PagerUnref(pNew); + } + return SQLITE_OK; } #endif diff --git a/test/tkt3761.test b/test/tkt3761.test new file mode 100644 index 0000000000..2601b151df --- /dev/null +++ b/test/tkt3761.test @@ -0,0 +1,40 @@ +# 2009 March 30 +# +# 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. +# +#*********************************************************************** +# +# Ticket #3761: Make sure that an incremental vacuum on an in-memory +# database can be rolled back. +# +# $Id: tkt3761.test,v 1.1 2009/03/31 02:54:40 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test tkt3761-1.1 { + db close + sqlite3 db :memory: + db eval { + PRAGMA auto_vacuum=INCREMENTAL; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(zeroblob(900)); + INSERT INTO t1 VALUES(zeroblob(900)); + INSERT INTO t1 SELECT x FROM t1; + INSERT INTO t1 SELECT x FROM t1; + INSERT INTO t1 SELECT x FROM t1; + INSERT INTO t1 SELECT x FROM t1; + BEGIN; + DELETE FROM t1 WHERE rowid%2; + PRAGMA incremental_vacuum(4); + ROLLBACK; + } + db eval {PRAGMA integrity_check} +} {ok} + +finish_test