/ Check-in [40249ed1]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix an auto-vacuum bug for btree entries that span more than one overflow page. (CVS 2039)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 40249ed19cd53cb61f9575d8165316faf2627479
User & Date: danielk1977 2004-11-02 14:40:32
Context
2004-11-02
18:05
Get btree.c to compile with -DNDEBUG=1. (CVS 2040) check-in: 8378c144 user: drh tags: trunk
14:40
Fix an auto-vacuum bug for btree entries that span more than one overflow page. (CVS 2039) check-in: 40249ed1 user: danielk1977 tags: trunk
14:24
Require that the page size be a power of 2. (CVS 2038) check-in: c33b34db user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.197 2004/11/02 14:24:34 drh Exp $
           12  +** $Id: btree.c,v 1.198 2004/11/02 14:40:32 danielk1977 Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
  1560   1560   **
  1561   1561   ** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
  1562   1562   **                   overflow page in the list.
  1563   1563   */
  1564   1564   static void modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
  1565   1565   
  1566   1566     if( eType==PTRMAP_OVERFLOW2 ){
         1567  +    /* The pointer is always the first 4 bytes of the page in this case.  */
  1567   1568       assert( get4byte(pPage->aData)==iFrom );
  1568         -    put4byte(pPage->aData, iFrom);
         1569  +    put4byte(pPage->aData, iTo);
  1569   1570     }else{
  1570   1571       int isInitOrig = pPage->isInit;
  1571   1572       int i;
  1572   1573       int nCell;
  1573   1574   
  1574   1575       initPage(pPage, 0);
  1575   1576       nCell = pPage->nCell;
  1576   1577   
  1577         -   /*  assert( !pPage->leaf && eType==PTRMAP_BTREE ); */
  1578         -
  1579   1578       for(i=0; i<nCell; i++){
  1580   1579         u8 *pCell = findCell(pPage, i);
  1581   1580         if( eType==PTRMAP_OVERFLOW1 ){
  1582   1581           CellInfo info;
  1583   1582           parseCellPtr(pPage, pCell, &info);
  1584   1583           if( info.iOverflow ){
  1585   1584             if( iFrom==get4byte(&pCell[info.iOverflow]) ){
................................................................................
  1691   1690         }
  1692   1691         rc = allocatePage(pBt, &pFreeMemPage, &iFreePage, 0);
  1693   1692         if( rc!=SQLITE_OK ) goto autovacuum_out;
  1694   1693         assert( iFreePage<=origDbSize );
  1695   1694       }while( iFreePage>finDbSize );
  1696   1695   
  1697   1696       /* Move page iDbPage from it's current location to page number iFreePage */
  1698         -    TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d)\n", 
  1699         -        iDbPage, iFreePage, iPtrPage));
         1697  +    TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", 
         1698  +        iDbPage, iFreePage, iPtrPage, eType));
  1700   1699       releasePage(pFreeMemPage);
  1701   1700       pFreeMemPage = 0;
  1702   1701       rc = sqlite3pager_movepage(pPager, pDbPage, iFreePage);
  1703   1702       if( rc!=SQLITE_OK ) goto autovacuum_out;
  1704   1703       pDbMemPage->pgno = iFreePage;
  1705   1704   
  1706   1705       /* If pDbPage was a btree-page, then it may have child pages and/or cells
  1707   1706       ** that point to overflow pages. The pointer map entries for all these
  1708   1707       ** pages need to be changed.
         1708  +    **
         1709  +    ** If pDbPage is an overflow page, then the first 4 bytes may store a
         1710  +    ** pointer to a subsequent overflow page. If this is the case, then
         1711  +    ** the pointer map needs to be updated for the subsequent overflow page.
  1709   1712       */
  1710   1713       if( eType==PTRMAP_BTREE ){
  1711   1714         rc = setChildPtrmaps(pDbMemPage);
  1712   1715         if( rc!=SQLITE_OK ) goto autovacuum_out;
         1716  +    }else{
         1717  +      Pgno nextOvfl = get4byte(pDbPage);
         1718  +      if( nextOvfl!=0 ){
         1719  +        assert( nextOvfl<=origDbSize );
         1720  +        rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage);
         1721  +        if( rc!=SQLITE_OK ) goto autovacuum_out;
         1722  +      }
  1713   1723       }
  1714   1724       releasePage(pDbMemPage);
  1715   1725       pDbMemPage = 0;
  1716   1726   
  1717   1727       /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
  1718   1728       ** that it points at iFreePage. Also fix the pointer map entry for
  1719   1729       ** iPtrPage.

Changes to test/autovacuum.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the SELECT statement.
    13     13   #
    14         -# $Id: autovacuum.test,v 1.1 2004/11/02 12:56:41 danielk1977 Exp $
           14  +# $Id: autovacuum.test,v 1.2 2004/11/02 14:40:32 danielk1977 Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   proc make_str {char len} {
    20     20     set str [string repeat $char. $len]
    21     21     return [string range $str 0 [expr $len-1]]
................................................................................
    24     24   proc file_pages {} {
    25     25     return [expr [file size test.db] / 1024]
    26     26   }
    27     27   
    28     28   do_test autovacuum-1.1 {
    29     29     execsql {
    30     30       CREATE TABLE av1(a);
           31  +    -- CREATE INDEX av1_idx ON av1(a);
    31     32     }
    32     33   } {}
    33     34   
    34         -set ENTRY_LEN 1100
           35  +set ENTRY_LEN 3000
    35     36   
    36     37   set delete_orders [list]
    37     38   lappend delete_orders {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20}
    38     39   lappend delete_orders {20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1} 
    39     40   lappend delete_orders {8 18 2 4 14 11 13 3 10 7 9 5 12 17 19 15 20 6 16 1}
    40     41   lappend delete_orders {10 3 11 17 19 20 7 4 13 6 1 14 16 12 9 18 8 15 5 2}
    41     42