-C Remove\sthe\sSQLITE_OMIT_BTREECOUNT\soption.\s\sBtree\scount\sis\srequired.
-D 2020-03-17T13:41:51.882
+C Provide\san\sestimated\srow\scount\sto\sstat_init()\sfor\sSTAT1\sanalysis.
+D 2020-03-17T17:11:23.756
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de
-F src/analyze.c aaeb41ef74002ffef24363891f3205aa0d544dfc0eb56a859d142fe08f9bc608
+F src/analyze.c 0df49eed25e472ef00bfe12184548a5a51890e7cd650c40fe2681430bdcae9d1
F src/attach.c fa5addce233a2bb2dfdefeee3b37000e154c47214d3269cab1bb331416e330db
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b
F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a
F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9
-F src/vdbe.c 1f5e82e73bc8fa158c643ed289a3ae15c0b7cf3c5f75ab96cef5b5f0798fdfee
+F src/vdbe.c 45896ffb6241d1b001a73a84a480af25036de89bab4a74ed1814d9020384d420
F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9
F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c38ea4139d87535b789f43eb1e38b2dc4b8312352a721035283e67cf0f3d5067
-R 10acd344478148ed927d0774ca99ede6
+P a9bfa47aeea27e91611ba913d33e6635d2016e2c2ab78f9b0657f1bd8933e1a8
+R 83170381358df6124fa4b6f4f7b0bc2e
U drh
-Z 526c8dc722a58bf8fb8a844ac4513f2a
+Z b22aba55e2c8d6bfe6ccc85eac867e5f
};
struct StatAccum {
sqlite3 *db; /* Database connection, for malloc() */
- tRowcnt nRow; /* Number of rows in the entire table */
+ tRowcnt nEst; /* Estimated number of rows */
+ tRowcnt nRow; /* Number of rows visited so far */
int nCol; /* Number of columns in index + pk/rowid */
int nKeyCol; /* Number of index columns w/o the pk/rowid */
StatSample current; /* Current row as a StatSample */
** are:
** N: The number of columns in the index including the rowid/pk (note 1)
** K: The number of columns in the index excluding the rowid/pk.
-** C: The number of rows in the index (note 2)
+** C: Estimated number of rows in the index
**
** Note 1: In the special case of the covering index that implements a
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
** total number of columns in the table.
**
-** Note 2: C is only used for STAT4.
-**
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
** PRIMARY KEY of the table. The covering index that implements the
}
p->db = db;
+ p->nEst = sqlite3_value_int64(argv[2]);
p->nRow = 0;
p->nCol = nCol;
p->nKeyCol = nKeyCol;
p->iGet = -1;
p->mxSample = mxSample;
- p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
+ p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
p->current.anLt = &p->current.anEq[nColUp];
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
{0}
};
-static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){
+static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
#ifdef SQLITE_ENABLE_STAT4
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1);
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
#elif SQLITE_DEBUG
assert( iParam==STAT_GET_STAT1 );
#else
UNUSED_PARAMETER( iParam );
#endif
- assert( regOut!=regStat4 && regOut!=regStat4+1 );
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4,
+ assert( regOut!=regStat && regOut!=regStat+1 );
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
&statGetFuncdef, 0);
}
int iDb; /* Index of database containing pTab */
u8 needTableCnt = 1; /* True to count the table */
int regNewRowid = iMem++; /* Rowid for the inserted record */
- int regStat4 = iMem++; /* Register to hold StatAccum object */
+ int regStat = iMem++; /* Register to hold StatAccum object */
int regChng = iMem++; /* Index of changed index field */
-#ifdef SQLITE_ENABLE_STAT4
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
-#endif
int regTemp = iMem++; /* Temporary use register */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
** (1) the number of columns in the index including the rowid
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
- ** (3) the number of rows in the index,
- **
- **
- ** The third argument is only used for STAT4
+ ** (3) estimated number of rows in the index,
*/
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
+ assert( regRowid==regStat+2 );
+ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
#ifdef SQLITE_ENABLE_STAT4
if( OptimizationEnabled(db, SQLITE_Stat4) ){
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
- }else{
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regStat4+3);
- }
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
+ }else
#endif
- sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
- sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4,
+ {
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
+ }
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 3,
&statInitFuncdef, 0);
/* Implementation of the following:
** goto next_push_0;
**
*/
- addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
- VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrNextRow = sqlite3VdbeCurrentAddr(v);
*/
#ifdef SQLITE_ENABLE_STAT4
if( OptimizationEnabled(db, SQLITE_Stat4) ){
- assert( regRowid==(regStat4+2) );
+ assert( regRowid==(regStat+2) );
if( HasRowid(pTab) ){
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
}else{
}
}
#endif
- assert( regChng==(regStat4+1) );
- sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4,
+ assert( regChng==(regStat+1) );
+ sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
&statPushFuncdef, 0);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
/* Add the entry to the stat1 table. */
- callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1);
+ callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
assert( "BBB"[0]==SQLITE_AFF_TEXT );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
addrNext = sqlite3VdbeCurrentAddr(v);
- callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid);
+ callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
VdbeCoverage(v);
- callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq);
- callStatGet(pParse, regStat4, STAT_GET_NLT, regLt);
- callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt);
+ callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
+ callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
+ callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
for(i=0; i<nCol; i++){