SQLite

Check-in [5dd865da5e]
Login

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

Overview
Comment:Separate verbs of sqlite3_config() and sqlite3_db_config() into their own namespaces. Allow SQLITE3_DBCONFIG_LOOKASIDE to specific an external memory buffer. (CVS 5536)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5dd865da5e787c10ef4c9e96647724bfab9dea01
User & Date: drh 2008-08-04 20:13:27.000
Context
2008-08-05
17:53
Add SQLITE_STATUS_PAGECACHE_SIZE and SQLITE_STATUS_SCRATCH_SIZE. (CVS 5537) (check-in: c4e9b82406 user: drh tags: trunk)
2008-08-04
20:13
Separate verbs of sqlite3_config() and sqlite3_db_config() into their own namespaces. Allow SQLITE3_DBCONFIG_LOOKASIDE to specific an external memory buffer. (CVS 5536) (check-in: 5dd865da5e user: drh tags: trunk)
14:50
Modify the configure script to avoid using the += operator. Not all shells support it. (CVS 5535) (check-in: f167b2745d user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.485 2008/08/01 18:47:02 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.486 2008/08/04 20:13:27 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
290
291
292
293
294
295
296






297
298
299
300
301
302
303
304
305

306
307
308




309

310
311
312

313
314
315
316
317
318
319
  return rc;
}

