/ Check-in [b0ccef61]
Login

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

Overview
Comment:Add the sqlite3_hard_heap_limit64() interface and the corresponding "PRAGMA hard_heap_limit=N" command.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | hard-heap-limit
Files: files | file ages | folders
SHA3-256: b0ccef61a7f92d20228becbf4f997bf0f4e46dad2deaf0896dc63b976ad1dd11
User & Date: drh 2019-04-25 18:15:38
Context
2019-05-02
14:15
Merge enhancements from trunk check-in: 3a4751a9 user: drh tags: hard-heap-limit
2019-04-25
18:15
Add the sqlite3_hard_heap_limit64() interface and the corresponding "PRAGMA hard_heap_limit=N" command. check-in: b0ccef61 user: drh tags: hard-heap-limit
2019-04-24
17:04
New test cases in test/fuzzdata8.db. check-in: 7be6222c user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/loadext.c.

   457    457   #ifdef SQLITE_ENABLE_NORMALIZE
   458    458     sqlite3_normalized_sql,
   459    459   #else
   460    460     0,
   461    461   #endif
   462    462     /* Version 3.28.0 and later */
   463    463     sqlite3_stmt_isexplain,
   464         -  sqlite3_value_frombind
          464  +  sqlite3_value_frombind,
          465  +  /* Version 3.29.0 and later */
          466  +  sqlite3_hard_heap_limit64
   465    467   };
   466    468   
   467    469   /*
   468    470   ** Attempt to load an SQLite extension library contained in the file
   469    471   ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
   470    472   ** default entry point name (sqlite3_extension_init) is used.  Use
   471    473   ** of the default name is recommended.

Changes to src/malloc.c.

    34     34   
    35     35   /*
    36     36   ** State information local to the memory allocation subsystem.
    37     37   */
    38     38   static SQLITE_WSD struct Mem0Global {
    39     39     sqlite3_mutex *mutex;         /* Mutex to serialize access */
    40     40     sqlite3_int64 alarmThreshold; /* The soft heap limit */
           41  +  sqlite3_int64 hardLimit;      /* The hard upper bound on memory */
    41     42   
    42     43     /*
    43     44     ** True if heap is nearly "full" where "full" is defined by the
    44     45     ** sqlite3_soft_heap_limit() setting.
    45     46     */
    46     47     int nearlyFull;
    47     48   } mem0 = { 0, 0, 0 };
................................................................................
    70     71     (void)pArg;
    71     72     (void)iThreshold;
    72     73     return SQLITE_OK;
    73     74   }
    74     75   #endif
    75     76   
    76     77   /*
    77         -** Set the soft heap-size limit for the library. Passing a zero or 
    78         -** negative value indicates no limit.
           78  +** Set the soft heap-size limit for the library.  An argument of
           79  +** zero disables the limit.  A negative argument is a no-op used to
           80  +** obtain the return value.
           81  +**
           82  +** The return value is the value of the heap limit just before this
           83  +** interface was called.
           84  +**
           85  +** If the hard heap limit is enabled, then the soft heap limit cannot
           86  +** be disabled nor raised above the hard heap limit.
    79     87   */
    80     88   sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
    81     89     sqlite3_int64 priorLimit;
    82     90     sqlite3_int64 excess;
    83     91     sqlite3_int64 nUsed;
    84     92   #ifndef SQLITE_OMIT_AUTOINIT
    85     93     int rc = sqlite3_initialize();
