]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Clean up the proper-subset cost adjustment logic to make it more compact
authordrh <drh@noemail.net>
Fri, 18 Apr 2014 22:20:31 +0000 (22:20 +0000)
committerdrh <drh@noemail.net>
Fri, 18 Apr 2014 22:20:31 +0000 (22:20 +0000)
and easier to read and so that full branch test coverage is more easily
obtained.

FossilOrigin-Name: 9a5d38c79d2482a23bcfbc3ff35ca4fa269c768d

manifest
manifest.uuid
src/where.c

index 97b4f2b46f3e239df96c6d2deb8bb33d02823a81..ad0f59f21ea8574729aa39fff1032481960ed6c0 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\sSQLITE_RUNTIME_BYTEORDER\scompile-time\soption\sto\sforce\sSQLite\sto\scheck\nthe\sprocessor\sbyte-order\sat\srun-time.\s\sAdd\sadditional\scompile-time\sbyte\sorder\nchecks\sfor\sARM,\sPPC,\sand\sSPARC.
-D 2014-04-18T00:49:29.419
+C Clean\sup\sthe\sproper-subset\scost\sadjustment\slogic\sto\smake\sit\smore\scompact\nand\seasier\sto\sread\sand\sso\sthat\sfull\sbranch\stest\scoverage\sis\smore\seasily\nobtained.
+D 2014-04-18T22:20:31.054
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -291,7 +291,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
 F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
-F src/where.c 7614c4383d8b6143558dc349da286d0325704d35
+F src/where.c 114b480d3c2eefd9fbc395ee96e03fbd883f418d
 F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -1160,7 +1160,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 9c6961967ae00e563ebe2859eaf2639a79f2cb01
-R 1b4cbcab83595d3a8147d0a70e1ae961
+P 2c5363873a6f990a0abaacac6303acd46b48befc
+R b712e75910761b4771536f725cdc6409
 U drh
-Z a694f54c65c4a003c92caa29b70309b3
+Z e77c4b2dd81e4b608cc5f9bf1e51b6ae
index 05a8b60e7e23e5ff2280e3f2abb5a5688a443e4c..3f9af7e6d6c1ec7d72ba231d677b65050a8edefb 100644 (file)
@@ -1 +1 @@
-2c5363873a6f990a0abaacac6303acd46b48befc
\ No newline at end of file
+9a5d38c79d2482a23bcfbc3ff35ca4fa269c768d
\ No newline at end of file
index e51eee53508d5c15edb16a7103110985c6ae0ec9..31a0dc545286d294dbfc1a2bde62aef8a9238a6f 100644 (file)
@@ -3712,18 +3712,36 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 }
 
 /*
-** Return TRUE if the set of WHERE clause terms used by pA is a proper
-** subset of the WHERE clause terms used by pB.
+** Return TRUE if both of the following are true:
+**
+**   (1)  X has the same or lower cost that Y
+**   (2)  X is a proper subset of Y
+**
+** By "proper subset" we mean that X uses fewer WHERE clause terms
+** than Y and that every WHERE clause term used by X is also used
+** by Y.
+**
+** If X is a proper subset of Y then Y is a better choice and ought
+** to have a lower cost.  This routine returns TRUE when that cost 
+** relationship is inverted and needs to be adjusted.
 */
-static int whereLoopProperSubset(const WhereLoop *pA, const WhereLoop *pB){
+static int whereLoopCheaperProperSubset(
+  const WhereLoop *pX,       /* First WhereLoop to compare */
+  const WhereLoop *pY        /* Compare against this WhereLoop */
+){
   int i, j;
-  assert( pA->nLTerm<pB->nLTerm );  /* Checked by calling function */
-  for(j=0, i=pA->nLTerm-1; i>=0 && j>=0; i--){
-    for(j=pB->nLTerm-1; j>=0; j--){
-      if( pB->aLTerm[j]==pA->aLTerm[i] ) break;
+  if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */
+  if( pX->rRun >= pY->rRun ){
+    if( pX->rRun > pY->rRun ) return 0;    /* X costs more than Y */
+    if( pX->nOut > pY->nOut ) return 0;    /* X costs more than Y */
+  }
+  for(j=0, i=pX->nLTerm-1; i>=0; i--){
+    for(j=pY->nLTerm-1; j>=0; j--){
+      if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
     }
+    if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
   }
-  return j>=0;
+  return 1;  /* All conditions meet */
 }
 
 /*
@@ -3745,19 +3763,14 @@ static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
   for(; p; p=p->pNextLoop){
     if( p->iTab!=pTemplate->iTab ) continue;
     if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
-    if( p->nLTerm<pTemplate->nLTerm
-     && (p->rRun<pTemplate->rRun || (p->rRun==pTemplate->rRun &&
-                                     p->nOut<=pTemplate->nOut))
-     && whereLoopProperSubset(p, pTemplate)
-    ){
+    if( whereLoopCheaperProperSubset(p, pTemplate) ){
+      /* Adjust pTemplate cost downward so that it is cheaper than its 
+      ** subset p */
       pTemplate->rRun = p->rRun;
       pTemplate->nOut = p->nOut - 1;
-    }else
-    if( p->nLTerm>pTemplate->nLTerm
-     && (p->rRun>pTemplate->rRun || (p->rRun==pTemplate->rRun &&
-                                     p->nOut>=pTemplate->nOut))
-     && whereLoopProperSubset(pTemplate, p)
-    ){
+    }else if( whereLoopCheaperProperSubset(pTemplate, p) ){
+      /* Adjust pTemplate cost upward so that it is costlier than p since
+      ** pTemplate is a proper subset of p */
       pTemplate->rRun = p->rRun;
       pTemplate->nOut = p->nOut + 1;
     }