/ Check-in [ba0538a4]
Login

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

Overview
Comment:Fix a resource leak introduced by the change-counter optimisation. Also add some test coverage. (CVS 3790)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ba0538a4977aefd6645554f1989f0a98b540b9cd
User & Date: danielk1977 2007-04-02 05:07:47
Context
2007-04-02
11:08
Correctly handle the obscure case of a read-only hot-journal file. (CVS 3791) check-in: 4d8c6bf4 user: danielk1977 tags: trunk
05:07
Fix a resource leak introduced by the change-counter optimisation. Also add some test coverage. (CVS 3790) check-in: ba0538a4 user: danielk1977 tags: trunk
00:53
Update the version number and change comments in preparation for the release of 3.3.14. (CVS 3789) check-in: d9f6fdb7 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.349 2007/03/31 02:36:44 drh Exp $
           12  +** $Id: btree.c,v 1.350 2007/04/02 05:07:47 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.
................................................................................
  2276   2276   
  2277   2277   /* Forward declaration required by autoVacuumCommit(). */
  2278   2278   static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
  2279   2279   
  2280   2280   /*
  2281   2281   ** This routine is called prior to sqlite3PagerCommit when a transaction
  2282   2282   ** is commited for an auto-vacuum database.
         2283  +**
         2284  +** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
         2285  +** the database file should be truncated to during the commit process. 
         2286  +** i.e. the database has been reorganized so that only the first *pnTrunc
         2287  +** pages are in use.
  2283   2288   */
  2284         -static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
         2289  +static int autoVacuumCommit(BtShared *pBt, Pgno *pnTrunc){
  2285   2290     Pager *pPager = pBt->pPager;
  2286   2291     Pgno nFreeList;            /* Number of pages remaining on the free-list. */
  2287   2292     int nPtrMap;               /* Number of pointer-map pages deallocated */
  2288   2293     Pgno origSize;             /* Pages in the database file */
  2289   2294     Pgno finSize;              /* Pages in the database file after truncation */
  2290   2295     int rc;                    /* Return code */
  2291   2296     u8 eType;
................................................................................
  2306   2311     }
  2307   2312   
  2308   2313     /* Figure out how many free-pages are in the database. If there are no
  2309   2314     ** free pages, then auto-vacuum is a no-op.
  2310   2315     */
  2311   2316     nFreeList = get4byte(&pBt->pPage1->aData[36]);
  2312   2317     if( nFreeList==0 ){
  2313         -    *nTrunc = 0;
         2318  +    *pnTrunc = 0;
  2314   2319       return SQLITE_OK;
  2315   2320     }
  2316   2321   
  2317   2322     /* This block figures out how many pages there are in the database
  2318   2323     ** now (variable origSize), and how many there will be after the
  2319   2324     ** truncation (variable finSize).
  2320   2325     **
................................................................................
  2397   2402     ** truncate the database file to finSize pages and consider the
  2398   2403     ** free-list empty.
  2399   2404     */
  2400   2405     rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  2401   2406     if( rc!=SQLITE_OK ) goto autovacuum_out;
  2402   2407     put4byte(&pBt->pPage1->aData[32], 0);
  2403   2408     put4byte(&pBt->pPage1->aData[36], 0);
  2404         -  *nTrunc = finSize;
         2409  +  *pnTrunc = finSize;
  2405   2410     assert( finSize!=PENDING_BYTE_PAGE(pBt) );
  2406   2411   
  2407   2412   autovacuum_out:
  2408   2413     assert( nRef==sqlite3PagerRefcount(pPager) );
  2409   2414     if( rc!=SQLITE_OK ){
  2410   2415       sqlite3PagerRollback(pPager);
  2411   2416     }

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.313 2007/04/01 23:49:52 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.314 2007/04/02 05:07:47 danielk1977 Exp $
    22     22   */
    23     23   #ifndef SQLITE_OMIT_DISKIO
    24     24   #include "sqliteInt.h"
    25     25   #include "os.h"
    26     26   #include "pager.h"
    27     27   #include <assert.h>
    28     28   #include <string.h>
