/ Check-in [55af8003]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge the latest trunk changes into the apple-osx branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: 55af80035f0432bbd4c4b3f4dbc9def13c5356b3
User & Date: drh 2011-08-26 19:18:50
Context
2011-09-14
19:05
Merge in the latest changes from trunk. check-in: 2456b4d0 user: drh tags: apple-osx
2011-08-26
19:18
Merge the latest trunk changes into the apple-osx branch. check-in: 55af8003 user: drh tags: apple-osx
11:25
Update compiler error message regarding the choice of memory allocator defines. check-in: 1dada515 user: mistachkin tags: trunk
2011-08-23
18:06
Merge latest trunk changes into the apple-osx branch. check-in: c5f7977b user: dan tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.msc.

     6      6   # that contains this "Makefile.msc".
     7      7   #
     8      8   TOP = .
     9      9   
    10     10   # Set this non-0 to create and use the SQLite amalgamation file.
    11     11   #
    12     12   USE_AMALGAMATION = 1
           13  +
           14  +# Set this to non-0 to create and use PDBs.
           15  +#
           16  +SYMBOLS = 1
           17  +
           18  +# Set this to one of the following values to enable various debugging
           19  +# features.  Each level includes the debugging options from the previous
           20  +# levels.  Currently, the recognized values for DEBUG are:
           21  +#
           22  +# 0 == NDEBUG: Disables assert() and other runtime diagnostics.
           23  +# 1 == Disables NDEBUG and all optimizations and then enables PDBs.
           24  +# 2 == SQLITE_DEBUG: Enables various diagnostics messages and code.
           25  +# 3 == SQLITE_WIN32_MALLOC_VALIDATE: Validate the Win32 native heap per call.
           26  +# 4 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
           27  +# 5 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
           28  +#
           29  +DEBUG = 0
    13     30   
    14     31   # Version numbers and release number for the SQLite being compiled.
    15     32   #
    16     33   VERSION = 3.7
    17     34   VERSION_NUMBER = 3007007
    18     35   RELEASE = 3.7.7
    19     36   
    20     37   # C Compiler and options for use in building executables that
    21     38   # will run on the platform that is doing the build.
    22     39   #
    23         -BCC = cl.exe -O2
           40  +BCC = cl.exe
    24     41   
    25     42   # C Compile and options for use in building executables that
    26     43   # will run on the target platform.  (BCC and TCC are usually the
    27     44   # same unless your are cross-compiling.)
    28     45   #
    29         -TCC = cl.exe -W3 -O2 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
           46  +TCC = cl.exe -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
    30     47   
    31     48   # The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in 
    32     49   # any extension header files by default.  For non-amalgamation
    33     50   # builds, we need to make sure the compiler can find these.
    34     51   #
    35     52   !IF $(USE_AMALGAMATION)==0
    36     53   TCC = $(TCC) -I$(TOP)\ext\fts3
................................................................................
    37     54   TCC = $(TCC) -I$(TOP)\ext\rtree
    38     55   !ENDIF
    39     56   
    40     57   # Define -DNDEBUG to compile without debugging (i.e., for production usage)
    41     58   # Omitting the define will cause extra debugging code to be inserted and
    42     59   # includes extra comments when "EXPLAIN stmt" is used.
    43     60   #
           61  +!IF $(DEBUG)==0
    44     62   TCC = $(TCC) -DNDEBUG
           63  +!ENDIF
           64  +
           65  +!IF $(DEBUG)>1
           66  +TCC = $(TCC) -DSQLITE_DEBUG
           67  +!ENDIF
           68  +
           69  +!IF $(DEBUG)>3
           70  +TCC = $(TCC) -DSQLITE_DEBUG_OS_TRACE=1
           71  +!ENDIF
           72  +
           73  +!IF $(DEBUG)>4
           74  +TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE
           75  +!ENDIF
    45     76   
    46     77   #
    47     78   # Prevent warnings about "insecure" runtime library functions being used.
    48     79   #
    49     80   TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
    50     81   
           82  +#
           83  +# Use native Win32 heap instead of malloc/free?
           84  +#
           85  +# TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1
           86  +
           87  +#
           88  +# Validate the heap on every call into the native Win32 heap subsystem?
           89  +#
           90  +!IF $(DEBUG)>2
           91  +TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
           92  +!ENDIF
           93  +
    51     94   # The locations of the Tcl header and library files.  Also, the library that
    52     95   # non-stubs enabled programs using Tcl must link against.  These variables
    53     96   # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
    54     97   # prior to running nmake in order to match the actual installed location and
    55     98   # version on this machine.
    56     99   #
    57    100   !if "$(TCLINCDIR)" == ""
................................................................................
   119    162   # END required Windows option
   120    163   
   121    164   TCC = $(TCC) $(OPT_FEATURE_FLAGS)
   122    165   
   123    166   # Add in any optional parameters specified on the make commane line
   124    167   # ie.  make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
   125    168   TCC = $(TCC) $(OPTS)
          169  +
          170  +# If symbols are enabled, enable PDBs.
          171  +# If debugging is enabled, disable all optimizations and enable PDBs.
          172  +!IF $(DEBUG)>0
          173  +TCC = $(TCC) -Od -D_DEBUG
          174  +!ELSE
          175  +TCC = $(TCC) -O2
          176  +!ENDIF
          177  +
          178  +!IF $(DEBUG)>0 || $(SYMBOLS)!=0
          179  +TCC = $(TCC) -Zi
          180  +!ENDIF
   126    181   
   127    182   # libtool compile/link
   128    183   LTCOMPILE = $(TCC) -Fo$@
   129    184   LTLIB = lib.exe
   130    185   LTLINK = $(TCC) -Fe$@
   131    186   
   132    187   # If a platform was set, force the linker to target that.
................................................................................
   133    188   # Note that the vcvars*.bat family of batch files typically
   134    189   # set this for you.  Otherwise, the linker will attempt
   135    190   # to deduce the binary type based on the object files.
   136    191   !IF "$(PLATFORM)"!=""
   137    192   LTLINKOPTS = /MACHINE:$(PLATFORM)
   138    193   LTLIBOPTS = /MACHINE:$(PLATFORM)
   139    194   !ENDIF
          195  +
          196  +# If debugging is enabled, enable PDBs.
          197  +!IF $(DEBUG)>0 || $(SYMBOLS)!=0
          198  +LTLINKOPTS = $(LTLINKOPTS) /DEBUG
          199  +!ENDIF
   140    200   
   141    201   # nawk compatible awk.
   142    202   NAWK = gawk.exe
   143    203   
   144    204   # You should not have to change anything below this line
   145    205   ###############################################################################
   146    206   

Changes to main.mk.

   384    384   sqlite3.c:	target_source $(TOP)/tool/mksqlite3c.tcl
   385    385   	tclsh $(TOP)/tool/mksqlite3c.tcl
   386    386   	echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
   387    387   	cat sqlite3.c >>tclsqlite3.c
   388    388   	echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
   389    389   	cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
   390    390   
   391         -sqlite3-debug.c:	target_source $(TOP)/tool/mksqlite3c.tcl
          391  +sqlite3.c-debug:	target_source $(TOP)/tool/mksqlite3c.tcl
   392    392   	tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros
   393    393   	echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
   394    394   	cat sqlite3.c >>tclsqlite3.c
   395    395   	echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
   396    396   	echo '#line 1 "tclsqlite.c"' >>tclsqlite3.c
   397    397   	cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
   398    398   

