From: drh Date: Wed, 19 Jun 2013 12:34:13 +0000 (+0000) Subject: Simplify and add invariants to the WhereLoop merging logic inside of X-Git-Tag: version-3.8.0~134^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dbb80234dabefcb518fb09fa073b6b09bd30f3af;p=thirdparty%2Fsqlite.git Simplify and add invariants to the WhereLoop merging logic inside of whereLoopInsert(). FossilOrigin-Name: 8f27f35f288434b9e7bc503c608f1e2b590ade4d --- diff --git a/manifest b/manifest index d232347684..37bf8cca81 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings.\s\sFix\sa\sharmless\soff-by-one\serror\sin\sthe\ssolver. -D 2013-06-19T03:27:12.614 +C Simplify\sand\sadd\sinvariants\sto\sthe\sWhereLoop\smerging\slogic\sinside\sof\nwhereLoopInsert(). +D 2013-06-19T12:34:13.186 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -289,7 +289,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c 5cc059bd283fe9f99800270c797fabdcbef8009a +F src/where.c e5ecc3d12c5b9d66d13f786e80641614530d1957 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1096,7 +1096,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 4fbb0c4d26c54aaefbe5397cde2a0b9d2ce3885f -R dae7f42197a8d862e7c14dd3769614f8 +P 10021941d0258951b916e788881df140113f0597 +R 38e2e388820d13ceac39bea07ba5a7cc U drh -Z e26ab5beb4ba36d99e52a8a301bdec10 +Z 087e132035ea5a36d1e5d81e4344a21a diff --git a/manifest.uuid b/manifest.uuid index 011a8dd71f..8aac6362f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10021941d0258951b916e788881df140113f0597 \ No newline at end of file +8f27f35f288434b9e7bc503c608f1e2b590ade4d \ No newline at end of file diff --git a/src/where.c b/src/where.c index 73fdcaa431..2626306c24 100644 --- a/src/where.c +++ b/src/where.c @@ -4115,14 +4115,30 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** priority over pTemplate. */ for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){ - if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue; + if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ + /* If either the iTab or iSortIdx values for two WhereLoop are different + ** then those WhereLoops need to be considered separately. Neither is + ** a candidate to replace the other. */ + continue; + } + /* In the current implementation, the rSetup value is either zero + ** or the cost of building an automatic index (NlogN) and the NlogN + ** is the same for compatible WhereLoops. */ + assert( p->rSetup==0 || pTemplate->rSetup==0 + || p->rSetup==pTemplate->rSetup ); + + /* whereLoopAddBtree() always generates and inserts the automatic index + ** case first. Hence compatible candidate WhereLoops never have a larger + ** rSetup. Call this SETUP-INVARIANT */ + assert( p->rSetup>=pTemplate->rSetup ); + if( (p->prereq & pTemplate->prereq)==p->prereq && p->rSetup<=pTemplate->rSetup && p->rRun<=pTemplate->rRun ){ /* This branch taken when p is equal or better than pTemplate in ** all of (1) dependences (2) setup-cost, and (3) run-cost. */ - testcase( p->rRun==pTemplate->rRun ); + assert( p->rSetup==pTemplate->rSetup ); if( p->nLTermnLTerm && (p->wsFlags & WHERE_INDEXED)!=0 && (pTemplate->wsFlags & WHERE_INDEXED)!=0 @@ -4133,38 +4149,22 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** more terms of the index */ pNext = p->pNextLoop; break; - }else if( p->nOut>pTemplate->nOut - && p->rSetup==pTemplate->rSetup - && p->rRun==pTemplate->rRun - ){ - /* Overwrite an existing WhereLoop with the same cost but more - ** outputs */ - pNext = p->pNextLoop; - break; }else{ /* pTemplate is not helpful. ** Return without changing or adding anything */ goto whereLoopInsert_noop; } } - testcase( (p->prereq & pTemplate->prereq)==p->prereq - && p->rSetup<=pTemplate->rSetup - && p->rRun==pTemplate->rRun+1 ); if( (p->prereq & pTemplate->prereq)==pTemplate->prereq - && p->rSetup>=pTemplate->rSetup && p->rRun>=pTemplate->rRun + && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */ ){ /* Overwrite an existing WhereLoop with a better one: one that is ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost ** and is no worse in any of those categories. */ - testcase( p->rSetup==pTemplate->rSetup ); - testcase( p->rRun==pTemplate->rRun ); pNext = p->pNextLoop; break; } - testcase( (p->prereq & pTemplate->prereq)==pTemplate->prereq - && p->rSetup>=pTemplate->rSetup - && p->rRun==pTemplate->rRun-1 ); } /* If we reach this point it means that either p[] should be overwritten