................................................................................
  2385   2385   }
  2386   2386   
  2387   2387   /*
  2388   2388   ** Sort the list of pages in accending order by pgno.  Pages are
  2389   2389   ** connected by pDirty pointers.  The pPrevDirty pointers are
  2390   2390   ** corrupted by this sort.
  2391   2391   */
  2392         -#define N_SORT_BUCKET 25
         2392  +#define N_SORT_BUCKET_ALLOC 25
         2393  +#define N_SORT_BUCKET       25
         2394  +#ifdef SQLITE_TEST
         2395  +  int sqlite3_pager_n_sort_bucket = 0;
         2396  +  #undef N_SORT_BUCKET
         2397  +  #define N_SORT_BUCKET \
         2398  +   (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC)
         2399  +#endif
  2393   2400   static PgHdr *sort_pagelist(PgHdr *pIn){
  2394         -  PgHdr *a[N_SORT_BUCKET], *p;
         2401  +  PgHdr *a[N_SORT_BUCKET_ALLOC], *p;
  2395   2402     int i;
  2396   2403     memset(a, 0, sizeof(a));
  2397   2404     while( pIn ){
  2398   2405       p = pIn;
  2399   2406       pIn = p->pDirty;
  2400   2407       p->pDirty = 0;
  2401   2408       for(i=0; i<N_SORT_BUCKET-1; i++){
................................................................................
  2404   2411           break;
  2405   2412         }else{
  2406   2413           p = merge_pagelist(a[i], p);
  2407   2414           a[i] = 0;
  2408   2415         }
  2409   2416       }
  2410   2417       if( i==N_SORT_BUCKET-1 ){
         2418  +      /* Coverage: To get here, there need to be 2^(N_SORT_BUCKET) 
         2419  +      ** elements in the input list. This is possible, but impractical.
         2420  +      ** Testing this line is the point of global variable
         2421  +      ** sqlite3_pager_n_sort_bucket.
         2422  +      */
  2411   2423         a[i] = merge_pagelist(a[i], p);
  2412   2424       }
  2413   2425     }
  2414   2426     p = a[0];
  2415   2427     for(i=1; i<N_SORT_BUCKET; i++){
  2416   2428       p = merge_pagelist(p, a[i]);
  2417   2429     }
