Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 399665beb5 | |||
| 5035c33df8 | |||
| 11969c1269 | |||
| 546d46a40d | |||
| aae210884c | |||
| 7b7a373706 | |||
| 2578cf2eb7 | |||
| 1544960b3d | |||
| 4f2bf6bf88 |
+10
-2
@@ -31,7 +31,7 @@ SQLITE_EXTENSION_INIT1
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
|
||||
#define STMT_NUM_INTEGER_COLUMN 10
|
||||
#define STMT_NUM_INTEGER_COLUMN 11
|
||||
typedef struct StmtRow StmtRow;
|
||||
struct StmtRow {
|
||||
sqlite3_int64 iRowid; /* Rowid value */
|
||||
@@ -95,11 +95,12 @@ static int stmtConnect(
|
||||
#define STMT_COLUMN_REPREP 8 /* SQLITE_STMTSTATUS_REPREPARE */
|
||||
#define STMT_COLUMN_RUN 9 /* SQLITE_STMTSTATUS_RUN */
|
||||
#define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */
|
||||
#define STMT_COLUMN_STATE 11 /* SQLITE_STMTSTATUS_STATE */
|
||||
|
||||
|
||||
rc = sqlite3_declare_vtab(db,
|
||||
"CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
|
||||
"reprep,run,mem)");
|
||||
"reprep,run,mem,state)");
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew = sqlite3_malloc64( sizeof(*pNew) );
|
||||
*ppVtab = (sqlite3_vtab*)pNew;
|
||||
@@ -175,6 +176,10 @@ static int stmtColumn(
|
||||
StmtRow *pRow = pCur->pRow;
|
||||
if( i==STMT_COLUMN_SQL ){
|
||||
sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT);
|
||||
}else if( i==STMT_COLUMN_STATE ){
|
||||
const char *azStateName[] = { "INIT", "READY", "RUN", "HALT", "CACHE" };
|
||||
int j = pRow->aCol[i];
|
||||
sqlite3_result_text(ctx, azStateName[j%5], -1, SQLITE_STATIC);
|
||||
}else{
|
||||
sqlite3_result_int(ctx, pRow->aCol[i]);
|
||||
}
|
||||
@@ -253,6 +258,9 @@ static int stmtFilter(
|
||||
pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status(
|
||||
p, SQLITE_STMTSTATUS_MEMUSED, 0
|
||||
);
|
||||
pNew->aCol[STMT_COLUMN_STATE] = sqlite3_stmt_status(
|
||||
p, SQLITE_STMTSTATUS_STATE, 0
|
||||
);
|
||||
pNew->iRowid = iRowid++;
|
||||
*ppRow = pNew;
|
||||
ppRow = &pNew->pNext;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Replace\sthe\sParse.disableVtab\sfield\swith\sParse.prepFlags\sfor\sincreased\ngenerality,\sa\ssmall\ssize\sreduction,\sand\sa\ssmall\sperformance\sincrease.
|
||||
D 2022-10-01T13:17:53.450
|
||||
C Merge\sthe\sParse.prepFlags\schange\sfrom\strunk.
|
||||
D 2022-10-01T13:28:04.924
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -328,7 +328,7 @@ F ext/misc/shathree.c 7b17615869a495659f1569ada1d8d3d21b4a24614f2746d93cc87ef7c0
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f
|
||||
F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6
|
||||
F ext/misc/stmt.c ed05ad78013edccd43f4fc33d8244001f6f886eb2dfd2106ba33616ac514c6fb
|
||||
F ext/misc/stmt.c 36ad8e9a5352e4795dd1da1d04c6ab9680c58d1dd648bdb26a53123c976a0f2b
|
||||
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
|
||||
F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
|
||||
F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b
|
||||
@@ -531,7 +531,7 @@ F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca
|
||||
F src/btree.c ef9c126d6dc5dff8ff76abc807dfef5b8aac42144e3be11cbcd9cb6eaecef580
|
||||
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
||||
F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
|
||||
F src/build.c 6e3ee380a4f0ff95de4b53bf510f66600cff08e4e04b92e95fae789072563f8f
|
||||
F src/build.c 50cf41a7710c5ebfd22e4a233d359598a10e62f55b984fa91c85b883b2e27d37
|
||||
F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 93e4b5f4faf6d3f688988a116773259a4fbfb4ddac0e9bf9d0ae0429390c2543
|
||||
@@ -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 8983b4a316d7e09946dd731913aa41712f02e2b55cb5c6c92126ccfe2473244a
|
||||
F src/main.c 123ac0cc427dee4befdd47ff0f999cbb8f035f805c5d5f365dda5ba577c03ea3
|
||||
F src/malloc.c dfddca1e163496c0a10250cedeafaf56dff47673e0f15888fb0925340a8e3f90
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@@ -583,17 +583,17 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc
|
||||
F src/pragma.c 9bf7d8a2a9ad3bc36df3ec0d61817a44c38a1da527d59c26c203047f906e334a
|
||||
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c 0e61df99f063f12896a89c893fd3f8868e9fb13252c05e3e4e8cea7422094d0a
|
||||
F src/prepare.c fbcfdd127ec6e0e011da7f31b9b30dfd70d520ce3f6b2e6c27d3e7904d0faea1
|
||||
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
|
||||
F src/random.c 546d6feb15ec69c1aafe9bb351a277cbb498fd5410e646add673acb805714960
|
||||
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c bb18acf4eded647fef88d4d543c673874dbebff516fbeba90a85e6c13f2a58cd
|
||||
F src/shell.c.in e7e7c2c69ae86c5ee9e8ad66227203d46ff6dce8700a1b1dababff01c71d33df
|
||||
F src/sqlite.h.in b9b7fd73239d94db20332bb6e504688001e5564b655e1318a4427a1caef4b99e
|
||||
F src/shell.c.in a1152c45017c9ce634b1616d16ccf530397df1260302fccc7aafee7afe57173a
|
||||
F src/sqlite.h.in 24e7d46e187456b778ca8f6e28b194667b80f8a61e4c1a861239a91fd6d3e686
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
|
||||
F src/sqliteInt.h 7571703e6d11cd0e0283be68e9b6baceefedf10e3bbac5869d12183e031c5254
|
||||
F src/sqliteInt.h 89f957680385f5725ec701ec94b41274d6d77ef25feb96fcda67a0aa545badb4
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -654,17 +654,17 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
|
||||
F src/treeview.c 07787f67cd297a6d09d04b8d70c06769c60c9c1d9080378f93929c16f8fd3298
|
||||
F src/trigger.c 4163ada044af89d51caba1cb713a73165347b2ec05fe84a283737c134d61fcd5
|
||||
F src/trigger.c 78dd02836a0559e41321318668f6f0c266b27cc172d1676879431765b27720c5
|
||||
F src/update.c c52a7991bece0453d22c77c08469512ee2f1391c12503fd347d1c939220c5877
|
||||
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
|
||||
F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8
|
||||
F src/vdbe.c 0d1e3c658d98a7bb7201532ea7a3e4d59bf9165421c780d5f84c361e372f1179
|
||||
F src/vdbe.h 64619af62603dc3c4f5ff6ff6d2c8f389abd667a29ce6007ed44bd22b3211cd0
|
||||
F src/vdbeInt.h 17b7461ffcf9ee760d1341731715a419f6b8c763089a7ece25c2e8098d702b3f
|
||||
F src/vdbeapi.c fc3183daf72808b4311b228989120fdbc2dc44972fb0d77d5c453460cc0e5b2c
|
||||
F src/vdbeaux.c c719cebaffa75e166f16a405b3dee96e7150d60fc563ab2dea716b60c6a51312
|
||||
F src/vdbe.c 5ea5f28e90ea64d53fc61ff638c2e6d76009a13aa872bd1c53765bf81ad5848a
|
||||
F src/vdbe.h c4c9defdf2ad9465f9c9c7f79c3b03555f47aa930ea2744f358d9b27269763c7
|
||||
F src/vdbeInt.h 1c58993f8bdf604706120838d018495289ab82dfb8d575748293a3396cd3e2d0
|
||||
F src/vdbeapi.c ba51a59b3c0ecbf76f337de087089986464da83d1bf42b4fdebef8d74de173b2
|
||||
F src/vdbeaux.c 173eb3ffc4f906411b1c1fb5fe7bb59a5bd53befd43a276fb07f6225ebb4702e
|
||||
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 8bf7ebac9ac316feed6656951249db531dc380c73fb3e3b22e224ffda96beff6
|
||||
F test/speedtest1.c 07b9d2cc48ea0d68ba7ab85de86b7a26af638737f6ac65054d557f3ca50efbfa
|
||||
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
@@ -2000,8 +2000,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 bd8ae5febbb8d3122f1e2e09b9fcdd6ac20c075ae1cf60bcdbd36080f3736417
|
||||
R b431f195d6909dd213769258d329fb1f
|
||||
P 7812aea6ea2a922599970cd56933dadaa340bcf40781701844f62456772501c2 b7da0bcdf70e53ab1ec00a0694e17c7429e23bc6eb3f39b622d06a930aa2f6a3
|
||||
R 4fea9345ef5af6b4a81a531a14cab26b
|
||||
U drh
|
||||
Z 5ff8e8c9111016b6f28cef573224105e
|
||||
Z a63cbed431bd786ee17d13092323f381
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
b7da0bcdf70e53ab1ec00a0694e17c7429e23bc6eb3f39b622d06a930aa2f6a3
|
||||
c8d77f398099f357bed0aab10f066c6b26ba4ad8ffd68bb7b4465c0c4999599b
|
||||
@@ -2791,6 +2791,7 @@ void sqlite3EndTable(
|
||||
#ifndef SQLITE_OMIT_VIEW
|
||||
}else{
|
||||
/* A view */
|
||||
sqlite3VdbeRunOnlyOnce(v);
|
||||
zType = "view";
|
||||
zType2 = "VIEW";
|
||||
#endif
|
||||
|
||||
+12
@@ -918,6 +918,16 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
va_start(ap, op);
|
||||
switch( op ){
|
||||
case SQLITE_DBCONFIG_STMTCACHE_SIZE: {
|
||||
int szDesired = va_arg(ap,int);
|
||||
int *pszNew = va_arg(ap,int*);
|
||||
if( szDesired>=0 ){
|
||||
sqlite3VdbeChangeStmtCacheSize(db, szDesired);
|
||||
}
|
||||
if( pszNew ) *pszNew = (int)db->mxCache;
|
||||
rc = SQLITE_OK;
|
||||
break;
|
||||
}
|
||||
case SQLITE_DBCONFIG_MAINDBNAME: {
|
||||
/* IMP: R-06824-28531 */
|
||||
/* IMP: R-36257-52125 */
|
||||
@@ -1214,6 +1224,7 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
|
||||
}
|
||||
|
||||
/* Force xDisconnect calls on all virtual tables */
|
||||
sqlite3VdbeChangeStmtCacheSize(db, 0);
|
||||
disconnectAllVtab(db);
|
||||
|
||||
/* If a transaction is open, the disconnectAllVtab() call above
|
||||
@@ -3252,6 +3263,7 @@ static int openDatabase(
|
||||
db->autoCommit = 1;
|
||||
db->nextAutovac = -1;
|
||||
db->szMmap = sqlite3GlobalConfig.szMmap;
|
||||
db->mxCache = SQLITE_DEFAULT_STMTCACHE_SIZE;
|
||||
db->nextPagesize = 0;
|
||||
db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */
|
||||
#ifdef SQLITE_ENABLE_SORTER_MMAP
|
||||
|
||||
+17
-2
@@ -686,6 +686,7 @@ static int sqlite3Prepare(
|
||||
int rc = SQLITE_OK; /* Result code */
|
||||
int i; /* Loop counter */
|
||||
Parse sParse; /* Parsing context */
|
||||
u32 hSql = 0; /* Hash of the input SQL */
|
||||
|
||||
/* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */
|
||||
memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
|
||||
@@ -698,10 +699,23 @@ static int sqlite3Prepare(
|
||||
if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory");
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
|
||||
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 avoid the use of
|
||||
** lookaside memory.
|
||||
*/
|
||||
if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
|
||||
if( prepFlags & (SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_CACHE) ){
|
||||
sParse.disableLookaside++;
|
||||
DisableLookaside;
|
||||
}
|
||||
@@ -776,7 +790,8 @@ static int sqlite3Prepare(
|
||||
}
|
||||
|
||||
if( db->init.busy==0 ){
|
||||
sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags);
|
||||
sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql),
|
||||
prepFlags, hSql);
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
sParse.rc = SQLITE_NOMEM_BKPT;
|
||||
|
||||
+85
-13
@@ -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() */
|
||||
@@ -2662,7 +2663,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,
|
||||
@@ -3858,7 +3859,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);
|
||||
@@ -3924,7 +3925,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();
|
||||
@@ -4023,7 +4024,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 ){
|
||||
@@ -4068,7 +4069,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);
|
||||
@@ -8320,8 +8321,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();
|
||||
@@ -8500,6 +8503,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 },
|
||||
@@ -8507,12 +8511,22 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int ii, v;
|
||||
open_db(p, 0);
|
||||
for(ii=0; ii<ArraySize(aDbConfig); ii++){
|
||||
int op;
|
||||
if( nArg>1 && 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) ){
|
||||
@@ -9926,6 +9940,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; i<nArg; i++){
|
||||
int op = 0;
|
||||
if( azArg[i][0]!='-' && azArg[i][0]!='+' ){
|
||||
utf8_printf(p->out, "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; i<nArg; i++){
|
||||
@@ -10242,6 +10297,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
/* UNDOCUMENTED COMMAND: .treetrace N
|
||||
**
|
||||
** For SQLite core debugging use only.
|
||||
**
|
||||
** Set the treetrace mask to N. Also called ".selectrace" for historical
|
||||
** compatibility.
|
||||
*/
|
||||
if( (c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0)
|
||||
|| (c=='t' && n==9 && strncmp(azArg[0], "treetrace", n)==0)
|
||||
){
|
||||
@@ -10743,6 +10805,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
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: %s\n","echo",
|
||||
azBool[ShellHasFlag(p, SHFLG_Echo)]);
|
||||
utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
|
||||
@@ -10765,9 +10830,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");
|
||||
@@ -11381,6 +11447,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);
|
||||
|
||||
+73
-9
@@ -2128,7 +2128,61 @@ struct sqlite3_mem_methods {
|
||||
** non-zero [error code] if a discontinued or unsupported configuration option
|
||||
** is invoked.
|
||||
**
|
||||
** Most of these configuration options are used to set, clear, or query flags.
|
||||
** All such options take two arguments: And integer (X) and a pointer to an
|
||||
** integer (P). If the X argument is greater than zero, the flag is set. If
|
||||
** X is equal to zero, the flag is cleared. If X is less than zero, the flag
|
||||
** remains unchanged. In all cases, the value of the flag after any changes
|
||||
** (either 0 or 1) is written into the integer pointed to by P. All of the
|
||||
** configuration options listed below operate this way, with the following
|
||||
** exceptions:
|
||||
**
|
||||
** <ul>
|
||||
** <li> [SQLITE_DBCONFIG_MAINDBNAME]
|
||||
** <li> [SQLITE_DBCONFIG_LOOKASIDE]
|
||||
** <li> [SQLITE_DBCONFIG_STMTCACHE_SIZE]
|
||||
** </ul>
|
||||
**
|
||||
** <dl>
|
||||
** [[SQLITE_DBCONFIG_STMTCACHE_SIZE]] <dt>SQLITE_DBCONFIG_STMTCACHE_SIZE</dt>
|
||||
** <dd> The SQLITE_DBCONFIG_STMTCACHE_SIZE option is used to query or change
|
||||
** the maximum number of [prepared statements] that SQLite will cache. Prepared
|
||||
** statements are only candidates for caching if they are prepared using
|
||||
** [sqlite3_prepare_v3()] with the [SQLITE_PREPARE_PERSISTENT] option. If
|
||||
** SQLite chooses to cache a perpared statement, that means that when
|
||||
** [sqlite3_finalize()] is called on the prepared statement, the statement is
|
||||
** not immediately deleted, but instead is put into the cache. Subsequent
|
||||
** calls to any of the [sqlite3_prepare()] ineterfaces with the exact same
|
||||
** SQL text may reuse the cached prepared statement rather than creating a new
|
||||
** prepared statement. This setting adjusts the maximum number of prepared
|
||||
** statements that SQLite will keep in cache. The default value is
|
||||
** SQLITE_DEFAULT_STMTCACHE_SIZE which is 10 unless overridden at compile-time.
|
||||
** Setting the maximum cache size to zero disables the cache. The cache is
|
||||
** automatically trimmed back to its maximum size when the cache size is
|
||||
** reduced. Hence the cache can be flushed, by set the cache size to zero
|
||||
** then set it back to its original value.
|
||||
** <p>This configuration option takes two parameters. The first parameter (N) is
|
||||
** an integer which is the desired new size of the statement cache. A negative
|
||||
** value for N leaves the cache size unchanged. The second parameter (P)
|
||||
** is a pointer to an integer into which the new cache size is written.
|
||||
** The database connection is free to limit or truncate the N value that is
|
||||
** passed in, so the new cache size returned in P is not necessarily the same
|
||||
** as the N argument.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
|
||||
** <dd> ^This option is used to change the name of the "main" database
|
||||
** schema. ^The sole argument is a pointer to a constant UTF8 string
|
||||
** which will become the new schema name in place of "main". ^SQLite
|
||||
** does not make a copy of the new main schema name string, so the application
|
||||
** must ensure that the argument passed into this DBCONFIG option is unchanged
|
||||
** until after the database connection closes. The application is responsible
|
||||
** for managing the storage associated with the string passed in as the
|
||||
** argument. SQLite does not attempt to free the string, or do anything else
|
||||
** to reclaim storage space associated with the string, when the database
|
||||
** connection closes.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_LOOKASIDE]]
|
||||
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
|
||||
** <dd> ^This option takes three additional arguments that determine the
|
||||
@@ -2229,15 +2283,6 @@ struct sqlite3_mem_methods {
|
||||
** be a NULL pointer, in which case the new setting is not reported back.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
|
||||
** <dd> ^This option is used to change the name of the "main" database
|
||||
** schema. ^The sole argument is a pointer to a constant UTF8 string
|
||||
** which will become the new schema name in place of "main". ^SQLite
|
||||
** does not make a copy of the new main schema name string, so the application
|
||||
** must ensure that the argument passed into this DBCONFIG option is unchanged
|
||||
** until after the database connection closes.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
|
||||
** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
|
||||
** <dd> Usually, when a database in wal mode is closed or detached from a
|
||||
@@ -2396,6 +2441,7 @@ struct sqlite3_mem_methods {
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_DBCONFIG_STMTCACHE_SIZE 999 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
|
||||
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
|
||||
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
|
||||
@@ -4047,11 +4093,19 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
|
||||
** to return an error (error code SQLITE_ERROR) if the statement uses
|
||||
** any virtual tables.
|
||||
**
|
||||
** [[SQLITE_PREPARE_CACHE]] <td>SQLITE_PREPARE_CACHE</dt>
|
||||
** <dd>The SQLITE_PREPARE_CACHE flag gives SQLite permission to attempt
|
||||
** to cache the prepared statement after it is
|
||||
** [sqlite3_finalized|finalized] and attempt to reuse it as the
|
||||
** return value for the next call to a [sqlite3_prepare()] that has
|
||||
** the same SQL. This flag also implies [SQLITE_PREPARE_PERSISTENT].
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_PREPARE_PERSISTENT 0x01
|
||||
#define SQLITE_PREPARE_NORMALIZE 0x02
|
||||
#define SQLITE_PREPARE_NO_VTAB 0x04
|
||||
#define SQLITE_PREPARE_CACHE 0x08
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compiling An SQL Statement
|
||||
@@ -8560,6 +8614,15 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
||||
** times that the Bloom filter returned a find, and thus the join step
|
||||
** had to be processed as normal.
|
||||
**
|
||||
** [[SQLITE_STMTSTATUS_STATE]] <dt>SQLITE_STMTSTATUS_STATE</dt>
|
||||
** <dd>During its lifetime, a prepare statement transitions through
|
||||
** various "states". This interface returns the current state of the
|
||||
** prepared statement, as an integer. This information is intended
|
||||
** for use by SQLite core developers only. The internal state numbers
|
||||
** for prepared statements can and do change from one release of
|
||||
** SQLite to the next. Hence the value returned for this property
|
||||
** code can change from one release of SQLite to the next.
|
||||
**
|
||||
** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
|
||||
** <dd>^This is the approximate number of bytes of heap memory
|
||||
** used to store the prepared statement. ^This value is not actually
|
||||
@@ -8576,6 +8639,7 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
||||
#define SQLITE_STMTSTATUS_RUN 6
|
||||
#define SQLITE_STMTSTATUS_FILTER_MISS 7
|
||||
#define SQLITE_STMTSTATUS_FILTER_HIT 8
|
||||
#define SQLITE_STMTSTATUS_STATE 98
|
||||
#define SQLITE_STMTSTATUS_MEMUSED 99
|
||||
|
||||
/*
|
||||
|
||||
@@ -352,6 +352,16 @@
|
||||
# define SQLITE_DEFAULT_MEMSTATUS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Set the default maximum statement cache size
|
||||
*/
|
||||
#if !defined(SQLITE_DEFAULT_STMTCACHE_SIZE)
|
||||
# define SQLITE_DEFAULT_STMTCACHE_SIZE 10
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_STMTCACHE_SIZE<0 || SQLITE_DEFAULT_STMTCACHE_SIZE>254
|
||||
# error SQLITE_DEFAULT_STMTCACHE_SIZE must be between 0 and 254
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Exactly one of the following macros must be defined in order to
|
||||
** specify which memory allocation subsystem to use.
|
||||
@@ -1565,6 +1575,7 @@ struct sqlite3 {
|
||||
u8 noSharedCache; /* True if no shared-cache backends */
|
||||
u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
|
||||
u8 eOpenState; /* Current condition of the connection */
|
||||
u8 mxCache, nCache; /* Max and current size of statement cache */
|
||||
int nextPagesize; /* Pagesize after VACUUM if >0 */
|
||||
i64 nChange; /* Value returned by sqlite3_changes() */
|
||||
i64 nTotalChange; /* Value returned by sqlite3_total_changes() */
|
||||
|
||||
@@ -372,6 +372,7 @@ void sqlite3FinishTrigger(
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ) goto triggerfinish_cleanup;
|
||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||
sqlite3VdbeRunOnlyOnce(v);
|
||||
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
|
||||
testcase( z==0 );
|
||||
sqlite3NestedParse(pParse,
|
||||
|
||||
+15
-7
@@ -753,14 +753,20 @@ int sqlite3VdbeExec(
|
||||
nProgressLimit = LARGEST_UINT64;
|
||||
}
|
||||
#endif
|
||||
if( p->rc==SQLITE_NOMEM ){
|
||||
/* This happens if a malloc() inside a call to sqlite3_column_text() or
|
||||
** sqlite3_column_text16() failed. */
|
||||
goto no_mem;
|
||||
if( p->rc ){
|
||||
if( p->rc==SQLITE_NOMEM ){
|
||||
/* This happens if a malloc() inside a call to sqlite3_column_text() or
|
||||
** sqlite3_column_text16() failed. */
|
||||
goto no_mem;
|
||||
}
|
||||
if( p->rc==SQLITE_TOOBIG ){
|
||||
/* This happens if the SQLITE_LENGTH is reduced on a cached prepared
|
||||
** statement. */
|
||||
goto too_big;
|
||||
}
|
||||
assert( (p->rc&0xff)==SQLITE_BUSY );
|
||||
p->rc = SQLITE_OK;
|
||||
}
|
||||
assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
|
||||
testcase( p->rc!=SQLITE_OK );
|
||||
p->rc = SQLITE_OK;
|
||||
assert( p->bIsReader || p->readOnly!=0 );
|
||||
p->iCurrentTime = 0;
|
||||
assert( p->explain==0 );
|
||||
@@ -6631,6 +6637,7 @@ case OP_CreateBtree: { /* out2 */
|
||||
Db *pDb;
|
||||
|
||||
sqlite3VdbeIncrWriteCounter(p, 0);
|
||||
p->hSql = 0;
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pgno = 0;
|
||||
assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
|
||||
@@ -7702,6 +7709,7 @@ case OP_Expire: {
|
||||
}else{
|
||||
p->expired = pOp->p2+1;
|
||||
}
|
||||
p->hSql = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -262,7 +262,9 @@ int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
|
||||
void sqlite3VdbeCountChanges(Vdbe*);
|
||||
sqlite3 *sqlite3VdbeDb(Vdbe*);
|
||||
u8 sqlite3VdbePrepareFlags(Vdbe*);
|
||||
void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
|
||||
void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8, u32);
|
||||
Vdbe *sqlite3VdbeFindInStmtCache(sqlite3*,const char*,int,u32*);
|
||||
void sqlite3VdbeChangeStmtCacheSize(sqlite3*,int);
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
|
||||
int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*);
|
||||
|
||||
@@ -470,6 +470,8 @@ struct Vdbe {
|
||||
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
|
||||
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
|
||||
u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
|
||||
u32 hSql; /* Hash for zSql. 0 if non-cacheable. */
|
||||
int nSql; /* Number of bytes in zSql[] */
|
||||
char *zSql; /* Text of the SQL statement that generated this */
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
char *zNormSql; /* Normalization of the associated SQL statement */
|
||||
@@ -496,6 +498,7 @@ struct Vdbe {
|
||||
#define VDBE_READY_STATE 1 /* Ready to run but not yet started */
|
||||
#define VDBE_RUN_STATE 2 /* Run in progress */
|
||||
#define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */
|
||||
#define VDBE_CACHE_STATE 4 /* In statement cache */
|
||||
|
||||
/*
|
||||
** Structure used to store the context required by the
|
||||
@@ -653,9 +656,11 @@ int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
|
||||
#ifdef SQLITE_DEBUG
|
||||
void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*);
|
||||
void sqlite3VdbeAssertAbortable(Vdbe*);
|
||||
void sqlite3VdbeCheckActiveVdbeCount(sqlite3*);
|
||||
#else
|
||||
# define sqlite3VdbeIncrWriteCounter(V,C)
|
||||
# define sqlite3VdbeAssertAbortable(V)
|
||||
# define sqlite3VdbeCheckActiveVdbeCount(D)
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||
|
||||
+16
-1
@@ -110,7 +110,19 @@ int sqlite3_finalize(sqlite3_stmt *pStmt){
|
||||
checkProfileCallback(db, v);
|
||||
assert( v->eVdbeState>=VDBE_READY_STATE );
|
||||
rc = sqlite3VdbeReset(v);
|
||||
sqlite3VdbeDelete(v);
|
||||
if( v->hSql>0
|
||||
&& db->mxCache>0
|
||||
&& v->expired==0
|
||||
){
|
||||
v->eVdbeState = VDBE_CACHE_STATE;
|
||||
db->nCache++;
|
||||
if( db->nCache>db->mxCache){
|
||||
sqlite3VdbeChangeStmtCacheSize(db, db->mxCache);
|
||||
}
|
||||
}else{
|
||||
sqlite3VdbeDelete(v);
|
||||
}
|
||||
sqlite3VdbeCheckActiveVdbeCount(db);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
sqlite3LeaveMutexAndCloseZombie(db);
|
||||
}
|
||||
@@ -689,6 +701,7 @@ static int sqlite3Step(Vdbe *p){
|
||||
if( p->bIsReader ) db->nVdbeRead++;
|
||||
p->pc = 0;
|
||||
p->eVdbeState = VDBE_RUN_STATE;
|
||||
sqlite3VdbeCheckActiveVdbeCount(db);
|
||||
}else
|
||||
|
||||
if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){
|
||||
@@ -1842,6 +1855,8 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
|
||||
db->pnBytesFreed = 0;
|
||||
db->lookaside.pEnd = db->lookaside.pTrueEnd;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
}else if( op==SQLITE_STMTSTATUS_STATE ){
|
||||
v = pVdbe->eVdbeState;
|
||||
}else{
|
||||
v = pVdbe->aCounter[op];
|
||||
if( resetFlag ) pVdbe->aCounter[op] = 0;
|
||||
|
||||
+107
-6
@@ -64,10 +64,29 @@ 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; i<nSql; i++){
|
||||
hSql = (hSql + zSql[i]) * 0x9e3779b1;
|
||||
}
|
||||
hSql |= 1;
|
||||
return hSql;
|
||||
}
|
||||
|
||||
/*
|
||||
** Remember the SQL string for a prepared statement.
|
||||
*/
|
||||
void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
|
||||
void sqlite3VdbeSetSql(
|
||||
Vdbe *p, /* The VDBE whose SQL text is to be set */
|
||||
const char *z, /* the SQL text */
|
||||
int n, /* Number of bytes in z[] */
|
||||
u8 prepFlags, /* prepFlags */
|
||||
u32 hSql /* Hash of z[] used for fast cache lookups */
|
||||
){
|
||||
if( p==0 ) return;
|
||||
p->prepFlags = prepFlags;
|
||||
if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
|
||||
@@ -75,8 +94,58 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
|
||||
}
|
||||
assert( p->zSql==0 );
|
||||
p->zSql = sqlite3DbStrNDup(p->db, z, n);
|
||||
p->nSql = n;
|
||||
if( prepFlags & SQLITE_PREPARE_CACHE ){
|
||||
if( hSql==0 ) hSql = sqlHash(z, n);
|
||||
p->hSql = hSql;
|
||||
}else{
|
||||
p->hSql = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Search for a cached VDBE that that implements the given SQL.
|
||||
*/
|
||||
Vdbe *sqlite3VdbeFindInStmtCache(
|
||||
sqlite3 *db, /* The database connection holding the cache */
|
||||
const char *zSql, /* Input SQL text */
|
||||
int nSql, /* Size of zSql[] in bytes */
|
||||
u32 *phSql /* Write the hash value here if not found */
|
||||
){
|
||||
Vdbe *pCache; /* Candidate statement */
|
||||
u32 hSql; /* A hash of the SQL input */
|
||||
|
||||
assert( nSql>=0 );
|
||||
hSql = sqlHash(zSql, nSql);
|
||||
if( db->nCache ){
|
||||
for(pCache = db->pVdbe; pCache; pCache=pCache->pVNext){
|
||||
if( pCache->hSql==hSql
|
||||
&& pCache->eVdbeState==VDBE_CACHE_STATE
|
||||
&& pCache->nSql==nSql
|
||||
&& strncmp(zSql, pCache->zSql, nSql)==0
|
||||
){
|
||||
pCache->eVdbeState = VDBE_READY_STATE;
|
||||
db->nCache--;
|
||||
if( pCache!=db->pVdbe ){
|
||||
if( pCache->pVNext ){
|
||||
pCache->pVNext->ppVPrev = pCache->ppVPrev;
|
||||
}
|
||||
*pCache->ppVPrev = pCache->pVNext;
|
||||
pCache->pVNext = db->pVdbe;
|
||||
pCache->ppVPrev = &db->pVdbe;
|
||||
db->pVdbe->ppVPrev = &pCache->pVNext;
|
||||
db->pVdbe = pCache;
|
||||
}
|
||||
sqlite3VdbeCheckActiveVdbeCount(db);
|
||||
return pCache;
|
||||
}
|
||||
}
|
||||
}
|
||||
*phSql = hSql;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SQLITE_ENABLE_NORMALIZE
|
||||
/*
|
||||
** Add a new element to the Vdbe->pDblStr list.
|
||||
@@ -3010,7 +3079,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
|
||||
** This is a no-op if NDEBUG is defined.
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
static void checkActiveVdbeCnt(sqlite3 *db){
|
||||
void sqlite3VdbeCheckActiveVdbeCount(sqlite3 *db){
|
||||
Vdbe *p;
|
||||
int cnt = 0;
|
||||
int nWrite = 0;
|
||||
@@ -3028,10 +3097,36 @@ static void checkActiveVdbeCnt(sqlite3 *db){
|
||||
assert( nWrite==db->nVdbeWrite );
|
||||
assert( nRead==db->nVdbeRead );
|
||||
}
|
||||
#else
|
||||
#define checkActiveVdbeCnt(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Attempt to change the statement cache size. If the statement cache
|
||||
** size is reduced remove excess elements from the cache.
|
||||
**
|
||||
** The argument is the *desired* new statement cache size. The new
|
||||
** statement cache size will not necessarily be the same size.
|
||||
*/
|
||||
void sqlite3VdbeChangeStmtCacheSize(sqlite3 *db, int szDesired){
|
||||
assert( szDesired>=0 );
|
||||
if( szDesired>100 ) szDesired = 100;
|
||||
if( db->nCache>szDesired ){
|
||||
Vdbe *p, *pNext;
|
||||
int n = szDesired;
|
||||
for(p=db->pVdbe; p; p=pNext){
|
||||
pNext = p->pVNext;
|
||||
if( p->hSql==0 ) continue;
|
||||
if( p->eVdbeState!=VDBE_CACHE_STATE ) continue;
|
||||
if( n>0 ){ n--; continue; }
|
||||
sqlite3VdbeDelete(p);
|
||||
assert( db->nCache>szDesired );
|
||||
db->nCache--;
|
||||
}
|
||||
assert( db->nCache==szDesired );
|
||||
}
|
||||
db->mxCache = szDesired;
|
||||
sqlite3VdbeCheckActiveVdbeCount(db);
|
||||
}
|
||||
|
||||
/*
|
||||
** If the Vdbe passed as the first argument opened a statement-transaction,
|
||||
** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
|
||||
@@ -3160,7 +3255,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
p->rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
closeAllCursors(p);
|
||||
checkActiveVdbeCnt(db);
|
||||
sqlite3VdbeCheckActiveVdbeCount(db);
|
||||
|
||||
/* No commit or rollback needed if the program never started or if the
|
||||
** SQL statement does not read or write a database file. */
|
||||
@@ -3319,7 +3414,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
assert( db->nVdbeRead>=db->nVdbeWrite );
|
||||
assert( db->nVdbeWrite>=0 );
|
||||
p->eVdbeState = VDBE_HALT_STATE;
|
||||
checkActiveVdbeCnt(db);
|
||||
sqlite3VdbeCheckActiveVdbeCount(db);
|
||||
if( db->mallocFailed ){
|
||||
p->rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
@@ -5106,6 +5201,12 @@ void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){
|
||||
for(p = db->pVdbe; p; p=p->pVNext){
|
||||
p->expired = iCode+1;
|
||||
}
|
||||
if( db->nCache>0 ){
|
||||
u8 mxCache = db->mxCache;
|
||||
sqlite3VdbeChangeStmtCacheSize(db, 0);
|
||||
assert( db->nCache==0 );
|
||||
db->mxCache = mxCache;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+34
-4
@@ -25,6 +25,7 @@ static const char zHelp[] =
|
||||
" --output FILE Store SQL output in FILE\n"
|
||||
" --pagesize N Set the page size to N\n"
|
||||
" --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
|
||||
" --persist Use the SQLITE_PREPARE_PERSISTENT flag\n"
|
||||
" --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n"
|
||||
" --repeat N Repeat each SELECT N times (default: 1)\n"
|
||||
" --reprepare Reprepare each statement upon every invocation\n"
|
||||
@@ -37,6 +38,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"
|
||||
@@ -66,6 +68,10 @@ static const char zHelp[] =
|
||||
# define sqlite3_int64 sqlite_int64
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_PREPARE_CACHE
|
||||
# define SQLITE_PREPARE_CACHE 0x40000000
|
||||
#endif
|
||||
|
||||
typedef sqlite3_uint64 u64;
|
||||
|
||||
/*
|
||||
@@ -88,6 +94,7 @@ static struct Global {
|
||||
sqlite3_int64 iTotal; /* Total time */
|
||||
int bWithoutRowid; /* True for --without-rowid */
|
||||
int bReprepare; /* True to reprepare the SQL on each rerun */
|
||||
unsigned int mPrepFlags; /* Flags passed into sqlite3_prepare_v3() */
|
||||
int bSqlOnly; /* True to print the SQL once only */
|
||||
int bExplain; /* Print SQL with EXPLAIN prefix */
|
||||
int bVerify; /* Try to verify that results are correct */
|
||||
@@ -97,6 +104,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 */
|
||||
@@ -502,7 +510,7 @@ char *speedtest1_once(const char *zFormat, ...){
|
||||
if( g.bSqlOnly ){
|
||||
printSql(zSql);
|
||||
}else{
|
||||
int rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
|
||||
int rc = sqlite3_prepare_v3(g.db, zSql, -1, 0, &pStmt, 0);
|
||||
if( rc ){
|
||||
fatal_error("SQL error: %s\n", sqlite3_errmsg(g.db));
|
||||
}
|
||||
@@ -534,7 +542,7 @@ void speedtest1_prepare(const char *zFormat, ...){
|
||||
}else{
|
||||
int rc;
|
||||
if( g.pStmt ) sqlite3_finalize(g.pStmt);
|
||||
rc = sqlite3_prepare_v2(g.db, zSql, -1, &g.pStmt, 0);
|
||||
rc = sqlite3_prepare_v3(g.db, zSql, -1, g.mPrepFlags, &g.pStmt, 0);
|
||||
if( rc ){
|
||||
fatal_error("SQL error: %s\n", sqlite3_errmsg(g.db));
|
||||
}
|
||||
@@ -602,8 +610,16 @@ void speedtest1_run(void){
|
||||
#if SQLITE_VERSION_NUMBER>=3006001
|
||||
if( g.bReprepare ){
|
||||
sqlite3_stmt *pNew;
|
||||
sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
|
||||
sqlite3_finalize(g.pStmt);
|
||||
if( g.mPrepFlags & SQLITE_PREPARE_CACHE ){
|
||||
char zBuf[1000];
|
||||
strncpy(zBuf, sqlite3_sql(g.pStmt), sizeof(zBuf));
|
||||
zBuf[sizeof(zBuf)-1] = 0;
|
||||
sqlite3_finalize(g.pStmt);
|
||||
sqlite3_prepare_v3(g.db, zBuf, -1, g.mPrepFlags, &pNew, 0);
|
||||
}else{
|
||||
sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
|
||||
sqlite3_finalize(g.pStmt);
|
||||
}
|
||||
g.pStmt = pNew;
|
||||
}else
|
||||
#endif
|
||||
@@ -2289,6 +2305,8 @@ int main(int argc, char **argv){
|
||||
if( i>=argc-1 ) fatal_error("missing arguments on %s\n", argv[i]);
|
||||
g.nRepeat = integerValue(argv[i+1]);
|
||||
i += 1;
|
||||
}else if( strcmp(z,"persist")==0 ){
|
||||
g.mPrepFlags |= SQLITE_PREPARE_PERSISTENT;
|
||||
}else if( strcmp(z,"reprepare")==0 ){
|
||||
g.bReprepare = 1;
|
||||
#if SQLITE_VERSION_NUMBER>=3006000
|
||||
@@ -2311,6 +2329,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 ){
|
||||
@@ -2405,6 +2427,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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user