From cd61c2816f9dad776b2aa91d2efeed9dbc856c99 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Mar 2002 22:01:34 +0000 Subject: [PATCH] Added the default_cache_size and default_synchronous pragmas. Added additional tests for pragmas. Added a new speedtest script. (CVS 421) FossilOrigin-Name: 161c0c5f5db66815e4345c9b5f7a600c03a67475 --- manifest | 30 ++++--- manifest.uuid | 2 +- src/btree.c | 14 ++- src/build.c | 125 +++++++++++++++++++++++++- src/main.c | 8 +- src/pager.c | 9 +- src/sqliteInt.h | 3 +- src/vdbe.c | 5 +- test/all.test | 7 +- test/pragma.test | 120 +++++++++++++++++++++++++ test/tester.tcl | 5 +- tool/speedtest.tcl | 38 +++++--- tool/speedtest2.tcl | 207 ++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 533 insertions(+), 40 deletions(-) create mode 100644 test/pragma.test create mode 100644 tool/speedtest2.tcl diff --git a/manifest b/manifest index 42c7d5d7a1..6d1e7261bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimizations\sto\sthe\sprocessing\sof\sinteger\scomparisons.\s(CVS\s420) -D 2002-03-06T03:08:26 +C Added\sthe\sdefault_cache_size\sand\sdefault_synchronous\spragmas.\s\sAdded\sadditional\ntests\sfor\spragmas.\s\sAdded\sa\snew\sspeedtest\sscript.\s(CVS\s421) +D 2002-03-06T22:01:35 F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 @@ -19,20 +19,20 @@ F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1 F publish.sh 5b59f4aff037aafa0e4a3b6fa599495dbd73f360 F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 -F src/btree.c b7d1b8875113ab4061a6a8cc759f75728ae7daf0 +F src/btree.c 7dd7ddc66459982dd0cb9800958c1f8d65a32d9f F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3 -F src/build.c 0f3c6b6482e0b74284b22661de1b813a0bfb0197 +F src/build.c d01b81f41481e733e27ab2fa8e1bfcc64f24257d F src/delete.c 577da499162291c1855f0b304b211bffcf9da945 F src/expr.c d2adad05dc2fe112aef364bdb9c0eb8877618bbe F src/func.c 87516e7dc37190c24af77593931a5d09d797520a F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892 F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9 F src/insert.c 42bfd145efd428d7e5f200dd49ea0b816fc30d79 -F src/main.c 3015c23faeff1709b1528f07c0bfe839284090a8 +F src/main.c b21019084b93fe685a8a25217d01f6958584ae9b F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c F src/os.c db969ecd1bcb4fef01b0b541b8b17401b0eb7ed2 F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6 -F src/pager.c e1419353e68c45aaae2555d2000f72de6525faac +F src/pager.c f136f5ba82c896d500a10b6a2e5caea62abf716b F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e F src/parse.y f7483ccff7b8f16d3655df59775d85b62b06897e F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d @@ -41,7 +41,7 @@ F src/select.c 49c78aa0c96dda036846937b516658536db98b56 F src/shell.c b3454229599246b944cdb5b95753af3fca5d8bb0 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in a9b5772604265f98f3120573ef29e37b9d917216 -F src/sqliteInt.h 46f41e2f4cf90cdbe002f6b4143ae3f16ae0b872 +F src/sqliteInt.h 6f4a1bea4858089eb516f59562762965c6ef5cb8 F src/table.c 203a09d5d0009eeeb1f670370d52b4ce163a3b52 F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f @@ -51,10 +51,10 @@ F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af F src/update.c 7dd714a6a7fa47f849ebb36b6d915974d6c6accb F src/util.c b34cd91387bbfdc79319ea451a7d120cef478120 -F src/vdbe.c fcbe9d3c1b87f18ed3d7f0553f6c4194fb74a85d +F src/vdbe.c ce375b8948fb3b21da50536b7d063a3071b5c982 F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc F src/where.c 34d91fd5d822c2663caeb023f72d60df316ebf29 -F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049 +F test/all.test 6aa106eee4d7127afa5cee97c51a783a79694ead F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/btree.test bf326f546a666617367a7033fa2c07451bd4f8e1 F test/btree2.test e3b81ec33dc2f89b3e6087436dfe605b870c9080 @@ -78,6 +78,7 @@ F test/minmax.test fb6ab400271ae1f5bc88617c2882f2f081ea8e6d F test/misc1.test 7fd54d33547177da86e39e13e9608c5112681831 F test/notnull.test b1f3e42fc475b0b5827b27b2e9b562081995ff30 F test/pager.test b0c0d00cd5dce0ce21f16926956b195c0ab5044c +F test/pragma.test 0b9675ef1f5ba5b43abfa337744445fc5b01a34a F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da F test/quick.test 6f023c7a73fc413e6d65b7a1879c79764038dc05 F test/quote.test 286db944717afa9a9bf829dd85e59185c65d5435 @@ -94,7 +95,7 @@ F test/table.test 17b0b6eafa3faaee5545b7a94e6c1ff73f0880f3 F test/tableapi.test 51d0c209aa6b1158cb952ec917c656d4ce66e9e4 F test/tclsqlite.test ca8dd89b02ab68bd4540163c24551756a69f6783 F test/temptable.test 0e9934283259a5e637eec756a7eefd6964c0f79b -F test/tester.tcl 96db1b49157388edb57e11bf33285e3811a897e4 +F test/tester.tcl dc1b56bd628b487e4d75bfd1e7480b5ed8810ac6 F test/trans.test 9e49495c06b1c41f889bf4f0fb195a015b126de0 F test/unique.test 07776624b82221a80c8b4138ce0dd8b0853bb3ea F test/update.test 3cf1ca0565f678063c2dfa9a7948d2d66ae1a778 @@ -108,7 +109,8 @@ F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9 F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816 -F tool/speedtest.tcl 61660a00b9a5ad8566dbc48e9b09071b1ad8a1c3 +F tool/speedtest.tcl 6d89431651f2eb800fb0998a8de44b84168e08b9 +F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4 F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b @@ -128,7 +130,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 480eef1a3a4f049bc0d0cbee32dc8a8d138597c6 -R 293e4b0f9d71b9a7cc31da9375205a15 +P b7a7dae919be0e4c35b1fe8cb24fa7359a4b1200 +R 4ed5325a3b84cb330db6f062fc9a97e7 U drh -Z be460c9473f4d69e9aab54c7c0b566d7 +Z 34b0d04d29e433a78df2f11cc397e416 diff --git a/manifest.uuid b/manifest.uuid index dbe1aa79fb..3d71b2d9c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7a7dae919be0e4c35b1fe8cb24fa7359a4b1200 \ No newline at end of file +161c0c5f5db66815e4345c9b5f7a600c03a67475 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a3a269e315..7a39089944 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.59 2002/03/05 12:41:20 drh Exp $ +** $Id: btree.c,v 1.60 2002/03/06 22:01:35 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -650,6 +650,18 @@ int sqliteBtreeClose(Btree *pBt){ /* ** Change the limit on the number of pages allowed the cache. +** +** The maximum number of cache pages is set to the absolute +** value of mxPage. If mxPage is negative, the pager will +** operate asynchronously - it will not stop to do fsync()s +** to insure data is written to the disk surface before +** continuing. Transactions still work if synchronous is off, +** and the database cannot be corrupted if this program +** crashes. But if the operating system crashes or there is +** an abrupt power failure when synchronous is off, the database +** could be left in an inconsistent and unrecoverable state. +** Synchronous is on by default so database corruption is not +** normally a worry. */ int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){ sqlitepager_set_cachesize(pBt->pPager, mxPage); diff --git a/src/build.c b/src/build.c index 639ba00f7a..108bb4bdf3 100644 --- a/src/build.c +++ b/src/build.c @@ -25,7 +25,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.85 2002/03/05 01:11:13 drh Exp $ +** $Id: build.c,v 1.86 2002/03/06 22:01:36 drh Exp $ */ #include "sqliteInt.h" #include @@ -1736,10 +1736,30 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ sqliteDequote(zRight); } - if( sqliteStrICmp(zLeft,"cache_size")==0 ){ + /* + ** PRAGMA default_cache_size + ** PRAGMA default_cache_size=N + ** + ** The first form reports the current persistent setting for the + ** page cache size. The value returned is the maximum number of + ** pages in the page cache. The second form sets both the current + ** page cache size value and the persistent page cache size value + ** stored in the database file. + ** + ** The default cache size is stored in meta-value 2 of page 1 of the + ** database file. The cache size is actually the absolute value of + ** this memory location. The sign of meta-value 2 determines the + ** synchronous setting. A negative value means synchronous is off + ** and a positive value means synchronous is on. + */ + if( sqliteStrICmp(zLeft,"default_cache_size")==0 ){ static VdbeOp getCacheSize[] = { { OP_ReadCookie, 0, 2, 0}, { OP_AbsValue, 0, 0, 0}, + { OP_Dup, 0, 0, 0}, + { OP_Integer, 0, 0, 0}, + { OP_Ne, 0, 6, 0}, + { OP_Integer, MAX_PAGES,0, 0}, { OP_ColumnCount, 1, 0, 0}, { OP_ColumnName, 0, 0, "cache_size"}, { OP_Callback, 1, 0, 0}, @@ -1760,10 +1780,71 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ sqliteVdbeAddOp(v, OP_Negative, 0, 0); sqliteVdbeAddOp(v, OP_SetCookie, 0, 2); sqliteEndWriteOperation(pParse); + db->cache_size = db->cache_size<0 ? -size : size; + sqliteBtreeSetCacheSize(db->pBe, db->cache_size); } }else - if( sqliteStrICmp(zLeft,"synchronous")==0 ){ + /* + ** PRAGMA cache_size + ** PRAGMA cache_size=N + ** + ** The first form reports the current local setting for the + ** page cache size. The local setting can be different from + ** the persistent cache size value that is stored in the database + ** file itself. The value returned is the maximum number of + ** pages in the page cache. The second form sets the local + ** page cache size value. It does not change the persistent + ** cache size stored on the disk so the cache size will revert + ** to its default value when the database is closed and reopened. + ** N should be a positive integer. + */ + if( sqliteStrICmp(zLeft,"cache_size")==0 ){ + static VdbeOp getCacheSize[] = { + { OP_ColumnCount, 1, 0, 0}, + { OP_ColumnName, 0, 0, "cache_size"}, + { OP_Callback, 1, 0, 0}, + }; + Vdbe *v = sqliteGetVdbe(pParse); + if( v==0 ) return; + if( pRight->z==pLeft->z ){ + int size = db->cache_size;; + if( size<0 ) size = -size; + sqliteVdbeAddOp(v, OP_Integer, size, 0); + sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); + }else{ + int size = atoi(zRight); + if( size<0 ) size = -size; + if( db->cache_size<0 ) size = -size; + db->cache_size = size; + sqliteBtreeSetCacheSize(db->pBe, db->cache_size); + } + }else + + /* + ** PRAGMA default_synchronous + ** PRAGMA default_synchronous=BOOLEAN + ** + ** The first form returns the persistent value of the "synchronous" setting + ** that is stored in the database. This is the synchronous setting that + ** is used whenever the database is opened unless overridden by a separate + ** "synchronous" pragma. The second form changes the persistent and the + ** local synchronous setting to the value given. + ** + ** If synchronous is on, SQLite will do an fsync() system call at strategic + ** points to insure that all previously written data has actually been + ** written onto the disk surface before continuing. This mode insures that + ** the database will always be in a consistent state event if the operating + ** system crashes or power to the computer is interrupted unexpectedly. + ** When synchronous is off, SQLite will not wait for changes to actually + ** be written to the disk before continuing. As soon as it hands changes + ** to the operating system, it assumes that the changes are permanent and + ** it continues going. The database cannot be corrupted by a program crash + ** even with synchronous off, but an operating system crash or power loss + ** could potentially corrupt data. On the other hand, synchronous off is + ** faster than synchronous on. + */ + if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){ static VdbeOp getSync[] = { { OP_Integer, 0, 0, 0}, { OP_ReadCookie, 0, 2, 0}, @@ -1780,14 +1861,52 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ sqliteVdbeAddOpList(v, ArraySize(getSync), getSync); }else{ int addr; + int size = db->cache_size; + if( size<0 ) size = -size; sqliteBeginWriteOperation(pParse); sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2); + sqliteVdbeAddOp(v, OP_Dup, 0, 0); + addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0); + sqliteVdbeAddOp(v, OP_Ne, 0, addr+3); + sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0); sqliteVdbeAddOp(v, OP_AbsValue, 0, 0); if( !getBoolean(zRight) ){ sqliteVdbeAddOp(v, OP_Negative, 0, 0); + size = -size; } sqliteVdbeAddOp(v, OP_SetCookie, 0, 2); sqliteEndWriteOperation(pParse); + db->cache_size = size; + sqliteBtreeSetCacheSize(db->pBe, db->cache_size); + } + }else + + /* + ** PRAGMA synchronous + ** PRAGMA synchronous=BOOLEAN + ** + ** Return or set the local value of the synchronous flag. Changing + ** the local value does not make changes to the disk file and the + ** default value will be restored the next time the database is + ** opened. + */ + if( sqliteStrICmp(zLeft,"synchronous")==0 ){ + static VdbeOp getSync[] = { + { OP_ColumnCount, 1, 0, 0}, + { OP_ColumnName, 0, 0, "synchronous"}, + { OP_Callback, 1, 0, 0}, + }; + Vdbe *v = sqliteGetVdbe(pParse); + if( v==0 ) return; + if( pRight->z==pLeft->z ){ + sqliteVdbeAddOp(v, OP_Integer, db->cache_size>=0, 0); + sqliteVdbeAddOpList(v, ArraySize(getSync), getSync); + }else{ + int size = db->cache_size; + if( size<0 ) size = -size; + if( !getBoolean(zRight) ) size = -size; + db->cache_size = size; + sqliteBtreeSetCacheSize(db->pBe, db->cache_size); } }else diff --git a/src/main.c b/src/main.c index 62f0952a3a..389507903c 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.67 2002/03/05 01:11:14 drh Exp $ +** $Id: main.c,v 1.68 2002/03/06 22:01:36 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -44,9 +44,9 @@ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){ switch( argv[0][0] ){ case 'c': { /* Recommended pager cache size */ int size = atoi(argv[3]); - if( size!=0 ){ - sqliteBtreeSetCacheSize(db->pBe, size); - } + if( size==0 ){ size = MAX_PAGES; } + db->cache_size = size; + sqliteBtreeSetCacheSize(db->pBe, size); break; } case 'f': { /* File format */ diff --git a/src/pager.c b/src/pager.c index 1f0fb3aed8..ced0016bb2 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.43 2002/03/05 12:41:20 drh Exp $ +** @(#) $Id: pager.c,v 1.44 2002/03/06 22:01:36 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" @@ -434,6 +434,13 @@ end_ckpt_playback: /* ** Change the maximum number of in-memory pages that are allowed. +** +** The maximum number is the absolute value of the mxPage parameter. +** If mxPage is negative, the noSync flag is also set. noSync bypasses +** calls to sqliteOsSync(). The pager runs much faster with noSync on, +** but if the operating system crashes or there is an abrupt power +** failure, the database file might be left in an inconsistent and +** unrepairable state. */ void sqlitepager_set_cachesize(Pager *pPager, int mxPage){ if( mxPage>=0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3520a94e93..e404a7388a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.102 2002/03/05 01:11:14 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.103 2002/03/06 22:01:36 drh Exp $ */ #include "sqlite.h" #include "hash.h" @@ -155,6 +155,7 @@ struct sqlite { int file_format; /* What file format version is this database? */ int schema_cookie; /* Magic number that changes with the schema */ int next_cookie; /* Value of schema_cookie after commit */ + int cache_size; /* Number of pages to use in the cache */ int nTable; /* Number of tables in the database */ void *pBusyArg; /* 1st Argument to the busy callback */ int (*xBusyCallback)(void *,const char*,int); /* The busy callback */ diff --git a/src/vdbe.c b/src/vdbe.c index adb3fbe5e7..f37d57ef3b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -30,7 +30,7 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.132 2002/03/06 03:08:26 drh Exp $ +** $Id: vdbe.c,v 1.133 2002/03/06 22:01:36 drh Exp $ */ #include "sqliteInt.h" #include @@ -4309,7 +4309,8 @@ case OP_MemLoad: { memcpy(&aStack[tos], &p->aMem[i].s, sizeof(aStack[tos])-NBFS);; if( aStack[tos].flags & STK_Str ){ zStack[tos] = p->aMem[i].z; - aStack[tos].flags = STK_Str | STK_Static; + aStack[tos].flags |= STK_Static; + aStack[tos].flags &= ~STK_Dyn; } break; } diff --git a/test/all.test b/test/all.test index 3139bbab3d..ff5c4fbc77 100644 --- a/test/all.test +++ b/test/all.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: all.test,v 1.12 2002/02/18 01:17:00 drh Exp $ +# $Id: all.test,v 1.13 2002/03/06 22:01:36 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -37,6 +37,11 @@ set EXCLUDE { } for {set Counter 0} {$Counter<$COUNT && $nErr==0} {incr Counter} { + if {$Counter%2} { + set ::SETUP_SQL {PRAGMA default_synchronous=off;} + } else { + catch {unset ::SETUP_SQL} + } foreach testfile [lsort -dictionary [glob $testdir/*.test]] { set tail [file tail $testfile] if {[lsearch -exact $EXCLUDE $tail]>=0} continue diff --git a/test/pragma.test b/test/pragma.test new file mode 100644 index 0000000000..f69cb6cb82 --- /dev/null +++ b/test/pragma.test @@ -0,0 +1,120 @@ +# 2002 March 6 +# +# 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 implements regression tests for SQLite library. +# +# This file implements tests for the PRAGMA command. +# +# $Id: pragma.test,v 1.1 2002/03/06 22:01:37 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Delete the preexisting database to avoid the special setup +# that the "all.test" script does. +# +db close +file delete test.db +sqlite db test.db + +do_test pragma-1.1 { + execsql { + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {2000 2000 1 1} +do_test pragma-1.2 { + execsql { + PRAGMA cache_size=1234; + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {1234 2000 1 1} +do_test pragma-1.3 { + db close + sqlite db test.db + execsql { + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {2000 2000 1 1} +do_test pragma-1.4 { + execsql { + PRAGMA synchronous=OFF; + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {2000 2000 0 1} +do_test pragma-1.5 { + execsql { + PRAGMA cache_size=4321; + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {4321 2000 0 1} +do_test pragma-1.6 { + execsql { + PRAGMA synchronous=ON; + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {4321 2000 1 1} +do_test pragma-1.7 { + db close + sqlite db test.db + execsql { + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {2000 2000 1 1} +do_test pragma-1.8 { + execsql { + PRAGMA default_synchronous=OFF; + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {2000 2000 0 0} +do_test pragma-1.9 { + execsql { + PRAGMA default_cache_size=123; + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {123 123 0 0} +do_test pragma-1.10 { + db close + sqlite db test.db + execsql { + PRAGMA cache_size; + PRAGMA default_cache_size; + PRAGMA synchronous; + PRAGMA default_synchronous; + } +} {123 123 0 0} + +finish_test diff --git a/test/tester.tcl b/test/tester.tcl index a30dad84f2..bcda99d29c 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -11,7 +11,7 @@ # This file implements some common TCL routines used for regression # testing the SQLite library # -# $Id: tester.tcl,v 1.21 2001/11/09 22:41:45 drh Exp $ +# $Id: tester.tcl,v 1.22 2002/03/06 22:01:37 drh Exp $ # Make sure tclsqlite was compiled correctly. Abort now with an # error message if not. @@ -46,6 +46,9 @@ catch {db close} file delete -force test.db file delete -force test.db-journal sqlite db ./test.db +if {[info exists ::SETUP_SQL]} { + db eval $::SETUP_SQL +} # Abort early if this script has been run before. # diff --git a/tool/speedtest.tcl b/tool/speedtest.tcl index 276fcc1896..7090e2e425 100644 --- a/tool/speedtest.tcl +++ b/tool/speedtest.tcl @@ -37,9 +37,9 @@ proc runtest {title} { set t [expr {[lindex $t 0]/1000000.0}] puts [format $format PostgreSQL: $t] exec sync; after $delay; -# set t [time "exec mysql -f drh <$sqlfile" 1] -# set t [expr {[lindex $t 0]/1000000.0}] -# puts [format $format MySQL: $t] + set t [time "exec mysql -f drh <$sqlfile" 1] + set t [expr {[lindex $t 0]/1000000.0}] + puts [format $format MySQL: $t] # set t [time "exec ./sqlite232 s232.db <$sqlfile" 1] # set t [expr {[lindex $t 0]/1000000.0}] # puts [format $format {SQLite 2.3.2:} $t] @@ -73,12 +73,17 @@ close $fd catch {exec psql drh =$lwr AND a<$upr;" } puts $fd "COMMIT;" close $fd -runtest {100 UPDATEs without an index} +runtest {1000 UPDATEs without an index} set fd [open test$cnt.sql w] puts $fd "BEGIN;" for {set i 1} {$i<=25000} {incr i} { - puts $fd "UPDATE t2 SET b=b+a WHERE a=$i;" + set r [expr {int(rand()*500000)}] + puts $fd "UPDATE t2 SET b=$r WHERE a=$i;" } puts $fd "COMMIT;" close $fd runtest {25000 UPDATEs with an index} +set fd [open test$cnt.sql w] +puts $fd "BEGIN;" +for {set i 1} {$i<=25000} {incr i} { + set r [expr {int(rand()*500000)}] + puts $fd "UPDATE t2 SET c='[number_name $r]' WHERE a=$i;" +} +puts $fd "COMMIT;" +close $fd +runtest {25000 text UPDATEs with an index} + + set fd [open test$cnt.sql w] puts $fd "BEGIN;" @@ -232,7 +248,7 @@ runtest {A big INSERT after a big DELETE} set fd [open test$cnt.sql w] puts $fd {BEGIN;} puts $fd {DELETE FROM t1;} -for {set i 1} {$i<=1000} {incr i} { +for {set i 1} {$i<=3000} {incr i} { set r [expr {int(rand()*100000)}] puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" } diff --git a/tool/speedtest2.tcl b/tool/speedtest2.tcl new file mode 100644 index 0000000000..4fd632d4c7 --- /dev/null +++ b/tool/speedtest2.tcl @@ -0,0 +1,207 @@ +#!/usr/bin/tclsh +# +# Run this script using TCLSH to do a speed comparison between +# various versions of SQLite and PostgreSQL and MySQL +# + +# Run a test +# +set cnt 1 +proc runtest {title} { + global cnt + set sqlfile test$cnt.sql + puts "

Test $cnt: $title

" + incr cnt + set fd [open $sqlfile r] + set sql [string trim [read $fd [file size $sqlfile]]] + close $fd + set sx [split $sql \n] + set n [llength $sx] + if {$n>8} { + set sql {} + for {set i 0} {$i<3} {incr i} {append sql [lindex $sx $i]
\n} + append sql "... [expr {$n-6}] lines omitted
\n" + for {set i [expr {$n-3}]} {$i<$n} {incr i} { + append sql [lindex $sx $i]
\n + } + } else { + regsub -all \n [string trim $sql]
sql + } + puts "
" + puts "$sql" + puts "
" + set format {} + set delay 1000 + exec sync; after $delay; + set t [time "exec psql drh <$sqlfile" 1] + set t [expr {[lindex $t 0]/1000000.0}] + puts [format $format PostgreSQL: $t] + exec sync; after $delay; + set t [time "exec mysql -f drh <$sqlfile" 1] + set t [expr {[lindex $t 0]/1000000.0}] + puts [format $format MySQL: $t] +# set t [time "exec ./sqlite232 s232.db <$sqlfile" 1] +# set t [expr {[lindex $t 0]/1000000.0}] +# puts [format $format {SQLite 2.3.2:} $t] +# set t [time "exec ./sqlite-100 s100.db <$sqlfile" 1] +# set t [expr {[lindex $t 0]/1000000.0}] +# puts [format $format {SQLite 2.4 (cache=100):} $t] + exec sync; after $delay; + set t [time "exec ./sqlite240 s2k.db <$sqlfile" 1] + set t [expr {[lindex $t 0]/1000000.0}] + puts [format $format {SQLite 2.4:} $t] + exec sync; after $delay; + set t [time "exec ./sqlite240 sns.db <$sqlfile" 1] + set t [expr {[lindex $t 0]/1000000.0}] + puts [format $format {SQLite 2.4 (nosync):} $t] +# set t [time "exec ./sqlite-t1 st1.db <$sqlfile" 1] +# set t [expr {[lindex $t 0]/1000000.0}] +# puts [format $format {SQLite 2.4 (test):} $t] + puts "
%s   %.3f
" +} + +# Initialize the environment +# +expr srand(1) +catch {exec /bin/sh -c {rm -f s*.db}} +set fd [open clear.sql w] +puts $fd { + drop table t1; + drop table t2; +} +close $fd +catch {exec psql drh =1000} { + set txt "[number_name [expr {$n/1000}]] thousand" + set n [expr {$n%1000}] + } else { + set txt {} + } + if {$n>=100} { + append txt " [lindex $::ones [expr {$n/100}]] hundred" + set n [expr {$n%100}] + } + if {$n>=20} { + append txt " [lindex $::tens [expr {$n/10}]]" + set n [expr {$n%10}] + } + if {$n>0} { + append txt " [lindex $::ones $n]" + } + set txt [string trim $txt] + if {$txt==""} {set txt zero} + return $txt +} + + +set fd [open test$cnt.sql w] +puts $fd "BEGIN;" +puts $fd "CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));" +for {set i 1} {$i<=25000} {incr i} { + set r [expr {int(rand()*500000)}] + puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" +} +puts $fd "COMMIT;" +close $fd +runtest {25000 INSERTs in a transaction} + + +set fd [open test$cnt.sql w] +puts $fd "DELETE FROM t1;" +close $fd +runtest {DELETE everything} + + +set fd [open test$cnt.sql w] +puts $fd "BEGIN;" +for {set i 1} {$i<=25000} {incr i} { + set r [expr {int(rand()*500000)}] + puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" +} +puts $fd "COMMIT;" +close $fd +runtest {25000 INSERTs in a transaction} + + +set fd [open test$cnt.sql w] +puts $fd "DELETE FROM t1;" +close $fd +runtest {DELETE everything} + + +set fd [open test$cnt.sql w] +puts $fd "BEGIN;" +for {set i 1} {$i<=25000} {incr i} { + set r [expr {int(rand()*500000)}] + puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" +} +puts $fd "COMMIT;" +close $fd +runtest {25000 INSERTs in a transaction} + + +set fd [open test$cnt.sql w] +puts $fd "DELETE FROM t1;" +close $fd +runtest {DELETE everything} + + +set fd [open test$cnt.sql w] +puts $fd "BEGIN;" +for {set i 1} {$i<=25000} {incr i} { + set r [expr {int(rand()*500000)}] + puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" +} +puts $fd "COMMIT;" +close $fd +runtest {25000 INSERTs in a transaction} + + +set fd [open test$cnt.sql w] +puts $fd "DELETE FROM t1;" +close $fd +runtest {DELETE everything} + + +set fd [open test$cnt.sql w] +puts $fd "BEGIN;" +for {set i 1} {$i<=25000} {incr i} { + set r [expr {int(rand()*500000)}] + puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" +} +puts $fd "COMMIT;" +close $fd +runtest {25000 INSERTs in a transaction} + + +set fd [open test$cnt.sql w] +puts $fd "DELETE FROM t1;" +close $fd +runtest {DELETE everything} + + +set fd [open test$cnt.sql w] +puts $fd {DROP TABLE t1;} +close $fd +runtest {DROP TABLE}