-C Provide\san\sestimated\srow\scount\sto\sstat_init()\sfor\sSTAT1\sanalysis.
-D 2020-03-17T17:11:23.756
+C Add\sthe\sSQLITE_ANALYZE_LIMIT\scompile-time\soption\s(expected\sto\sbe\stemporary)\nthat\ssets\sa\sthreshold\sat\swhich\sANALYZE\sstarts\sto\suse\sapproximations\sduring\nthe\sanalysis\sprocess.
+D 2020-03-18T14:43:05.229
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 0df49eed25e472ef00bfe12184548a5a51890e7cd650c40fe2681430bdcae9d1
+F src/analyze.c 2ae3d2e13387eac29ffb4f94279e00ec1f96145f56a06a8aa57533bd0c64bd99
F src/attach.c fa5addce233a2bb2dfdefeee3b37000e154c47214d3269cab1bb331416e330db
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a9bfa47aeea27e91611ba913d33e6635d2016e2c2ab78f9b0657f1bd8933e1a8
-R 83170381358df6124fa4b6f4f7b0bc2e
+P 714419fe85cfdad22979183a94e4569c87740652758ab76b646753cf2b013b54
+R 9e076c207b1e065d9ce5cb1bfdf9885a
U drh
-Z b22aba55e2c8d6bfe6ccc85eac867e5f
+Z 74d44bcaa72564678d221e098ce4dbd2
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 */
+ u8 nSkipAhead; /* Number of times of skip-ahead */
StatSample current; /* Current row as a StatSample */
#ifdef SQLITE_ENABLE_STAT4
tRowcnt nPSample; /* How often to do a periodic sample */
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
- sqlite3 *db; /* Database connection */
+ sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
#ifdef SQLITE_ENABLE_STAT4
/* Maximum number of samples. 0 if STAT4 data is not collected */
- int mxSample = sqlite3_value_int64(argv[2]) ? SQLITE_STAT4_SAMPLES : 0;
+ int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
#endif
/* Decode the three function arguments */
p->nRow = 0;
p->nCol = nCol;
p->nKeyCol = nKeyCol;
+ p->nSkipAhead = 0;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp];
#ifdef SQLITE_ENABLE_STAT4
+ p->mxSample = mxSample;
if( mxSample ){
u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */
p->iGet = -1;
- p->mxSample = mxSample;
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]);
}
#endif /* SQLITE_ENABLE_STAT4 */
+/*
+** A limit on the number of rows of an index that will be examined
+** by ANALYZE before it starts going with approximations. Zero means
+** "no limit".
+*/
+#ifndef SQLITE_ANALYZE_LIMIT
+# define SQLITE_ANALYZE_LIMIT 0
+#endif
+
/*
** Implementation of the stat_push SQL function: stat_push(P,C,R)
** Arguments:
** R Rowid for the current row. Might be a key record for
** WITHOUT ROWID tables.
**
-** This SQL function always returns NULL. It's purpose it to accumulate
-** statistical data and/or samples in the StatAccum object about the
-** index being analyzed. The stat_get() SQL function will later be used to
-** extract relevant information for constructing the sqlite_statN tables.
+** The purpose of this routine is to collect statistical data and/or
+** samples from the index being analyzed into the StatAccum object.
+** The stat_get() SQL function will be used afterwards to
+** retrieve the information gathered.
+**
+** This SQL function usually returns NULL, but might return an integer
+** if it wants the byte-code to do special processing.
**
** The R parameter is only used for STAT4
*/
p->current.anEq[i] = 1;
}
}
+
p->nRow++;
#ifdef SQLITE_ENABLE_STAT4
if( p->mxSample ){
sampleCopy(p, &p->aBest[i], &p->current);
}
}
+ }else
+#endif
+#if SQLITE_ANALYZE_LIMIT
+ if( p->nRow>SQLITE_ANALYZE_LIMIT*(p->nSkipAhead+1) ){
+ p->nSkipAhead++;
+ sqlite3_result_int(context, p->current.anDLt[0]>0);
}
#endif
}
+
static const FuncDef statPushFuncdef = {
2+IsStat4, /* nArg */
SQLITE_UTF8, /* funcFlags */
return;
}
- sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
+ sqlite3_snprintf(24, zRet, "%llu",
+ p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
z = zRet + sqlite3Strlen30(zRet);
for(i=0; i<p->nKeyCol; i++){
u64 nDistinct = p->current.anDLt[i] + 1;
}
#endif
assert( regChng==(regStat+1) );
- sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
- &statPushFuncdef, 0);
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+ {
+ int j1, j2, j3;
+ sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
+ &statPushFuncdef, 0);
+ j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp);
+ j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp);
+ j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
+ sqlite3VdbeJumpHere(v, j1);
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, j2);
+ sqlite3VdbeJumpHere(v, j3);
+ }
/* Add the entry to the stat1 table. */
callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);