Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -12,11 +12,11 @@ ** 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.483 2008/07/28 19:34:53 drh Exp $ +** $Id: main.c,v 1.484 2008/08/01 16:31:14 drh Exp $ */ #include "sqliteInt.h" #include #ifdef SQLITE_ENABLE_FTS3 @@ -328,18 +328,22 @@ /* ** Configuration settings for an individual database connection */ int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; - int rc = SQLITE_OK; + 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; } } va_end(ap); return rc; } Index: src/malloc.c ================================================================== --- src/malloc.c +++ src/malloc.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. ** -** $Id: malloc.c,v 1.32 2008/07/31 17:16:05 drh Exp $ +** $Id: malloc.c,v 1.33 2008/08/01 16:31:14 drh Exp $ */ #include "sqliteInt.h" #include #include @@ -110,12 +110,12 @@ } memset(&mem0, 0, sizeof(mem0)); if( sqlite3Config.bCoreMutex ){ mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } - if( sqlite3Config.pScratch && sqlite3Config.szScratch>=3000 - && sqlite3Config.nScratch>0 ){ + if( sqlite3Config.pScratch && sqlite3Config.szScratch>=100 + && sqlite3Config.nScratch>=0 ){ int i; sqlite3Config.szScratch -= 4; mem0.aScratchFree = (u32*)&((char*)sqlite3Config.pScratch) [sqlite3Config.szScratch*sqlite3Config.nScratch]; for(i=0; i=512 - && sqlite3Config.nPage>1 ){ + && sqlite3Config.nPage>=1 ){ int i; int overhead; int sz = sqlite3Config.szPage; int n = sqlite3Config.nPage; overhead = (4*n + sz - 1)/sz; Index: src/status.c ================================================================== --- src/status.c +++ src/status.c @@ -11,11 +11,11 @@ ************************************************************************* ** ** This module implements the sqlite3_status() interface and related ** functionality. ** -** $Id: status.c,v 1.5 2008/07/28 19:34:54 drh Exp $ +** $Id: status.c,v 1.6 2008/08/01 16:31:14 drh Exp $ */ #include "sqliteInt.h" /* ** Variables in which to record status information. @@ -101,8 +101,11 @@ if( resetFlag ){ db->lookaside.mxOut = db->lookaside.nOut; } break; } + default: { + return SQLITE_ERROR; + } } return SQLITE_OK; } Index: src/test_malloc.c ================================================================== --- src/test_malloc.c +++ src/test_malloc.c @@ -11,11 +11,11 @@ ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** -** $Id: test_malloc.c,v 1.44 2008/07/31 17:16:05 drh Exp $ +** $Id: test_malloc.c,v 1.45 2008/08/01 16:31:14 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include #include @@ -884,11 +884,11 @@ free(buf); if( sz<0 ){ buf = 0; rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, 0, 0, 0); }else{ - buf = malloc( sz*N ); + buf = malloc( sz*N + 1 ); rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N); } pResult = Tcl_NewObj(); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N)); @@ -1069,10 +1069,48 @@ } Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); return TCL_OK; } + +/* +** tclcmd: sqlite3_config_error [DB] +** +** Invoke sqlite3_config() or sqlite3_db_config() with invalid +** opcodes and verify that they return errors. +*/ +static int test_config_error( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int getDbPointer(Tcl_Interp*, const char*, sqlite3**); + + if( objc!=2 && objc!=1 ){ + Tcl_WrongNumArgs(interp, 1, objv, "[DB]"); + return TCL_ERROR; + } + if( objc==2 ){ + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + if( sqlite3_db_config(db, 99999)!=SQLITE_ERROR ){ + Tcl_AppendResult(interp, + "sqlite3_db_config(db, 99999) does not return SQLITE_ERROR", + (char*)0); + return TCL_ERROR; + } + }else{ + if( sqlite3_config(99999)!=SQLITE_ERROR ){ + Tcl_AppendResult(interp, + "sqlite3_config(99999) does not return SQLITE_ERROR", + (char*)0); + return TCL_ERROR; + } + } + return TCL_OK; +} /* ** Usage: ** ** sqlite3_dump_memsys3 FILENAME @@ -1269,10 +1307,11 @@ { "install_malloc_faultsim", test_install_malloc_faultsim ,0 }, { "sqlite3_config_heap", test_config_heap ,0 }, { "sqlite3_config_memstatus", test_config_memstatus ,0 }, { "sqlite3_config_chunkalloc", test_config_chunkalloc ,0 }, { "sqlite3_config_lookaside", test_config_lookaside ,0 }, + { "sqlite3_config_error", test_config_error ,0 }, { "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 }, { "sqlite3_dump_memsys3", test_dump_memsys3 ,3 }, { "sqlite3_dump_memsys5", test_dump_memsys3 ,5 } }; int i; ADDED test/lookaside.test Index: test/lookaside.test ================================================================== --- /dev/null +++ test/lookaside.test @@ -0,0 +1,82 @@ +# 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.1 2008/08/01 16:31:14 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# 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);} + sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0 +} {0 7 20} +do_test lookaside-1.5 { + sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 1 +} {0 7 20} +do_test lookaside-1.6 { + sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0 +} {0 7 7} +do_test lookaside-1.7 { + db cache flush + sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0 +} {0 0 7} +do_test lookaside-1.8 { + db cache flush + sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 1 +} {0 0 7} +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);} + sqlite3_db_status db SQLITE_DBSTATUS_LOOKASIDE_USED 0 +} {0 10 48} +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} + +# Test that an invalid verb on sqlite3_config() is detected and +# reported as an error. +# +do_test lookaside-4.1 { + db close + sqlite3_shutdown + catch sqlite3_config_error +} {0} +sqlite3_initialize