Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for #3918. Also, fix the TRACE macros in balance_nonroot(). (CVS 6772) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
368e44ec2e648b04f3b817f82586ccd8 |
User & Date: | danielk1977 2009-06-17 11:13:28.000 |
Context
2009-06-17
| ||
11:49 | Fix a bug affecting secure-delete mode introduced by (6768). (CVS 6773) (check-in: a433ca821c user: danielk1977 tags: trunk) | |
11:13 | Fix for #3918. Also, fix the TRACE macros in balance_nonroot(). (CVS 6772) (check-in: 368e44ec2e user: danielk1977 tags: trunk) | |
01:17 | A minor simplification to the tokenizer. (CVS 6771) (check-in: 18f2076ac2 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.631 2009/06/17 11:13:28 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
4521 4522 4523 4524 4525 4526 4527 | } put4byte(&pPrevTrunk->aData[0], iNewTrunk); } } pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif | | | 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 | } put4byte(&pPrevTrunk->aData[0], iNewTrunk); } } pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif }else if( k>0 ){ /* Extract a leaf from the trunk */ int closest; Pgno iPage; unsigned char *aData = pTrunk->aData; rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ){ goto end_allocate_page; |
︙ | ︙ | |||
5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 | u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ pBt = pParent->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); /* At this point pParent may have at most one overflow cell. And if ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function ** is called (indirectly) from sqlite3BtreeDelete(). */ assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx ); | > > | 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 | u8 *aSpace1; /* Space for copies of dividers cells */ Pgno pgno; /* Temp var to store a page number in */ pBt = pParent->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); #if 0 TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); #endif /* At this point pParent may have at most one overflow cell. And if ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function ** is called (indirectly) from sqlite3BtreeDelete(). */ assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx ); |
︙ | ︙ | |||
5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 | /* Either we found one or more cells (cntnew[0])>0) or pPage is ** a virtual root page. A virtual root page is when the real root ** page is page 1 and we are the only child of that page. */ assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); /* ** Allocate k new pages. Reuse old pages where possible. */ if( apOld[0]->pgno<=1 ){ rc = SQLITE_CORRUPT; goto balance_cleanup; } | > > > > > > | 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 | /* Either we found one or more cells (cntnew[0])>0) or pPage is ** a virtual root page. A virtual root page is when the real root ** page is page 1 and we are the only child of that page. */ assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); TRACE(("BALANCE: old: %d %d %d ", apOld[0]->pgno, nOld>=2 ? apOld[1]->pgno : 0, nOld>=3 ? apOld[2]->pgno : 0 )); /* ** Allocate k new pages. Reuse old pages where possible. */ if( apOld[0]->pgno<=1 ){ rc = SQLITE_CORRUPT; goto balance_cleanup; } |
︙ | ︙ | |||
5711 5712 5713 5714 5715 5716 5717 | MemPage *pT; t = apNew[i]->pgno; pT = apNew[i]; apNew[i] = apNew[minI]; apNew[minI] = pT; } } | | < < < | 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 | MemPage *pT; t = apNew[i]->pgno; pT = apNew[i]; apNew[i] = apNew[minI]; apNew[minI] = pT; } } TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n", apNew[0]->pgno, szNew[0], nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0)); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
︙ | ︙ | |||
5910 5911 5912 5913 5914 5915 5916 | ** cause an assert() statement to fail. */ ptrmapCheckPages(apNew, nNew); ptrmapCheckPages(&pParent, 1); #endif } assert( pParent->isInit ); | | | | 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 | ** cause an assert() statement to fail. */ ptrmapCheckPages(apNew, nNew); ptrmapCheckPages(&pParent, 1); #endif } assert( pParent->isInit ); TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", nOld, nNew, nCell)); /* ** Cleanup before returning. */ balance_cleanup: sqlite3ScratchFree(apCell); for(i=0; i<nOld; i++){ |
︙ | ︙ |
Added test/tkt3918.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # 2009 June 17 # # 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. # #*********************************************************************** # # $Id: tkt3918.test,v 1.1 2009/06/17 11:13:28 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test tkt3918.1 { execsql { PRAGMA page_size = 1024; PRAGMA auto_vacuum = incremental; CREATE TABLE t1(i, x); } } {} do_test tkt3918.2 { execsql { INSERT INTO t1 VALUES(1, randstr(1000,1000)); INSERT INTO t1 VALUES(2, zeroblob(248*1020 + 100)); INSERT INTO t1 VALUES(3, zeroblob(2*1020 + 100)); } } {} # This set of statements sets up the free list so that the # first free-list trunk page contains only a single leaf. # The leaf page is also the last page in the database. The # second free-list trunk page contains, amongst other things, # page number 4. do_test tkt3918.3 { execsql { DELETE FROM t1 WHERE i = 2; DELETE FROM t1 WHERE i = 1; DELETE FROM t1 WHERE i = 3; } } {} # Incrementally vacuum the database to reduce its size by a single # page. This will remove the single leaf from the first page in # the linked list of free-list trunk pages. do_test tkt3918.4 { execsql { PRAGMA incremental_vacuum = 1 } } {} # Create another table. This operation will attempt to extract # page 4 from the database free-list. Bug 3918 caused sqlite to # incorrectly report corruption here. do_test tkt3918.5 { execsql { CREATE TABLE t2(a, b) } } {} finish_test |