mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add an sqlite3_db_config() option - SQLITE_DBCONFIG_STMT_SCANSTATS - for enabling and disabling the collection of sqlite3_stmt_scanstats() statistics in SQLITE_ENABLE_STMT_SCANSTATUS builds. Collection of statistics is disabled by default.
FossilOrigin-Name: 0f5579bef27b84ee855065cfe87703c51e1f9773906a9e0d4e4dafc90bd0e553
This commit is contained in:
36
manifest
36
manifest
@ -1,5 +1,5 @@
|
||||
C Only\suse\sa\sBloom\sfilter\son\san\sautomatic\sindex\sif\sone\sor\smore\sof\sthe\skey\ncolumns\sin\sthe\sindex\scan\stake\son\snon-TEXT\svalues.
|
||||
D 2023-02-28T18:06:52.731
|
||||
C Add\san\ssqlite3_db_config()\soption\s-\sSQLITE_DBCONFIG_STMT_SCANSTATS\s-\sfor\senabling\sand\sdisabling\sthe\scollection\sof\ssqlite3_stmt_scanstats()\sstatistics\sin\sSQLITE_ENABLE_STMT_SCANSTATUS\sbuilds.\sCollection\sof\sstatistics\sis\sdisabled\sby\sdefault.
|
||||
D 2023-02-28T19:39:59.514
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -577,7 +577,7 @@ F src/expr.c 2e5e67e800c9416996df52409746a2f3c7dadf5d38b5a367ce379b239e3f40c8
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 722f20779f5342a787922deded3628d8c74b5249cab04098cf17ee2f2aaff002
|
||||
F src/func.c d187be57a886ddf4e6b7ef584a494361899be3df5eee6d4a747b68ff4aff4122
|
||||
F src/global.c e06ff8e0acd85aec13563c9ecb44fbbf38232ccf73594998fd880b92d619594b
|
||||
F src/global.c 428d2580a1cdf5dbe1f356d1feab83710ae0cc862ece0fb57bc8259e43838c74
|
||||
F src/hash.c c6af5f96a7a76d000f07c5402c48c318c2566beecdee9e78b9d9f60ce7119565
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h b638809e083b601b618df877b2e89cb87c2a47a01f4def10be4c4ebb54664ac7
|
||||
@ -586,7 +586,7 @@ F src/insert.c 7940fce7d4aa855606432d82d20694e17c18a03956f5f5776f2404e2df7c18a8
|
||||
F src/json.c c85ed6fce06f43d414b0d7fff64749d43a0dbd1067123ee407bd3a0752454161
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c b04eb648cedc45efe4298e1ef439ac4f0096ae27b5f01accb0a1f49d57789128
|
||||
F src/main.c cb5b7277b525ac8f7663426485332bb4f3c1fd9d07f4051980dcab806b780808
|
||||
F src/main.c 834e257234fdf9e74c204c1a130920941618e48b2065747162862773ba5416b5
|
||||
F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@ -624,16 +624,16 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c d62c5665279cc7485f9d45b5e20911cc7b19c203f268321a90d05d74f4725750
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 230dc0601f55ae4909b5f88bc002bfa1f1fb331e51f2c6d670d3effc2ced365e
|
||||
F src/shell.c.in cb763c332be668ecba48c85de52df52a86f992867b813460d55c3bccaaf4c0eb
|
||||
F src/sqlite.h.in 5f308635ad467b50af858f271e403d14f8bcc574c2610f7cfd2d00f5bb37f616
|
||||
F src/shell.c.in a319e2a6cdb166d65a91ad0e69a2e9dea6afd066acbf9adce883a6762b43ec49
|
||||
F src/sqlite.h.in 7a2fed8c11df276bc35bc9ac47981cb0a7f9db39b85761a7dd50028fe77d28ce
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
||||
F src/sqliteInt.h cb7182dcdc9910d5f1352c90762545cc5ffb79c4a47f4ae7c5ee044fdb80423b
|
||||
F src/sqliteInt.h e40980dd50f31aa57bed8dbb32c8fecf64b3ad9bc235a3abb24a3b95734cafeb
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c 8522a04fb9c84faa1d80354430ae0ee9349727a3a4b32e3cfe39b9be8324cabd
|
||||
F src/test1.c ad4a8503c4290d37805f107107a503874ff42d8405dd1558fbe2a1a71039816d
|
||||
F src/test1.c 5ca9cb48a5dfef5980417bf5f76594071ae94795cbb8d065f8a1290c3b308ec6
|
||||
F src/test2.c 827446e259a3b7ab949da1542953edda7b5117982576d3e6f1c24a0dd20a5cef
|
||||
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
|
||||
F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664
|
||||
@ -693,11 +693,11 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 3ff7bc2b48dd425b1448304bb86273b05da1621f136d51dbb9789f8803559a1f
|
||||
F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd
|
||||
F src/vdbe.c 523fbe2086179b42dfdc07093f592443f0a3e9583d1ff17ef0d03a25777c1347
|
||||
F src/vdbe.c 1ddcb8a799d1a4e0c3dcc5c3641923d1343439070b35872c1801a78a0059234e
|
||||
F src/vdbe.h 73b904a6b3bb27f308c6cc287a5751ebc7f1f89456be0ed068a12b92844c6e8c
|
||||
F src/vdbeInt.h a4147a4ddf613cb1bcb555ace9e9e74a9c099d65facd88155f191b1fb4d74cfb
|
||||
F src/vdbeapi.c 40c47b1528d308a322203de21d2e0d711753257ed9771771b6129214b1d65932
|
||||
F src/vdbeaux.c 3f9e3b6585e7434aa11300169dd66ddf0fc963a0c6f7940bdc058335dadeb353
|
||||
F src/vdbeaux.c 0f5201346a83a35a08e833c3a03abe626119c07b7361c28bc6a259b98540f1d6
|
||||
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
|
||||
F src/vdbemem.c 0388576b7cf0be13ce14b9e3b8aa90b8a1b923b60321d0242131ae0b5732b43b
|
||||
F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
|
||||
@ -708,9 +708,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c 76d2014b1e69935cc9b50a710f08321d63f7827f2cf6fd9f21cde7e909a61a6c
|
||||
F src/where.c 6b45dc4c47d636f5adb0d78ed71cefab5ab2a7287fb80c86604a5f7874d2ba22
|
||||
F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c
|
||||
F src/wherecode.c b82d0d33315e1526904b95155e55e61149c4462147668e1cc4567c812735eff1
|
||||
F src/wherecode.c 9919e5a22f4b24dd96c49b8981484cbe6bbfcf466ff73ac40a06e1356aa8bf87
|
||||
F src/whereexpr.c 1dfda1695e4480c24248157df55bb4d66c732dc8d14ac16b4f076bb15de93d63
|
||||
F src/window.c 76a27cff9ea2ded0c2c3527187029259440fabcc4cc4c07b11d942c78494a614
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
@ -1436,8 +1436,8 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
|
||||
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||
F test/scanstatus.test 74391c2c0926994bf0962db6c04c9ff5b95d15a41d2e076fe011b73f92815e70
|
||||
F test/scanstatus2.test ca6c258425977e5935f0ff3a8670d9b5d813dd5b83cf0bbe39acfc0fd2b5a0b1
|
||||
F test/scanstatus.test 177fe0fea60898b2190328fbe358bafa2637e81856f90fb527a792efaf249c14
|
||||
F test/scanstatus2.test 7c367a5c818bad1936f291d33f688a3daa42279d4e989d920660c7002d67d3a2
|
||||
F test/schema.test 5dd11c96ba64744de955315d2e4f8992e447533690153b93377dffb2a5ef5431
|
||||
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||
F test/schema3.test 8ed4ae66e082cdd8b1b1f22d8549e1e7a0db4527a8e6ee8b6193053ee1e5c9ce
|
||||
@ -2048,8 +2048,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 090304b870419acb5b05205a07fc75830b556928149f76a843cda526f77a6fc0
|
||||
R 192a8af525d9a67c0614fb52e425206b
|
||||
U drh
|
||||
Z d906284cbfaa2356b8109e77d4c16f08
|
||||
P 5916705c731604d2e6b51a307cc8d7b67f4c102062bfdfcbc716a2916e0b0d86
|
||||
R 62c12b75bd9869fbb782d0697362eb0c
|
||||
U dan
|
||||
Z 823edb92d517eed03d3961ba1e99b0c0
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
5916705c731604d2e6b51a307cc8d7b67f4c102062bfdfcbc716a2916e0b0d86
|
||||
0f5579bef27b84ee855065cfe87703c51e1f9773906a9e0d4e4dafc90bd0e553
|
@ -291,7 +291,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
|
||||
0, /* iPrngSeed */
|
||||
#ifdef SQLITE_DEBUG
|
||||
{0,0,0,0,0,0} /* aTune */
|
||||
{0,0,0,0,0,0}, /* aTune */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -970,6 +970,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
{ SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML },
|
||||
{ SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt },
|
||||
{ SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema },
|
||||
{ SQLITE_DBCONFIG_STMT_SCANSTATS, SQLITE_StmtScanStats },
|
||||
};
|
||||
unsigned int i;
|
||||
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
|
||||
|
@ -5416,8 +5416,13 @@ static void open_db(ShellState *p, int openFlags){
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if( p->bSafeModePersist && p->db!=0 ){
|
||||
sqlite3_set_authorizer(p->db, safeModeAuth, p);
|
||||
if( p->db!=0 ){
|
||||
if( p->bSafeModePersist ){
|
||||
sqlite3_set_authorizer(p->db, safeModeAuth, p);
|
||||
}
|
||||
sqlite3_db_config(
|
||||
p->db, SQLITE_DBCONFIG_STMT_SCANSTATS, p->scanstatsOn, (int*)0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9769,6 +9774,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else{
|
||||
p->scanstatsOn = (u8)booleanValue(azArg[1]);
|
||||
}
|
||||
sqlite3_db_config(
|
||||
p->db, SQLITE_DBCONFIG_STMT_SCANSTATS, p->scanstatsOn, (int*)0
|
||||
);
|
||||
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
|
||||
#endif
|
||||
|
@ -2456,6 +2456,16 @@ struct sqlite3_mem_methods {
|
||||
** not considered a bug since SQLite versions 3.3.0 and earlier do not support
|
||||
** either generated columns or decending indexes.
|
||||
** </dd>
|
||||
|
||||
** [[SQLITE_DBCONFIG_STMT_SCANSTATS]]
|
||||
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATS</td>
|
||||
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATS option is only useful in
|
||||
** SQLITE_ENABLE_STMT_SCANSTATS builds. In this case, it sets or clears
|
||||
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
|
||||
** statistics. For statistics to be collected, the flag must be set on
|
||||
** the database handle both when the SQL statement is prepared and when it
|
||||
** is stepped. The flag is clear (collection of statistics is disabled)
|
||||
** by default.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
|
||||
@ -2476,7 +2486,8 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */
|
||||
#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */
|
||||
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_STMT_SCANSTATS 1018 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1018 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
|
@ -1757,7 +1757,7 @@ struct sqlite3 {
|
||||
#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
|
||||
/* result set is empty */
|
||||
#define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */
|
||||
#define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */
|
||||
#define SQLITE_StmtScanStats 0x00000400 /* Enable stmt_scanstats() counters */
|
||||
#define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */
|
||||
#define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */
|
||||
#define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */
|
||||
@ -1783,6 +1783,7 @@ struct sqlite3 {
|
||||
/* DELETE, or UPDATE and return */
|
||||
/* the count using a callback. */
|
||||
#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
|
||||
#define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */
|
||||
|
||||
/* Flags used only if debugging */
|
||||
#ifdef SQLITE_DEBUG
|
||||
@ -5581,4 +5582,10 @@ int sqlite3KvvfsInit(void);
|
||||
sqlite3_uint64 sqlite3Hwtime(void);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
# define IS_STMT_SCANSTATUS(db) (db->flags & SQLITE_StmtScanStats)
|
||||
#else
|
||||
# define IS_STMT_SCANSTATUS(db) 0
|
||||
#endif
|
||||
|
||||
#endif /* SQLITEINT_H */
|
||||
|
@ -2400,7 +2400,6 @@ static int SQLITE_TCLAPI test_create_null_module(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc;
|
||||
sqlite3 *db;
|
||||
char *zName;
|
||||
|
||||
@ -8314,6 +8313,7 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
|
||||
{ "DQS_DML", SQLITE_DBCONFIG_DQS_DML },
|
||||
{ "DQS_DDL", SQLITE_DBCONFIG_DQS_DDL },
|
||||
{ "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
|
||||
{ "STMT_SCANSTATS", SQLITE_DBCONFIG_STMT_SCANSTATS },
|
||||
};
|
||||
int i;
|
||||
int v = 0;
|
||||
|
19
src/vdbe.c
19
src/vdbe.c
@ -736,6 +736,7 @@ int sqlite3VdbeExec(
|
||||
Mem *pOut = 0; /* Output operand */
|
||||
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
|
||||
u64 *pnCycle = 0;
|
||||
int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0;
|
||||
#endif
|
||||
/*** INSERT STACK UNION HERE ***/
|
||||
|
||||
@ -800,13 +801,17 @@ int sqlite3VdbeExec(
|
||||
|
||||
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
|
||||
nVmStep++;
|
||||
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
|
||||
|
||||
#if defined(VDBE_PROFILE)
|
||||
pOp->nExec++;
|
||||
pnCycle = &pOp->nCycle;
|
||||
# ifdef VDBE_PROFILE
|
||||
if( sqlite3NProfileCnt==0 )
|
||||
# endif
|
||||
if( sqlite3NProfileCnt==0 ) *pnCycle -= sqlite3Hwtime();
|
||||
#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS)
|
||||
if( bStmtScanStatus ){
|
||||
pOp->nExec++;
|
||||
pnCycle = &pOp->nCycle;
|
||||
*pnCycle -= sqlite3Hwtime();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Only allow tracing if SQLITE_DEBUG is defined.
|
||||
@ -8758,8 +8763,10 @@ default: { /* This is really OP_Noop, OP_Explain */
|
||||
*pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
|
||||
pnCycle = 0;
|
||||
#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS)
|
||||
*pnCycle += sqlite3Hwtime();
|
||||
pnCycle = 0;
|
||||
if( pnCycle ){
|
||||
*pnCycle += sqlite3Hwtime();
|
||||
pnCycle = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The following code adds nothing to the actual functionality
|
||||
|
@ -443,10 +443,10 @@ void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
|
||||
*/
|
||||
int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
|
||||
int addr = 0;
|
||||
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
|
||||
#if !defined(SQLITE_DEBUG)
|
||||
/* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
|
||||
** But omit them (for performance) during production builds */
|
||||
if( pParse->explain==2 )
|
||||
if( pParse->explain==2 || IS_STMT_SCANSTATUS(pParse->db) )
|
||||
#endif
|
||||
{
|
||||
char *zMsg;
|
||||
@ -1122,18 +1122,20 @@ void sqlite3VdbeScanStatus(
|
||||
LogEst nEst, /* Estimated number of output rows */
|
||||
const char *zName /* Name of table or index being scanned */
|
||||
){
|
||||
sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus);
|
||||
ScanStatus *aNew;
|
||||
aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
|
||||
if( aNew ){
|
||||
ScanStatus *pNew = &aNew[p->nScan++];
|
||||
memset(pNew, 0, sizeof(ScanStatus));
|
||||
pNew->addrExplain = addrExplain;
|
||||
pNew->addrLoop = addrLoop;
|
||||
pNew->addrVisit = addrVisit;
|
||||
pNew->nEst = nEst;
|
||||
pNew->zName = sqlite3DbStrDup(p->db, zName);
|
||||
p->aScan = aNew;
|
||||
if( IS_STMT_SCANSTATUS(p->db) ){
|
||||
sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus);
|
||||
ScanStatus *aNew;
|
||||
aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
|
||||
if( aNew ){
|
||||
ScanStatus *pNew = &aNew[p->nScan++];
|
||||
memset(pNew, 0, sizeof(ScanStatus));
|
||||
pNew->addrExplain = addrExplain;
|
||||
pNew->addrLoop = addrLoop;
|
||||
pNew->addrVisit = addrVisit;
|
||||
pNew->nEst = nEst;
|
||||
pNew->zName = sqlite3DbStrDup(p->db, zName);
|
||||
p->aScan = aNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1150,20 +1152,22 @@ void sqlite3VdbeScanStatusRange(
|
||||
int addrStart,
|
||||
int addrEnd
|
||||
){
|
||||
ScanStatus *pScan = 0;
|
||||
int ii;
|
||||
for(ii=p->nScan-1; ii>=0; ii--){
|
||||
pScan = &p->aScan[ii];
|
||||
if( pScan->addrExplain==addrExplain ) break;
|
||||
pScan = 0;
|
||||
}
|
||||
if( pScan ){
|
||||
if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1;
|
||||
for(ii=0; ii<ArraySize(pScan->aAddrRange); ii+=2){
|
||||
if( pScan->aAddrRange[ii]==0 ){
|
||||
pScan->aAddrRange[ii] = addrStart;
|
||||
pScan->aAddrRange[ii+1] = addrEnd;
|
||||
break;
|
||||
if( IS_STMT_SCANSTATUS(p->db) ){
|
||||
ScanStatus *pScan = 0;
|
||||
int ii;
|
||||
for(ii=p->nScan-1; ii>=0; ii--){
|
||||
pScan = &p->aScan[ii];
|
||||
if( pScan->addrExplain==addrExplain ) break;
|
||||
pScan = 0;
|
||||
}
|
||||
if( pScan ){
|
||||
if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1;
|
||||
for(ii=0; ii<ArraySize(pScan->aAddrRange); ii+=2){
|
||||
if( pScan->aAddrRange[ii]==0 ){
|
||||
pScan->aAddrRange[ii] = addrStart;
|
||||
pScan->aAddrRange[ii+1] = addrEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1180,19 +1184,21 @@ void sqlite3VdbeScanStatusCounters(
|
||||
int addrLoop,
|
||||
int addrVisit
|
||||
){
|
||||
ScanStatus *pScan = 0;
|
||||
int ii;
|
||||
for(ii=p->nScan-1; ii>=0; ii--){
|
||||
pScan = &p->aScan[ii];
|
||||
if( pScan->addrExplain==addrExplain ) break;
|
||||
pScan = 0;
|
||||
}
|
||||
if( pScan ){
|
||||
pScan->addrLoop = addrLoop;
|
||||
pScan->addrVisit = addrVisit;
|
||||
if( IS_STMT_SCANSTATUS(p->db) ){
|
||||
ScanStatus *pScan = 0;
|
||||
int ii;
|
||||
for(ii=p->nScan-1; ii>=0; ii--){
|
||||
pScan = &p->aScan[ii];
|
||||
if( pScan->addrExplain==addrExplain ) break;
|
||||
pScan = 0;
|
||||
}
|
||||
if( pScan ){
|
||||
pScan->addrLoop = addrLoop;
|
||||
pScan->addrVisit = addrVisit;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(SQLITE_ENABLE_STMT_SCANSTATUS) */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -831,7 +831,7 @@ static void explainAutomaticIndex(
|
||||
int bPartial, /* True if pIdx is a partial index */
|
||||
int *pAddrExplain /* OUT: Address of OP_Explain */
|
||||
){
|
||||
if( pParse->explain!=2 ){
|
||||
if( IS_STMT_SCANSTATUS(pParse->db) && pParse->explain!=2 ){
|
||||
Table *pTab = pIdx->pTable;
|
||||
const char *zSep = "";
|
||||
char *zText = 0;
|
||||
|
@ -111,9 +111,9 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
|
||||
|
||||
/*
|
||||
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
|
||||
** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
|
||||
** defined at compile-time. If it is not a no-op, a single OP_Explain opcode
|
||||
** is added to the output to describe the table scan strategy in pLevel.
|
||||
** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG
|
||||
** was defined at compile-time. If it is not a no-op, a single OP_Explain
|
||||
** opcode is added to the output to describe the table scan strategy in pLevel.
|
||||
**
|
||||
** If an OP_Explain opcode is added to the VM, its address is returned.
|
||||
** Otherwise, if no OP_Explain is coded, zero is returned.
|
||||
@ -125,8 +125,8 @@ int sqlite3WhereExplainOneScan(
|
||||
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
|
||||
){
|
||||
int ret = 0;
|
||||
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
|
||||
if( sqlite3ParseToplevel(pParse)->explain==2 )
|
||||
#if !defined(SQLITE_DEBUG)
|
||||
if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) )
|
||||
#endif
|
||||
{
|
||||
SrcItem *pItem = &pTabList->a[pLevel->iFrom];
|
||||
@ -292,27 +292,29 @@ void sqlite3WhereAddScanStatus(
|
||||
WhereLevel *pLvl, /* Level to add scanstatus() entry for */
|
||||
int addrExplain /* Address of OP_Explain (or 0) */
|
||||
){
|
||||
const char *zObj = 0;
|
||||
WhereLoop *pLoop = pLvl->pWLoop;
|
||||
int wsFlags = pLoop->wsFlags;
|
||||
int viaCoroutine = 0;
|
||||
if( IS_STMT_SCANSTATUS( sqlite3VdbeDb(v) ) ){
|
||||
const char *zObj = 0;
|
||||
WhereLoop *pLoop = pLvl->pWLoop;
|
||||
int wsFlags = pLoop->wsFlags;
|
||||
int viaCoroutine = 0;
|
||||
|
||||
if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){
|
||||
zObj = pLoop->u.btree.pIndex->zName;
|
||||
}else{
|
||||
zObj = pSrclist->a[pLvl->iFrom].zName;
|
||||
viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine;
|
||||
}
|
||||
sqlite3VdbeScanStatus(
|
||||
v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
|
||||
);
|
||||
|
||||
if( viaCoroutine==0 ){
|
||||
if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){
|
||||
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur);
|
||||
if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){
|
||||
zObj = pLoop->u.btree.pIndex->zName;
|
||||
}else{
|
||||
zObj = pSrclist->a[pLvl->iFrom].zName;
|
||||
viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine;
|
||||
}
|
||||
if( wsFlags & WHERE_INDEXED ){
|
||||
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
|
||||
sqlite3VdbeScanStatus(
|
||||
v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
|
||||
);
|
||||
|
||||
if( viaCoroutine==0 ){
|
||||
if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){
|
||||
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur);
|
||||
}
|
||||
if( wsFlags & WHERE_INDEXED ){
|
||||
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,11 @@ proc do_scanstatus_test {tn res} {
|
||||
uplevel [list do_test $tn [list set {} $ret] [list {*}$res]]
|
||||
}
|
||||
|
||||
do_execsql_test 1.0a { SELECT count(*) FROM t1, t2; } 6
|
||||
do_scanstatus_test 1.0b { }
|
||||
|
||||
sqlite3_db_config db STMT_SCANSTATS 1
|
||||
|
||||
do_execsql_test 1.1 { SELECT count(*) FROM t1, t2; } 6
|
||||
do_scanstatus_test 1.2 {
|
||||
nLoop 1 nVisit 2 nEst 1048576.0 zName t1 zExplain {SCAN t1}
|
||||
@ -94,6 +99,7 @@ do_scanstatus_test 1.10 {
|
||||
# Try a few different types of scans.
|
||||
#
|
||||
reset_db
|
||||
sqlite3_db_config db STMT_SCANSTATS 1
|
||||
do_execsql_test 2.1 {
|
||||
CREATE TABLE x1(i INTEGER PRIMARY KEY, j);
|
||||
INSERT INTO x1 VALUES(1, 'one');
|
||||
@ -277,6 +283,7 @@ do_scanstatus_test 4.2.2 {
|
||||
# Further tests of different scan types.
|
||||
#
|
||||
reset_db
|
||||
sqlite3_db_config db STMT_SCANSTATS 1
|
||||
proc tochar {i} {
|
||||
set alphabet {a b c d e f g h i j k l m n o p q r s t u v w x y z}
|
||||
return [lindex $alphabet [expr $i % [llength $alphabet]]]
|
||||
@ -365,6 +372,7 @@ do_eqp_test 5.5.1 {
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN t3
|
||||
|--BLOOM FILTER ON t1 (c=?)
|
||||
`--SEARCH t1 USING AUTOMATIC COVERING INDEX (c=?)
|
||||
}
|
||||
do_execsql_test 5.5.2 {
|
||||
|
@ -19,6 +19,8 @@ ifcapable !scanstatus {
|
||||
return
|
||||
}
|
||||
|
||||
sqlite3_db_config db STMT_SCANSTATS 1
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(x, y);
|
||||
@ -141,6 +143,7 @@ QUERY (nCycle=nnn)
|
||||
#-------------------------------------------------------------------------
|
||||
ifcapable fts5 {
|
||||
reset_db
|
||||
sqlite3_db_config db STMT_SCANSTATS 1
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts5(a);
|
||||
INSERT INTO ft VALUES('abc');
|
||||
@ -158,6 +161,7 @@ QUERY (nCycle=nnn)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
sqlite3_db_config db STMT_SCANSTATS 1
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE x1(a, b);
|
||||
CREATE TABLE x2(c, d);
|
||||
@ -173,11 +177,13 @@ do_graph_test 2.1 {
|
||||
QUERY (nCycle=nnn)
|
||||
--SCAN x1 (nCycle=nnn)
|
||||
--CREATE AUTOMATIC INDEX ON x2(c, d) (nCycle=nnn)
|
||||
--BLOOM FILTER ON x2 (c=?)
|
||||
--SEARCH x2 USING AUTOMATIC COVERING INDEX (c=?) (nCycle=nnn)
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
sqlite3_db_config db STMT_SCANSTATS 1
|
||||
do_execsql_test 4.0 {
|
||||
CREATE TABLE rt1 (id INTEGER PRIMARY KEY, x1, x2);
|
||||
CREATE TABLE rt2 (id, x1, x2);
|
||||
@ -189,6 +195,7 @@ do_graph_test 4.1 {
|
||||
QUERY (nCycle=nnn)
|
||||
--SCAN rt1 (nCycle=nnn)
|
||||
--CREATE AUTOMATIC INDEX ON rt2(x1, id, x2) (nCycle=nnn)
|
||||
--BLOOM FILTER ON rt2 (x1=?)
|
||||
--SEARCH rt2 USING AUTOMATIC COVERING INDEX (x1=?) (nCycle=nnn)
|
||||
}
|
||||
|
||||
@ -198,6 +205,7 @@ do_graph_test 4.2 {
|
||||
QUERY (nCycle=nnn)
|
||||
--SCAN rt1 (nCycle=nnn)
|
||||
--CREATE AUTOMATIC INDEX ON rt2(x1, id) (nCycle=nnn)
|
||||
--BLOOM FILTER ON rt2 (x1=?)
|
||||
--SEARCH rt2 USING AUTOMATIC COVERING INDEX (x1=?) (nCycle=nnn)
|
||||
}
|
||||
|
||||
@ -215,6 +223,7 @@ do_graph_test 4.4 {
|
||||
QUERY (nCycle=nnn)
|
||||
--SCAN rt1 (nCycle=nnn)
|
||||
--CREATE AUTOMATIC INDEX ON rt2(x1, id) WHERE <expr> (nCycle=nnn)
|
||||
--BLOOM FILTER ON rt2 (x1=?)
|
||||
--SEARCH rt2 USING AUTOMATIC PARTIAL COVERING INDEX (x1=?) (nCycle=nnn)
|
||||
}
|
||||
|
||||
@ -229,6 +238,7 @@ QUERY (nCycle=nnn)
|
||||
----USE TEMP B-TREE FOR GROUP BY
|
||||
--SCAN rt1 (nCycle=nnn)
|
||||
--CREATE AUTOMATIC INDEX ON v1(x1, cnt) (nCycle=nnn)
|
||||
--BLOOM FILTER ON v1 (x1=?)
|
||||
--SEARCH v1 USING AUTOMATIC COVERING INDEX (x1=?) (nCycle=nnn)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user