................................................................................
    86     94     if( rc ) return -1;
    87     95   #endif
    88     96     sqlite3_mutex_enter(mem0.mutex);
    89     97     priorLimit = mem0.alarmThreshold;
    90     98     if( n<0 ){
    91     99       sqlite3_mutex_leave(mem0.mutex);
    92    100       return priorLimit;
          101  +  }
          102  +  if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
          103  +    n = mem0.hardLimit;
    93    104     }
    94    105     mem0.alarmThreshold = n;
    95    106     nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
    96    107     mem0.nearlyFull = (n>0 && n<=nUsed);
    97    108     sqlite3_mutex_leave(mem0.mutex);
    98    109     excess = sqlite3_memory_used() - n;
    99    110     if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
   100    111     return priorLimit;
   101    112   }
   102    113   void sqlite3_soft_heap_limit(int n){
   103    114     if( n<0 ) n = 0;
   104    115     sqlite3_soft_heap_limit64(n);
   105    116   }
          117  +
          118  +/*
          119  +** Set the hard heap-size limit for the library. An argument of zero
          120  +** disables the hard heap limit.  A negative argument is a no-op used
          121  +** to obtain the return value without affecting the hard heap limit.
          122  +**
          123  +** The return value is the value of the hard heap limit just prior to
          124  +** calling this interface.
          125  +**
          126  +** Setting the hard heap limit will also activate the soft heap limit
          127  +** and constrain the soft heap limit to be no more than the hard heap
          128  +** limit.
          129  +*/
          130  +sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){
          131  +  sqlite3_int64 priorLimit;
          132  +#ifndef SQLITE_OMIT_AUTOINIT
          133  +  int rc = sqlite3_initialize();
          134  +  if( rc ) return -1;
          135  +#endif
          136  +  sqlite3_mutex_enter(mem0.mutex);
          137  +  priorLimit = mem0.hardLimit;
          138  +  if( n>=0 ){
          139  +    mem0.hardLimit = n;
          140  +    if( n<mem0.alarmThreshold || mem0.alarmThreshold==0 ){
          141  +      mem0.alarmThreshold = n;
          142  +    }
          143  +  }
          144  +  sqlite3_mutex_leave(mem0.mutex);
          145  +  return priorLimit;
          146  +}
          147  +
   106    148   
   107    149   /*
   108    150   ** Initialize the memory allocation subsystem.
   109    151   */
   110    152   int sqlite3MallocInit(void){
   111    153     int rc;
   112    154     if( sqlite3GlobalConfig.m.xMalloc==0 ){
................................................................................
   199    241   
   200    242     sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
   201    243     if( mem0.alarmThreshold>0 ){
   202    244       sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
   203    245       if( nUsed >= mem0.alarmThreshold - nFull ){
   204    246         mem0.nearlyFull = 1;
   205    247         sqlite3MallocAlarm(nFull);
          248  +      if( mem0.hardLimit ){
          249  +        nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
          250  +        if( nUsed >= mem0.hardLimit - nFull ){
          251  +          *pp = 0;
          252  +          return;
          253  +        }
          254  +      }
   206    255       }else{
   207    256         mem0.nearlyFull = 0;
   208    257       }
   209    258     }
   210    259     p = sqlite3GlobalConfig.m.xMalloc(nFull);
   211    260   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   212    261     if( p==0 && mem0.alarmThreshold>0 ){

Changes to src/pragma.c.

  2056   2056     ** sqlite3_soft_heap_limit64(-1) C-language function.
  2057   2057     */
  2058   2058     case PragTyp_SOFT_HEAP_LIMIT: {
  2059   2059       sqlite3_int64 N;
  2060   2060       if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
  2061   2061         sqlite3_soft_heap_limit64(N);
  2062   2062       }
         2063  +    returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
         2064  +    break;
         2065  +  }
         2066  +
         2067  +  /*
         2068  +  **   PRAGMA hard_heap_limit
         2069  +  **   PRAGMA hard_heap_limit = N
         2070  +  **
         2071  +  ** Invoke sqlite3_hard_heap_limit64() to query or set the hard heap
         2072  +  ** limit.  The hard heap limit can be activated or lowered by this
         2073  +  ** pragma, but not raised or deactivated.  Only the
         2074  +  ** sqlite3_hard_heap_limit64() C-language API can raise or deactivate
         2075  +  ** the hard heap limit.  This allows an application to set a heap limit
         2076  +  ** constraint that cannot be relaxed by an untrusted SQL script.
         2077  +  */
         2078  +  case PragTyp_HARD_HEAP_LIMIT: {
         2079  +    sqlite3_int64 N;
         2080  +    if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
         2081  +      sqlite3_int64 iPrior = sqlite3_hard_heap_limit64(-1);
         2082  +      if( N>0 && (iPrior==0 || iPrior>N) ) sqlite3_hard_heap_limit64(N);
         2083  +    }
  2063   2084       returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
  2064   2085       break;
  2065   2086     }
  2066   2087   
  2067   2088     /*
  2068   2089     **   PRAGMA threads
  2069   2090     **   PRAGMA threads = N

Changes to src/pragma.h.

    17     17   #define PragTyp_DATA_STORE_DIRECTORY           9
    18     18   #define PragTyp_DATABASE_LIST                 10
    19     19   #define PragTyp_DEFAULT_CACHE_SIZE            11
    20     20   #define PragTyp_ENCODING                      12
    21     21   #define PragTyp_FOREIGN_KEY_CHECK             13
    22     22   #define PragTyp_FOREIGN_KEY_LIST              14
    23     23   #define PragTyp_FUNCTION_LIST                 15
    24         -#define PragTyp_INCREMENTAL_VACUUM            16
    25         -#define PragTyp_INDEX_INFO                    17
    26         -#define PragTyp_INDEX_LIST                    18
    27         -#define PragTyp_INTEGRITY_CHECK               19
    28         -#define PragTyp_JOURNAL_MODE                  20
    29         -#define PragTyp_JOURNAL_SIZE_LIMIT            21
    30         -#define PragTyp_LOCK_PROXY_FILE               22
    31         -#define PragTyp_LOCKING_MODE                  23
    32         -#define PragTyp_PAGE_COUNT                    24
    33         -#define PragTyp_MMAP_SIZE                     25
    34         -#define PragTyp_MODULE_LIST                   26
    35         -#define PragTyp_OPTIMIZE                      27
    36         -#define PragTyp_PAGE_SIZE                     28
    37         -#define PragTyp_PRAGMA_LIST                   29
    38         -#define PragTyp_SECURE_DELETE                 30
    39         -#define PragTyp_SHRINK_MEMORY                 31
    40         -#define PragTyp_SOFT_HEAP_LIMIT               32
    41         -#define PragTyp_SYNCHRONOUS                   33
    42         -#define PragTyp_TABLE_INFO                    34
    43         -#define PragTyp_TEMP_STORE                    35
    44         -#define PragTyp_TEMP_STORE_DIRECTORY          36
    45         -#define PragTyp_THREADS                       37
    46         -#define PragTyp_WAL_AUTOCHECKPOINT            38
    47         -#define PragTyp_WAL_CHECKPOINT                39
    48         -#define PragTyp_ACTIVATE_EXTENSIONS           40
    49         -#define PragTyp_HEXKEY                        41
    50         -#define PragTyp_KEY                           42
    51         -#define PragTyp_LOCK_STATUS                   43
    52         -#define PragTyp_STATS                         44
           24  +#define PragTyp_HARD_HEAP_LIMIT               16
           25  +#define PragTyp_INCREMENTAL_VACUUM            17
           26  +#define PragTyp_INDEX_INFO                    18
           27  +#define PragTyp_INDEX_LIST                    19
           28  +#define PragTyp_INTEGRITY_CHECK               20
           29  +#define PragTyp_JOURNAL_MODE                  21
           30  +#define PragTyp_JOURNAL_SIZE_LIMIT            22
           31  +#define PragTyp_LOCK_PROXY_FILE               23
           32  +#define PragTyp_LOCKING_MODE                  24
           33  +#define PragTyp_PAGE_COUNT                    25
           34  +#define PragTyp_MMAP_SIZE                     26
           35  +#define PragTyp_MODULE_LIST                   27
           36  +#define PragTyp_OPTIMIZE                      28
           37  +#define PragTyp_PAGE_SIZE                     29
           38  +#define PragTyp_PRAGMA_LIST                   30
           39  +#define PragTyp_SECURE_DELETE                 31
           40  +#define PragTyp_SHRINK_MEMORY                 32
           41  +#define PragTyp_SOFT_HEAP_LIMIT               33
           42  +#define PragTyp_SYNCHRONOUS                   34
           43  +#define PragTyp_TABLE_INFO                    35
           44  +#define PragTyp_TEMP_STORE                    36
           45  +#define PragTyp_TEMP_STORE_DIRECTORY          37
           46  +#define PragTyp_THREADS                       38
           47  +#define PragTyp_WAL_AUTOCHECKPOINT            39
           48  +#define PragTyp_WAL_CHECKPOINT                40
           49  +#define PragTyp_ACTIVATE_EXTENSIONS           41
           50  +#define PragTyp_HEXKEY                        42
           51  +#define PragTyp_KEY                           43
           52  +#define PragTyp_LOCK_STATUS                   44
           53  +#define PragTyp_STATS                         45
    53     54   
    54     55   /* Property flags associated with various pragma. */
    55     56   #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
    56     57   #define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
    57     58   #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
    58     59   #define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
    59     60   #define PragFlg_Result0    0x10 /* Acts as query when no argument */
................................................................................
   314    315    {/* zName:     */ "function_list",
   315    316     /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
   316    317     /* ePragFlg:  */ PragFlg_Result0,
   317    318     /* ColNames:  */ 41, 2,
   318    319     /* iArg:      */ 0 },
   319    320   #endif
   320    321   #endif
          322  + {/* zName:     */ "hard_heap_limit",
          323  +  /* ePragTyp:  */ PragTyp_HARD_HEAP_LIMIT,
          324  +  /* ePragFlg:  */ PragFlg_Result0,
          325  +  /* ColNames:  */ 0, 0,
          326  +  /* iArg:      */ 0 },
   321    327   #if defined(SQLITE_HAS_CODEC)
   322    328    {/* zName:     */ "hexkey",
   323    329     /* ePragTyp:  */ PragTyp_HEXKEY,
   324    330     /* ePragFlg:  */ 0,
   325    331     /* ColNames:  */ 0, 0,
   326    332     /* iArg:      */ 2 },
   327    333    {/* zName:     */ "hexrekey",
................................................................................
   663    669    {/* zName:     */ "writable_schema",
   664    670     /* ePragTyp:  */ PragTyp_FLAG,
   665    671     /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   666    672     /* ColNames:  */ 0, 0,
   667    673     /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
   668    674   #endif
   669    675   };
   670         -/* Number of pragmas: 62 on by default, 81 total. */
          676  +/* Number of pragmas: 63 on by default, 82 total. */

Changes to src/sqlite.h.in.

  6033   6033   **
  6034   6034   ** See also: [sqlite3_release_memory()]
  6035   6035   */
  6036   6036   int sqlite3_db_release_memory(sqlite3*);
  6037   6037   
  6038   6038   /*
  6039   6039   ** CAPI3REF: Impose A Limit On Heap Size
         6040  +**
         6041  +** These interfaces impose limits on the amount of heap memory that will be
         6042  +** by all database connections within a single process.
  6040   6043   **
  6041   6044   ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
  6042   6045   ** soft limit on the amount of heap memory that may be allocated by SQLite.
  6043   6046   ** ^SQLite strives to keep heap memory utilization below the soft heap
  6044   6047   ** limit by reducing the number of pages held in the page cache
  6045   6048   ** as heap memory usages approaches the limit.
  6046   6049   ** ^The soft heap limit is "soft" because even though SQLite strives to stay
  6047   6050   ** below the limit, it will exceed the limit rather than generate
  6048   6051   ** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
  6049   6052   ** is advisory only.
  6050   6053   **
  6051         -** ^The return value from sqlite3_soft_heap_limit64() is the size of
  6052         -** the soft heap limit prior to the call, or negative in the case of an
         6054  +** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of
         6055  +** N bytes on the amount of memory that will be allocated.  ^The
         6056  +** sqlite3_hard_heap_limit64(N) interface is similar to
         6057  +** sqlite3_soft_heap_limit64(N) except that memory allocations will fail
         6058  +** when the hard heap limit is reached.
         6059  +**
         6060  +** ^The return value from both sqlite3_soft_heap_limit64() and
         6061  +** sqlite3_hard_heap_limit64() is the size of
         6062  +** the heap limit prior to the call, or negative in the case of an
  6053   6063   ** error.  ^If the argument N is negative
  6054         -** then no change is made to the soft heap limit.  Hence, the current
  6055         -** size of the soft heap limit can be determined by invoking
  6056         -** sqlite3_soft_heap_limit64() with a negative argument.
         6064  +** then no change is made to the heap limit.  Hence, the current
         6065  +** size of heap limits can be determined by invoking
         6066  +** sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1).
  6057   6067   **
  6058         -** ^If the argument N is zero then the soft heap limit is disabled.
         6068  +** ^Setting the heap limits to zero disables the heap limiter mechanism.
  6059   6069   **
  6060         -** ^(The soft heap limit is not enforced in the current implementation
         6070  +** ^The soft heap limit may not be greater than the hard heap limit.
         6071  +** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N)
         6072  +** is invoked with a value of N that is greater than the hard heap limit,
         6073  +** the the soft heap limit is set to the value of the hard heap limit.
         6074  +** ^The soft heap limit is automatically enabled whenever the hard heap
         6075  +** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and
         6076  +** the soft heap limit is outside the range of 1..N, then the soft heap
         6077  +** limit is set to N.  ^Invoking sqlite3_soft_heap_limit64(0) when the
         6078  +** hard heap limit is enabled makes the soft heap limit equal to the
         6079  +** hard heap limit.
         6080  +**
         6081  +** The soft heap limits can also be adjusted using
         6082  +** [PRAGMA soft_heap_limit] and [PRAGMA hard_heap_limit].
         6083  +**
         6084  +** ^(The heap limits are not enforced in the current implementation
  6061   6085   ** if one or more of following conditions are true:
  6062   6086   **
  6063   6087   ** <ul>
  6064         -** <li> The soft heap limit is set to zero.
         6088  +** <li> The limit value is set to zero.
  6065   6089   ** <li> Memory accounting is disabled using a combination of the
  6066   6090   **      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
  6067   6091   **      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
  6068   6092   ** <li> An alternative page cache implementation is specified using
  6069   6093   **      [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
  6070   6094   ** <li> The page cache allocates from its own memory pool supplied
  6071   6095   **      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
  6072   6096   **      from the heap.
  6073   6097   ** </ul>)^
  6074   6098   **
  6075         -** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), 
  6076         -** the soft heap limit is enforced
  6077         -** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
  6078         -** compile-time option is invoked.  With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
  6079         -** the soft heap limit is enforced on every memory allocation.  Without
  6080         -** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
  6081         -** when memory is allocated by the page cache.  Testing suggests that because
  6082         -** the page cache is the predominate memory user in SQLite, most
  6083         -** applications will achieve adequate soft heap limit enforcement without
  6084         -** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
  6085         -**
  6086         -** The circumstances under which SQLite will enforce the soft heap limit may
         6099  +** The circumstances under which SQLite will enforce the heap limits may
  6087   6100   ** changes in future releases of SQLite.
  6088   6101   */
  6089   6102   sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
         6103  +sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
  6090   6104   
  6091   6105   /*
  6092   6106   ** CAPI3REF: Deprecated Soft Heap Limit Interface
  6093   6107   ** DEPRECATED
  6094   6108   **
  6095   6109   ** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
  6096   6110   ** interface.  This routine is provided for historical compatibility

Changes to src/sqlite3ext.h.

   318    318                               void (*xInv)(sqlite3_context*,int,sqlite3_value**),
   319    319                               void(*xDestroy)(void*));
   320    320     /* Version 3.26.0 and later */
   321    321     const char *(*normalized_sql)(sqlite3_stmt*);
   322    322     /* Version 3.28.0 and later */
   323    323     int (*stmt_isexplain)(sqlite3_stmt*);
   324    324     int (*value_frombind)(sqlite3_value*);
          325  +  /* Version 3.29.0 and later */
          326  +  sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
   325    327   };
   326    328   
   327    329   /*
   328    330   ** This is the function signature used for all extension entry points.  It
   329    331   ** is also defined in the file "loadext.c".
   330    332   */
   331    333   typedef int (*sqlite3_loadext_entry)(
................................................................................
   610    612   /* Version 3.25.0 and later */
   611    613   #define sqlite3_create_window_function sqlite3_api->create_window_function
   612    614   /* Version 3.26.0 and later */
   613    615   #define sqlite3_normalized_sql         sqlite3_api->normalized_sql
   614    616   /* Version 3.28.0 and later */
   615    617   #define sqlite3_stmt_isexplain         sqlite3_api->isexplain
   616    618   #define sqlite3_value_frombind         sqlite3_api->frombind
          619  +/* Version 3.29.0 and later */
          620  +#define sqlite3_hard_heap_limit64      sqlite3_api->hard_heap_limit64
   617    621   #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
   618    622   
   619    623   #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   620    624     /* This case when the file really is being compiled as a loadable 
   621    625     ** extension */
   622    626   # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
   623    627   # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/test1.c.

  5472   5472     if( objc==2 ){
  5473   5473       if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
  5474   5474     }
  5475   5475     amt = sqlite3_soft_heap_limit64(N);
  5476   5476     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt));
  5477   5477     return TCL_OK;
  5478   5478   }
         5479  +
         5480  +/*
         5481  +** Usage:  sqlite3_hard_heap_limit ?N?
         5482  +**
         5483  +** Query or set the hard heap limit for the current thread.  The
         5484  +** limit is only changed if the N is present.  The previous limit
         5485  +** is returned.
         5486  +*/
         5487  +static int SQLITE_TCLAPI test_hard_heap_limit(
         5488  +  void * clientData,
         5489  +  Tcl_Interp *interp,
         5490  +  int objc,
         5491  +  Tcl_Obj *CONST objv[]
         5492  +){
         5493  +  sqlite3_int64 amt;
         5494  +  Tcl_WideInt N = -1;
         5495  +  if( objc!=1 && objc!=2 ){
         5496  +    Tcl_WrongNumArgs(interp, 1, objv, "?N?");
         5497  +    return TCL_ERROR;
         5498  +  }
         5499  +  if( objc==2 ){
         5500  +    if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
         5501  +  }
         5502  +  amt = sqlite3_hard_heap_limit64(N);
         5503  +  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt));
         5504  +  return TCL_OK;
         5505  +}
  5479   5506   
  5480   5507   /*
  5481   5508   ** Usage:   sqlite3_thread_cleanup
  5482   5509   **
  5483   5510   ** Call the sqlite3_thread_cleanup API.
  5484   5511   */
  5485   5512   static int SQLITE_TCLAPI test_thread_cleanup(
................................................................................
  7876   7903        { "sqlite3_release_memory",        test_release_memory,     0},
  7877   7904        { "sqlite3_db_release_memory",     test_db_release_memory,  0},
  7878   7905        { "sqlite3_db_cacheflush",         test_db_cacheflush,      0},
  7879   7906        { "sqlite3_system_errno",          test_system_errno,       0},
  7880   7907        { "sqlite3_db_filename",           test_db_filename,        0},
  7881   7908        { "sqlite3_db_readonly",           test_db_readonly,        0},
  7882   7909        { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
         7910  +     { "sqlite3_soft_heap_limit64",     test_soft_heap_limit,    0},
         7911  +     { "sqlite3_hard_heap_limit64",     test_hard_heap_limit,    0},
  7883   7912        { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
  7884   7913        { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},
  7885   7914   
  7886   7915        { "sqlite3_load_extension",        test_load_extension,     0},
  7887   7916        { "sqlite3_enable_load_extension", test_enable_load,        0},
  7888   7917        { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
  7889   7918        { "sqlite3_limit",                 test_limit,                 0},

Changes to src/treeview.c.

    62     62       }
    63     63       sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
    64     64     }
    65     65     if( zFormat!=0 ){
    66     66       va_start(ap, zFormat);
    67     67       sqlite3_str_vappendf(&acc, zFormat, ap);
    68     68       va_end(ap);
    69         -    assert( acc.nChar>0 );
           69  +    assert( acc.nChar>0 || acc.accError );
    70     70       sqlite3_str_append(&acc, "\n", 1);
    71     71     }
    72     72     sqlite3StrAccumFinish(&acc);
    73     73     fprintf(stdout,"%s", zBuf);
    74     74     fflush(stdout);
    75     75   }
    76     76   

Changes to tool/mkpragmatab.tcl.

   400    400     IF:   defined(SQLITE_HAS_CODEC)
   401    401   
   402    402     NAME: activate_extensions
   403    403     IF:   defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
   404    404   
   405    405     NAME: soft_heap_limit
   406    406     FLAG: Result0
          407  +
          408  +  NAME: hard_heap_limit
          409  +  FLAG: Result0
   407    410   
   408    411     NAME: threads
   409    412     FLAG: Result0
   410    413   
   411    414     NAME: optimize
   412    415     FLAG: Result1 NeedSchema
   413    416