Changes to src/backup.c.

   406    406       }
   407    407     
   408    408       /* Update the schema version field in the destination database. This
   409    409       ** is to make sure that the schema-version really does change in
   410    410       ** the case where the source and destination databases have the
   411    411       ** same schema version.
   412    412       */
   413         -    if( rc==SQLITE_DONE 
   414         -     && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK
   415         -    ){
   416         -      int nDestTruncate;
   417         -  
   418         -      if( p->pDestDb ){
   419         -        sqlite3ResetInternalSchema(p->pDestDb, -1);
   420         -      }
   421         -
   422         -      if( destMode==PAGER_JOURNALMODE_WAL ){
   423         -        /* This call cannot fail. The success of the BtreeUpdateMeta() 
   424         -        ** method above indicates that a write transaction has been opened 
   425         -        ** and page 1 is already dirty. Therefore this always succeeds.
   426         -        */
   427         -        TESTONLY(int rc2 =) sqlite3BtreeSetVersion(p->pDest, 2);
   428         -        assert( rc2==SQLITE_OK );
          413  +    if( rc==SQLITE_DONE ){
          414  +      rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
          415  +      if( rc==SQLITE_OK ){
          416  +        if( p->pDestDb ){
          417  +          sqlite3ResetInternalSchema(p->pDestDb, -1);
          418  +        }
          419  +        if( destMode==PAGER_JOURNALMODE_WAL ){
          420  +          rc = sqlite3BtreeSetVersion(p->pDest, 2);
          421  +        }
   429    422         }
   430         -
   431         -      /* Set nDestTruncate to the final number of pages in the destination
   432         -      ** database. The complication here is that the destination page
   433         -      ** size may be different to the source page size. 
   434         -      **
   435         -      ** If the source page size is smaller than the destination page size, 
   436         -      ** round up. In this case the call to sqlite3OsTruncate() below will
   437         -      ** fix the size of the file. However it is important to call
   438         -      ** sqlite3PagerTruncateImage() here so that any pages in the 
   439         -      ** destination file that lie beyond the nDestTruncate page mark are
   440         -      ** journalled by PagerCommitPhaseOne() before they are destroyed
   441         -      ** by the file truncation.
   442         -      */
   443         -      assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
   444         -      assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
   445         -      if( pgszSrc<pgszDest ){
   446         -        int ratio = pgszDest/pgszSrc;
   447         -        nDestTruncate = (nSrcPage+ratio-1)/ratio;
   448         -        if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
   449         -          nDestTruncate--;
   450         -        }
   451         -      }else{
   452         -        nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
   453         -      }
   454         -      sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
   455         -
   456         -      if( pgszSrc<pgszDest ){
   457         -        /* If the source page-size is smaller than the destination page-size,
   458         -        ** two extra things may need to happen:
          423  +      if( rc==SQLITE_OK ){
          424  +        int nDestTruncate;
          425  +        /* Set nDestTruncate to the final number of pages in the destination
          426  +        ** database. The complication here is that the destination page
          427  +        ** size may be different to the source page size. 
   459    428           **
   460         -        **   * The destination may need to be truncated, and
   461         -        **
   462         -        **   * Data stored on the pages immediately following the 
   463         -        **     pending-byte page in the source database may need to be
   464         -        **     copied into the destination database.
          429  +        ** If the source page size is smaller than the destination page size, 
          430  +        ** round up. In this case the call to sqlite3OsTruncate() below will
          431  +        ** fix the size of the file. However it is important to call
          432  +        ** sqlite3PagerTruncateImage() here so that any pages in the 
          433  +        ** destination file that lie beyond the nDestTruncate page mark are
          434  +        ** journalled by PagerCommitPhaseOne() before they are destroyed
          435  +        ** by the file truncation.
   465    436           */
   466         -        const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
   467         -        sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
   468         -        i64 iOff;
   469         -        i64 iEnd;
   470         -
   471         -        assert( pFile );
   472         -        assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
   473         -              nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
   474         -           && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
   475         -        ));
   476         -
   477         -        /* This call ensures that all data required to recreate the original
   478         -        ** database has been stored in the journal for pDestPager and the
   479         -        ** journal synced to disk. So at this point we may safely modify
   480         -        ** the database file in any way, knowing that if a power failure
   481         -        ** occurs, the original database will be reconstructed from the 
   482         -        ** journal file.  */
   483         -        rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
   484         -
   485         -        /* Write the extra pages and truncate the database file as required. */
   486         -        iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
   487         -        for(
   488         -          iOff=PENDING_BYTE+pgszSrc; 
   489         -          rc==SQLITE_OK && iOff<iEnd; 
   490         -          iOff+=pgszSrc
   491         -        ){
   492         -          PgHdr *pSrcPg = 0;
   493         -          const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
   494         -          rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
          437  +        assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
          438  +        assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
          439  +        if( pgszSrc<pgszDest ){
          440  +          int ratio = pgszDest/pgszSrc;
          441  +          nDestTruncate = (nSrcPage+ratio-1)/ratio;
          442  +          if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
          443  +            nDestTruncate--;
          444  +          }
          445  +        }else{
          446  +          nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
          447  +        }
          448  +        sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
          449  +
          450  +        if( pgszSrc<pgszDest ){
          451  +          /* If the source page-size is smaller than the destination page-size,
          452  +          ** two extra things may need to happen:
          453  +          **
          454  +          **   * The destination may need to be truncated, and
          455  +          **
          456  +          **   * Data stored on the pages immediately following the 
          457  +          **     pending-byte page in the source database may need to be
          458  +          **     copied into the destination database.
          459  +          */
          460  +          const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
          461  +          sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
          462  +          i64 iOff;
          463  +          i64 iEnd;
          464  +
          465  +          assert( pFile );
          466  +          assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
          467  +                nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
          468  +             && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
          469  +          ));
          470  +
          471  +          /* This call ensures that all data required to recreate the original
          472  +          ** database has been stored in the journal for pDestPager and the
          473  +          ** journal synced to disk. So at this point we may safely modify
          474  +          ** the database file in any way, knowing that if a power failure
          475  +          ** occurs, the original database will be reconstructed from the 
          476  +          ** journal file.  */
          477  +          rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
          478  +
          479  +          /* Write the extra pages and truncate the database file as required */
          480  +          iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
          481  +          for(
          482  +            iOff=PENDING_BYTE+pgszSrc; 
          483  +            rc==SQLITE_OK && iOff<iEnd; 
          484  +            iOff+=pgszSrc
          485  +          ){
          486  +            PgHdr *pSrcPg = 0;
          487  +            const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
          488  +            rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
          489  +            if( rc==SQLITE_OK ){
          490  +              u8 *zData = sqlite3PagerGetData(pSrcPg);
          491  +              rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
          492  +            }
          493  +            sqlite3PagerUnref(pSrcPg);
          494  +          }
          495  +          if( rc==SQLITE_OK ){
          496  +            rc = backupTruncateFile(pFile, iSize);
          497  +          }
          498  +
          499  +          /* Sync the database file to disk. */
   495    500             if( rc==SQLITE_OK ){
   496         -            u8 *zData = sqlite3PagerGetData(pSrcPg);
   497         -            rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
          501  +            rc = sqlite3PagerSync(pDestPager);
   498    502             }
   499         -          sqlite3PagerUnref(pSrcPg);
          503  +        }else{
          504  +          rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
   500    505           }
   501         -        if( rc==SQLITE_OK ){
   502         -          rc = backupTruncateFile(pFile, iSize);
          506  +    
          507  +        /* Finish committing the transaction to the destination database. */
          508  +        if( SQLITE_OK==rc
          509  +         && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
          510  +        ){
          511  +          rc = SQLITE_DONE;
   503    512           }
   504         -
   505         -        /* Sync the database file to disk. */
   506         -        if( rc==SQLITE_OK ){
   507         -          rc = sqlite3PagerSync(pDestPager);
   508         -        }
   509         -      }else{
   510         -        rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
   511         -      }
   512         -  
   513         -      /* Finish committing the transaction to the destination database. */
   514         -      if( SQLITE_OK==rc
   515         -       && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
   516         -      ){
   517         -        rc = SQLITE_DONE;
   518    513         }
   519    514       }
   520    515     
   521    516       /* If bCloseTrans is true, then this function opened a read transaction
   522    517       ** on the source database. Close the read transaction here. There is
   523    518       ** no need to check the return values of the btree methods here, as
   524    519       ** "committing" a read-only transaction cannot fail.

Changes to src/btree.c.

  1736   1736   
  1737   1737     /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */
  1738   1738     assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 );
  1739   1739   
  1740   1740     /* A BTREE_SINGLE database is always a temporary and/or ephemeral */
  1741   1741     assert( (flags & BTREE_SINGLE)==0 || isTempDb );
  1742   1742   
         1743  +  /* The BTREE_SORTER flag is only used if SQLITE_OMIT_MERGE_SORT is undef */
         1744  +#ifdef SQLITE_OMIT_MERGE_SORT
         1745  +  assert( (flags & BTREE_SORTER)==0 );
         1746  +#endif
         1747  +
         1748  +  /* BTREE_SORTER is always on a BTREE_SINGLE, BTREE_OMIT_JOURNAL */
         1749  +  assert( (flags & BTREE_SORTER)==0 ||
         1750  +          (flags & (BTREE_SINGLE|BTREE_OMIT_JOURNAL))
         1751  +                                        ==(BTREE_SINGLE|BTREE_OMIT_JOURNAL) );
         1752  +
  1743   1753     if( db->flags & SQLITE_NoReadlock ){
  1744   1754       flags |= BTREE_NO_READLOCK;
  1745   1755     }
  1746   1756     if( isMemdb ){
  1747   1757       flags |= BTREE_MEMORY;
         1758  +    flags &= ~BTREE_SORTER;
  1748   1759     }
  1749   1760     if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){
  1750   1761       vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
  1751   1762     }
  1752   1763     p = sqlite3MallocZero(sizeof(Btree));
  1753   1764     if( !p ){
  1754   1765       return SQLITE_NOMEM;
................................................................................
  8197   8208         }
  8198   8209       }
  8199   8210     }
  8200   8211   
  8201   8212     pBt->doNotUseWAL = 0;
  8202   8213     return rc;
  8203   8214   }
  8204         -
  8205         -

Changes to src/btree.h.

    57     57   ** pager.h.
    58     58   */
    59     59   #define BTREE_OMIT_JOURNAL  1  /* Do not create or use a rollback journal */
    60     60   #define BTREE_NO_READLOCK   2  /* Omit readlocks on readonly files */
    61     61   #define BTREE_MEMORY        4  /* This is an in-memory DB */
    62     62   #define BTREE_SINGLE        8  /* The file contains at most 1 b-tree */
    63     63   #define BTREE_UNORDERED    16  /* Use of a hash implementation is OK */
           64  +#define BTREE_SORTER       32  /* Used as accumulator in external merge sort */
    64     65   
    65     66   int sqlite3BtreeClose(Btree*);
    66     67   int sqlite3BtreeSetCacheSize(Btree*,int);
    67     68   int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
    68     69   int sqlite3BtreeSyncDisabled(Btree*);
    69     70   int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
    70     71   int sqlite3BtreeGetPageSize(Btree*);

