-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
-C Make\suse\sof\shistogram\sdata\sto\smake\sbetter\sestimates\sfor\sthe\snumber\sof\srows\nthat\swill\sbe\sreturned\sfrom\s"x\sIN\s(v1,v2,v3,...)"\sconstraints.
-D 2011-01-21T16:27:18.621
+C Adjustments\sto\sthe\sresult\srow\sestimator\sfor\sthe\sIN\soperator\sso\sthat\sit\sgives\nthe\ssame\sestimates\sas\sthe\sequivalent\sOR\soperator.\s\sTest\scases\sfor\sthe\ssame.
+D 2011-01-21T18:18:13.960
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in de6498556d536ae60bb8bb10e8c1ba011448658c
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/wal.c dbca424f71678f663a286ab2a98f947af1d412a7
F src/wal.h c1aac6593a0b02b15dc625987e619edeab39292e
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
-F src/where.c 7f2844afffd9e09373e874a74de81d3502b2a35c
+F src/where.c 2de6723cfb051bcfcfd3d3ca1ac04bb1388ba530
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125
F test/analyze2.test f45ac8d54bdad822139e53fc6307fc6b5ee41c69
F test/analyze3.test 820ddfb7591b49607fbaf77240c7955ac3cabb04
F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045
-F test/analyze5.test b2139886ee199a226df8f319e37aa7bd78b8f402
+F test/analyze5.test c19fe600c48dade660eb374fa7209435463c2d4a
F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3
F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P f73a167b434fadcbbd15e3891c4b7f4f87f6363c
-R 46f7d508c889f9891a64638b5f1737ae
+P fd3977a27ae68e694df12a4713e55515c1e87c5d
+R cea6312924a8fb4373e961fbaf9716e5
U drh
-Z 14ba122ed035896c7c1b08aa324c4833
+Z d2cdc178cbf264c31de567c61a7d5758
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
-iD8DBQFNObPpoxKgR168RlERAmgEAJ97hcV3wI5jmVOjUrAeDzSnM45gLACghPy2
-7kt0j2FfeGbbS4tWO9hsJaU=
-=BYPr
+iD8DBQFNOc3poxKgR168RlERAkIwAKCEe6e9BZEE6g3M5kOLzfgzYu8BvQCghsyD
+JkbODaFMx8NcwWU/YYsOcuo=
+=cn1U
-----END PGP SIGNATURE-----
#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
+#define TERM_NOHELP 0x80 /* This term does not reduce the search space */
/*
** An instance of the following structure holds all information about a
}else{
sqlite3ExprListDelete(db, pList);
}
+ pTerm->wtFlags |= TERM_NOHELP;
pTerm->eOperator = 0; /* case 1 trumps case 2 */
}
}
#ifdef SQLITE_ENABLE_STAT2
/*
** Estimate the number of rows that will be returned based on
-** an IN constraint "x IN (V1,V2,V3,...)" where the right-hand side
-** of the IN operator is a list of values.
+** an IN constraint where the right-hand side of the IN operator
+** is a list of values. Example:
+**
+** WHERE x IN (1,2,3,4)
**
** Write the estimated row count into *pnRow and return SQLITE_OK.
** If unable to make an estimate, leave *pnRow unchanged and return
sqlite3_value *pVal = 0; /* One value from list */
int iLower, iUpper; /* Range of histogram regions containing pRhs */
u8 aff; /* Column affinity */
- int rc; /* Subfunction return code */
+ int rc = SQLITE_OK; /* Subfunction return code */
double nRowEst; /* New estimate of the number of rows */
- int nRegion = 0; /* Number of histogram regions spanned */
- int nSingle = 0; /* Count of values contained within one region */
+ int nSpan = 0; /* Number of histogram regions spanned */
+ int nSingle = 0; /* Histogram regions hit by a single value */
int nNotFound = 0; /* Count of values that are not constants */
- int i; /* Loop counter */
- u8 aHit[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions that are spanned */
+ int i; /* Loop counter */
+ u8 aSpan[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions that are spanned */
+ u8 aSingle[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions hit once */
assert( p->aSample!=0 );
aff = p->pTable->aCol[p->aiColumn[0]].affinity;
- memset(aHit, 0, sizeof(aHit));
+ memset(aSpan, 0, sizeof(aSpan));
+ memset(aSingle, 0, sizeof(aSingle));
for(i=0; i<pList->nExpr; i++){
sqlite3ValueFree(pVal);
rc = valueFromExpr(pParse, pList->a[i].pExpr, aff, &pVal);
if( rc ) break;
- if( pVal==0 ){
+ if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
nNotFound++;
continue;
}
rc = whereRangeRegion(pParse, p, pVal, 1, &iUpper);
if( rc ) break;
if( iLower>=iUpper ){
- nSingle++;
+ aSingle[iLower] = 1;
+ }else{
+ assert( iLower>=0 && iUpper<=SQLITE_INDEX_SAMPLES );
+ while( iLower<iUpper ) aSpan[iLower++] = 1;
}
- assert( iLower>=0 && iUpper<=SQLITE_INDEX_SAMPLES );
- while( iLower<=iUpper ) aHit[iLower++] = 1;
}
if( rc==SQLITE_OK ){
- for(i=nRegion=0; i<ArraySize(aHit); i++) nRegion += aHit[i];
- nRowEst = nRegion*p->aiRowEst[0]/(SQLITE_INDEX_SAMPLES+1)
+ for(i=nSpan=0; i<=SQLITE_INDEX_SAMPLES; i++){
+ if( aSpan[i] ){
+ nSpan++;
+ }else if( aSingle[i] ){
+ nSingle++;
+ }
+ }
+ nRowEst = (nSpan*2+nSingle)*p->aiRowEst[0]/(2*SQLITE_INDEX_SAMPLES)
+ nNotFound*p->aiRowEst[1];
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
*pnRow = nRowEst;
- WHERETRACE(("IN row estimate: nRegion=%d, nSingle=%d, nNotFound=%d\n",
- nRegion, nSingle, nNotFound));
+ WHERETRACE(("IN row estimate: nSpan=%d, nSingle=%d, nNotFound=%d, est=%g\n",
+ nSpan, nSingle, nNotFound, nRowEst));
}
sqlite3ValueFree(pVal);
return rc;
thisTab = getMask(pWC->pMaskSet, iCur);
for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){
- if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_NOHELP) ) continue;
if( (pTerm->prereqAll & notValid)!=thisTab ) continue;
if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
if( nSkipEq ){
}
}else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
if( nSkipRange ){
- /* Ignore the first nBound range constraints since the index
+ /* Ignore the first nSkipRange range constraints since the index
** has already accounted for these */
nSkipRange--;
}else{