From: drh <> Date: Wed, 24 Aug 2022 23:50:45 +0000 (+0000) Subject: Change sqlite3_prepare_v3() to require SQLITE_PREPARE_CACHE in order for a X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1544960b3d1b26b90f3c90fe56f7cb4444b75d17;p=thirdparty%2Fsqlite.git Change sqlite3_prepare_v3() to require SQLITE_PREPARE_CACHE in order for a statement to be a cache candidate. But any statement can pull from the cache. Also add statement cache control to the CLI. FossilOrigin-Name: c9dc536db9d13c0d66e5b84e564d6813c184ae26c889413a64b365781bf8ee50 --- diff --git a/manifest b/manifest index 9c1bc75ff2..1125980cd0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C First\sattempt\sat\sadding\sa\sbuilt-in\sprepared\sstatement\scache.\s\sThis\sis\nmostly\sworking,\sbut\sstill\shas\sa\sfew\sobscure\sfaults. -D 2022-08-24T17:55:27.625 +C Change\ssqlite3_prepare_v3()\sto\srequire\sSQLITE_PREPARE_CACHE\sin\sorder\sfor\sa\nstatement\sto\sbe\sa\scache\scandidate.\s\sBut\sany\sstatement\scan\spull\sfrom\sthe\scache.\nAlso\sadd\sstatement\scache\scontrol\sto\sthe\sCLI. +D 2022-08-24T23:50:45.133 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/insert.c aea5361767817f917b0f0f647a1f0b1621bd858938ae6ae545c3b6b9814b798f F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 853385cc7a604157e137585097949252d5d0c731768e16b044608e5c95c3614b -F src/main.c 5c82ba33d2032f099c90fbb2a7a05ed684164a0ddecb7aaeda4374d97f4055b5 +F src/main.c a9a6dbe70301a39a1d63b6460e329c4f9548a42b7a334d167fb077acdee9d275 F src/malloc.c b7a3430cbe91d3e8e04fc10c2041b3a19794e63556ad2441a13d8dadd9b2bafc F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -583,13 +583,13 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 0b4245cd4964e635f2630908c2533cd8e9da7af3ca592e23ae8730aa25ae5eb9 F src/pragma.c b57a859a366472131194a9ad35cd76d5920577226b04c884b1b9085605faa280 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c 54839876dd40924279004e98ba35e38a64aed728b9be5ba8641f10a9a5203496 +F src/prepare.c b0fb76a2c82587013410f0e27fcdb2ef5624f036d00179f7fd4f28a52acc0155 F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764 F src/random.c 546d6feb15ec69c1aafe9bb351a277cbb498fd5410e646add673acb805714960 F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c ccce37e7fbe71089cf6aec91e7134c9c0c1d4840cff9f02587bbc71240d914a5 -F src/shell.c.in 269f682249c1bce2962883e5b99c8702b16a488a43b9ae186daa178713a93c5d +F src/shell.c.in 6c18f7d3a42c590035f1c702265c73a8301fda79dda951a713bdae5ae185583b F src/sqlite.h.in f34d1ca4091c969e1b4b4744839f415c7963618bb10b34bbe1ef6a356ace0840 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d @@ -664,7 +664,7 @@ F src/vdbe.c 0150d16da21cb96b2b0f2880aad6acd80ddedf93a9f3eb2c5200aef864854fe6 F src/vdbe.h c4c9defdf2ad9465f9c9c7f79c3b03555f47aa930ea2744f358d9b27269763c7 F src/vdbeInt.h e332f7d165b2cb984772c425c45f67f1d57e3c032d8dbf74a9ef8f1cebfa4bb2 F src/vdbeapi.c 8087dba84836f59d0d5340a6c554948cf4fef03ace62a8d7dd3c8f310107e3f4 -F src/vdbeaux.c fdbf1df03cfcf4d11c49178be30b23d2b750082edd4d7b6aa663479e7dc65f7c +F src/vdbeaux.c 7e682b9cae69e3801d2c04fefe2c80b40e5fcca470a4e11aa53342e2218aa1ab F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c c3ce80af15e2ff5c2824a8db881681cbf511376f13613da020bac6d320c535b1 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1480,7 +1480,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c -F test/speedtest1.c d37467faf7a43711b134f05e9cde7abfd1504bf8f16f6220f67d8db1bc0fc51f +F test/speedtest1.c ace4f2f7053d01237d41ab3a9baaf785eab1f22457bdc0113a41d573a506d2c5 F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1957,7 +1957,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c F tool/showwal.c 0253c187ae16fdae9cde89e63e1dfcd3bb35e5416d066415f99e2f8cac6ab03d F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl 1b5be34c6223cb1af06da2a10fb77863eb869b1962d055820b0a11cf2336ab45 -F tool/speed-check.sh fc224ee49062fedf3bbef87779197bb5103f6f796603e4255ea558633360e8ba +F tool/speed-check.sh 13f8e07dbfe25f3aecda33fb6068894665af61ca1360a7b654be0ad0c3f3ae0b F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1999,11 +1999,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 34b8ea31877ae8b40729d37b3f51ae7e15f38be841881ea4a37c9c8f0a52896d -R 08d11f60d527a9ebc32a98574ca5f0f9 -T *branch * stmt-cache -T *sym-stmt-cache * -T -sym-trunk * +P c217b763b148e8bece9d1f72525fd5026d3f710b337c010ffd0306fde4f9add8 +R 46f3adc34868ee6f9be56f487a4c1aae U drh -Z c8d2ef694a3736c7eee4ba211f6abfcb +Z 42a77517994ced9f374a6cd335be1880 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9e6622d10d..e5c4112044 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c217b763b148e8bece9d1f72525fd5026d3f710b337c010ffd0306fde4f9add8 \ No newline at end of file +c9dc536db9d13c0d66e5b84e564d6813c184ae26c889413a64b365781bf8ee50 \ No newline at end of file diff --git a/src/main.c b/src/main.c index ac09341eb8..8f33c7790b 100644 --- a/src/main.c +++ b/src/main.c @@ -923,7 +923,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ if( szDesired>=0 ){ sqlite3VdbeChangeStmtCacheSize(db, szDesired); } - *pszNew = (int)db->mxCache; + if( pszNew ) *pszNew = (int)db->mxCache; rc = SQLITE_OK; break; } diff --git a/src/prepare.c b/src/prepare.c index 0ac4c8d97b..355703e2af 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -699,24 +699,25 @@ static int sqlite3Prepare( if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory"); assert( sqlite3_mutex_held(db->mutex) ); - if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ - /* Check to see if the prepared statement can be resolved from cache. */ - if( db->mxCache>0 ){ - Vdbe *pCache; - if( nBytes<0 ) nBytes = sqlite3Strlen30(zSql); - pCache = sqlite3VdbeFindInStmtCache(db, zSql, nBytes, &hSql); - if( pCache ){ - *ppStmt = (sqlite3_stmt*)pCache; - if( pzTail ){ - *pzTail = &zSql[nBytes]; - } - goto end_prepare; + if( db->nCache>0 ){ + Vdbe *pCache; + if( nBytes<0 ) nBytes = sqlite3Strlen30(zSql); + pCache = sqlite3VdbeFindInStmtCache(db, zSql, nBytes, &hSql); + if( pCache ){ + *ppStmt = (sqlite3_stmt*)pCache; + if( pzTail ){ + *pzTail = &zSql[nBytes]; } + goto end_prepare; } + } - /* For a long-term use prepared statement should avoid the use of - ** lookaside memory. - */ + /* For a long-term use prepared statement should avoid the use of + ** lookaside memory. + */ + if( prepFlags & (SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_CACHE) ){ + testcase( prepFlags & SQLITE_PREPARE_PERSISTENT ); + testcase( prepFlags & SQLITE_PREPARE_CACHE ); sParse.disableLookaside++; DisableLookaside; } diff --git a/src/shell.c.in b/src/shell.c.in index 5feadd7bf0..92079d598b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1112,6 +1112,7 @@ struct ShellState { int cnt; /* Number of records displayed so far */ int lineno; /* Line number of last line read from in */ int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */ + int prepFlags; /* Flags for sqlite3_prepare_v3() */ FILE *in; /* Read commands from this stream */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ @@ -2649,7 +2650,7 @@ static int run_table_dump_query( int nResult; int i; const char *z; - rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); + rc = sqlite3_prepare_v3(p->db, zSelect, -1, p->prepFlags, &pSelect, 0); if( rc!=SQLITE_OK || !pSelect ){ char *zContext = shell_error_context(zSelect, p->db); utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n%s", rc, @@ -3845,7 +3846,7 @@ static int shell_exec( while( zSql[0] && (SQLITE_OK == rc) ){ static const char *zStmtSql; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); + rc = sqlite3_prepare_v3(db, zSql, -1, pArg->prepFlags, &pStmt, &zLeftover); if( SQLITE_OK != rc ){ if( pzErrMsg ){ *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql); @@ -3911,7 +3912,7 @@ static int shell_exec( sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); /* Reprepare pStmt before reactiving trace modes */ sqlite3_finalize(pStmt); - sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_prepare_v3(db, zSql, -1, pArg->prepFlags, &pStmt, 0); if( pArg ) pArg->pStmt = pStmt; } restore_debug_trace_modes(); @@ -4010,7 +4011,7 @@ static char **tableColumnList(ShellState *p, const char *zTab){ zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); shell_check_oom(zSql); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v3(p->db, zSql, -1, p->prepFlags, &pStmt, 0); sqlite3_free(zSql); if( rc ) return 0; while( sqlite3_step(pStmt)==SQLITE_ROW ){ @@ -4055,7 +4056,7 @@ static char **tableColumnList(ShellState *p, const char *zTab){ zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" " WHERE origin='pk'", zTab); shell_check_oom(zSql); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v3(p->db, zSql, -1, p->prepFlags, &pStmt, 0); sqlite3_free(zSql); if( rc ){ freeColumnList(azCol); @@ -8307,8 +8308,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - /* The undocumented ".breakpoint" command causes a call to the no-op - ** routine named test_breakpoint(). + /* UNDOCUMENTED COMMAND: .breakpoint + ** + ** Causes a call to the no-op routine named test_breakpoint(). This provides + ** a convenient function on which to set a breakpoint. */ if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ test_breakpoint(); @@ -8487,6 +8490,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, + { "stmtcache_size", SQLITE_DBCONFIG_STMTCACHE_SIZE }, { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, @@ -8494,12 +8498,22 @@ static int do_meta_command(char *zLine, ShellState *p){ int ii, v; open_db(p, 0); for(ii=0; ii1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue; + op = aDbConfig[ii].op; if( nArg>=3 ){ - sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); + if( op==SQLITE_DBCONFIG_STMTCACHE_SIZE ){ + sqlite3_db_config(p->db, op, (int)integerValue(azArg[2]), 0); + }else{ + sqlite3_db_config(p->db, op, booleanValue(azArg[2]), 0); + } + } + sqlite3_db_config(p->db, op, -1, &v); + if( op==SQLITE_DBCONFIG_STMTCACHE_SIZE ){ + utf8_printf(p->out, "%19s %d\n", aDbConfig[ii].zName, v); + }else{ + utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); } - sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); - utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); if( nArg>1 ) break; } if( nArg>1 && ii==ArraySize(aDbConfig) ){ @@ -9913,6 +9927,47 @@ static int do_meta_command(char *zLine, ShellState *p){ showHelp(p->out, "parameter"); }else + /* UNDOCUMENTED COMMAND: .prepflags (+|-)FLAG ... + ** + ** For SQLite core debugging use only. + ** + ** Change the value of ShellState.prepFlags which becomes the flags + ** parameter to sqlite3_prepare_v3() in some calls in this application. + */ + if( c=='p' && n>=3 && strncmp(azArg[0], "prepflags", n)==0 ){ + int i; + for(i=1; iout, "unknown option: \"%s\"\n", azArg[i]); + rc = 1; + goto meta_command_exit; + } + if( strcmp(azArg[i]+1, "persist")==0 ){ + op = SQLITE_PREPARE_PERSISTENT; + }else if( strcmp(azArg[i]+1, "no-vtab")==0 ){ + op = SQLITE_PREPARE_NO_VTAB; + }else if( strcmp(azArg[i]+1, "cache")==0 ){ + op = SQLITE_PREPARE_CACHE; + }else{ + utf8_printf(p->out, "option \"%s\" should be one of: \"%cpersist\"" + "\"%cno-vtab\" \"%ccache\"\n", + azArg[i], azArg[i][0],azArg[i][0],azArg[i][0]); + rc = 1; + goto meta_command_exit; + } + if( azArg[i][0]=='+' ){ + p->prepFlags |= op; + }else{ + p->prepFlags &= ~op; + } + } + utf8_printf(p->out, " prepflags:"); + utf8_printf(p->out, " %cpersist", (p->prepFlags & SQLITE_PREPARE_PERSISTENT)?'+':'-'); + utf8_printf(p->out, " %cno-vtab", (p->prepFlags & SQLITE_PREPARE_NO_VTAB)?'+':'-'); + utf8_printf(p->out, " %ccache\n", (p->prepFlags & SQLITE_PREPARE_CACHE)?'+':'-'); + }else + if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){ int i; for(i=1; iout,"%12.12s: ", "colseparator"); + output_c_string(p->out, p->colSeparator); + raw_printf(p->out, "\n"); utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[ShellHasFlag(p, SHFLG_Echo)]); utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); @@ -10752,9 +10817,10 @@ static int do_meta_command(char *zLine, ShellState *p){ raw_printf(p->out, "\n"); utf8_printf(p->out,"%12.12s: %s\n","output", strlen30(p->outfile) ? p->outfile : "stdout"); - utf8_printf(p->out,"%12.12s: ", "colseparator"); - output_c_string(p->out, p->colSeparator); - raw_printf(p->out, "\n"); + utf8_printf(p->out,"%12.12s:", "prepflags"); + utf8_printf(p->out," %cpersist",(p->prepFlags&SQLITE_PREPARE_PERSISTENT)?'+':'-'); + utf8_printf(p->out," %cno-vtab",(p->prepFlags&SQLITE_PREPARE_NO_VTAB)?'+':'-'); + utf8_printf(p->out," %ccache\n",(p->prepFlags&SQLITE_PREPARE_CACHE)?'+':'-'); utf8_printf(p->out,"%12.12s: ", "rowseparator"); output_c_string(p->out, p->rowSeparator); raw_printf(p->out, "\n"); @@ -11368,6 +11434,12 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + /* UNDOCUMENTED COMMMAND: .wheretrace NUMBER + ** + ** For SQLite core debugging use only. + ** + ** See the wheretrace mask to NUMBER. + */ if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 916b2277e3..e60158978d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -64,6 +64,19 @@ void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){ va_end(ap); } +/* +** Compute a hash on the SQL used to generate a prepared statement. +*/ +static u32 sqlHash(const char *zSql, int nSql){ + u32 hSql = 0; + int i; + for(i=0; izSql==0 ); p->zSql = sqlite3DbStrNDup(p->db, z, n); p->nSql = n; - p->hSql = hSql; + if( prepFlags & SQLITE_PREPARE_CACHE ){ + if( hSql==0 ) hSql = sqlHash(z, n); + p->hSql = hSql; + }else{ + p->hSql = 0; + } } /* @@ -94,19 +112,11 @@ Vdbe *sqlite3VdbeFindInStmtCache( int nSql, /* Size of zSql[] in bytes */ u32 *phSql /* Write the hash value here if not found */ ){ - int i; /* Loop counter */ Vdbe *pCache; /* Candidate statement */ - u32 c; /* One character of SQL input */ u32 hSql; /* A hash of the SQL input */ - int n; /* Number of SQL input characters to be hashed */ - hSql = 0; - n = nSql; - if( n>100 ) n = 100; - for(i=0; i=0 ); + hSql = sqlHash(zSql, nSql); if( db->nCache ){ for(pCache = db->pVdbe; pCache; pCache=pCache->pVNext){ if( pCache->hSql==hSql diff --git a/test/speedtest1.c b/test/speedtest1.c index e782e7313c..2f87809f22 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -37,6 +37,7 @@ static const char zHelp[] = " --size N Relative test size. Default=100\n" " --strict Use STRICT table where appropriate\n" " --stats Show statistics at the end\n" + " --stmtcache N Use a statement cache of size N\n" " --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n" " --testset T Run test-set T (main, cte, rtree, orm, fp, debug)\n" " --trace Turn on SQL tracing\n" @@ -98,6 +99,7 @@ static struct Global { int nRepeat; /* Repeat selects this many times */ int doCheckpoint; /* Run PRAGMA wal_checkpoint after each trans */ int nReserve; /* Reserve bytes */ + int szStmtCache; /* Size of the statement cache */ const char *zWR; /* Might be WITHOUT ROWID */ const char *zNN; /* Might be NOT NULL */ const char *zPK; /* Might be UNIQUE or PRIMARY KEY */ @@ -588,7 +590,7 @@ void speedtest1_run(void){ #if SQLITE_VERSION_NUMBER>=3006001 if( g.bReprepare ){ sqlite3_stmt *pNew; - if( g.mPrepFlags & SQLITE_PREPARE_PERSISTENT ){ + if( g.mPrepFlags & SQLITE_PREPARE_CACHE ){ char zBuf[1000]; strncpy(zBuf, sqlite3_sql(g.pStmt), sizeof(zBuf)); zBuf[sizeof(zBuf)-1] = 0; @@ -2300,6 +2302,10 @@ int main(int argc, char **argv){ }else if( strcmp(z,"size")==0 ){ if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); g.szTest = integerValue(argv[++i]); + }else if( strcmp(z,"stmtcache")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + g.szStmtCache = integerValue(argv[++i]); + g.mPrepFlags |= SQLITE_PREPARE_CACHE; }else if( strcmp(z,"stats")==0 ){ showStats = 1; }else if( strcmp(z,"temp")==0 ){ @@ -2394,6 +2400,14 @@ int main(int argc, char **argv){ if( rc ) fatal_error("lookaside configuration failed: %d\n", rc); } #endif +#ifdef SQLITE_DBCONFIG_STMTCACHE_SIZE + if( g.mPrepFlags & SQLITE_PREPARE_CACHE ){ + int nCache = 0; + rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_STMTCACHE_SIZE, + g.szStmtCache, &nCache); + if( rc ) fatal_error("statement cache configuration failed: %d\n", rc); + } +#endif /* SQLITE_DBCONFIG_STMTCACHE_SIZE */ if( g.nReserve>0 ){ sqlite3_file_control(g.db, 0, SQLITE_FCNTL_RESERVE_BYTES, &g.nReserve); } diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 6d69ea0320..879ffa9562 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -96,6 +96,9 @@ while test "$1" != ""; do --cachesize) shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1" ;; + --stmtcache) + shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --stmtcache $1" + ;; --checkpoint) SPEEDTEST_OPTS="$SPEEDTEST_OPTS --checkpoint" ;;