Changes to src/build.c.

  1670   1670     int noErr          /* Suppress error messages if VIEW already exists */
  1671   1671   ){
  1672   1672     Table *p;
  1673   1673     int n;
  1674   1674     const char *z;
  1675   1675     Token sEnd;
  1676   1676     DbFixer sFix;
  1677         -  Token *pName;
         1677  +  Token *pName = 0;
  1678   1678     int iDb;
  1679   1679     sqlite3 *db = pParse->db;
  1680   1680   
  1681   1681     if( pParse->nVar>0 ){
  1682   1682       sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
  1683   1683       sqlite3SelectDelete(db, pSelect);
  1684   1684       return;
................................................................................
  2368   2368       sqlite3VdbeChangeP5(v, 1);
  2369   2369     }
  2370   2370   
  2371   2371     /* Open the sorter cursor if we are to use one. */
  2372   2372     if( bUseSorter ){
  2373   2373       iSorter = pParse->nTab++;
  2374   2374       sqlite3VdbeAddOp4(v, OP_OpenSorter, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
         2375  +    sqlite3VdbeChangeP5(v, BTREE_SORTER);
  2375   2376     }
  2376   2377   
  2377   2378     /* Open the table. Loop through all rows of the table, inserting index
  2378   2379     ** records into the sorter. */
  2379   2380     sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  2380   2381     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
  2381   2382     regRecord = sqlite3GetTempReg(pParse);

Changes to src/main.c.

   232    232       assert(sizeof(x)==8);
   233    233       assert(sizeof(x)==sizeof(y));
   234    234       memcpy(&y, &x, 8);
   235    235       assert( sqlite3IsNaN(y) );
   236    236     }
   237    237   #endif
   238    238   #endif
          239  +
          240  +  /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT
          241  +  ** compile-time option.
          242  +  */
          243  +#ifdef SQLITE_EXTRA_INIT
          244  +  if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
          245  +    int SQLITE_EXTRA_INIT(void);
          246  +    rc = SQLITE_EXTRA_INIT();
          247  +  }
          248  +#endif
   239    249   
   240    250     return rc;
   241    251   }
   242    252   
   243    253   /*
   244    254   ** Undo the effects of sqlite3_initialize().  Must not be called while
   245    255   ** there are outstanding database connections or memory allocations or

Changes to src/os_unix.c.

   256    256   
   257    257   /*
   258    258   ** Allowed values for the unixFile.ctrlFlags bitmask:
   259    259   */
   260    260   #define UNIXFILE_EXCL        0x01     /* Connections from one process only */
   261    261   #define UNIXFILE_RDONLY      0x02     /* Connection is read only */
   262    262   #define UNIXFILE_PERSIST_WAL 0x04     /* Persistent WAL mode */
   263         -#define UNIXFILE_DIRSYNC     0x08     /* Directory sync needed */
          263  +#ifndef SQLITE_DISABLE_DIRSYNC
          264  +# define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
          265  +#else
          266  +# define UNIXFILE_DIRSYNC    0x00
          267  +#endif
   264    268   
   265    269   /*
   266    270   ** Include code that is common to all os_*.c files
   267    271   */
   268    272   #include "os_common.h"
   269    273   
   270    274   /*
................................................................................
  3735   3739         if( close(pFile->dirfd) ){
  3736   3740           pFile->lastErrno = errno;
  3737   3741           rc = SQLITE_IOERR_DIR_CLOSE;
  3738   3742         }
  3739   3743   #else
  3740   3744         robust_close(pFile, dirfd, __LINE__);
  3741   3745   #endif
         3746  +    }else if( rc==SQLITE_CANTOPEN ){
         3747  +      rc = SQLITE_OK;
  3742   3748       }
  3743   3749       pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
  3744   3750   
  3745   3751     }
  3746   3752     return rc;
  3747   3753   }
  3748   3754   
................................................................................
  5896   5902   #if OSCLOSE_CHECK_CLOSE_IOERR
  5897   5903         if( close(fd)&&!rc ){
  5898   5904           rc = SQLITE_IOERR_DIR_CLOSE;
  5899   5905         }
  5900   5906   #else
  5901   5907         robust_close(0, fd, __LINE__);
  5902   5908   #endif
         5909  +    }else if( rc==SQLITE_CANTOPEN ){
         5910  +      rc = SQLITE_OK;
  5903   5911       }
  5904   5912     }
  5905   5913   #endif
  5906   5914     return rc;
  5907   5915   }
  5908   5916   
  5909   5917   /*

Changes to src/os_win.c.

   115    115     HANDLE hMutex;          /* Mutex used to control access to shared lock */  
   116    116     HANDLE hShared;         /* Shared memory segment used for locking */
   117    117     winceLock local;        /* Locks obtained by this instance of winFile */
   118    118     winceLock *shared;      /* Global shared lock memory for the file  */
   119    119   #endif
   120    120   };
   121    121   
          122  +/*
          123  + * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
          124  + * various Win32 API heap functions instead of our own.
          125  + */
          126  +#ifdef SQLITE_WIN32_MALLOC
          127  +/*
          128  + * The initial size of the Win32-specific heap.  This value may be zero.
          129  + */
          130  +#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
          131  +#  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
          132  +                                       (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
          133  +#endif
          134  +
          135  +/*
          136  + * The maximum size of the Win32-specific heap.  This value may be zero.
          137  + */
          138  +#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
          139  +#  define SQLITE_WIN32_HEAP_MAX_SIZE  (0)
          140  +#endif
          141  +
          142  +/*
          143  + * The extra flags to use in calls to the Win32 heap APIs.  This value may be
          144  + * zero for the default behavior.
          145  + */
          146  +#ifndef SQLITE_WIN32_HEAP_FLAGS
          147  +#  define SQLITE_WIN32_HEAP_FLAGS     (0)
          148  +#endif
          149  +
          150  +/*
          151  +** The winMemData structure stores information required by the Win32-specific
          152  +** sqlite3_mem_methods implementation.
          153  +*/
          154  +typedef struct winMemData winMemData;
          155  +struct winMemData {
          156  +#ifndef NDEBUG
          157  +  u32 magic;    /* Magic number to detect structure corruption. */
          158  +#endif
          159  +  HANDLE hHeap; /* The handle to our heap. */
          160  +  BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
          161  +};
          162  +
          163  +#ifndef NDEBUG
          164  +#define WINMEM_MAGIC     0x42b2830b
          165  +#endif
          166  +
          167  +static struct winMemData win_mem_data = {
          168  +#ifndef NDEBUG
          169  +  WINMEM_MAGIC,
          170  +#endif
          171  +  NULL, FALSE
          172  +};
          173  +
          174  +#ifndef NDEBUG
          175  +#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
          176  +#else
          177  +#define winMemAssertMagic()
          178  +#endif
          179  +
          180  +#define winMemGetHeap() win_mem_data.hHeap
          181  +
          182  +static void *winMemMalloc(int nBytes);
          183  +static void winMemFree(void *pPrior);
          184  +static void *winMemRealloc(void *pPrior, int nBytes);
          185  +static int winMemSize(void *p);
          186  +static int winMemRoundup(int n);
          187  +static int winMemInit(void *pAppData);
          188  +static void winMemShutdown(void *pAppData);
          189  +
          190  +const sqlite3_mem_methods *sqlite3MemGetWin32(void);
          191  +#endif /* SQLITE_WIN32_MALLOC */
   122    192   
   123    193   /*
   124    194   ** Forward prototypes.
   125    195   */
   126    196   static int getSectorSize(
   127    197       sqlite3_vfs *pVfs,
   128    198       const char *zRelative     /* UTF-8 file name */
................................................................................
   167    237         GetVersionEx(&sInfo);
   168    238         sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
   169    239       }
   170    240       return sqlite3_os_type==2;
   171    241     }
   172    242   #endif /* SQLITE_OS_WINCE */
   173    243   
          244  +#ifdef SQLITE_WIN32_MALLOC
          245  +/*
          246  +** Allocate nBytes of memory.
          247  +*/
          248  +static void *winMemMalloc(int nBytes){
          249  +  HANDLE hHeap;
          250  +  void *p;
          251  +
          252  +  winMemAssertMagic();
          253  +  hHeap = winMemGetHeap();
          254  +  assert( hHeap!=0 );
          255  +  assert( hHeap!=INVALID_HANDLE_VALUE );
          256  +#ifdef SQLITE_WIN32_MALLOC_VALIDATE
          257  +  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          258  +#endif
          259  +  assert( nBytes>=0 );
          260  +  p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
          261  +  if( !p ){
          262  +    sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
          263  +        nBytes, GetLastError(), (void*)hHeap);
          264  +  }
          265  +  return p;
          266  +}
          267  +
          268  +/*
          269  +** Free memory.
          270  +*/
          271  +static void winMemFree(void *pPrior){
          272  +  HANDLE hHeap;
          273  +
          274  +  winMemAssertMagic();
          275  +  hHeap = winMemGetHeap();
          276  +  assert( hHeap!=0 );
          277  +  assert( hHeap!=INVALID_HANDLE_VALUE );
          278  +#ifdef SQLITE_WIN32_MALLOC_VALIDATE
          279  +  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
          280  +#endif
          281  +  if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
          282  +  if( !HeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
          283  +    sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
          284  +        pPrior, GetLastError(), (void*)hHeap);
          285  +  }
          286  +}
          287  +
          288  +/*
          289  +** Change the size of an existing memory allocation
          290  +*/
          291  +static void *winMemRealloc(void *pPrior, int nBytes){
          292  +  HANDLE hHeap;
          293  +  void *p;
          294  +
          295  +  winMemAssertMagic();
          296  +  hHeap = winMemGetHeap();
          297  +  assert( hHeap!=0 );
          298  +  assert( hHeap!=INVALID_HANDLE_VALUE );
          299  +#ifdef SQLITE_WIN32_MALLOC_VALIDATE
          300  +  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
          301  +#endif
          302  +  assert( nBytes>=0 );
          303  +  if( !pPrior ){
          304  +    p = HeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
          305  +  }else{
          306  +    p = HeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
          307  +  }
          308  +  if( !p ){
          309  +    sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
          310  +        pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, GetLastError(),
          311  +        (void*)hHeap);
          312  +  }
          313  +  return p;
          314  +}
          315  +
          316  +/*
          317  +** Return the size of an outstanding allocation, in bytes.
          318  +*/
          319  +static int winMemSize(void *p){
          320  +  HANDLE hHeap;
          321  +  SIZE_T n;
          322  +
          323  +  winMemAssertMagic();
          324  +  hHeap = winMemGetHeap();
          325  +  assert( hHeap!=0 );
          326  +  assert( hHeap!=INVALID_HANDLE_VALUE );
          327  +#ifdef SQLITE_WIN32_MALLOC_VALIDATE
          328  +  assert ( HeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          329  +#endif
          330  +  if( !p ) return 0;
          331  +  n = HeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
          332  +  if( n==(SIZE_T)-1 ){
          333  +    sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
          334  +        p, GetLastError(), (void*)hHeap);
          335  +    return 0;
          336  +  }
          337  +  return (int)n;
          338  +}
          339  +
          340  +/*
          341  +** Round up a request size to the next valid allocation size.
          342  +*/
          343  +static int winMemRoundup(int n){
          344  +  return n;
          345  +}
          346  +
          347  +/*
          348  +** Initialize this module.
          349  +*/
          350  +static int winMemInit(void *pAppData){
          351  +  winMemData *pWinMemData = (winMemData *)pAppData;
          352  +
          353  +  if( !pWinMemData ) return SQLITE_ERROR;
          354  +  assert( pWinMemData->magic==WINMEM_MAGIC );
          355  +  if( !pWinMemData->hHeap ){
          356  +    pWinMemData->hHeap = HeapCreate(SQLITE_WIN32_HEAP_FLAGS,
          357  +                                    SQLITE_WIN32_HEAP_INIT_SIZE,
          358  +                                    SQLITE_WIN32_HEAP_MAX_SIZE);
          359  +    if( !pWinMemData->hHeap ){
          360  +      sqlite3_log(SQLITE_NOMEM,
          361  +          "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
          362  +          GetLastError(), SQLITE_WIN32_HEAP_FLAGS, SQLITE_WIN32_HEAP_INIT_SIZE,
          363  +          SQLITE_WIN32_HEAP_MAX_SIZE);
          364  +      return SQLITE_NOMEM;
          365  +    }
          366  +    pWinMemData->bOwned = TRUE;
          367  +  }
          368  +  assert( pWinMemData->hHeap!=0 );
          369  +  assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
          370  +#ifdef SQLITE_WIN32_MALLOC_VALIDATE
          371  +  assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          372  +#endif
          373  +  return SQLITE_OK;
          374  +}
          375  +
          376  +/*
          377  +** Deinitialize this module.
          378  +*/
          379  +static void winMemShutdown(void *pAppData){
          380  +  winMemData *pWinMemData = (winMemData *)pAppData;
          381  +
          382  +  if( !pWinMemData ) return;
          383  +  if( pWinMemData->hHeap ){
          384  +    assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
          385  +#ifdef SQLITE_WIN32_MALLOC_VALIDATE
          386  +    assert( HeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
          387  +#endif
          388  +    if( pWinMemData->bOwned ){
          389  +      if( !HeapDestroy(pWinMemData->hHeap) ){
          390  +        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
          391  +            GetLastError(), (void*)pWinMemData->hHeap);
          392  +      }
          393  +      pWinMemData->bOwned = FALSE;
          394  +    }
          395  +    pWinMemData->hHeap = NULL;
          396  +  }
          397  +}
          398  +
          399  +/*
          400  +** Populate the low-level memory allocation function pointers in
          401  +** sqlite3GlobalConfig.m with pointers to the routines in this file. The
          402  +** arguments specify the block of memory to manage.
          403  +**
          404  +** This routine is only called by sqlite3_config(), and therefore
          405  +** is not required to be threadsafe (it is not).
          406  +*/
          407  +const sqlite3_mem_methods *sqlite3MemGetWin32(void){
          408  +  static const sqlite3_mem_methods winMemMethods = {
          409  +    winMemMalloc,
          410  +    winMemFree,
          411  +    winMemRealloc,
          412  +    winMemSize,
          413  +    winMemRoundup,
          414  +    winMemInit,
          415  +    winMemShutdown,
          416  +    &win_mem_data
          417  +  };
          418  +  return &winMemMethods;
          419  +}
          420  +
          421  +void sqlite3MemSetDefault(void){
          422  +  sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
          423  +}
          424  +#endif /* SQLITE_WIN32_MALLOC */
          425  +
   174    426   /*
   175    427   ** Convert a UTF-8 string to microsoft unicode (UTF-16?). 
   176    428   **
   177    429   ** Space to hold the returned string is obtained from malloc.
   178    430   */
   179    431   static WCHAR *utf8ToUnicode(const char *zFilename){
   180    432     int nChar;
................................................................................
  1347   1599         return SQLITE_OK;
  1348   1600       }
  1349   1601       case SQLITE_FCNTL_CHUNK_SIZE: {
  1350   1602         pFile->szChunk = *(int *)pArg;
  1351   1603         return SQLITE_OK;
  1352   1604       }
  1353   1605       case SQLITE_FCNTL_SIZE_HINT: {
  1354         -      sqlite3_int64 sz = *(sqlite3_int64*)pArg;
  1355         -      SimulateIOErrorBenign(1);
  1356         -      winTruncate(id, sz);
  1357         -      SimulateIOErrorBenign(0);
  1358         -      return SQLITE_OK;
         1606  +      winFile *pFile = (winFile*)id;
         1607  +      sqlite3_int64 oldSz;
         1608  +      int rc = winFileSize(id, &oldSz);
         1609  +      if( rc==SQLITE_OK ){
         1610  +        sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
         1611  +        if( newSz>oldSz ){
         1612  +          SimulateIOErrorBenign(1);
         1613  +          rc = winTruncate(id, newSz);
         1614  +          SimulateIOErrorBenign(0);
         1615  +        }
         1616  +      }
         1617  +      return rc;
  1359   1618       }
  1360   1619       case SQLITE_FCNTL_PERSIST_WAL: {
  1361   1620         int bPersist = *(int*)pArg;
  1362   1621         if( bPersist<0 ){
  1363   1622           *(int*)pArg = pFile->bPersistWal;
  1364   1623         }else{
  1365   1624           pFile->bPersistWal = bPersist!=0;

Changes to src/pager.c.

   616    616     u8 noSync;                  /* Do not sync the journal if true */
   617    617     u8 fullSync;                /* Do extra syncs of the journal for robustness */
   618    618     u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
   619    619     u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
   620    620     u8 tempFile;                /* zFilename is a temporary file */
   621    621     u8 readOnly;                /* True for a read-only database */
   622    622     u8 memDb;                   /* True to inhibit all file I/O */
          623  +  u8 hasSeenStress;           /* pagerStress() called one or more times */
          624  +  u8 isSorter;                /* True for a PAGER_SORTER */
   623    625   
   624    626     /**************************************************************************
   625    627     ** The following block contains those class members that change during
   626    628     ** routine opertion.  Class members not in this block are either fixed
   627    629     ** when the pager is first created or else only change when there is a
   628    630     ** significant mode change (such as changing the page_size, locking_mode,
   629    631     ** or the journal_mode).  From another view, these class members describe
................................................................................
   838    840       assert( p->noSync );
   839    841       assert( p->journalMode==PAGER_JOURNALMODE_OFF 
   840    842            || p->journalMode==PAGER_JOURNALMODE_MEMORY 
   841    843       );
   842    844       assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
   843    845       assert( pagerUseWal(p)==0 );
   844    846     }
          847  +
          848  +  /* A sorter is a temp file that never spills to disk and always has
          849  +  ** the doNotSpill flag set
          850  +  */
          851  +  if( p->isSorter ){
          852  +    assert( p->tempFile );
          853  +    assert( p->doNotSpill );
          854  +    assert( p->fd->pMethods==0 );
          855  +  }
   845    856   
   846    857     /* If changeCountDone is set, a RESERVED lock or greater must be held
   847    858     ** on the file.
   848    859     */
   849    860     assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
   850    861     assert( p->eLock!=PENDING_LOCK );
   851    862   
................................................................................
  3747   3758   ** is made to roll it back. If an error occurs during the rollback 
  3748   3759   ** a hot journal may be left in the filesystem but no error is returned
  3749   3760   ** to the caller.
  3750   3761   */
  3751   3762   int sqlite3PagerClose(Pager *pPager){
  3752   3763     u8 *pTmp = (u8 *)pPager->pTmpSpace;
  3753   3764   
         3765  +  assert( assert_pager_state(pPager) );
  3754   3766     disable_simulated_io_errors();
  3755   3767     sqlite3BeginBenignMalloc();
  3756   3768     /* pPager->errCode = 0; */
  3757   3769     pPager->exclusiveMode = 0;
  3758   3770   #ifndef SQLITE_OMIT_WAL
  3759   3771     sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
  3760   3772     pPager->pWal = 0;
................................................................................
  4181   4193     ** Spilling is also prohibited when in an error state since that could
  4182   4194     ** lead to database corruption.   In the current implementaton it 
  4183   4195     ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1
  4184   4196     ** while in the error state, hence it is impossible for this routine to
  4185   4197     ** be called in the error state.  Nevertheless, we include a NEVER()
  4186   4198     ** test for the error state as a safeguard against future changes.
  4187   4199     */
         4200  +  pPager->hasSeenStress = 1;
  4188   4201     if( NEVER(pPager->errCode) ) return SQLITE_OK;
  4189   4202     if( pPager->doNotSpill ) return SQLITE_OK;
  4190   4203     if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
  4191   4204       return SQLITE_OK;
  4192   4205     }
  4193   4206   
  4194   4207     pPg->pDirty = 0;
................................................................................
  4556   4569     }else if( memDb ){
  4557   4570       pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
  4558   4571     }
  4559   4572     /* pPager->xBusyHandler = 0; */
  4560   4573     /* pPager->pBusyHandlerArg = 0; */
  4561   4574     pPager->xReiniter = xReinit;
  4562   4575     /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
         4576  +#ifndef SQLITE_OMIT_MERGE_SORT
         4577  +  if( flags & PAGER_SORTER ){
         4578  +    pPager->doNotSpill = 1;
         4579  +    pPager->isSorter = 1;
         4580  +  }
         4581  +#endif
  4563   4582   
  4564   4583     *ppPager = pPager;
  4565   4584     return SQLITE_OK;
  4566   4585   }
  4567   4586   
  4568   4587   
  4569   4588   
