-C Test\sthat\sthe\srollback-hook\sis\sinvoked\sif\sa\scommit-hook\simplementation\sreturns\snon-zero\s(causing\sa\srollback).\sRemove\sdocumentation\scomment\sthat\ssays\sotherwise\sfrom\ssqlite.h.in.
-D 2010-04-13T06:18:02
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+C The\squery\splanner\suses\snon-indexable\sWHERE\sclause\sterms\sto\sreduce\sthe\nestimated\snumber\sof\soutput\srows,\sthen\suses\sthe\sestimated\snumber\sof\soutput\nrows\sas\sa\stie-breaker\swhen\schoosing\stable\sorder.
+D 2010-04-14T19:01:45
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
-F src/where.c 9472b11332699aff0f8926dbe6175f3fb0bb08a3
+F src/where.c 458b6e0d5e3e4eaaf75e352a88641ab2d7e21cad
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P e7e7127f0b0db582274338a9fefc30a0c0be07c3
-R 169f65701c60c914b5babe14af8a5a2d
-U dan
-Z 59ba641787a7f590bcc552c76de3273b
+P 012cf101bf8be9e39c138786ea5a5039b8131e55
+R e6913462c9fc35ffdd8fb296dee81dc4
+U drh
+Z b112ddd6d5441568434e7011a246cd66
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFLxhEcoxKgR168RlERAr4AAJ4o9PzYb8/4qM3TXJMcn3pTohzAyQCeOO2/
+T96saJ5mGiq/UIbcA3uQVL0=
+=Qkym
+-----END PGP SIGNATURE-----
int nBound = 100;
int bSort = 0;
int bLookup = 0;
+ WhereTerm *pTerm; /* A single term of the WHERE clause */
/* Determine the values of nEq and nInMul */
for(nEq=0; nEq<pProbe->nColumn; nEq++){
- WhereTerm *pTerm; /* A single term of the WHERE clause */
int j = pProbe->aiColumn[nEq];
pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
if( pTerm==0 ) break;
}
}
- /**** Begin adding up the cost of using this index (Needs improvements)
- **
+ /*
** Estimate the number of rows of output. For an IN operator,
** do not let the estimate exceed half the rows in the table.
*/
}
/**** Cost of using this index has now been computed ****/
+ /* If there are additional constraints on this table that cannot
+ ** be used with the current index, but which might lower the number
+ ** of output rows, adjust the nRow value accordingly. This only
+ ** matters if the current index is the least costly, so do not bother
+ ** with this step if we already know this index will not be chosen.
+ */
+ if( nRow>2 && cost<=pCost->rCost ){
+ int k;
+ int nSkip = nEq;
+ Bitmask 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->prereqAll & notReady)!=thisTab ) continue;
+ if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
+ if( nSkip ){
+ /* Ignore the first nEq equality matches since the index
+ ** has already accounted for these */
+ nSkip--;
+ }else{
+ /* Assume each additional equality match reduces the result
+ ** set size by a factor of 10 */
+ nRow /= 10;
+ }
+ }else{
+ /* Any other expression lowers the output row count by half */
+ nRow /= 2;
+ }
+ }
+ if( nRow<2 ) nRow = 2;
+ }
+
+
WHERETRACE((
"%s(%s): nEq=%d nInMul=%d nBound=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
" notReady=0x%llx nRow=%.2f cost=%.2f used=0x%llx\n",
/* If this index is the best we have seen so far, then record this
** index and its cost in the pCost structure.
*/
- if( (!pIdx || wsFlags) && cost<pCost->rCost ){
+ if( (!pIdx || wsFlags)
+ && (cost<pCost->rCost || (cost==pCost->rCost && nRow<pCost->nRow))
+ ){
pCost->rCost = cost;
pCost->nRow = nRow;
pCost->used = used;
);
WHERETRACE(("best index is: %s\n",
- (pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
+ ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" :
+ pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
));
bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost);
assert( isOptimal || (sCost.used¬Ready)==0 );
if( (sCost.used¬Ready)==0
- && (j==iFrom || sCost.rCost<bestPlan.rCost)
+ && (j==iFrom || sCost.rCost<bestPlan.rCost
+ || (sCost.rCost==bestPlan.rCost && sCost.nRow<bestPlan.nRow))
){
bestPlan = sCost;
bestJ = j;