]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Coverage testing for balance_quick() and balance_deeper(). (CVS 5382)
authordanielk1977 <danielk1977@noemail.net>
Wed, 9 Jul 2008 11:49:46 +0000 (11:49 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Wed, 9 Jul 2008 11:49:46 +0000 (11:49 +0000)
FossilOrigin-Name: 491f8f9613d2b886acad2ab8f631a4ec61ad698d

manifest
manifest.uuid
src/btree.c
test/ioerr.test

index 151828c9d6dee39fb35c5d41090e26e9cd3d09ec..3def778a713fe520f69a1ba380cb8a1bbd9e28ca 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Additional\stest\scoverage\sin\sselect.c\sand\sexpr.c.\s(CVS\s5381)
-D 2008-07-09T01:39:44
+C Coverage\stesting\sfor\sbalance_quick()\sand\sbalance_deeper().\s(CVS\s5382)
+D 2008-07-09T11:49:47
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a03f7cb4f7ad50bc53a788c6c544430e81f95de4
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -95,7 +95,7 @@ F src/attach.c b18ba42c77f7d3941f5d23d2ca20fa1d841a4e91
 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
 F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d
 F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
-F src/btree.c a52b0a1d0459e3a028a90df84a84ec1c58148574
+F src/btree.c fbc557de64457effea261699c11fc0cf7696ccd6
 F src/btree.h b1bd7e0b8c2e33658aaf447cb0d1d94f74664b6b
 F src/btreeInt.h 8f6e0817365ac822da0afffedc664ba03047718b
 F src/build.c bac7233d984be3805aaa41cf500f7ee12dc97249
@@ -356,7 +356,7 @@ F test/insert5.test 509017213328147d3acdfa2c441bfd82362dda41
 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
 F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
 F test/io.test 833a1746518ec3005aa7792f9bcb8f01923ff544
-F test/ioerr.test f87e5be364a5938996e8741091088845eb9ce802
+F test/ioerr.test 404edbb58143b4581a6f23c2031d40db931d7b90
 F test/ioerr2.test 5598405c48842c6c0187daad9eb49eff2c54f80d
 F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
 F test/ioerr4.test fc6eddfec2efc2f1ed217b9eae4c1c1d3516ce86
@@ -600,7 +600,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P cbd3c1585b7a8f8042aa1448fe1be87de056c41a
-R 9c8b6c813e587d92b499775ff9d0704e
-U drh
-Z 797145b83fcaf2766400631bd4924b1a
+P c6cf08477cc4d622a05ad6706cb9418cf7eea432
+R 229bd421824f3bb6fb90dfe5637660e4
+U danielk1977
+Z 426328c9a228ac588ec10fbe5f06c5ef
index 1333ce0d6c8b6b313b3e3398cac1203b587c9063..8405a35362e05c563ec8f73999a976daa509abbf 100644 (file)
@@ -1 +1 @@
-c6cf08477cc4d622a05ad6706cb9418cf7eea432
\ No newline at end of file
+491f8f9613d2b886acad2ab8f631a4ec61ad698d
\ No newline at end of file
index 23df64f0d391d9cdae9df9a08e9df20226414d6c..a1564ec3db03d7953d48e1c9ad9cfb9021de1ca1 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.473 2008/07/08 19:34:07 drh Exp $
+** $Id: btree.c,v 1.474 2008/07/09 11:49:47 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -667,7 +667,7 @@ static int ptrmapPutOvfl(MemPage *pPage, int iCell){
 ** big FreeBlk that occurs in between the header and cell
 ** pointer array and the cell content area.
 */
-static int defragmentPage(MemPage *pPage){
+static void defragmentPage(MemPage *pPage){
   int i;                     /* Loop counter */
   int pc;                    /* Address of a i-th cell */
   int addr;                  /* Offset of first byte after cell pointer array */
@@ -712,7 +712,6 @@ static int defragmentPage(MemPage *pPage){
   data[hdr+7] = 0;
   addr = cellOffset+2*nCell;
   memset(&data[addr], 0, brk-addr);
-  return SQLITE_OK;
 }
 
 /*
@@ -773,7 +772,7 @@ static int allocateSpace(MemPage *pPage, int nByte){
   nCell = get2byte(&data[hdr+3]);
   cellOffset = pPage->cellOffset;
   if( nFrag>=60 || cellOffset + 2*nCell > top - nByte ){
-    if( defragmentPage(pPage) ) return 0;
+    defragmentPage(pPage);
     top = get2byte(&data[hdr+5]);
   }
   top -= nByte;
@@ -4645,8 +4644,7 @@ static int insertCell(
     end = cellOffset + 2*pPage->nCell + 2;
     ins = cellOffset + 2*i;
     if( end > top - sz ){
-      rc = defragmentPage(pPage);
-      if( rc!=SQLITE_OK ) return rc;
+      defragmentPage(pPage);
       top = get2byte(&data[hdr+5]);
       assert( end + sz <= top );
     }
@@ -4798,19 +4796,24 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
   /* pPage is currently the right-child of pParent. Change this
   ** so that the right-child is the new page allocated above and
   ** pPage is the next-to-right child. 
+  **
+  ** Ignore the return value of the call to fillInCell(). fillInCell()
+  ** may only return other than SQLITE_OK if it is required to allocate
+  ** one or more overflow pages. Since an internal table B-Tree cell 
+  ** may never spill over onto an overflow page (it is a maximum of 
+  ** 13 bytes in size), it is not neccessary to check the return code.
+  **
+  ** Similarly, the insertCell() function cannot fail if the page
+  ** being inserted into is already writable and the cell does not 
+  ** contain an overflow pointer. So ignore this return code too.
   */
   assert( pPage->nCell>0 );
   pCell = findCell(pPage, pPage->nCell-1);
   sqlite3BtreeParseCellPtr(pPage, pCell, &info);
-  rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
+  fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
   assert( parentSize<64 );
-  rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
+  assert( sqlite3PagerIswriteable(pParent->pDbPage) );
+  insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
   put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
   put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
 
@@ -4918,6 +4921,7 @@ static int balance_nonroot(MemPage *pPage){
   if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
     return rc;
   }
+
   TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
 
 #ifndef SQLITE_OMIT_QUICKBALANCE
@@ -5599,7 +5603,7 @@ static int balance_deeper(MemPage *pPage){
     for(i=0; i<pChild->nCell; i++){
       rc = ptrmapPutOvfl(pChild, i);
       if( rc!=SQLITE_OK ){
-        return rc;
+        goto balancedeeper_out;
       }
     }
   }
index ef24357490a50ee68ead0c0a3194d2846287a44d..4785ad2d8c02f70547e57b00b9a514775f422d88 100644 (file)
@@ -15,7 +15,7 @@
 # The tests in this file use special facilities that are only
 # available in the SQLite test fixture.
 #
-# $Id: ioerr.test,v 1.39 2008/07/08 17:13:59 danielk1977 Exp $
+# $Id: ioerr.test,v 1.40 2008/07/09 11:49:48 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -328,6 +328,81 @@ do_ioerr_test ioerr-12 -ckrefcount true -erc 1 -tclprep {
   db eval { INSERT INTO t1 VALUES(randomblob(2000)); }
 }
 sqlite3_simulate_device -char {} -sectorsize 0
+catch {db close}
+
+do_ioerr_test ioerr-13 -ckrefcount true -erc 1 -sqlprep {
+  PRAGMA auto_vacuum = incremental;
+  CREATE TABLE t1(x);
+  CREATE TABLE t2(x);
+  INSERT INTO t2 VALUES(randomblob(1500));
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t1 VALUES(randomblob(20));
+  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;
+  INSERT INTO t1 SELECT x FROM t1;
+  INSERT INTO t1 SELECT x FROM t1;             /* 64 entries in t1 */
+  INSERT INTO t1 SELECT x FROM t1 LIMIT 14;    /* 78 entries in t1 */
+  DELETE FROM t2 WHERE rowid = 3;
+} -sqlbody {
+  -- This statement uses the balance_quick() optimization. The new page
+  -- is appended to the database file. But the overflow page used by
+  -- the new record will be positioned near the start of the database
+  -- file, in the gap left by the "DELETE FROM t2 WHERE rowid=3" statement
+  -- above.
+  --
+  -- The point of this is that the statement wil need to update two pointer
+  -- map pages. Which introduces another opportunity for an IO error.
+  --
+  INSERT INTO t1 VALUES(randomblob(2000));
+}
+
+do_ioerr_test ioerr-14 -ckrefcount true -erc 1 -sqlprep {
+  PRAGMA auto_vacuum = incremental;
+  CREATE TABLE t1(x);
+  CREATE TABLE t2(x);
+  INSERT INTO t2 VALUES(randomblob(1500));
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+  INSERT INTO t2 SELECT randomblob(1500) FROM t2;
+
+  -- This statement inserts a row into t1 with an overflow page at the
+  -- end of the file. A long way from its parent (the root of t1).
+  INSERT INTO t1 VALUES(randomblob(1500));
+  DELETE FROM t2 WHERE rowid<10;
+} -sqlbody {
+  -- This transaction will cause the root-page of table t1 to divide
+  -- (by calling balance_deeper()). When it does, the "parent" page of the
+  -- overflow page inserted in the -sqlprep block above will change and
+  -- the corresponding pointer map page be updated. This test case attempts
+  -- to cause an IO error during the pointer map page update.
+  --
+  BEGIN;
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  INSERT INTO t1 VALUES(randomblob(100));
+  COMMIT;
+}
 
 finish_test