................................................................................
  6110   6129   
  6111   6130   /*
  6112   6131   ** Return true if this is an in-memory pager.
  6113   6132   */
  6114   6133   int sqlite3PagerIsMemdb(Pager *pPager){
  6115   6134     return MEMDB;
  6116   6135   }
         6136  +
         6137  +#ifndef SQLITE_OMIT_MERGE_SORT
         6138  +/*
         6139  +** Return true if the pager has seen a pagerStress callback.
         6140  +*/
         6141  +int sqlite3PagerUnderStress(Pager *pPager){
         6142  +  assert( pPager->isSorter );
         6143  +  assert( pPager->doNotSpill );
         6144  +  return pPager->hasSeenStress;
         6145  +}
         6146  +#endif
  6117   6147   
  6118   6148   /*
  6119   6149   ** Check that there are at least nSavepoint savepoints open. If there are
  6120   6150   ** currently less than nSavepoints open, then open one or more savepoints
  6121   6151   ** to make up the difference. If the number of savepoints is already
  6122   6152   ** equal to nSavepoint, then this function is a no-op.
  6123   6153   **

Changes to src/pager.h.

    56     56   ** Allowed values for the flags parameter to sqlite3PagerOpen().
    57     57   **
    58     58   ** NOTE: These values must match the corresponding BTREE_ values in btree.h.
    59     59   */
    60     60   #define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
    61     61   #define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */
    62     62   #define PAGER_MEMORY        0x0004    /* In-memory database */
           63  +#define PAGER_SORTER        0x0020    /* Accumulator in external merge sort */
    63     64   
    64     65   /*
    65     66   ** Valid values for the second argument to sqlite3PagerLockingMode().
    66     67   */
    67     68   #define PAGER_LOCKINGMODE_QUERY      -1
    68     69   #define PAGER_LOCKINGMODE_NORMAL      0
    69     70   #define PAGER_LOCKINGMODE_EXCLUSIVE   1
................................................................................
   151    152   const char *sqlite3PagerFilename(Pager*);
   152    153   const sqlite3_vfs *sqlite3PagerVfs(Pager*);
   153    154   sqlite3_file *sqlite3PagerFile(Pager*);
   154    155   const char *sqlite3PagerJournalname(Pager*);
   155    156   int sqlite3PagerNosync(Pager*);
   156    157   void *sqlite3PagerTempSpace(Pager*);
   157    158   int sqlite3PagerIsMemdb(Pager*);
          159  +#ifndef SQLITE_OMIT_MERGE_SORT
          160  +int sqlite3PagerUnderStress(Pager*);
          161  +#endif
   158    162   
   159    163   /* Functions used to truncate the database file. */
   160    164   void sqlite3PagerTruncateImage(Pager*,Pgno);
   161    165   
   162    166   #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
   163    167   void *sqlite3PagerCodec(DbPage *);
   164    168   #endif

Changes to src/pcache1.c.

    52     52   struct PGroup {
    53     53     sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
    54     54     int nMaxPage;                  /* Sum of nMax for purgeable caches */
    55     55     int nMinPage;                  /* Sum of nMin for purgeable caches */
    56     56     int mxPinned;                  /* nMaxpage + 10 - nMinPage */
    57     57     int nCurrentPage;              /* Number of purgeable pages allocated */
    58     58     PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
           59  +#ifdef SQLITE_PAGECACHE_BLOCKALLOC
           60  +  int isBusy;                    /* Do not run ReleaseMemory() if true */
    59     61     PGroupBlockList *pBlockList;   /* List of block-lists for this group */
           62  +#endif
    60     63   };
    61     64   
    62     65   /*
    63     66   ** If SQLITE_PAGECACHE_BLOCKALLOC is defined when the library is built,
    64     67   ** each PGroup structure has a linked list of the the following starting
    65     68   ** at PGroup.pBlockList. There is one entry for each distinct page-size 
    66     69   ** currently used by members of the PGroup (i.e. 1024 bytes, 4096 bytes
................................................................................
   397    400     PGroupBlockList *pList;
   398    401     PGroupBlock *pBlock;
   399    402     int i;
   400    403   
   401    404     nByte += sizeof(PGroupBlockList *);
   402    405     nByte = ROUND8(nByte);
   403    406   
   404         -  do{
          407  +  for(pList=pGroup->pBlockList; pList; pList=pList->pNext){
          408  +    if( pList->nByte==nByte ) break;
          409  +  }
          410  +  if( pList==0 ){
          411  +    PGroupBlockList *pNew;
          412  +    assert( pGroup->isBusy==0 );
          413  +    assert( sqlite3_mutex_held(pGroup->mutex) );
          414  +    pGroup->isBusy = 1;  /* Disable sqlite3PcacheReleaseMemory() */
          415  +    pNew = (PGroupBlockList *)sqlite3MallocZero(sizeof(PGroupBlockList));
          416  +    pGroup->isBusy = 0;  /* Reenable sqlite3PcacheReleaseMemory() */
          417  +    if( pNew==0 ){
          418  +      /* malloc() failure. Return early. */
          419  +      return 0;
          420  +    }
          421  +#ifdef SQLITE_DEBUG
   405    422       for(pList=pGroup->pBlockList; pList; pList=pList->pNext){
   406         -      if( pList->nByte==nByte ) break;
          423  +      assert( pList->nByte!=nByte );
   407    424       }
   408         -    if( pList==0 ){
   409         -      PGroupBlockList *pNew;
   410         -      pcache1LeaveMutex(pCache->pGroup);
   411         -      pNew = (PGroupBlockList *)sqlite3MallocZero(sizeof(PGroupBlockList));
   412         -      pcache1EnterMutex(pCache->pGroup);
   413         -      if( pNew==0 ){
   414         -        /* malloc() failure. Return early. */
   415         -        return 0;
   416         -      }
   417         -      for(pList=pGroup->pBlockList; pList; pList=pList->pNext){
   418         -        if( pList->nByte==nByte ) break;
   419         -      }
   420         -      if( pList ){
   421         -        sqlite3_free(pNew);
   422         -      }else{
   423         -        pNew->nByte = nByte;
   424         -        pNew->pNext = pGroup->pBlockList;
   425         -        pGroup->pBlockList = pNew;
   426         -        pList = pNew;
   427         -      }
   428         -    }
   429         -  }while( pList==0 );
          425  +#endif
          426  +    pNew->nByte = nByte;
          427  +    pNew->pNext = pGroup->pBlockList;
          428  +    pGroup->pBlockList = pNew;
          429  +    pList = pNew;
          430  +  }
   430    431   
   431    432     pBlock = pList->pFirst;
   432    433     if( pBlock==0 || pBlock->mUsed==(((Bitmask)1<<pBlock->nEntry)-1) ){
   433    434       int sz;
   434    435   
   435    436       /* Allocate a new block. Try to allocate enough space for the PGroupBlock
   436    437       ** structure and MINENTRY allocations of nByte bytes each. If the 
   437    438       ** allocator returns more memory than requested, then more than MINENTRY 
   438    439       ** allocations may fit in it. */
          440  +    assert( sqlite3_mutex_held(pGroup->mutex) );
   439    441       pcache1LeaveMutex(pCache->pGroup);
   440    442       sz = sizeof(PGroupBlock) + PAGECACHE_BLOCKALLOC_MINENTRY * nByte;
   441    443       pBlock = (PGroupBlock *)sqlite3Malloc(sz);
   442    444       pcache1EnterMutex(pCache->pGroup);
   443    445   
   444    446       if( !pBlock ){
   445    447         freeListIfEmpty(pGroup, pList);
................................................................................
   477    479       pList->pFirst = pBlock->pNext;
   478    480       pList->pFirst->pPrev = 0;
   479    481       pBlock->pPrev = pList->pLast;
   480    482       pBlock->pNext = 0;
   481    483       pList->pLast->pNext = pBlock;
   482    484       pList->pLast = pBlock;
   483    485     }
          486  +  p = PAGE_TO_PGHDR1(pCache, pPg);
          487  +  if( pCache->bPurgeable ){
          488  +    pCache->pGroup->nCurrentPage++;
          489  +  }
   484    490   #else
   485    491     /* The group mutex must be released before pcache1Alloc() is called. This
   486    492     ** is because it may call sqlite3_release_memory(), which assumes that 
   487    493     ** this mutex is not held. */
   488    494     assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
   489    495     pcache1LeaveMutex(pCache->pGroup);
   490    496     pPg = pcache1Alloc(nByte);
   491    497     pcache1EnterMutex(pCache->pGroup);
   492         -#endif
   493         -
   494    498     if( pPg ){
   495    499       p = PAGE_TO_PGHDR1(pCache, pPg);
   496    500       if( pCache->bPurgeable ){
   497    501         pCache->pGroup->nCurrentPage++;
   498    502       }
   499    503     }else{
   500    504       p = 0;
   501    505     }
          506  +#endif
   502    507     return p;
   503    508   }
   504    509   
   505    510   /*
   506    511   ** Free a page object allocated by pcache1AllocPage().
   507    512   **
   508    513   ** The pointer is allowed to be NULL, which is prudent.  But it turns out
................................................................................
  1161   1166   **
  1162   1167   ** nReq is the number of bytes of memory required. Once this much has
  1163   1168   ** been released, the function returns. The return value is the total number 
  1164   1169   ** of bytes of memory released.
  1165   1170   */
  1166   1171   int sqlite3PcacheReleaseMemory(int nReq){
  1167   1172     int nFree = 0;
         1173  +#ifdef SQLITE_PAGECACHE_BLOCKALLOC
         1174  +  if( pcache1.grp.isBusy ) return 0;
         1175  +#endif
  1168   1176     assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
  1169   1177     assert( sqlite3_mutex_notheld(pcache1.mutex) );
  1170   1178     if( pcache1.pStart==0 ){
  1171   1179       PgHdr1 *p;
  1172   1180       pcache1EnterMutex(&pcache1.grp);
  1173   1181       while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
  1174   1182         nFree += pcache1MemSize(PGHDR1_TO_PAGE(p));

Changes to src/sqlite.h.in.

  1202   1202   ** and that this object is only useful to a tiny minority of applications
  1203   1203   ** with specialized memory allocation requirements.  This object is
  1204   1204   ** also used during testing of SQLite in order to specify an alternative
  1205   1205   ** memory allocator that simulates memory out-of-memory conditions in
  1206   1206   ** order to verify that SQLite recovers gracefully from such
  1207   1207   ** conditions.
  1208   1208   **
  1209         -** The xMalloc and xFree methods must work like the
  1210         -** malloc() and free() functions from the standard C library.
  1211         -** The xRealloc method must work like realloc() from the standard C library
  1212         -** with the exception that if the second argument to xRealloc is zero,
  1213         -** xRealloc must be a no-op - it must not perform any allocation or
  1214         -** deallocation.  ^SQLite guarantees that the second argument to
         1209  +** The xMalloc, xRealloc, and xFree methods must work like the
         1210  +** malloc(), realloc() and free() functions from the standard C library.
         1211  +** ^SQLite guarantees that the second argument to
  1215   1212   ** xRealloc is always a value returned by a prior call to xRoundup.
  1216         -** And so in cases where xRoundup always returns a positive number,
  1217         -** xRealloc can perform exactly as the standard library realloc() and
  1218         -** still be in compliance with this specification.
  1219   1213   **
  1220   1214   ** xSize should return the allocated size of a memory allocation
  1221   1215   ** previously obtained from xMalloc or xRealloc.  The allocated size
  1222   1216   ** is always at least as big as the requested size but may be larger.
  1223   1217   **
  1224   1218   ** The xRoundup method returns what would be the allocated size of
  1225   1219   ** a memory allocation given a particular requested size.  Most memory

Changes to src/sqliteInt.h.

   143    143   #endif
   144    144   
   145    145   /*
   146    146   ** Exactly one of the following macros must be defined in order to
   147    147   ** specify which memory allocation subsystem to use.
   148    148   **
   149    149   **     SQLITE_SYSTEM_MALLOC          // Use normal system malloc()
          150  +**     SQLITE_WIN32_MALLOC           // Use Win32 native heap API
   150    151   **     SQLITE_MEMDEBUG               // Debugging version of system malloc()
          152  +**
          153  +** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
          154  +** assert() macro is enabled, each call into the Win32 native heap subsystem
          155  +** will cause HeapValidate to be called.  If heap validation should fail, an
          156  +** assertion will be triggered.
   151    157   **
   152    158   ** (Historical note:  There used to be several other options, but we've
   153    159   ** pared it down to just these two.)
   154    160   **
   155    161   ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
   156    162   ** the default.
   157    163   */
   158         -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)>1
          164  +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
   159    165   # error "At most one of the following compile-time configuration options\
   160         - is allows: SQLITE_SYSTEM_MALLOC, SQLITE_MEMDEBUG"
          166  + is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG"
   161    167   #endif
   162         -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)==0
          168  +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0
   163    169   # define SQLITE_SYSTEM_MALLOC 1
   164    170   #endif
   165    171   
   166    172   /*
   167    173   ** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
   168    174   ** sizes of memory allocations below this value where possible.
   169    175   */
