]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a couple of assert() failures that can occur in btree.c and pager.c. (CVS 6055)
authordanielk1977 <danielk1977@noemail.net>
Tue, 23 Dec 2008 10:37:47 +0000 (10:37 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Tue, 23 Dec 2008 10:37:47 +0000 (10:37 +0000)
FossilOrigin-Name: ae44e7482476478c8eeacfb80b282f17894530e5

manifest
manifest.uuid
src/btree.c
src/pager.c
test/insert3.test

index b67af0417ed9bab6c5fc05300727f263bd182f21..45f5c65c69fe00eae76a7d9157d8de35789320b7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sreference\scounting\sbug\sin\srtree.\sTicket\s#3549.\s(CVS\s6054)
-D 2008-12-22T15:04:32
+C Fix\sa\scouple\sof\sassert()\sfailures\sthat\scan\soccur\sin\sbtree.c\sand\spager.c.\s(CVS\s6055)
+D 2008-12-23T10:37:47
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 77635d0909c2067cee03889a1e04ce910d8fb809
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -103,7 +103,7 @@ F src/attach.c 1c35f95da3c62d19de75b44cfefd12c81c1791b3
 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
 F src/bitvec.c 4300d311b17fb3c1476623fd895a8feac02a0b08
 F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
-F src/btree.c ad51b56b1a90e3c9ad39aabd9368325aba5a6730
+F src/btree.c 69983b4e6567321478f2fb40cd2b0c95807927fe
 F src/btree.h 4f141cf748d2ee7c6d7fc175f64f87a45cd44113
 F src/btreeInt.h 7ef2c872371d7508657f8d7a4efe651c741d6ee6
 F src/build.c f3e8377cbc0d007b01aab1e7d4fc1d5b296c422e
@@ -142,7 +142,7 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
 F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
 F src/os_unix.c e6eacc7ec735ded605fefcbaf250058baa8feb12
 F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
-F src/pager.c 59b87841ac6ea5f6e5023f2321b69572b9883a8b
+F src/pager.c 5998dc0bfa382d43e1d8c1c498597d2600cc495b
 F src/pager.h 7191294438881eb4d13eedade97891e8dc993905
 F src/parse.y 4d0e33a702dc3ea7b69d8ae1914b3fbd32e46057
 F src/pcache.c 16dc8da6e6ba6250f8dfd9ee46036db1cbceedc6
@@ -394,7 +394,7 @@ F test/index3.test 727d55dceb9a4ec36675057bb5becfc265e28ca6
 F test/indexedby.test 03af52375e50d146e78f56442b6677d2932c4963
 F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
-F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677
+F test/insert3.test 7188f1da1126eb15f1b27cf34f4c2753c7d5fd27
 F test/insert4.test 6e382eaf7295a4463e6f29ea20fcd8e63d097eeb
 F test/insert5.test 1f93cbe9742110119133d7e8e3ccfe6d7c249766
 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
@@ -684,7 +684,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P ee0e6eae9f984472e44d7ee8f195c6e5d33f2efd
-R 84a43cb77701b394bb942c42ab498d4d
+P bbdc0e9f2481f8d59e05ea282b615f97e09fb471
+R 9a4f367c203efd1d1b7375ea1b15ec85
 U danielk1977
-Z a3c50f9a13d9f2d8f7a301ea5204d232
+Z f234b11339d566d37e09d7218e4eacc3
index 71c17be5fb23524dfc2bf9cc833d6e50b46633c3..30db9858a9b011bf001a02a1f12a0787c5d74660 100644 (file)
@@ -1 +1 @@
-bbdc0e9f2481f8d59e05ea282b615f97e09fb471
\ No newline at end of file
+ae44e7482476478c8eeacfb80b282f17894530e5
\ No newline at end of file
index 48a7dee002fc3e1bb397995521ccf466543318c6..cf70a0fc605144a9c5d029a0c48161c0a7c44ef5 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.550 2008/12/18 15:45:07 danielk1977 Exp $
+** $Id: btree.c,v 1.551 2008/12/23 10:37:47 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -4977,6 +4977,7 @@ static int balance_quick(BtCursor *pCur){
   */
   pPage->isInit = 0;
   sqlite3BtreeInitPage(pPage);
+  assert( pPage->nOverflow==0 );
 
   /* If everything else succeeded, balance the parent page, in 
   ** case the divider cell inserted caused it to become overfull.
@@ -5025,8 +5026,8 @@ static int balance_nonroot(BtCursor *pCur){
   BtShared *pBt;               /* The whole database */
   int nCell = 0;               /* Number of cells in apCell[] */
   int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
-  int nOld;                    /* Number of pages in apOld[] */
-  int nNew;                    /* Number of pages in apNew[] */
+  int nOld = 0;                /* Number of pages in apOld[] */
+  int nNew = 0;                /* Number of pages in apNew[] */
   int nDiv;                    /* Number of cells in apDiv[] */
   int i, j, k;                 /* Loop counters */
   int idx;                     /* Index of pPage in pParent->aCell[] */
@@ -5069,7 +5070,7 @@ static int balance_nonroot(BtCursor *pCur){
   pParent = pCur->apPage[pCur->iPage-1];
   assert( pParent );
   if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
-    return rc;
+    goto balance_cleanup;
   }
 
   TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
@@ -5100,7 +5101,7 @@ static int balance_nonroot(BtCursor *pCur){
 #endif
 
   if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){
-    return rc;
+    goto balance_cleanup;
   }
 
   /*
@@ -5111,12 +5112,6 @@ static int balance_nonroot(BtCursor *pCur){
   idx = pCur->aiIdx[pCur->iPage-1];
   assertParentIndex(pParent, idx, pPage->pgno);
 
-  /*
-  ** Initialize variables so that it will be safe to jump
-  ** directly to balance_cleanup at any moment.
-  */
-  nOld = nNew = 0;
-
   /*
   ** Find sibling pages to pPage and the cells in pParent that divide
   ** the siblings.  An attempt is made to find NN siblings on either
@@ -5578,6 +5573,9 @@ static int balance_nonroot(BtCursor *pCur){
   assert( pParent->isInit );
   sqlite3ScratchFree(apCell);
   apCell = 0;
+  TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
+          pPage->pgno, nOld, nNew, nCell));
+  pPage->nOverflow = 0;
   releasePage(pPage);
   pCur->iPage--;
   rc = balance(pCur, 0);
@@ -5594,11 +5592,7 @@ balance_cleanup:
   for(i=0; i<nNew; i++){
     releasePage(apNew[i]);
   }
-  pPage->nOverflow = 0;
-
-  /* releasePage(pParent); */
-  TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
-          pPage->pgno, nOld, nNew, nCell));
+  pCur->apPage[pCur->iPage]->nOverflow = 0;
 
   return rc;
 }
