Coverage testing for balance_quick() and balance_deeper(). (CVS 5382)
FossilOrigin-Name: 491f8f9613d2b886acad2ab8f631a4ec61ad698d
This commit is contained in:
parent
e49b146f30
commit
474b7cc785
16
manifest
16
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
|
||||
|
@ -1 +1 @@
|
||||
c6cf08477cc4d622a05ad6706cb9418cf7eea432
|
||||
491f8f9613d2b886acad2ab8f631a4ec61ad698d
|
34
src/btree.c
34
src/btree.c
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user