-C Fix\sa\sproblem\sin\sfts5\swhere\sa\scorrupt\sdb\scould\slead\sto\sa\s(huge)\sbuffer\soverread.
-D 2016-02-29T17:34:16.069
+C Modify\sthe\sANALYZE\scommand\sto\sstore\sworst-case\sstatistics\sin\ssqlite_stat1,\nrather\sthn\saverage\scase.
+D 2016-02-29T18:30:30.116
F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 4f319afb7c049d40aff7af6e8c4e7cc2ba18e079
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 44e18dfd78e8942d65d3cdaec4de972b5cd9f1f2
-F src/analyze.c ab57b6763dd4c6170a20673d14882c033affd188
+F src/analyze.c 37343619c6c560722aac521d156d34ebff746526
F src/attach.c a3724c64de1099d85e30751213d285752aed9505
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 251d6473f7c9ad95adbdcc49cb8eaf7c0956764b
-R 1a43d3061a1f154a38fc05ffa17e1f4a
-U dan
-Z 0ef60cd2035dd9bea82e9df13f5bcf57
+P c9a30e117f2c6c9ef0cc0c6ca5227d2961715b8f
+R 180de557065fd2bddac753825b6be69a
+T *branch * analyze-worst-case
+T *sym-analyze-worst-case *
+T -sym-trunk *
+U drh
+Z 3d046dcd3035333c5259dea36a77e4b0
struct Stat4Sample {
tRowcnt *anEq; /* sqlite_stat4.nEq */
tRowcnt *anDLt; /* sqlite_stat4.nDLt */
+ tRowcnt *amxEq; /* Maximum length run of equal values */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
tRowcnt *anLt; /* sqlite_stat4.nLt */
union {
/* Allocate the space required for the Stat4Accum object */
n = sizeof(*p)
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
- + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.amxEq */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
+ sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
p->nRow = 0;
p->nCol = nCol;
p->nKeyCol = nKeyCol;
- p->current.anDLt = (tRowcnt*)&p[1];
- p->current.anEq = &p->current.anDLt[nColUp];
+ p->current.anEq = (tRowcnt*)&p[1];
+ p->current.amxEq = &p->current.anEq[nColUp];
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
{
u8 *pSpace; /* Allocated space not yet assigned */
- int i; /* Used to iterate through p->aSample[] */
+ int i; /* Loop counter */
p->iGet = -1;
p->mxSample = mxSample;
p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
- p->current.anLt = &p->current.anEq[nColUp];
+ p->current.anDLt = &p->current.amxEq[nColUp];
+ p->current.anLt = &p->current.anDLt[nColUp];
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
/* Set up the Stat4Accum.a[] and aBest[] arrays */
if( p->nRow==0 ){
/* This is the first call to this function. Do initialization. */
- for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
+ for(i=0; i<p->nCol; i++){
+ p->current.anEq[i] = 1;
+ p->current.amxEq[i] = 1;
+ }
}else{
/* Second and subsequent calls get processed here */
samplePushPrevious(p, iChng);
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
** to the current row of the index. */
for(i=0; i<iChng; i++){
+ if( p->current.amxEq[i]==p->current.anEq[i] ) p->current.amxEq[i]++;
p->current.anEq[i]++;
}
for(i=iChng; i<p->nCol; i++){
- p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ p->current.anDLt[i]++;
p->current.anLt[i] += p->current.anEq[i];
#endif
p->current.anEq[i] = 1;
** the index. The first integer in the list is the total number of
** entries in the index. There is one additional integer in the list
** for each indexed column. This additional integer is an estimate of
- ** the number of rows matched by a stabbing query on the index using
+ ** the number of rows matched by a query on the index using
** a key with the corresponding number of fields. In other words,
** if the index is on columns (a,b) and the sqlite_stat1 value is
** "100 10 2", then SQLite estimates that:
** * "WHERE a=?" matches 10 rows, and
** * "WHERE a=? AND b=?" matches 2 rows.
**
- ** If D is the count of distinct values and K is the total number of
- ** rows, then each estimate is computed as:
- **
- ** I = (K+D-1)/D
+ ** Use the worst-case estimate: the maximum number of repeated entries
+ ** in the index.
*/
char *z;
int i;
sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
z = zRet + sqlite3Strlen30(zRet);
for(i=0; i<p->nKeyCol; i++){
- u64 nDistinct = p->current.anDLt[i] + 1;
- u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
+ u64 iVal = p->current.amxEq[i];
sqlite3_snprintf(24, z, " %llu", iVal);
z += sqlite3Strlen30(z);
assert( p->current.anEq[i] );