-C New\stest\scases\sin\stest/fuzzdata8.db.
-D 2019-04-24T17:04:02.548
+C An\sexperimental\sinterface\sfor\sretrieving\sthe\sestimated\scost\sand\sestimated\nnumber\sof\soutput\srows\sfor\sa\squery.
+D 2019-04-26T17:20:33.254
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93
-F src/shell.c.in bcfa17eb257bf8dc2359e99ba7e6bdfab7901705db013bc47a5be6d7fa7a037e
-F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd
+F src/shell.c.in 7544d68921f2c3919da2150c1f7b53a4942c212dd59e68b7926fd903101c3cab
+F src/sqlite.h.in 0c4ec0ea145005e2a458b892a8e6778d980efcd2ad36a68565b8774712eb79c1
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
F src/sqliteInt.h 866311ac436c0c2039fccc7ea976fbc79d40c1c2ea687161fa4ba64379b53ae6
F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
F src/vdbe.c 711ef421b3bb3db3b2476067b2dc3c71ef5844d9b1a723026578f89f6da621e8
-F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
-F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90
-F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92
-F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873
+F src/vdbe.h f99dbc42943d945f2aa61377dc67e571688310be51dbc9b3e4299bd0124fdd70
+F src/vdbeInt.h a9089cdf0d5f4a1f076d5b22e5690b6ee2f70b1db0a4814ae1a6397c497c838b
+F src/vdbeapi.c 69fae8eb6e1e762e04bfce308f8180294f98a95f7b346f6cb3a1364fd8095cdd
+F src/vdbeaux.c cf9159eaf4b2ac4d0c0daa61544055d9db924989d433c1f77e2af61ebdcb6a05
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
F src/vdbemem.c dd2ee49255c4c5450f2b0887ef44cea8faa1cd7a46501b39a1a82b113ae418e3
F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4
-F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369
-F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88
+F src/where.c 3e9689df25c0410dc60ee28d81ca21ea4dcdbdd925bff764afea95ef6c105975
+F src/whereInt.h 50e1ddaae281e056eb71d8209ffc194e730745fb521fa8f22d0867cc34e9f3d7
F src/wherecode.c 0e76672930bea322eb3606d891a4744be55c09bcd3a995bfd501af62a46e0625
F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c
F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P e1724f1d618cfbcfd1e495d8965a395656cfc1114e1bffd4bc3be0bd5cdb6550
-R 3e1175ca2cd3d699a0989ce182ed2c32
+P 7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf
+R f445bfaab7875d7e9d6792f1def24978
+T *branch * cost-est
+T *sym-cost-est *
+T -sym-trunk *
U drh
-Z b7a4bb53a6677ebeb4f1be668326c373
+Z b1b37fe7015f8bb5921c7a5e02cfd8b8
-7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf
\ No newline at end of file
+1b25fa108ab2c4ada75935abf919de2b4c3b39553b2a0ab2a485645a02352e7e
\ No newline at end of file
/*
** Display and reset the EXPLAIN QUERY PLAN data
*/
-static void eqp_render(ShellState *p){
+static void eqp_render(ShellState *p, sqlite3_stmt *pStmt){
EQPGraphRow *pRow = p->sGraph.pRow;
if( pRow ){
if( pRow->zText[0]=='-' ){
p->sGraph.pRow = pRow->pNext;
sqlite3_free(pRow);
}else{
- utf8_printf(p->out, "QUERY PLAN\n");
+ int iCost, nRow;
+ iCost = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_COST, 0);
+ nRow = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_EST_ROWS, 0);
+ utf8_printf(p->out, "QUERY PLAN (log est cost=%d rows=%d)\n", iCost, nRow);
}
p->sGraph.zPrefix[0] = 0;
eqp_render_level(p, 0);
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
int iEqpId = sqlite3_column_int(pExplain, 0);
int iParentId = sqlite3_column_int(pExplain, 1);
- if( zEQPLine[0]=='-' ) eqp_render(pArg);
+ if( zEQPLine[0]=='-' ) eqp_render(pArg, pExplain);
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
}
- eqp_render(pArg);
+ eqp_render(pArg, pExplain);
}
sqlite3_finalize(pExplain);
sqlite3_free(zEQP);
bind_prepared_stmt(pArg, pStmt);
exec_prepared_stmt(pArg, pStmt);
explain_data_delete(pArg);
- eqp_render(pArg);
+ eqp_render(pArg, pStmt);
/* print usage stats if stats on */
if( pArg && pArg->statsOn ){
** used to store the prepared statement. ^This value is not actually
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
+**
+** [[SQLITE_STMTSTATUS_EST_ROWS]] <dt>SQLITE_STMTSTATUS_EST_ROWS</dt>
+** <dd>^A return value of X indicates that the query planner estimated
+** that the query will return pow(2,X/10.0) rows.
+**
+** [[SQLITE_STMTSTATUS_EST_COST]] <dt>SQLITE_STMTSTATUS_EST_COST</dt>
+** <dd>^A return value of X indicates that the query planner estimated
+** the relative cost of running this statement to completion is
+** pow(2,X/10.0).
** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_REPREPARE 5
#define SQLITE_STMTSTATUS_RUN 6
#define SQLITE_STMTSTATUS_MEMUSED 99
+#define SQLITE_STMTSTATUS_EST_ROWS 100
+#define SQLITE_STMTSTATUS_EST_COST 101
/*
** CAPI3REF: Custom Page Cache Object
VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
void sqlite3VdbeSetVarmask(Vdbe*, int);
+void sqlite3VdbeUpdateCostEstimates(Parse*, LogEst, LogEst);
#ifndef SQLITE_OMIT_TRACE
char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
bft usesStmtJournal:1; /* True if uses a statement journal */
bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
+ LogEst nRowEst; /* Query planner of estimated number of output rows */
+ LogEst iCostEst; /* Query planner cost estimate */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
*/
int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
- u32 v;
-#ifdef SQLITE_ENABLE_API_ARMOR
- if( !pStmt
- || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
- ){
+ u32 v = 0;
+ if( !pStmt ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
-#endif
- if( op==SQLITE_STMTSTATUS_MEMUSED ){
- sqlite3 *db = pVdbe->db;
- sqlite3_mutex_enter(db->mutex);
- v = 0;
- db->pnBytesFreed = (int*)&v;
- sqlite3VdbeClearObject(db, pVdbe);
- sqlite3DbFree(db, pVdbe);
- db->pnBytesFreed = 0;
- sqlite3_mutex_leave(db->mutex);
- }else{
- v = pVdbe->aCounter[op];
- if( resetFlag ) pVdbe->aCounter[op] = 0;
+ switch( op ){
+ case SQLITE_STMTSTATUS_MEMUSED: {
+ sqlite3 *db = pVdbe->db;
+ sqlite3_mutex_enter(db->mutex);
+ v = 0;
+ db->pnBytesFreed = (int*)&v;
+ sqlite3VdbeClearObject(db, pVdbe);
+ sqlite3DbFree(db, pVdbe);
+ db->pnBytesFreed = 0;
+ sqlite3_mutex_leave(db->mutex);
+ break;
+ }
+ case SQLITE_STMTSTATUS_EST_ROWS: {
+ v = pVdbe->nRowEst;
+ break;
+ }
+ case SQLITE_STMTSTATUS_EST_COST: {
+ v = pVdbe->iCostEst;
+ break;
+ }
+ default: {
+ if( op>=0 && op<ArraySize(pVdbe->aCounter) ){
+ v = pVdbe->aCounter[op];
+ if( resetFlag ) pVdbe->aCounter[op] = 0;
+ }else{
+ (void)SQLITE_MISUSE_BKPT;
+ }
+ }
}
return (int)v;
}
}
}
+/*
+** Update the estimated cost fields
+*/
+void sqlite3VdbeUpdateCostEstimates(Parse *pParse, LogEst iCost, LogEst nRow){
+ Vdbe *v = pParse->pVdbe;
+ if( v->iCostEst ){
+ v->iCostEst = sqlite3LogEstAdd(v->iCostEst, iCost+pParse->nQueryLoop) + 1;
+ if( nRow > v->nRowEst ) v->nRowEst = nRow;
+ }else{
+ v->nRowEst = nRow;
+ v->iCostEst = iCost + 1;
+ }
+}
+
/*
** Cause a function to throw an error if it was call from OP_PureFunc
** rather than OP_Function.
pWInfo->nRowOut = pFrom->nRow;
+ pWInfo->iTotalCost = pFrom->rCost;
/* Free temporary memory and return success */
sqlite3DbFreeNN(db, pSpace);
/* Generate loop termination code.
*/
+ sqlite3VdbeUpdateCostEstimates(pParse, pWInfo->iTotalCost, pWInfo->nRowOut);
VdbeModuleComment((v, "End WHERE-core"));
for(i=pWInfo->nLevel-1; i>=0; i--){
int addr;
WhereLoop *pLoops; /* List of all WhereLoop objects */
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */
+ LogEst iTotalCost; /* Cost estimate for the whole plan */
WhereClause sWC; /* Decomposition of the WHERE clause */
WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
WhereLevel a[1]; /* Information about each nest loop in WHERE */