]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More changes for ticket #1171 after additional analysis. (CVS 2403)
authordrh <drh@noemail.net>
Sun, 20 Mar 2005 22:47:56 +0000 (22:47 +0000)
committerdrh <drh@noemail.net>
Sun, 20 Mar 2005 22:47:56 +0000 (22:47 +0000)
FossilOrigin-Name: 0471d6b86fd67c22da832beb280b31305c5aa812

manifest
manifest.uuid
src/pager.c

index 081f76e2f713ea2fb4e1dbf92f6fefac1d8472f3..be92197198130fba2ca239afc9d24ba87e1a3523 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Tentative\sfix\sfor\sticket\s#1171.\s\sMore\sresearch\sand\stesting\sneeded.\s(CVS\s2402)
-D 2005-03-20T19:10:12
+C More\schanges\sfor\sticket\s#1171\safter\sadditional\sanalysis.\s(CVS\s2403)
+D 2005-03-20T22:47:57
 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 bac21a13353a91cf8342e3c5ee7bd89a50e46917
+F src/pager.c e5000ca94ba2894d249213675318bbc918f97e9c
 F src/pager.h 70d496f372163abb6340f474288c4bb9ea962cf7
 F src/parse.y 10c0ace9efce31d5a06e03488a4284b9d97abc56
 F src/pragma.c 4b20dbc0f4b97f412dc511853d3d0c2e0d4adedc
@@ -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 f065b6102db838d48f1a1a9ed68b2a09cd440cf8
-R 2d3ac9a5328361b0e3fa76626887a5ca
+P f0a39cee78472b93cce5304fc255285ddea7d2bf
+R 43f1db9a2e69b0f7f7b43aff2c1a6b5f
 U drh
-Z 040f462f187d8ccdb87f470324a49732
+Z d771bce0fb6baa30068489aaa968f24c
index f736004c88ded088402ac88fc560c530bab1a947..5567f025787b04f996d9f78395a58700297b0acd 100644 (file)
@@ -1 +1 @@
-f0a39cee78472b93cce5304fc255285ddea7d2bf
\ No newline at end of file
+0471d6b86fd67c22da832beb280b31305c5aa812
\ No newline at end of file
index 0f3eff11bb16d0366e9898ebfc286124aab8dc47..d8baf81ae9571c157a0872a6ad45697a5a179708 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.195 2005/03/20 19:10:12 drh Exp $
+** @(#) $Id: pager.c,v 1.196 2005/03/20 22:47:57 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -935,6 +935,12 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
   u32 cksum;                    /* Checksum used for sanity checking */
   u8 aData[SQLITE_MAX_PAGE_SIZE];  /* Temp storage for a page */
 
+  /* useCksum should be true for the main journal and false for
+  ** statement journals.  Verify that this is always the case
+  */
+  assert( jfd == (useCksum ? &pPager->jfd : &pPager->stfd) );
+
+
   rc = read32bits(jfd, &pgno);
   if( rc!=SQLITE_OK ) return rc;
   rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
@@ -969,14 +975,27 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
   **
   ** If in EXCLUSIVE state, then we update the pager cache if it exists
   ** and the main file. The page is then marked not dirty.
+  **
+  ** Ticket #1171:  The statement journal might contain page content that is
+  ** different from the page content at the start of the transaction.
+  ** This occurs when a page is changed prior to the start of a statement
+  ** then changed again within the statement.  When rolling back such a
+  ** statement we must not write to the original database unless we know
+  ** for certain that original page contents are in the main rollback
+  ** journal.  Otherwise, if a full ROLLBACK occurs after the statement
+  ** rollback the full ROLLBACK will not restore the page to its original
+  ** content.  Two conditions must be met before writing to the database
+  ** files. (1) the database must be locked.  (2) we know that the original
+  ** page content is in the main journal either because the page is not in
+  ** cache or else it is marked as needSync==0.
   */
   pPg = pager_lookup(pPager, pgno);
-  assert( pPager->state>=PAGER_EXCLUSIVE || pPg );
+  assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 );
   TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno);
-  assert( jfd == (useCksum ? &pPager->jfd : &pPager->stfd) );
-  if( pPager->state>=PAGER_EXCLUSIVE && (useCksum || !pPg || !pPg->needSync) ){
+  if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){
     sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);
     rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);
+    if( pPg ) pPg->dirty = 0;
   }
   if( pPg ){
     /* No page should ever be explicitly rolled back that is in use, except
@@ -992,13 +1011,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
     if( pPager->xDestructor ){  /*** FIX ME:  Should this be xReinit? ***/
       pPager->xDestructor(pData, pPager->pageSize);
     }
-    if( pPager->state>=PAGER_EXCLUSIVE ){
-      pPg->dirty = 0;
-      pPg->needSync = 0;
 #ifdef SQLITE_CHECK_PAGES
-      pPg->pageHash = pager_pagehash(pPg);
+    pPg->pageHash = pager_pagehash(pPg);
 #endif
-    }
     CODEC(pPager, pData, pPg->pgno, 3);
   }
   return rc;