................................................................................
   362    368   ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
   363    369   ** on the command-line
   364    370   */
   365    371   #ifndef SQLITE_TEMP_STORE
   366    372   # define SQLITE_TEMP_STORE 1
   367    373   #endif
   368    374   
          375  +/*
          376  +** If all temporary storage is in-memory, then omit the external merge-sort
          377  +** logic since it is superfluous.
          378  +*/
          379  +#if SQLITE_TEMP_STORE==3 && !defined(SQLITE_OMIT_MERGE_SORT)
          380  +# define SQLITE_OMIT_MERGE_SORT
          381  +#endif
          382  +
   369    383   /*
   370    384   ** GCC does not define the offsetof() macro so we'll have to do it
   371    385   ** ourselves.
   372    386   */
   373    387   #ifndef offsetof
   374    388   #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
   375    389   #endif

Changes to src/test6.c.

   505    505     return sqlite3OsCheckReservedLock(((CrashFile *)pFile)->pRealFile, pResOut);
   506    506   }
   507    507   static int cfFileControl(sqlite3_file *pFile, int op, void *pArg){
   508    508     if( op==SQLITE_FCNTL_SIZE_HINT ){
   509    509       CrashFile *pCrash = (CrashFile *)pFile;
   510    510       i64 nByte = *(i64 *)pArg;
   511    511       if( nByte>pCrash->iSize ){
   512         -      return cfWrite(pFile, "", 1, nByte-1);
          512  +      if( SQLITE_OK==writeListAppend(pFile, nByte, 0, 0) ){
          513  +        pCrash->iSize = nByte;
          514  +      }
   513    515       }
          516  +    return SQLITE_OK;
   514    517     }
   515    518     return sqlite3OsFileControl(((CrashFile *)pFile)->pRealFile, op, pArg);
   516    519   }
   517    520   
   518    521   /*
   519    522   ** The xSectorSize() and xDeviceCharacteristics() functions return
   520    523   ** the global values configured by the [sqlite_crashparams] tcl

Changes to src/test_malloc.c.

  1218   1218     Tcl_Obj *CONST objv[]
  1219   1219   ){
  1220   1220     if( objc!=2 ){
  1221   1221       Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
  1222   1222       return TCL_ERROR;
  1223   1223     }
  1224   1224   
  1225         -  switch( (int)clientData ){
         1225  +  switch( SQLITE_PTR_TO_INT(clientData) ){
  1226   1226       case 3: {
  1227   1227   #ifdef SQLITE_ENABLE_MEMSYS3
  1228   1228         extern void sqlite3Memsys3Dump(const char*);
  1229   1229         sqlite3Memsys3Dump(Tcl_GetString(objv[1]));
  1230   1230         break;
  1231   1231   #endif
  1232   1232       }
................................................................................
  1456   1456        { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
  1457   1457        { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 },
  1458   1458        { "sqlite3_install_memsys3",    test_install_memsys3          ,0 },
  1459   1459        { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test          ,0 },
  1460   1460     };
  1461   1461     int i;
  1462   1462     for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
  1463         -    ClientData c = (ClientData)aObjCmd[i].clientData;
         1463  +    ClientData c = (ClientData)SQLITE_INT_TO_PTR(aObjCmd[i].clientData);
  1464   1464       Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
  1465   1465     }
  1466   1466     return TCL_OK;
  1467   1467   }
  1468   1468   #endif

Changes to src/test_quota.c.

    91     91   ** to the same file each point to a single instance of this object.
    92     92   */
    93     93   struct quotaFile {
    94     94     char *zFilename;                /* Name of this file */
    95     95     quotaGroup *pGroup;             /* Quota group to which this file belongs */
    96     96     sqlite3_int64 iSize;            /* Current size of this file */
    97     97     int nRef;                       /* Number of times this file is open */
           98  +  int deleteOnClose;              /* True to delete this file when it closes */
    98     99     quotaFile *pNext, **ppPrev;     /* Linked list of files in the same group */
    99    100   };
   100    101   
   101    102   /*
   102    103   ** An instance of the following object represents each open connection
   103    104   ** to a file that participates in quota tracking.  This object is a 
   104    105   ** subclass of sqlite3_file.  The sqlite3_file object for the underlying
................................................................................
   160    161   /*
   161    162   ** Acquire and release the mutex used to serialize access to the
   162    163   ** list of quotaGroups.
   163    164   */
   164    165   static void quotaEnter(void){ sqlite3_mutex_enter(gQuota.pMutex); }
   165    166   static void quotaLeave(void){ sqlite3_mutex_leave(gQuota.pMutex); }
   166    167   
          168  +/* Count the number of open files in a quotaGroup 
          169  +*/
          170  +static int quotaGroupOpenFileCount(quotaGroup *pGroup){
          171  +  int N = 0;
          172  +  quotaFile *pFile = pGroup->pFiles;
          173  +  while( pFile ){
          174  +    if( pFile->nRef ) N++;
          175  +    pFile = pFile->pNext;
          176  +  }
          177  +  return N;
          178  +}
          179  +
          180  +/* Remove a file from a quota group.
          181  +*/
          182  +static void quotaRemoveFile(quotaFile *pFile){
          183  +  quotaGroup *pGroup = pFile->pGroup;
          184  +  pGroup->iSize -= pFile->iSize;
          185  +  *pFile->ppPrev = pFile->pNext;
          186  +  if( pFile->pNext ) pFile->pNext->ppPrev = pFile->ppPrev;
          187  +  sqlite3_free(pFile);
          188  +}
          189  +
          190  +/* Remove all files from a quota group.  It is always the case that
          191  +** all files will be closed when this routine is called.
          192  +*/
          193  +static void quotaRemoveAllFiles(quotaGroup *pGroup){
          194  +  while( pGroup->pFiles ){
          195  +    assert( pGroup->pFiles->nRef==0 );
          196  +    quotaRemoveFile(pGroup->pFiles);
          197  +  }
          198  +}
          199  +
   167    200   
   168    201   /* If the reference count and threshold for a quotaGroup are both
   169    202   ** zero, then destroy the quotaGroup.
   170    203   */
   171    204   static void quotaGroupDeref(quotaGroup *pGroup){
   172         -  if( pGroup->pFiles==0 && pGroup->iLimit==0 ){
          205  +  if( pGroup->iLimit==0 && quotaGroupOpenFileCount(pGroup)==0 ){
          206  +    quotaRemoveAllFiles(pGroup);
   173    207       *pGroup->ppPrev = pGroup->pNext;
   174    208       if( pGroup->pNext ) pGroup->pNext->ppPrev = pGroup->ppPrev;
   175    209       if( pGroup->xDestroy ) pGroup->xDestroy(pGroup->pArg);
   176    210       sqlite3_free(pGroup);
   177    211     }
   178    212   }
   179    213   
................................................................................
   271    305   /* Translate an sqlite3_file* that is really a quotaConn* into
   272    306   ** the sqlite3_file* for the underlying original VFS.
   273    307   */
   274    308   static sqlite3_file *quotaSubOpen(sqlite3_file *pConn){
   275    309     quotaConn *p = (quotaConn*)pConn;
   276    310     return (sqlite3_file*)&p[1];
   277    311   }
          312  +
          313  +/* Find a file in a quota group and return a pointer to that file.
          314  +** Return NULL if the file is not in the group.
          315  +*/
          316  +static quotaFile *quotaFindFile(quotaGroup *pGroup, const char *zName){
          317  +  quotaFile *pFile = pGroup->pFiles;
          318  +  while( pFile && strcmp(pFile->zFilename, zName)!=0 ){
          319  +    pFile = pFile->pNext;
          320  +  }
          321  +  return pFile;
          322  +}
   278    323   
   279    324   /************************* VFS Method Wrappers *****************************/
   280    325   /*
   281    326   ** This is the xOpen method used for the "quota" VFS.
   282    327   **
   283    328   ** Most of the work is done by the underlying original VFS.  This method
   284    329   ** simply links the new file into the appropriate quota group if it is a
................................................................................
   315    360     }else{
   316    361       /* If we get to this point, it means the file needs to be quota tracked.
   317    362       */
   318    363       pQuotaOpen = (quotaConn*)pConn;
   319    364       pSubOpen = quotaSubOpen(pConn);
   320    365       rc = pOrigVfs->xOpen(pOrigVfs, zName, pSubOpen, flags, pOutFlags);
   321    366       if( rc==SQLITE_OK ){
   322         -      for(pFile=pGroup->pFiles; pFile && strcmp(pFile->zFilename, zName);
   323         -          pFile=pFile->pNext){}
          367  +      pFile = quotaFindFile(pGroup, zName);
   324    368         if( pFile==0 ){
   325    369           int nName = strlen(zName);
   326    370           pFile = (quotaFile *)sqlite3_malloc( sizeof(*pFile) + nName + 1 );
   327    371           if( pFile==0 ){
   328    372             quotaLeave();
   329    373             pSubOpen->pMethods->xClose(pSubOpen);
   330    374             return SQLITE_NOMEM;
................................................................................
   333    377           pFile->zFilename = (char*)&pFile[1];
   334    378           memcpy(pFile->zFilename, zName, nName+1);
   335    379           pFile->pNext = pGroup->pFiles;
   336    380           if( pGroup->pFiles ) pGroup->pFiles->ppPrev = &pFile->pNext;
   337    381           pFile->ppPrev = &pGroup->pFiles;
   338    382           pGroup->pFiles = pFile;
   339    383           pFile->pGroup = pGroup;
          384  +        pFile->deleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE)!=0;
   340    385         }
   341    386         pFile->nRef++;
   342    387         pQuotaOpen->pFile = pFile;
   343    388         if( pSubOpen->pMethods->iVersion==1 ){
   344    389           pQuotaOpen->base.pMethods = &gQuota.sIoMethodsV1;
   345    390         }else{
   346    391           pQuotaOpen->base.pMethods = &gQuota.sIoMethodsV2;
   347    392         }
   348    393       }
   349    394     }
   350    395     quotaLeave();
   351    396     return rc;
   352    397   }
          398  +
          399  +/*
          400  +** This is the xDelete method used for the "quota" VFS.
          401  +**
          402  +** If the file being deleted is part of the quota group, then reduce
          403  +** the size of the quota group accordingly.  And remove the file from
          404  +** the set of files in the quota group.
          405  +*/
          406  +static int quotaDelete(
          407  +  sqlite3_vfs *pVfs,          /* The quota VFS */
          408  +  const char *zName,          /* Name of file to be deleted */
          409  +  int syncDir                 /* Do a directory sync after deleting */
          410  +){
          411  +  int rc;                                    /* Result code */         
          412  +  quotaFile *pFile;                          /* Files in the quota */
          413  +  quotaGroup *pGroup;                        /* The group file belongs to */
          414  +  sqlite3_vfs *pOrigVfs = gQuota.pOrigVfs;   /* Real VFS */
          415  +
          416  +  /* Do the actual file delete */
          417  +  rc = pOrigVfs->xDelete(pOrigVfs, zName, syncDir);
          418  +
          419  +  /* If the file just deleted is a member of a quota group, then remove
          420  +  ** it from that quota group.
          421  +  */
          422  +  if( rc==SQLITE_OK ){
          423  +    quotaEnter();
          424  +    pGroup = quotaGroupFind(zName);
          425  +    if( pGroup ){
          426  +      pFile = quotaFindFile(pGroup, zName);
          427  +      if( pFile ){
          428  +        if( pFile->nRef ){
          429  +          pFile->deleteOnClose = 1;
          430  +        }else{
          431  +          quotaRemoveFile(pFile);
          432  +          quotaGroupDeref(pGroup);
          433  +        }
          434  +      }
          435  +    }
          436  +    quotaLeave();
          437  +  }
          438  +  return rc;
          439  +}
          440  +
   353    441   
   354    442   /************************ I/O Method Wrappers *******************************/
   355    443   
   356    444   /* xClose requests get passed through to the original VFS.  But we
   357    445   ** also have to unlink the quotaConn from the quotaFile and quotaGroup.
   358    446   ** The quotaFile and/or quotaGroup are freed if they are no longer in use.
   359    447   */