@@ -5792,17 +5786,18 @@ static int balance(BtCursor *pCur, int isInsert){
     rc = sqlite3PagerWrite(pPage->pDbPage);
     if( rc==SQLITE_OK && pPage->nOverflow>0 ){
       rc = balance_deeper(pCur);
+      assert( pCur->apPage[0]==pPage );
       assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
     }
     if( rc==SQLITE_OK && pPage->nCell==0 ){
       rc = balance_shallower(pCur);
+      assert( pCur->apPage[0]==pPage );
       assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
     }
   }else{
     if( pPage->nOverflow>0 || 
         (!isInsert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
       rc = balance_nonroot(pCur);
-      assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
     }
   }
   return rc;
@@ -5977,8 +5972,7 @@ int sqlite3BtreeInsert(
 
   /* Must make sure nOverflow is reset to zero even if the balance()
   ** fails.  Internal data structure corruption will result otherwise. */
-  assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
-  pPage->nOverflow = 0;
+  pCur->apPage[pCur->iPage]->nOverflow = 0;
 
   if( rc==SQLITE_OK ){
     moveToRoot(pCur);
index 9b326b37fe2cb7ccf728e8ff6a98683bc4e4ddcc..ca0853c49b7c6ee58f620d8c410e174f0a50154a 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.521 2008/12/22 11:43:36 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.522 2008/12/23 10:37:47 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -3289,6 +3289,7 @@ static int pager_write(PgHdr *pPg){
         */
         if( !pPager->noSync ){
           pPg->flags |= PGHDR_NEED_SYNC;
+          pPager->needSync = 1;
         }
 
         /* An error has occured writing to the journal file. The 
@@ -3305,14 +3306,12 @@ static int pager_write(PgHdr *pPg){
       }else{
         if( !pPager->journalStarted && !pPager->noSync ){
           pPg->flags |= PGHDR_NEED_SYNC;
+          pPager->needSync = 1;
         }
         PAGERTRACE4("APPEND %d page %d needSync=%d\n",
                 PAGERID(pPager), pPg->pgno,
                ((pPg->flags&PGHDR_NEED_SYNC)?1:0));
       }
-      if( pPg->flags&PGHDR_NEED_SYNC ){
-        pPager->needSync = 1;
-      }
     }
   
     /* If the statement journal is open and the page is not in it,
@@ -3409,6 +3408,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){
             rc = pager_write(pPage);
             if( pPage->flags&PGHDR_NEED_SYNC ){
               needSync = 1;
+              assert(pPager->needSync);
             }
             sqlite3PagerUnref(pPage);
           }
index 825b2acd47888b19fbe5904fac0ea87bb6334150..c3b60690b22e3523dbf4857d6cd3fa31c2256351 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing corner cases of the INSERT statement.
 #
-# $Id: insert3.test,v 1.7 2007/09/12 17:01:45 danielk1977 Exp $
+# $Id: insert3.test,v 1.8 2008/12/23 10:37:47 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -168,4 +168,36 @@ ifcapable bloblit {
 }
 db close
 
+file delete -force test.db
+sqlite3 db test.db
+
+#-------------------------------------------------------------------------
+# While developing tests for a different feature (savepoint) the following
+# sequence was found to cause an assert() in btree.c to fail. These
+# tests are included to ensure that that bug is fixed.
+#
+do_test insert3-4.1 {
+  execsql { 
+    CREATE TABLE t1(a, b, c);
+    CREATE INDEX i1 ON t1(a, b);
+    BEGIN;
+    INSERT INTO t1 VALUES(randstr(10,400),randstr(10,400),randstr(10,400));
+  }
+  set r "randstr(10,400)"
+  for {set ii 0} {$ii < 10} {incr ii} {
+    execsql "INSERT INTO t1 SELECT $r, $r, $r FROM t1"
+  }
+  execsql { COMMIT }
+} {}
+do_test insert3-4.2 {
+  execsql {
+    PRAGMA cache_size = 10;
+    BEGIN;
+      UPDATE t1 SET a = randstr(10,10) WHERE (rowid%4)==0;
+      DELETE FROM t1 WHERE rowid%2;
+      INSERT INTO t1 SELECT randstr(10,400), randstr(10,400), c FROM t1;
+    COMMIT;
+  }
+} {}
+
 finish_test