/*
** Set up the lookaside buffers for a database connection.
** Return SQLITE_OK on success.  
** If lookaside is already active, return SQLITE_BUSY.






*/
static int setupLookaside(sqlite3 *db, int sz, int cnt){
  void *pStart;
  if( db->lookaside.nOut ){
    return SQLITE_BUSY;
  }
  if( sz<0 ) sz = 0;
  if( cnt<0 ) cnt = 0;
  sz = (sz+7)&~7;

  sqlite3BeginBenignMalloc();
  pStart = sqlite3Malloc( sz*cnt );
  sqlite3EndBenignMalloc();




  sqlite3_free(db->lookaside.pStart);

  db->lookaside.pStart = pStart;
  db->lookaside.pFree = 0;
  db->lookaside.sz = sz;

  if( pStart ){
    int i;
    LookasideSlot *p;
    p = (LookasideSlot*)pStart;
    for(i=cnt-1; i>=0; i--){
      p->pNext = db->lookaside.pFree;
      db->lookaside.pFree = p;







>
>
>
>
>
>

|







>
|
|
|
>
>
>
>
|
>



>







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
  return rc;
}

/*
** Set up the lookaside buffers for a database connection.
** Return SQLITE_OK on success.  
** If lookaside is already active, return SQLITE_BUSY.
**
** The sz parameter is the number of bytes in each lookaside slot.
** The cnt parameter is the number of slots.  If pStart is NULL the
** space for the lookaside memory is obtained from sqlite3_malloc().
** If pStart is not NULL then it is sz*cnt bytes of memory to use for
** the lookaside memory.
*/
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
  void *pStart;
  if( db->lookaside.nOut ){
    return SQLITE_BUSY;
  }
  if( sz<0 ) sz = 0;
  if( cnt<0 ) cnt = 0;
  sz = (sz+7)&~7;
  if( pBuf==0 ){
    sqlite3BeginBenignMalloc();
    pStart = sqlite3Malloc( sz*cnt );
    sqlite3EndBenignMalloc();
  }else{
    pStart = pBuf;
  }
  if( db->lookaside.bMalloced ){
    sqlite3_free(db->lookaside.pStart);
  }
  db->lookaside.pStart = pStart;
  db->lookaside.pFree = 0;
  db->lookaside.sz = sz;
  db->lookaside.bMalloced = pBuf==0;
  if( pStart ){
    int i;
    LookasideSlot *p;
    p = (LookasideSlot*)pStart;
    for(i=cnt-1; i>=0; i--){
      p->pNext = db->lookaside.pFree;
      db->lookaside.pFree = p;
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
349
** Configuration settings for an individual database connection
*/
int sqlite3_db_config(sqlite3 *db, int op, ...){
  va_list ap;
  int rc;
  va_start(ap, op);
  switch( op ){
    case SQLITE_CONFIG_LOOKASIDE: {

      int sz = va_arg(ap, int);
      int cnt = va_arg(ap, int);
      rc = setupLookaside(db, sz, cnt);
      break;
    }
    default: {
      rc = SQLITE_ERROR;
      break;
    }
  }







|
>


|







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
** Configuration settings for an individual database connection
*/
int sqlite3_db_config(sqlite3 *db, int op, ...){
  va_list ap;
  int rc;
  va_start(ap, op);
  switch( op ){
    case SQLITE_DBCONFIG_LOOKASIDE: {
      void *pBuf = va_arg(ap, void*);
      int sz = va_arg(ap, int);
      int cnt = va_arg(ap, int);
      rc = setupLookaside(db, pBuf, sz, cnt);
      break;
    }
    default: {
      rc = SQLITE_ERROR;
      break;
    }
  }
541
542
543
544
545
546
547

548

549
550
551
552
553
554
555
  ** the same sqliteMalloc() as the one that allocates the database 
  ** structure?
  */
  sqlite3DbFree(db, db->aDb[1].pSchema);
  sqlite3_mutex_leave(db->mutex);
  db->magic = SQLITE_MAGIC_CLOSED;
  sqlite3_mutex_free(db->mutex);

  sqlite3_free(db->lookaside.pStart);

  sqlite3_free(db);
  return SQLITE_OK;
}

/*
** Rollback all database files.
*/







>
|
>







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
  ** the same sqliteMalloc() as the one that allocates the database 
  ** structure?
  */
  sqlite3DbFree(db, db->aDb[1].pSchema);
  sqlite3_mutex_leave(db->mutex);
  db->magic = SQLITE_MAGIC_CLOSED;
  sqlite3_mutex_free(db->mutex);
  if( db->lookaside.bMalloced ){
    sqlite3_free(db->lookaside.pStart);
  }
  sqlite3_free(db);
  return SQLITE_OK;
}

/*
** Rollback all database files.
*/
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
#ifdef SQLITE_DEFAULT_LOCKING_MODE
  db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
  sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
                          SQLITE_DEFAULT_LOCKING_MODE);
#endif

  /* Enable the lookaside-malloc subsystem */
  setupLookaside(db, sqlite3Config.szLookaside, sqlite3Config.nLookaside);

opendb_out:
  if( db ){
    assert( db->mutex!=0 || isThreadsafe==0 || sqlite3Config.bFullMutex==0 );
    sqlite3_mutex_leave(db->mutex);
  }
  if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){







|







1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
#ifdef SQLITE_DEFAULT_LOCKING_MODE
  db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
  sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
                          SQLITE_DEFAULT_LOCKING_MODE);
#endif

  /* Enable the lookaside-malloc subsystem */
  setupLookaside(db, 0, sqlite3Config.szLookaside, sqlite3Config.nLookaside);

opendb_out:
  if( db ){
    assert( db->mutex!=0 || isThreadsafe==0 || sqlite3Config.bFullMutex==0 );
    sqlite3_mutex_leave(db->mutex);
  }
  if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
Changes to src/sqlite.h.in.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.385 2008/08/04 13:44:57 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.386 2008/08/04 20:13:27 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
979
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994
** sqlite3_db_config() interface can only be used immediately after
** the database connection is created using [sqlite3_open()],
** [sqlite3_open16()], or [sqlite3_open_v2()].  
**
** The second argument to sqlite3_db_config(D,V,...)  is the
** configuration verb - an integer code that indicates what
** aspect of the [database connection] is being configured.
** Choices for this value are [SQLITE_CONFIG_LOOKASIDE].
** New verbs are likely to be added in future releases of SQLite.

*/
int sqlite3_db_config(sqlite3*, int op, ...);

/*
** CAPI3REF: Memory Allocation Routines {H10155} <S20120>
** EXPERIMENTAL
**







|

>







979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
** sqlite3_db_config() interface can only be used immediately after
** the database connection is created using [sqlite3_open()],
** [sqlite3_open16()], or [sqlite3_open_v2()].  
**
** The second argument to sqlite3_db_config(D,V,...)  is the
** configuration verb - an integer code that indicates what
** aspect of the [database connection] is being configured.
** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE].
** New verbs are likely to be added in future releases of SQLite.
** Additional arguments depend on the verb.
*/
int sqlite3_db_config(sqlite3*, int op, ...);

/*
** CAPI3REF: Memory Allocation Routines {H10155} <S20120>
** EXPERIMENTAL
**
1188
1189
1190
1191
1192
1193
1194






























1195
1196
1197
1198
1199
1200
1201
#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_CHUNKALLOC   12  /* int threshold */
#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
































/*
** CAPI3REF: Enable Or Disable Extended Result Codes {H12200} <S10700>
**
** The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. The extended result
** codes are disabled by default for historical compatibility considerations.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_CHUNKALLOC   12  /* int threshold */
#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */

/*
** CAPI3REF: Configuration Options {H10170} <S20000>
** EXPERIMENTAL
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued.  Applications
** should check the return code from [sqlite3_db_config()] to make sure that
** the call worked.  The [sqlite3_db_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
** <dl>
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd>This option takes three additional arguments that determine the 
** [lookaside memory allocator] configuration for the [database connection].
** The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.  The first
** argument may be NULL in which case SQLite will allocate the lookaside
** buffer itself using [sqlite3_malloc()].  The second argument is the
** size of each lookaside buffer slot and the third argument is the number of
** slots.  The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.</dd>
**
** </dl>
*/
#define SQLITE_DBCONFIG_LOOKASIDE    1001  /* void* int int */


/*
** CAPI3REF: Enable Or Disable Extended Result Codes {H12200} <S10700>
**
** The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. The extended result
** codes are disabled by default for historical compatibility considerations.
Changes to src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.751 2008/08/02 15:32:40 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.752 2008/08/04 20:13:27 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
571
572
573
574
575
576
577

578
579
580
581
582
583
584
** lookaside malloc subsystem.  Each available memory allocation in
** the lookaside subsystem is stored on a linked list of LookasideSlot
** objects.
*/
struct Lookaside {
  u16 sz;                 /* Size of each buffer in bytes */
  u8 bEnabled;            /* True if use lookaside.  False to ignore it */

  int nOut;               /* Number of buffers currently checked out */
  int mxOut;              /* Highwater mark for nOut */
  LookasideSlot *pFree;   /* List if available buffers */
  void *pStart;           /* First byte of available memory space */
  void *pEnd;             /* First byte past end of available space */
};
struct LookasideSlot {







>







571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
** lookaside malloc subsystem.  Each available memory allocation in
** the lookaside subsystem is stored on a linked list of LookasideSlot
** objects.
*/
struct Lookaside {
  u16 sz;                 /* Size of each buffer in bytes */
  u8 bEnabled;            /* True if use lookaside.  False to ignore it */
  u8 bMalloced;           /* True if pStart obtained from sqlite3_malloc() */
  int nOut;               /* Number of buffers currently checked out */
  int mxOut;              /* Highwater mark for nOut */
  LookasideSlot *pFree;   /* List if available buffers */
  void *pStart;           /* First byte of available memory space */
  void *pEnd;             /* First byte past end of available space */
};
struct LookasideSlot {
Changes to src/test_malloc.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.45 2008/08/01 16:31:14 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>








|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.46 2008/08/04 20:13:27 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

1001
1002
1003
1004
1005
1006
1007
1008
1009



1010
1011
1012
1013
1014
1015
1016
1017
1018
1019


1020
1021
1022
1023
1024
1025
1026
1027


1028






1029
1030
1031
1032
1033
1034
1035
  rc = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return TCL_OK;
}


/*
** Usage:    sqlite3_db_config_lookaside  CONNECTION  SIZE  COUNT
**



*/
static int test_db_config_lookaside(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc;
  int sz, cnt;
  sqlite3 *db;


  int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SIZE COUNT");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[3], &cnt) ) return TCL_ERROR;


  rc = sqlite3_db_config(db, SQLITE_CONFIG_LOOKASIDE, sz, cnt);






  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return TCL_OK;
}

/*
** Usage:
**







|

>
>
>










>
>

|
|



|
|
>
>
|
>
>
>
>
>
>







1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
  rc = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, cnt);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return TCL_OK;
}


/*
** Usage:    sqlite3_db_config_lookaside  CONNECTION  BUFID  SIZE  COUNT
**
** There are two static buffers with BUFID 1 and 2.   Each static buffer
** is 10KB in size.  A BUFID of 0 indicates that the buffer should be NULL
** which will cause sqlite3_db_config() to allocate space on its own.
*/
static int test_db_config_lookaside(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc;
  int sz, cnt;
  sqlite3 *db;
  int bufid;
  static char azBuf[2][10000];
  int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
  if( objc!=5 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BUFID SIZE COUNT");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &bufid) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR;
  if( bufid==0 ){
    rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, 0, sz, cnt);
  }else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){
    rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt);
  }else{
    Tcl_AppendResult(interp, "illegal arguments - see documentation", (char*)0);
    return TCL_ERROR;
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return TCL_OK;
}

/*
** Usage:
**
Changes to test/altermalloc.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ALTER TABLE statement and
# specifically out-of-memory conditions within that command.
#
# $Id: altermalloc.test,v 1.8 2008/08/01 18:47:02 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable||!memdebug {
  finish_test
  return
}

source $testdir/malloc_common.tcl

do_malloc_test altermalloc-1 -tclprep {
  db close
} -tclbody {
  if {[catch {sqlite3 db test.db}]} {
    error "out of memory"
  }
  sqlite3_db_config_lookaside db 0 0
  sqlite3_extended_result_codes db 1
} -sqlbody {
  CREATE TABLE t1(a int);
  ALTER TABLE t1 ADD COLUMN b INTEGER DEFAULT NULL;
  ALTER TABLE t1 ADD COLUMN c TEXT DEFAULT 'default-text';
  ALTER TABLE t1 RENAME TO t2;
}

# Test malloc() failure on an ALTER TABLE on a virtual table.
#
ifcapable vtab {
  do_malloc_test altermalloc-vtab -tclprep {
    sqlite3 db2 test.db 
    sqlite3_db_config_lookaside db2 0 0
    sqlite3_extended_result_codes db2 1
    register_echo_module [sqlite3_connection_pointer db2]
    db2 eval {
      CREATE TABLE t1(a, b VARCHAR, c INTEGER);
      CREATE VIRTUAL TABLE t1echo USING echo(t1);
    }
    db2 close







|



















|













|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ALTER TABLE statement and
# specifically out-of-memory conditions within that command.
#
# $Id: altermalloc.test,v 1.9 2008/08/04 20:13:27 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable||!memdebug {
  finish_test
  return
}

source $testdir/malloc_common.tcl

do_malloc_test altermalloc-1 -tclprep {
  db close
} -tclbody {
  if {[catch {sqlite3 db test.db}]} {
    error "out of memory"
  }
  sqlite3_db_config_lookaside db 0 0 0
  sqlite3_extended_result_codes db 1
} -sqlbody {
  CREATE TABLE t1(a int);
  ALTER TABLE t1 ADD COLUMN b INTEGER DEFAULT NULL;
  ALTER TABLE t1 ADD COLUMN c TEXT DEFAULT 'default-text';
  ALTER TABLE t1 RENAME TO t2;
}

# Test malloc() failure on an ALTER TABLE on a virtual table.
#
ifcapable vtab {
  do_malloc_test altermalloc-vtab -tclprep {
    sqlite3 db2 test.db 
    sqlite3_db_config_lookaside db2 0 0 0
    sqlite3_extended_result_codes db2 1
    register_echo_module [sqlite3_connection_pointer db2]
    db2 eval {
      CREATE TABLE t1(a, b VARCHAR, c INTEGER);
      CREATE VIRTUAL TABLE t1echo USING echo(t1);
    }
    db2 close
Changes to test/attachmalloc.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH statement and
# specifically out-of-memory conditions within that command.
#
# $Id: attachmalloc.test,v 1.8 2008/08/01 20:10:09 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !memdebug||!attach {
  finish_test







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH statement and
# specifically out-of-memory conditions within that command.
#
# $Id: attachmalloc.test,v 1.9 2008/08/04 20:13:27 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !memdebug||!attach {
  finish_test
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    file delete -force test$i.db
    file delete -force test$i.db-journal
  }
} -tclbody {
  if {[catch {sqlite3 db test.db}]} {
    error "out of memory"
  }
  sqlite3_db_config_lookaside db 0 0
  sqlite3_extended_result_codes db 1
} -sqlbody {
  ATTACH 'test2.db' AS two;
  CREATE TABLE two.t1(x);
  ATTACH 'test3.db' AS three;
  CREATE TABLE three.t1(x);
  ATTACH 'test4.db' AS four;
  CREATE TABLE four.t1(x);
}

finish_test







|











31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    file delete -force test$i.db
    file delete -force test$i.db-journal
  }
} -tclbody {
  if {[catch {sqlite3 db test.db}]} {
    error "out of memory"
  }
  sqlite3_db_config_lookaside db 0 0 0
  sqlite3_extended_result_codes db 1
} -sqlbody {
  ATTACH 'test2.db' AS two;
  CREATE TABLE two.t1(x);
  ATTACH 'test3.db' AS three;
  CREATE TABLE three.t1(x);
  ATTACH 'test4.db' AS four;
  CREATE TABLE four.t1(x);
}

finish_test
Changes to test/lookaside.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 2008 August 01
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests for the lookaside memory allocator.
#
# $Id: lookaside.test,v 1.2 2008/08/01 18:47:02 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

catch {db close}
sqlite3_shutdown
sqlite3_config_pagecache 0 0
sqlite3_config_scratch 0 0
sqlite3_initialize
sqlite3 db test.db

# Make sure sqlite3_db_config() and sqlite3_db_status are working.
#
do_test lookaside-1.1 {
  catch {sqlite3_config_error db}
} {0}
do_test lookaside-1.2 {
  sqlite3_db_config_lookaside db 20 20
} {0}
do_test lookaside-1.3 {
  sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0
} {0 0 0}
do_test lookaside-1.4 {
  db eval {CREATE TABLE t1(x);}
  foreach {x y z} [sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0] break













|

















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 2008 August 01
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests for the lookaside memory allocator.
#
# $Id: lookaside.test,v 1.3 2008/08/04 20:13:27 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

catch {db close}
sqlite3_shutdown
sqlite3_config_pagecache 0 0
sqlite3_config_scratch 0 0
sqlite3_initialize
sqlite3 db test.db

# Make sure sqlite3_db_config() and sqlite3_db_status are working.
#
do_test lookaside-1.1 {
  catch {sqlite3_config_error db}
} {0}
do_test lookaside-1.2 {
  sqlite3_db_config_lookaside db 1 20 20
} {0}
do_test lookaside-1.3 {
  sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0
} {0 0 0}
do_test lookaside-1.4 {
  db eval {CREATE TABLE t1(x);}
  foreach {x y z} [sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0] break
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
} {1}
do_test lookaside-1.9 {
  db cache flush
  sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0
} {0 0 0}

do_test lookaside-2.1 {
  sqlite3_db_config_lookaside db 100 1000
} {0}
do_test lookaside-2.2 {
  db eval {CREATE TABLE t2(x);}
  foreach {x y z} [sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0] break
  expr {$x==0 && $y<$z && $z>10 && $z<100}
} {1}
do_test lookaside-2.3 {
  sqlite3_db_config_lookaside db 50 50
} {5}  ;# SQLITE_BUSY
do_test lookaside-2.4 {
  db cache flush
  sqlite3_db_config_lookaside db 50 50
} {0}  ;# SQLITE_OK

# sqlite3_db_status() with an invalid verb returns an error.
#
do_test lookaside-3.1 {
  sqlite3_db_status db 99999 0
} {1 0 0}







|







|



|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
} {1}
do_test lookaside-1.9 {
  db cache flush
  sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0
} {0 0 0}

do_test lookaside-2.1 {
  sqlite3_db_config_lookaside db 0 100 1000
} {0}
do_test lookaside-2.2 {
  db eval {CREATE TABLE t2(x);}
  foreach {x y z} [sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0] break
  expr {$x==0 && $y<$z && $z>10 && $z<100}
} {1}
do_test lookaside-2.3 {
  sqlite3_db_config_lookaside db 0 50 50
} {5}  ;# SQLITE_BUSY
do_test lookaside-2.4 {
  db cache flush
  sqlite3_db_config_lookaside db 0 50 50
} {0}  ;# SQLITE_OK

# sqlite3_db_status() with an invalid verb returns an error.
#
do_test lookaside-3.1 {
  sqlite3_db_status db 99999 0
} {1 0 0}
Changes to test/malloc_common.tcl.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.20 2008/08/01 18:47:02 drh Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable builtin_test {
  set MEMDEBUG 1
} else {
  set MEMDEBUG 0







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains common code used by many different malloc tests
# within the test suite.
#
# $Id: malloc_common.tcl,v 1.21 2008/08/04 20:13:27 drh Exp $

# If we did not compile with malloc testing enabled, then do nothing.
#
ifcapable builtin_test {
  set MEMDEBUG 1
} else {
  set MEMDEBUG 0
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
        if {[info exists ::mallocopts(-testdb)]} {
          file copy $::mallocopts(-testdb) test.db
        }
        catch { sqlite3 db test.db }
        if {[info commands db] ne ""} {
          sqlite3_extended_result_codes db 1
        }
        sqlite3_db_config_lookaside db 0 0
  
        # Execute any -tclprep and -sqlprep scripts.
        #
        if {[info exists ::mallocopts(-tclprep)]} {
          eval $::mallocopts(-tclprep)
        }
        if {[info exists ::mallocopts(-sqlprep)]} {







|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
        if {[info exists ::mallocopts(-testdb)]} {
          file copy $::mallocopts(-testdb) test.db
        }
        catch { sqlite3 db test.db }
        if {[info commands db] ne ""} {
          sqlite3_extended_result_codes db 1
        }
        sqlite3_db_config_lookaside db 0 0 0
  
        # Execute any -tclprep and -sqlprep scripts.
        #
        if {[info exists ::mallocopts(-tclprep)]} {
          eval $::mallocopts(-tclprep)
        }
        if {[info exists ::mallocopts(-sqlprep)]} {
Changes to test/memsubsys1.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 2008 June 18
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests of the memory allocation subsystem
#
# $Id: memsubsys1.test,v 1.7 2008/07/31 17:20:59 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
sqlite3_reset_auto_extension

# This procedure constructs a new database in test.db.  It fills
# this database with many small records (enough to force multiple
# rebalance operations in the btree-layer and to require a large
# page cache), verifies correct results, then returns.
#
proc build_test_db {testname pragmas} {
  catch {db close}
  file delete -force test.db test.db-journal
  sqlite3 db test.db
  sqlite3_db_config_lookaside db 0 0
  db eval $pragmas
  db eval {
    CREATE TABLE t1(x, y);
    CREATE TABLE t2(a, b);
    CREATE INDEX i1 ON t1(x,y);
    INSERT INTO t1 VALUES(1, 100);
    INSERT INTO t1 VALUES(2, 200);













|














|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 2008 June 18
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests of the memory allocation subsystem
#
# $Id: memsubsys1.test,v 1.8 2008/08/04 20:13:27 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
sqlite3_reset_auto_extension

# This procedure constructs a new database in test.db.  It fills
# this database with many small records (enough to force multiple
# rebalance operations in the btree-layer and to require a large
# page cache), verifies correct results, then returns.
#
proc build_test_db {testname pragmas} {
  catch {db close}
  file delete -force test.db test.db-journal
  sqlite3 db test.db
  sqlite3_db_config_lookaside db 0 0 0
  db eval $pragmas
  db eval {
    CREATE TABLE t1(x, y);
    CREATE TABLE t2(a, b);
    CREATE INDEX i1 ON t1(x,y);
    INSERT INTO t1 VALUES(1, 100);
    INSERT INTO t1 VALUES(2, 200);