................................................................................
   363    451     sqlite3_file *pSubOpen = quotaSubOpen(pConn);
   364    452     int rc;
   365    453     rc = pSubOpen->pMethods->xClose(pSubOpen);
   366    454     quotaEnter();
   367    455     pFile->nRef--;
   368    456     if( pFile->nRef==0 ){
   369    457       quotaGroup *pGroup = pFile->pGroup;
   370         -    pGroup->iSize -= pFile->iSize;
   371         -    if( pFile->pNext ) pFile->pNext->ppPrev = pFile->ppPrev;
   372         -    *pFile->ppPrev = pFile->pNext;
          458  +    if( pFile->deleteOnClose ) quotaRemoveFile(pFile);
   373    459       quotaGroupDeref(pGroup);
   374         -    sqlite3_free(pFile);
   375    460     }
   376    461     quotaLeave();
   377    462     return rc;
   378    463   }
   379    464   
   380    465   /* Pass xRead requests directory thru to the original VFS without
   381    466   ** further processing.
................................................................................
   582    667     if( !gQuota.pMutex ){
   583    668       return SQLITE_NOMEM;
   584    669     }
   585    670     gQuota.isInitialized = 1;
   586    671     gQuota.pOrigVfs = pOrigVfs;
   587    672     gQuota.sThisVfs = *pOrigVfs;
   588    673     gQuota.sThisVfs.xOpen = quotaOpen;
          674  +  gQuota.sThisVfs.xDelete = quotaDelete;
   589    675     gQuota.sThisVfs.szOsFile += sizeof(quotaConn);
   590    676     gQuota.sThisVfs.zName = "quota";
   591    677     gQuota.sIoMethodsV1.iVersion = 1;
   592    678     gQuota.sIoMethodsV1.xClose = quotaClose;
   593    679     gQuota.sIoMethodsV1.xRead = quotaRead;
   594    680     gQuota.sIoMethodsV1.xWrite = quotaWrite;
   595    681     gQuota.sIoMethodsV1.xTruncate = quotaTruncate;
................................................................................
   613    699   
   614    700   /*
   615    701   ** Shutdown the quota system.
   616    702   **
   617    703   ** All SQLite database connections must be closed before calling this
   618    704   ** routine.
   619    705   **
   620         -** THIS ROUTINE IS NOT THREADSAFE.  Call this routine exactly one while
          706  +** THIS ROUTINE IS NOT THREADSAFE.  Call this routine exactly once while
   621    707   ** shutting down in order to free all remaining quota groups.
   622    708   */
   623    709   int sqlite3_quota_shutdown(void){
   624    710     quotaGroup *pGroup;
   625    711     if( gQuota.isInitialized==0 ) return SQLITE_MISUSE;
   626    712     for(pGroup=gQuota.pGroup; pGroup; pGroup=pGroup->pNext){
   627         -    if( pGroup->pFiles ) return SQLITE_MISUSE;
          713  +    if( quotaGroupOpenFileCount(pGroup)>0 ) return SQLITE_MISUSE;
   628    714     }
   629    715     while( gQuota.pGroup ){
   630    716       pGroup = gQuota.pGroup;
   631    717       gQuota.pGroup = pGroup->pNext;
   632    718       pGroup->iLimit = 0;
          719  +    assert( quotaGroupOpenFileCount(pGroup)==0 );
   633    720       quotaGroupDeref(pGroup);
   634    721     }
   635    722     gQuota.isInitialized = 0;
   636    723     sqlite3_mutex_free(gQuota.pMutex);
   637    724     sqlite3_vfs_unregister(&gQuota.sThisVfs);
   638    725     memset(&gQuota, 0, sizeof(gQuota));
   639    726     return SQLITE_OK;
................................................................................
   703    790     }
   704    791     pGroup->pArg = pArg;
   705    792     pGroup->xDestroy = xDestroy;
   706    793     quotaGroupDeref(pGroup);
   707    794     quotaLeave();
   708    795     return SQLITE_OK;
   709    796   }
          797  +
          798  +/*
          799  +** Bring the named file under quota management.  Or if it is already under
          800  +** management, update its size.
          801  +*/
          802  +int sqlite3_quota_file(const char *zFilename){
          803  +  char *zFull;
          804  +  sqlite3_file *fd;
          805  +  int rc;
          806  +  int outFlags = 0;
          807  +  sqlite3_int64 iSize;
          808  +  fd = sqlite3_malloc(gQuota.sThisVfs.szOsFile + gQuota.sThisVfs.mxPathname+1);
          809  +  if( fd==0 ) return SQLITE_NOMEM;
          810  +  zFull = gQuota.sThisVfs.szOsFile + (char*)fd;
          811  +  rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename,
          812  +                                      gQuota.sThisVfs.mxPathname+1, zFull);
          813  +  if( rc==SQLITE_OK ){
          814  +    rc = quotaOpen(&gQuota.sThisVfs, zFull, fd, 
          815  +                   SQLITE_OPEN_READONLY | SQLITE_OPEN_MAIN_DB, &outFlags);
          816  +  }
          817  +  if( rc==SQLITE_OK ){
          818  +    fd->pMethods->xFileSize(fd, &iSize);
          819  +    fd->pMethods->xClose(fd);
          820  +  }else if( rc==SQLITE_CANTOPEN ){
          821  +    quotaGroup *pGroup;
          822  +    quotaFile *pFile;
          823  +    quotaEnter();
          824  +    pGroup = quotaGroupFind(zFull);
          825  +    if( pGroup ){
          826  +      pFile = quotaFindFile(pGroup, zFull);
          827  +      if( pFile ) quotaRemoveFile(pFile);
          828  +    }
          829  +    quotaLeave();
          830  +  }
          831  +  sqlite3_free(fd);
          832  +  return rc;
          833  +}
   710    834   
   711    835     
   712    836   /***************************** Test Code ***********************************/
   713    837   #ifdef SQLITE_TEST
   714    838   #include <tcl.h>
   715    839   
   716    840   /*
................................................................................
   879   1003   
   880   1004     /* Invoke sqlite3_quota_set() */
   881   1005     rc = sqlite3_quota_set(zPattern, iLimit, xCallback, (void*)p, xDestroy);
   882   1006   
   883   1007     Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
   884   1008     return TCL_OK;
   885   1009   }
         1010  +
         1011  +/*
         1012  +** tclcmd: sqlite3_quota_file FILENAME
         1013  +*/
         1014  +static int test_quota_file(
         1015  +  void * clientData,
         1016  +  Tcl_Interp *interp,
         1017  +  int objc,
         1018  +  Tcl_Obj *CONST objv[]
         1019  +){
         1020  +  const char *zFilename;          /* File pattern to configure */
         1021  +  int rc;                         /* Value returned by quota_file() */
         1022  +
         1023  +  /* Process arguments */
         1024  +  if( objc!=2 ){
         1025  +    Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
         1026  +    return TCL_ERROR;
         1027  +  }
         1028  +  zFilename = Tcl_GetString(objv[1]);
         1029  +
         1030  +  /* Invoke sqlite3_quota_file() */
         1031  +  rc = sqlite3_quota_file(zFilename);
         1032  +
         1033  +  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
         1034  +  return TCL_OK;
         1035  +}
   886   1036   
   887   1037   /*
   888   1038   ** tclcmd:  sqlite3_quota_dump
   889   1039   */
   890   1040   static int test_quota_dump(
   891   1041     void * clientData,
   892   1042     Tcl_Interp *interp,
................................................................................
   913   1063         pFileTerm = Tcl_NewObj();
   914   1064         Tcl_ListObjAppendElement(interp, pFileTerm,
   915   1065               Tcl_NewStringObj(pFile->zFilename, -1));
   916   1066         Tcl_ListObjAppendElement(interp, pFileTerm,
   917   1067               Tcl_NewWideIntObj(pFile->iSize));
   918   1068         Tcl_ListObjAppendElement(interp, pFileTerm,
   919   1069               Tcl_NewWideIntObj(pFile->nRef));
         1070  +      Tcl_ListObjAppendElement(interp, pFileTerm,
         1071  +            Tcl_NewWideIntObj(pFile->deleteOnClose));
   920   1072         Tcl_ListObjAppendElement(interp, pGroupTerm, pFileTerm);
   921   1073       }
   922   1074       Tcl_ListObjAppendElement(interp, pResult, pGroupTerm);
   923   1075     }
   924   1076     quotaLeave();
   925   1077     Tcl_SetObjResult(interp, pResult);
   926   1078     return TCL_OK;