................................................................................
  2587   2599       IOTRACE(("ALWAYS_ROLLBACK %p\n", pPager))
  2588   2600       pPager->alwaysRollback = 1;
  2589   2601     }
  2590   2602   
  2591   2603     /* Unlink the old page from the free list and the hash table
  2592   2604     */
  2593   2605     unlinkPage(pPg);
  2594         -  TEST_INCR(pPager->nOvfl);
         2606  +  if( pPg && pPg->pgno!=0 ){
         2607  +    TEST_INCR(pPager->nOvfl);
         2608  +  }
  2595   2609   
  2596   2610     *ppPg = pPg;
  2597   2611     return SQLITE_OK;
  2598   2612   }
  2599   2613   
  2600   2614   /*
  2601   2615   ** This function is called to free superfluous dynamically allocated memory
................................................................................
  2767   2781           }
  2768   2782           assert(pPager->state==PAGER_SHARED || 
  2769   2783               (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
  2770   2784           );
  2771   2785         }
  2772   2786   
  2773   2787         if( pPager->pAll ){
         2788  +        /* The shared-lock has just been acquired on the database file
         2789  +        ** and there are already pages in the cache (from a previous
         2790  +        ** read or write transaction). If the value of the change-counter
         2791  +        ** stored in Pager.iChangeCount matches that found on page 1 of
         2792  +        ** the database file, then no database changes have occured since
         2793  +        ** the cache was last valid and it is safe to retain the cached
         2794  +        ** pages. Otherwise, if Pager.iChangeCount does not match the
         2795  +        ** change-counter on page 1 of the file, the current cache contents
         2796  +        ** must be discarded.
         2797  +        */
         2798  +
  2774   2799           PgHdr *pPage1 = pager_lookup(pPager, 1);
  2775   2800           if( pPage1 ){
  2776         -          unlinkHashChain(pPager, pPage1);
         2801  +          unlinkPage(pPage1);
         2802  +
         2803  +          assert( pPager->pFirst==pPager->pFirstSynced );
         2804  +          pPage1->pNextFree = pPager->pFirst;
         2805  +          if( pPager->pFirst ){
         2806  +            pPager->pFirst->pPrevFree = pPage1;
         2807  +          }else{
         2808  +            assert( !pPager->pLast );
         2809  +            pPager->pLast = pPage1;
         2810  +          }
         2811  +          pPager->pFirst = pPage1;
         2812  +          pPager->pFirstSynced = pPage1;
         2813  +
  2777   2814           }
  2778   2815   
  2779   2816           assert( !pager_lookup(pPager, 1) );
  2780   2817           rc = sqlite3PagerAcquire(pPager, 1, &pPage1, 0);
  2781   2818           if( rc==SQLITE_OK ){
  2782   2819   	  /* The change-counter is stored at offset 24. See also
  2783   2820             ** pager_incr_changecounter().
................................................................................
  2797   2834       if( pPager->state==PAGER_UNLOCK ){
  2798   2835         pPager->state = PAGER_SHARED;
  2799   2836       }
  2800   2837     }
  2801   2838   
  2802   2839     return rc;
  2803   2840   }
         2841  +
         2842  +/*
         2843  +** Allocate or recycle space for a single page.
         2844  +*/
         2845  +static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){
         2846  +  int rc = SQLITE_OK;
         2847  +  PgHdr *pPg;
         2848  +
         2849  +  if( !(pPager->pFirstSynced && pPager->pFirstSynced->pgno==0) && (
         2850  +      pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ||
         2851  +      (pPager->pFirstSynced==0 && pPager->doNotSync)
         2852  +  ) ){
         2853  +    /* Create a new page */
         2854  +    if( pPager->nPage>=pPager->nHash ){
         2855  +      pager_resize_hash_table(pPager,
         2856  +         pPager->nHash<256 ? 256 : pPager->nHash*2);
         2857  +      if( pPager->nHash==0 ){
         2858  +        rc = SQLITE_NOMEM;
         2859  +        goto pager_allocate_out;
         2860  +      }
         2861  +    }
         2862  +    pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
         2863  +                            + sizeof(u32) + pPager->nExtra
         2864  +                            + MEMDB*sizeof(PgHistory) );
         2865  +    if( pPg==0 ){
         2866  +      rc = SQLITE_NOMEM;
         2867  +      goto pager_allocate_out;
         2868  +    }
         2869  +    memset(pPg, 0, sizeof(*pPg));
         2870  +    if( MEMDB ){
         2871  +      memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
         2872  +    }
         2873  +    pPg->pPager = pPager;
         2874  +    pPg->pNextAll = pPager->pAll;
         2875  +    pPager->pAll = pPg;
         2876  +    pPager->nPage++;
         2877  +    if( pPager->nPage>pPager->nMaxPage ){
         2878  +      assert( pPager->nMaxPage==(pPager->nPage-1) );
         2879  +      pPager->nMaxPage++;
         2880  +    }
         2881  +  }else{
         2882  +    /* Recycle an existing page with a zero ref-count. */
         2883  +    rc = pager_recycle(pPager, 1, &pPg);
         2884  +    if( rc!=SQLITE_OK ){
         2885  +      goto pager_allocate_out;
         2886  +    }
         2887  +    assert( pPager->state>=SHARED_LOCK );
         2888  +    assert(pPg);
         2889  +  }
         2890  +  *ppPg = pPg;
         2891  +
         2892  +pager_allocate_out:
         2893  +  return rc;
         2894  +}
  2804   2895   
  2805   2896   /*
  2806   2897   ** Acquire a page.
  2807   2898   **
  2808   2899   ** A read lock on the disk file is obtained when the first page is acquired. 
  2809   2900   ** This read lock is dropped when the last page is released.
  2810   2901   **
................................................................................
  2863   2954   
  2864   2955     pPg = pager_lookup(pPager, pgno);
  2865   2956     if( pPg==0 ){
  2866   2957       /* The requested page is not in the page cache. */
  2867   2958       int nMax;
  2868   2959       int h;
  2869   2960       TEST_INCR(pPager->nMiss);
  2870         -    if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ||
  2871         -        (pPager->pFirstSynced==0 && pPager->doNotSync)
  2872         -    ){
  2873         -      /* Create a new page */
  2874         -      if( pPager->nPage>=pPager->nHash ){
  2875         -        pager_resize_hash_table(pPager,
  2876         -           pPager->nHash<256 ? 256 : pPager->nHash*2);
  2877         -        if( pPager->nHash==0 ){
  2878         -          return SQLITE_NOMEM;
  2879         -        }
  2880         -      }
  2881         -      pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
  2882         -                              + sizeof(u32) + pPager->nExtra
  2883         -                              + MEMDB*sizeof(PgHistory) );
  2884         -      if( pPg==0 ){
  2885         -        return SQLITE_NOMEM;
  2886         -      }
  2887         -      memset(pPg, 0, sizeof(*pPg));
  2888         -      if( MEMDB ){
  2889         -        memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
  2890         -      }
  2891         -      pPg->pPager = pPager;
  2892         -      pPg->pNextAll = pPager->pAll;
  2893         -      pPager->pAll = pPg;
  2894         -      pPager->nPage++;
  2895         -      if( pPager->nPage>pPager->nMaxPage ){
  2896         -        assert( pPager->nMaxPage==(pPager->nPage-1) );
  2897         -        pPager->nMaxPage++;
  2898         -      }
  2899         -    }else{
  2900         -      rc = pager_recycle(pPager, 1, &pPg);
  2901         -      if( rc!=SQLITE_OK ){
  2902         -        return rc;
  2903         -      }
  2904         -      assert( pPager->state>=SHARED_LOCK );
  2905         -      assert(pPg);
         2961  +    rc = pagerAllocatePage(pPager, &pPg);
         2962  +    if( rc!=SQLITE_OK ){
         2963  +      return rc;
  2906   2964       }
         2965  +
  2907   2966       pPg->pgno = pgno;
  2908   2967       if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
  2909   2968         sqlite3CheckMemory(pPager->aInJournal, pgno/8);
  2910   2969         assert( pPager->journalOpen );
  2911   2970         pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
  2912   2971         pPg->needSync = 0;
  2913   2972       }else{

Changes to src/test2.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the pager.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test2.c,v 1.42 2007/03/30 14:06:34 drh Exp $
           16  +** $Id: test2.c,v 1.43 2007/04/02 05:07:47 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "os.h"
    20     20   #include "pager.h"
    21     21   #include "tcl.h"
    22     22   #include <stdlib.h>
    23     23   #include <string.h>
................................................................................
   566    566   */
   567    567   int Sqlitetest2_Init(Tcl_Interp *interp){
   568    568     extern int sqlite3_io_error_persist;
   569    569     extern int sqlite3_io_error_pending;
   570    570     extern int sqlite3_io_error_hit;
   571    571     extern int sqlite3_diskfull_pending;
   572    572     extern int sqlite3_diskfull;
          573  +  extern int sqlite3_pager_n_sort_bucket;
   573    574     static struct {
   574    575       char *zName;
   575    576       Tcl_CmdProc *xProc;
   576    577     } aCmd[] = {
   577    578       { "pager_open",              (Tcl_CmdProc*)pager_open          },
   578    579       { "pager_close",             (Tcl_CmdProc*)pager_close         },
   579    580       { "pager_commit",            (Tcl_CmdProc*)pager_commit        },
................................................................................
   608    609        (char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
   609    610     Tcl_LinkVar(interp, "sqlite_diskfull",
   610    611        (char*)&sqlite3_diskfull, TCL_LINK_INT);
   611    612     Tcl_LinkVar(interp, "sqlite_pending_byte",
   612    613        (char*)&sqlite3_pending_byte, TCL_LINK_INT);
   613    614     Tcl_LinkVar(interp, "pager_pagesize",
   614    615        (char*)&test_pagesize, TCL_LINK_INT);
          616  +  Tcl_LinkVar(interp, "sqlite_pager_n_sort_bucket",
          617  +     (char*)&sqlite3_pager_n_sort_bucket, TCL_LINK_INT);
   615    618     return TCL_OK;
   616    619   }

Added test/cache.test.

            1  +# 2007 March 24
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# $Id: cache.test,v 1.1 2007/04/02 05:07:48 danielk1977 Exp $
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +
           17  +ifcapable {!pager_pragmas} {
           18  +  finish_test
           19  +  return
           20  +}
           21  +
           22  +proc pager_cache_size {db} {
           23  +  set bt [btree_from_db $db]
           24  +  array set stats [btree_pager_stats $bt]
           25  +  return $stats(page)
           26  +}
           27  +
           28  +do_test cache-1.1 {
           29  +  pager_cache_size db
           30  +} {0}
           31  +
           32  +do_test cache-1.2 {
           33  +  execsql {
           34  +    CREATE TABLE abc(a, b, c);
           35  +    INSERT INTO abc VALUES(1, 2, 3);
           36  +  }
           37  +  pager_cache_size db
           38  +} {2}
           39  +
           40  +# At one point, repeatedly locking and unlocking the cache was causing
           41  +# a resource leak of one page per repetition. The page wasn't actually
           42  +# leaked, but would not be reused until the pager-cache was full (i.e. 
           43  +# 2000 pages by default).
           44  +#
           45  +# This tests that once the pager-cache is initialised, it can be locked
           46  +# and unlocked repeatedly without internally allocating any new pages.
           47  +#
           48  +set cache_size [pager_cache_size db]
           49  +for {set ii 0} {$ii < 10} {incr ii} {
           50  +
           51  +  do_test cache-1.3.$ii {
           52  +    execsql {SELECT * FROM abc}
           53  +    pager_cache_size db
           54  +  } $::cache_size
           55  +
           56  +}
           57  +
           58  +finish_test

Changes to test/malloc5.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   # This file contains test cases focused on the two memory-management APIs, 
    13     13   # sqlite3_soft_heap_limit() and sqlite3_release_memory().
    14     14   #
    15         -# $Id: malloc5.test,v 1.7 2006/01/19 08:43:32 danielk1977 Exp $
           15  +# $Id: malloc5.test,v 1.8 2007/04/02 05:07:48 danielk1977 Exp $
    16     16   
    17     17   #---------------------------------------------------------------------------
    18     18   # NOTES ON EXPECTED BEHAVIOUR
    19     19   #
    20     20   #---------------------------------------------------------------------------
    21     21   
    22     22   
................................................................................
    81     81     catchsql {
    82     82       SELECT * FROM abc;
    83     83     } db2
    84     84   } {0 {}}
    85     85   do_test malloc5-1.5 {
    86     86     # Manipulate the cache so that it contains two unused pages. One requires 
    87     87     # a journal-sync to free, the other does not.
           88  +  db2 close
    88     89     execsql {
    89     90       SELECT * FROM abc;
    90     91       CREATE TABLE def(d, e, f);
    91     92     }
    92     93     sqlite3_release_memory 500
    93     94   } $::pgalloc
    94     95   do_test malloc5-1.6 {
    95     96     # Database should not be locked this time. The above test case only
    96     97     # requested 500 bytes of memory, which can be obtained by freeing the page
    97     98     # that does not require an fsync().
           99  +  sqlite3 db2 test.db
    98    100     catchsql {
    99    101       SELECT * FROM abc;
   100    102     } db2
   101    103   } {0 {}}
   102    104   do_test malloc5-1.7 {
   103    105     # Release another 500 bytes of memory. This time we require a sync(), 
   104    106     # so the database file will be locked afterwards.
          107  +  db2 close
   105    108     sqlite3_release_memory 500
   106    109   } $::pgalloc
   107    110   do_test malloc5-1.8 {
          111  +  sqlite3 db2 test.db
   108    112     catchsql {
   109    113       SELECT * FROM abc;
   110    114     } db2
   111    115   } {1 {database is locked}}
   112    116   do_test malloc5-1.9 {
   113    117     execsql {
   114    118       COMMIT;

Changes to test/misc7.test.

     6      6   #    May you do good and not evil.
     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.
    12     12   #
    13         -# $Id: misc7.test,v 1.9 2007/03/31 10:00:49 danielk1977 Exp $
           13  +# $Id: misc7.test,v 1.10 2007/04/02 05:07:48 danielk1977 Exp $
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   do_test misc7-1 {
    19     19     c_misuse_test
    20     20   } {}
................................................................................
   154    154   } {hello}
   155    155   do_test misc7-7.2 {
   156    156     execsql {
   157    157       DETACH aux;
   158    158     }
   159    159   } {}
   160    160   
   161         -# Test malloc failure whilst installing a foriegn key.
          161  +# Test the UTF-16 version of the "out of memory" message (used when
          162  +# malloc fails during sqlite3_open() ).
   162    163   #
   163    164   ifcapable utf16 {
   164    165     do_test misc7-8 {
   165    166       encoding convertfrom unicode [sqlite3_errmsg16 0x00000000]
   166    167     } {out of memory}
   167    168   }
   168    169   
................................................................................
   323    324     if {!$rc || ($rc && [string first "columns" $msg]==0)} {
   324    325       set msg
   325    326     } else {
   326    327       error $msg
   327    328     }
   328    329   }
   329    330   
   330         -
   331         -
          331  +sqlite3 db test.db
          332  +set sqlite_pager_n_sort_bucket 4
          333  +do_test misc7-17 {
          334  +  execsql {
          335  +    PRAGMA integrity_check;
          336  +    VACUUM;
          337  +    PRAGMA integrity_check;
          338  +  }
          339  +} {ok ok}
          340  +set sqlite_pager_n_sort_bucket 0
   332    341   
   333    342   finish_test

Changes to test/pager.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 script is page cache subsystem.
    13     13   #
    14         -# $Id: pager.test,v 1.26 2007/03/23 18:12:07 danielk1977 Exp $
           14  +# $Id: pager.test,v 1.27 2007/04/02 05:07:48 danielk1977 Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   if {[info commands pager_open]!=""} {
    21     21   db close
................................................................................
   115    115     expr {$::g1!=0}
   116    116   } {1}
   117    117   do_test pager-2.12 {
   118    118     page_number $::g1
   119    119   } {1}
   120    120   do_test pager-2.13 {
   121    121     pager_stats $::p1
   122         -} {ref 1 page 2 max 10 size 0 state 1 err 0 hit 1 miss 2 ovfl 0}
          122  +} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 1 miss 2 ovfl 0}
   123    123   do_test pager-2.14 {
   124    124     set v [catch {
   125    125       page_write $::g1 "Page-One"
   126    126     } msg]
   127    127     lappend v $msg
   128    128   } {0 {}}
   129    129   do_test pager-2.15 {
   130    130     pager_stats $::p1
   131         -} {ref 1 page 2 max 10 size 1 state 2 err 0 hit 1 miss 2 ovfl 0}
          131  +} {ref 1 page 1 max 10 size 1 state 2 err 0 hit 1 miss 2 ovfl 0}
   132    132   do_test pager-2.16 {
   133    133     page_read $::g1
   134    134   } {Page-One}
   135    135   do_test pager-2.17 {
   136    136     set v [catch {
   137    137       pager_commit $::p1
   138    138     } msg]
   139    139     lappend v $msg
   140    140   } {0 {}}
   141    141   do_test pager-2.20 {
   142    142     pager_stats $::p1
   143         -} {ref 1 page 2 max 10 size -1 state 1 err 0 hit 2 miss 2 ovfl 0}
          143  +} {ref 1 page 1 max 10 size -1 state 1 err 0 hit 2 miss 2 ovfl 0}
   144    144   do_test pager-2.19 {
   145    145     pager_pagecount $::p1
   146    146   } {1}
   147    147   do_test pager-2.21 {
   148    148     pager_stats $::p1
   149         -} {ref 1 page 2 max 10 size 1 state 1 err 0 hit 2 miss 2 ovfl 0}
          149  +} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 2 miss 2 ovfl 0}
   150    150   do_test pager-2.22 {
   151    151     page_unref $::g1
   152    152   } {}
   153    153   do_test pager-2.23 {
   154    154     pager_stats $::p1
   155         -} {ref 0 page 2 max 10 size -1 state 0 err 0 hit 2 miss 2 ovfl 0}
          155  +} {ref 0 page 1 max 10 size -1 state 0 err 0 hit 2 miss 2 ovfl 0}
   156    156   do_test pager-2.24 {
   157    157     set v [catch {
   158    158       page_get $::p1 1
   159    159     } ::g1]
   160    160     if {$v} {lappend v $::g1}
   161    161     set v
   162    162   } {0}