................................................................................
   935   1087     static struct {
   936   1088        char *zName;
   937   1089        Tcl_ObjCmdProc *xProc;
   938   1090     } aCmd[] = {
   939   1091       { "sqlite3_quota_initialize", test_quota_initialize },
   940   1092       { "sqlite3_quota_shutdown", test_quota_shutdown },
   941   1093       { "sqlite3_quota_set", test_quota_set },
         1094  +    { "sqlite3_quota_file", test_quota_file },
   942   1095       { "sqlite3_quota_dump", test_quota_dump },
   943   1096     };
   944   1097     int i;
   945   1098   
   946   1099     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
   947   1100       Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
   948   1101     }
   949   1102   
   950   1103     return TCL_OK;
   951   1104   }
   952   1105   #endif

Changes to src/test_rtree.c.

    14     14   */
    15     15   
    16     16   #include "sqlite3.h"
    17     17   
    18     18   /* Solely for the UNUSED_PARAMETER() macro. */
    19     19   #include "sqliteInt.h"
    20     20   
           21  +#ifdef SQLITE_ENABLE_RTREE
    21     22   /* 
    22     23   ** Type used to cache parameter information for the "circle" r-tree geometry
    23     24   ** callback.
    24     25   */
    25     26   typedef struct Circle Circle;
    26     27   struct Circle {
    27     28     struct Box {
................................................................................
   226    227      && aCoord[5]>=pCube->z
   227    228     ){
   228    229       *piRes = 1;
   229    230     }
   230    231   
   231    232     return SQLITE_OK;
   232    233   }
          234  +#endif /* SQLITE_ENABLE_RTREE */
   233    235   
   234    236   static int register_cube_geom(
   235    237     void * clientData,
   236    238     Tcl_Interp *interp,
   237    239     int objc,
   238    240     Tcl_Obj *CONST objv[]
   239    241   ){

Changes to src/test_thread.c.

   301    301   static int sqlthread_id(
   302    302     ClientData clientData,
   303    303     Tcl_Interp *interp,
   304    304     int objc,
   305    305     Tcl_Obj *CONST objv[]
   306    306   ){
   307    307     Tcl_ThreadId id = Tcl_GetCurrentThread();
   308         -  Tcl_SetObjResult(interp, Tcl_NewIntObj((int)id));
          308  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(SQLITE_PTR_TO_INT(id)));
   309    309     UNUSED_PARAMETER(clientData);
   310    310     UNUSED_PARAMETER(objc);
   311    311     UNUSED_PARAMETER(objv);
   312    312     return TCL_OK;
   313    313   }
   314    314   
   315    315   

Changes to src/vdbe.c.

  3127   3127     ** and report database corruption if they were not, but this check has
  3128   3128     ** since moved into the btree layer.  */  
  3129   3129     pCur->isTable = pOp->p4type!=P4_KEYINFO;
  3130   3130     pCur->isIndex = !pCur->isTable;
  3131   3131     break;
  3132   3132   }
  3133   3133   
  3134         -/* Opcode: OpenEphemeral P1 P2 * P4 *
         3134  +/* Opcode: OpenEphemeral P1 P2 * P4 P5
  3135   3135   **
  3136   3136   ** Open a new cursor P1 to a transient table.
  3137   3137   ** The cursor is always opened read/write even if 
  3138   3138   ** the main database is read-only.  The ephemeral
  3139   3139   ** table is deleted automatically when the cursor is closed.
  3140   3140   **
  3141   3141   ** P2 is the number of columns in the ephemeral table.
................................................................................
  3144   3144   ** that defines the format of keys in the index.
  3145   3145   **
  3146   3146   ** This opcode was once called OpenTemp.  But that created
  3147   3147   ** confusion because the term "temp table", might refer either
  3148   3148   ** to a TEMP table at the SQL level, or to a table opened by
  3149   3149   ** this opcode.  Then this opcode was call OpenVirtual.  But
  3150   3150   ** that created confusion with the whole virtual-table idea.
         3151  +**
         3152  +** The P5 parameter can be a mask of the BTREE_* flags defined
         3153  +** in btree.h.  These flags control aspects of the operation of
         3154  +** the btree.  The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are
         3155  +** added automatically.
  3151   3156   */
  3152   3157   /* Opcode: OpenAutoindex P1 P2 * P4 *
  3153   3158   **
  3154   3159   ** This opcode works the same as OP_OpenEphemeral.  It has a
  3155   3160   ** different name to distinguish its use.  Tables created using
  3156   3161   ** by this opcode will be used for automatically created transient
  3157   3162   ** indices in joins.
  3158   3163   */
         3164  +/* Opcode: OpenSorter P1 P2 * P4 *
         3165  +**
         3166  +** This opcode works like OP_OpenEphemeral except that it opens
         3167  +** a transient index that is specifically designed to sort large
         3168  +** tables using an external merge-sort algorithm.
         3169  +*/
  3159   3170   case OP_OpenSorter: 
  3160   3171   case OP_OpenAutoindex: 
  3161   3172   case OP_OpenEphemeral: {
  3162   3173     VdbeCursor *pCx;
  3163   3174     static const int vfsFlags = 
  3164   3175         SQLITE_OPEN_READWRITE |
  3165   3176         SQLITE_OPEN_CREATE |
  3166   3177         SQLITE_OPEN_EXCLUSIVE |
  3167   3178         SQLITE_OPEN_DELETEONCLOSE |
  3168   3179         SQLITE_OPEN_TRANSIENT_DB;
  3169   3180   
  3170   3181     assert( pOp->p1>=0 );
         3182  +  assert( (pOp->opcode==OP_OpenSorter)==((pOp->p5 & BTREE_SORTER)!=0) );
  3171   3183     pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  3172   3184     if( pCx==0 ) goto no_mem;
  3173   3185     pCx->nullRow = 1;
  3174   3186     rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, 
  3175   3187                           BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
  3176   3188     if( rc==SQLITE_OK ){
  3177   3189       rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);

Changes to src/vdbe.h.

   169    169   int sqlite3VdbeAddOp1(Vdbe*,int,int);
   170    170   int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
   171    171   int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
   172    172   int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
   173    173   int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
   174    174   int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
   175    175   void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
   176         -void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
   177         -void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
   178         -void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
          176  +void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
          177  +void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
          178  +void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
   179    179   void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
   180    180   void sqlite3VdbeJumpHere(Vdbe*, int addr);
   181    181   void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
   182    182   void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
   183    183   void sqlite3VdbeUsesBtree(Vdbe*, int);
   184    184   VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
   185    185   int sqlite3VdbeMakeLabel(Vdbe*);

Changes to src/vdbeaux.c.

   520    520   
   521    521   /*
   522    522   ** Change the value of the P1 operand for a specific instruction.
   523    523   ** This routine is useful when a large program is loaded from a
   524    524   ** static array using sqlite3VdbeAddOpList but we want to make a
   525    525   ** few minor changes to the program.
   526    526   */
   527         -void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
          527  +void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
   528    528     assert( p!=0 );
   529         -  assert( addr>=0 );
   530         -  if( p->nOp>addr ){
          529  +  if( ((u32)p->nOp)>addr ){
   531    530       p->aOp[addr].p1 = val;
   532    531     }
   533    532   }
   534    533   
   535    534   /*
   536    535   ** Change the value of the P2 operand for a specific instruction.
   537    536   ** This routine is useful for setting a jump destination.
   538    537   */
   539         -void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
          538  +void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
   540    539     assert( p!=0 );
   541         -  assert( addr>=0 );
   542         -  if( p->nOp>addr ){
          540  +  if( ((u32)p->nOp)>addr ){
   543    541       p->aOp[addr].p2 = val;
   544    542     }
   545    543   }
   546    544   
   547    545   /*
   548    546   ** Change the value of the P3 operand for a specific instruction.
   549    547   */
   550         -void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
          548  +void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
   551    549     assert( p!=0 );
   552         -  assert( addr>=0 );
   553         -  if( p->nOp>addr ){
          550  +  if( ((u32)p->nOp)>addr ){
   554    551       p->aOp[addr].p3 = val;
   555    552     }
   556    553   }
   557    554   
   558    555   /*
   559    556   ** Change the value of the P5 operand for the most recently
   560    557   ** added operation.

Changes to src/vdbesort.c.

   384    384   **       key). The varint is the number of bytes in the blob of data.
   385    385   */
   386    386   static int vdbeSorterBtreeToPMA(sqlite3 *db, VdbeCursor *pCsr){
   387    387     int rc = SQLITE_OK;             /* Return code */
   388    388     VdbeSorter *pSorter = pCsr->pSorter;
   389    389     int res = 0;
   390    390   
          391  +  /* sqlite3BtreeFirst() cannot fail because sorter btrees are always held
          392  +  ** in memory and so an I/O error is not possible. */
   391    393     rc = sqlite3BtreeFirst(pCsr->pCursor, &res);
   392         -  if( rc!=SQLITE_OK || res ) return rc;
          394  +  if( NEVER(rc!=SQLITE_OK) || res ) return rc;
   393    395     assert( pSorter->nBtree>0 );
   394    396   
   395    397     /* If the first temporary PMA file has not been opened, open it now. */
   396    398     if( pSorter->pTemp1==0 ){
   397    399       rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1);
   398    400       assert( rc!=SQLITE_OK || pSorter->pTemp1 );
   399    401       assert( pSorter->iWriteOff==0 );
................................................................................
   425    427           }else{
   426    428             nMalloc = nKey;
   427    429           }
   428    430         }
   429    431   
   430    432         /* Write the record itself to the output file */
   431    433         if( rc==SQLITE_OK ){
          434  +        /* sqlite3BtreeKey() cannot fail because sorter btrees held in memory */
   432    435           rc = sqlite3BtreeKey(pCsr->pCursor, 0, nKey, aMalloc);
   433         -        if( rc==SQLITE_OK ){
          436  +        if( ALWAYS(rc==SQLITE_OK) ){
   434    437             rc = sqlite3OsWrite(pSorter->pTemp1, aMalloc, nKey, iWriteOff);
   435    438             iWriteOff += nKey;
   436    439           }
   437    440         }
   438    441   
   439    442         if( rc!=SQLITE_OK ) break;
   440    443       }
................................................................................
   470    473   int sqlite3VdbeSorterWrite(sqlite3 *db, VdbeCursor *pCsr, int nKey){
   471    474     int rc = SQLITE_OK;             /* Return code */
   472    475     VdbeSorter *pSorter = pCsr->pSorter;
   473    476     if( pSorter ){
   474    477       Pager *pPager = sqlite3BtreePager(pCsr->pBt);
   475    478       int nPage;                    /* Current size of temporary file in pages */
   476    479   
          480  +    /* Sorters never spill to disk */
          481  +    assert( sqlite3PagerFile(pPager)->pMethods==0 );
          482  +
   477    483       /* Determine how many pages the temporary b-tree has grown to */
   478    484       sqlite3PagerPagecount(pPager, &nPage);
   479    485   
   480    486       /* If pSorter->nWorking is still zero, but the temporary file has been
   481    487       ** created in the file-system, then the most recent insert into the
   482    488       ** current b-tree segment probably caused the cache to overflow (it is
   483    489       ** also possible that sqlite3_release_memory() was called). So set the
   484    490       ** size of the working set to a little less than the current size of the 
   485    491       ** file in pages.  */
   486         -    if( pSorter->nWorking==0 && sqlite3PagerFile(pPager)->pMethods ){
          492  +    if( pSorter->nWorking==0 && sqlite3PagerUnderStress(pPager) ){
   487    493         pSorter->nWorking = nPage-5;
   488    494         if( pSorter->nWorking<SORTER_MIN_WORKING ){
   489    495           pSorter->nWorking = SORTER_MIN_WORKING;
   490    496         }
   491    497       }
   492    498   
   493    499       /* If the number of pages used by the current b-tree segment is greater
................................................................................
   622    628         if( rc==SQLITE_OK ){
   623    629           rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2);
   624    630         }
   625    631   
   626    632         if( rc==SQLITE_OK ){
   627    633           int bEof = 0;
   628    634           while( rc==SQLITE_OK && bEof==0 ){
   629         -          int nByte;
          635  +          int nToWrite;
   630    636             VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ];
   631    637             assert( pIter->pFile );
   632         -          nByte = pIter->nKey + sqlite3VarintLen(pIter->nKey);
   633         -          rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nByte, iWrite2);
   634         -          iWrite2 += nByte;
          638  +          nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey);
          639  +          rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2);
          640  +          iWrite2 += nToWrite;
   635    641             if( rc==SQLITE_OK ){
   636    642               rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
   637    643             }
   638    644           }
   639    645         }
   640    646       }
   641    647   

Changes to test/pager1.test.

  2422   2422     
  2423   2423     hexio_write test.db2-journal 24 00000000
  2424   2424     sqlite3 db2 test.db2
  2425   2425     execsql { PRAGMA integrity_check } db2
  2426   2426   } {ok}
  2427   2427   }
  2428   2428   
         2429  +#-------------------------------------------------------------------------
         2430  +# Test that a database file can be "pre-hinted" to a certain size and that
         2431  +# subsequent spilling of the pager cache does not result in the database
         2432  +# file being shrunk.
         2433  +#
         2434  +catch {db close}
         2435  +forcedelete test.db
         2436  +
         2437  +do_test pager1-32.1 {
         2438  +  sqlite3 db test.db
         2439  +  execsql {
         2440  +    CREATE TABLE t1(x, y);
         2441  +  }
         2442  +  db close
         2443  +  sqlite3 db test.db
         2444  +  execsql {
         2445  +    BEGIN;
         2446  +    INSERT INTO t1 VALUES(1, randomblob(10000));
         2447  +  }
         2448  +  file_control_sizehint_test db main 20971520; # 20MB
         2449  +  execsql {
         2450  +    PRAGMA cache_size = 10;
         2451  +    INSERT INTO t1 VALUES(1, randomblob(10000));
         2452  +    INSERT INTO t1 VALUES(2, randomblob(10000));
         2453  +    INSERT INTO t1 SELECT x+2, randomblob(10000) from t1;
         2454  +    INSERT INTO t1 SELECT x+4, randomblob(10000) from t1;
         2455  +    INSERT INTO t1 SELECT x+8, randomblob(10000) from t1;
         2456  +    INSERT INTO t1 SELECT x+16, randomblob(10000) from t1;
         2457  +    SELECT count(*) FROM t1;
         2458  +    COMMIT;
         2459  +  }
         2460  +  db close
         2461  +  file size test.db
         2462  +} {20971520}
         2463  +
         2464  +# Cleanup 20MB file left by the previous test.
         2465  +forcedelete test.db
  2429   2466   
  2430   2467   finish_test

Changes to test/quota.test.

   219    219   
   220    220   do_test quota-3.2.X {
   221    221     foreach db {db1a db2a db2b db1b} { catch { $db close } }
   222    222     sqlite3_quota_set * 0 {}
   223    223   } {SQLITE_OK}
   224    224   
   225    225   #-------------------------------------------------------------------------
   226         -# Quotas are deleted when unused and when there limit is set to zero
          226  +# Quotas are deleted when unused and when their limit is set to zero
   227    227   #
   228    228   
   229    229   # Return a list of all currently defined quotas.  Each quota is identified
   230    230   # by its pattern.
   231    231   proc quota_list {} {
   232    232     set allq {}
   233    233     foreach q [sqlite3_quota_dump] {
   234    234       lappend allq [lindex $q 0]
   235    235     }
   236    236     return [lsort $allq]
          237  +}
          238  +proc quota_size {name} {
          239  +  set allq {}
          240  +  foreach q [sqlite3_quota_dump] {
          241  +    if {[lindex $q 0]==$name} {return [lindex $q 2]}
          242  +  }
          243  +  return 0
   237    244   }
   238    245   
   239    246   do_test quota-4.1.1 {
   240    247     sqlite3_quota_set *test.db 0 {}
   241    248     quota_list
   242    249   } {}
   243    250   do_test quota-4.1.2 {
................................................................................
   325    332     sqlite3_quota_set A 1000 quota_callback
   326    333     sqlite3 db A
   327    334     sqlite3_quota_set A 0 quota_callback
   328    335     db close
   329    336     quota_list
   330    337   } {}
   331    338   
          339  +unset -nocomplain quotagroup
          340  +if {$tcl_platform(platform)=="windows"} {
          341  +  set quotagroup *\\quota-test-A?.db
          342  +} else {
          343  +  set quotagroup */quota-test-A?.db
          344  +} 
          345  +foreach file [glob -nocomplain quota-test-A*] {
          346  +  forcedelete $file
          347  +}
   332    348   do_test quota-4.4.1 {
          349  +  set ::quota {}
          350  +  sqlite3_quota_set $::quotagroup 10000 quota_callback
          351  +  file delete -force ./quota-test-A1.db ./quota-test-A2.db
          352  +  sqlite3 db ./quota-test-A1.db
          353  +  db eval {
          354  +     CREATE TABLE t1(x);
          355  +     INSERT INTO t1 VALUES(randomblob(5000));
          356  +  }
          357  +  quota_list
          358  +} [list $quotagroup]
          359  +do_test quota-4.4.2 {
          360  +  expr {$::quota==""}
          361  +} {1}
          362  +do_test quota-4.4.3 {
          363  +  db close
          364  +  sqlite3 db ./quota-test-A2.db
          365  +  db eval {
          366  +     CREATE TABLE t1(x);
          367  +     INSERT INTO t1 VALUES(randomblob(5000));
          368  +  }
          369  +  quota_list
          370  +} [list $quotagroup]
          371  +do_test quota-4.4.4 {
          372  +  expr {$::quota!=""}
          373  +} {1}
          374  +do_test quota-4.4.5 {
          375  +  db close
          376  +  sqlite3_quota_set $::quotagroup 0 {}
          377  +  sqlite3_quota_dump
          378  +} {}
          379  +do_test quota-4.4.6 {
          380  +  sqlite3_quota_set $quotagroup 10000 quota_callback
          381  +  sqlite3 db quota-test-A1.db
          382  +  db eval {SELECT count(*) FROM sqlite_master}
          383  +  quota_size $quotagroup
          384  +} [file size quota-test-A1.db]
          385  +do_test quota-4.4.7 {
          386  +  sqlite3_quota_file quota-test-A2.db
          387  +  quota_size $::quotagroup
          388  +} [expr {[file size quota-test-A1.db]+[file size quota-test-A2.db]}]
          389  +
          390  +unset -nocomplain quotagroup
          391  +if {$tcl_platform(platform)=="windows"} {
          392  +  set quotagroup *\\quota-test-B*
          393  +} else {
          394  +  set quotagroup */quota-test-B*
          395  +} 
          396  +foreach file [glob -nocomplain quota-test-B*] {
          397  +  forcedelete $file
          398  +}
          399  +do_test quota-4.5.1 {
          400  +  sqlite3_quota_set $::quotagroup 100000 quota_callback
          401  +  quota_size $::quotagroup
          402  +} {0}
          403  +do_test quota-4.5.2 {
          404  +  sqlite3_quota_file quota-test-B1.txt
          405  +  quota_size $::quotagroup
          406  +} {0}
          407  +proc add_to_file {name n} {
          408  +  set out [open $name a]
          409  +  fconfigure $out -translation binary
          410  +  puts -nonewline $out [string repeat x $n]
          411  +  close $out
          412  +}
          413  +do_test quota-4.5.3 {
          414  +  add_to_file quota-test-B1.txt 123
          415  +  sqlite3_quota_file quota-test-B1.txt
          416  +  quota_size $::quotagroup
          417  +} {123}
          418  +do_test quota-4.5.4 {
          419  +  add_to_file quota-test-B2.txt 234
          420  +  sqlite3_quota_file quota-test-B2.txt
          421  +  quota_size $::quotagroup
          422  +} {357}
          423  +do_test quota-4.5.5 {
          424  +  add_to_file quota-test-B1.txt 2000
          425  +  sqlite3_quota_file quota-test-B1.txt
          426  +  quota_size $::quotagroup
          427  +} {2357}
          428  +do_test quota-4.5.6 {
          429  +  forcedelete quota-test-B1.txt
          430  +  sqlite3_quota_file quota-test-B1.txt
          431  +  quota_size $::quotagroup
          432  +} {234}
          433  +do_test quota-4.5.7 {
          434  +  forcedelete quota-test-B2.txt
          435  +  sqlite3_quota_file quota-test-B2.txt
          436  +  quota_size $::quotagroup
          437  +} {0}
          438  +do_test quota-4.5.8 {
          439  +  add_to_file quota-test-B3.txt 1234
          440  +  sqlite3_quota_file quota-test-B3.txt
          441  +  quota_size $::quotagroup
          442  +} {1234}
          443  +do_test quota-4.5.9 {
          444  +  sqlite3_quota_set $quotagroup 0 {}
          445  +  quota_size $::quotagroup
          446  +} {0}
          447  +
          448  +do_test quota-4.9.1 {
          449  +  db close
   333    450     sqlite3_quota_set A 1000 quota_callback
   334    451     sqlite3_quota_shutdown
   335    452   } {SQLITE_OK}
   336         -do_test quota-4.4.2 {
          453  +do_test quota-4.9.2 {
   337    454     quota_list
   338    455   } {}
   339    456   
   340    457   #-------------------------------------------------------------------------
   341    458   # The following tests test that the quota VFS handles malloc and IO 
   342    459   # errors.
   343    460   #

Changes to test/win32lock.test.

    65     65           regsub {\d+} $::log # x
    66     66           set x
    67     67         } {{delayed #ms for lock/sharing conflict}}
    68     68       }
    69     69     }
    70     70     if {[llength $win32_lock_ok] && [llength $win32_lock_error]} break
    71     71     incr delay1 25
           72  +  if {$delay1 > 12500} {
           73  +    puts "Timed out waiting for \"ok\" and \"error\" results."
           74  +    break
           75  +  }
    72     76     sqlite3_sleep 10
    73     77   }
    74     78   
    75     79   do_test win32lock-2.0 {
    76     80     file_control_win32_av_retry db -1 -1
    77     81   } {0 10 25}
    78     82   do_test win32lock-2.1 {
................................................................................
   109    113           regsub {\d+} $::log # x
   110    114           set x
   111    115         } {{delayed #ms for lock/sharing conflict}}
   112    116       }
   113    117     }
   114    118     if {[llength $win32_lock_ok] && [llength $win32_lock_error]} break
   115    119     incr delay1 1
          120  +  if {$delay1 > 500} {
          121  +    puts "Timed out waiting for \"ok\" and \"error\" results."
          122  +    break
          123  +  }
   116    124     sqlite3_sleep 10
   117    125   }
   118    126   
   119    127   file_control_win32_av_retry db 10 25
   120    128   sqlite3_test_control_pending_byte $old_pending_byte
          129  +db close
   121    130   sqlite3_shutdown
   122    131   test_sqlite3_log 
   123    132   sqlite3_initialize
   124    133   finish_test

Changes to tool/warnings.sh.

     1      1   #/bin/sh
     2      2   #
     3      3   # Run this script in a directory with a working makefile to check for 
     4      4   # compiler warnings in SQLite.
     5      5   #
     6         -make sqlite3.c
            6  +rm -f sqlite3.c
            7  +make sqlite3.c-debug
     7      8   echo '********** No optimizations.  Includes FTS4 and RTREE *********'
     8      9   gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
     9     10         -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
    10     11         sqlite3.c
    11     12   echo '********** No optimizations. ENABLE_STAT2. THREADSAFE=0 *******'
    12     13   gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
    13     14         -ansi -DSQLITE_ENABLE_STAT2 -DSQLITE_THREADSAFE=0 \
    14     15         sqlite3.c
    15     16   echo '********** Optimized -O3.  Includes FTS4 and RTREE ************'
    16     17   gcc -O3 -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
    17     18         -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
    18     19         sqlite3.c