/ Check-in [8f27f35f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplify and add invariants to the WhereLoop merging logic inside of whereLoopInsert().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | nextgen-query-plan-exp
Files: files | file ages | folders
SHA1:8f27f35f288434b9e7bc503c608f1e2b590ade4d
User & Date: drh 2013-06-19 12:34:13
Context
2013-06-19
13:32
Fix a harmless uninitialized variable warning. check-in: 9d3ef3bd user: drh tags: nextgen-query-plan-exp
12:34
Simplify and add invariants to the WhereLoop merging logic inside of whereLoopInsert(). check-in: 8f27f35f user: drh tags: nextgen-query-plan-exp
03:27
Fix compiler warnings. Fix a harmless off-by-one error in the solver. check-in: 10021941 user: drh tags: nextgen-query-plan-exp
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/where.c.

  4111   4111       return SQLITE_OK;
  4112   4112     }
  4113   4113   
  4114   4114     /* Search for an existing WhereLoop to overwrite, or which takes
  4115   4115     ** priority over pTemplate.
  4116   4116     */
  4117   4117     for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){
  4118         -    if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ) continue;
         4118  +    if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){
         4119  +      /* If either the iTab or iSortIdx values for two WhereLoop are different
         4120  +      ** then those WhereLoops need to be considered separately.  Neither is
         4121  +      ** a candidate to replace the other. */
         4122  +      continue;
         4123  +    }
         4124  +    /* In the current implementation, the rSetup value is either zero
         4125  +    ** or the cost of building an automatic index (NlogN) and the NlogN
         4126  +    ** is the same for compatible WhereLoops. */
         4127  +    assert( p->rSetup==0 || pTemplate->rSetup==0 
         4128  +                 || p->rSetup==pTemplate->rSetup );
         4129  +
         4130  +    /* whereLoopAddBtree() always generates and inserts the automatic index
         4131  +    ** case first.  Hence compatible candidate WhereLoops never have a larger
         4132  +    ** rSetup. Call this SETUP-INVARIANT */
         4133  +    assert( p->rSetup>=pTemplate->rSetup );
         4134  +
  4119   4135       if( (p->prereq & pTemplate->prereq)==p->prereq
  4120   4136        && p->rSetup<=pTemplate->rSetup
  4121   4137        && p->rRun<=pTemplate->rRun
  4122   4138       ){
  4123   4139         /* This branch taken when p is equal or better than pTemplate in 
  4124   4140         ** all of (1) dependences (2) setup-cost, and (3) run-cost. */
  4125         -      testcase( p->rRun==pTemplate->rRun );
         4141  +      assert( p->rSetup==pTemplate->rSetup );
  4126   4142         if( p->nLTerm<pTemplate->nLTerm
  4127   4143          && (p->wsFlags & WHERE_INDEXED)!=0
  4128   4144          && (pTemplate->wsFlags & WHERE_INDEXED)!=0
  4129   4145          && p->u.btree.pIndex==pTemplate->u.btree.pIndex
  4130   4146          && p->prereq==pTemplate->prereq
  4131   4147         ){
  4132   4148           /* Overwrite an existing WhereLoop with an similar one that uses
  4133   4149           ** more terms of the index */
  4134   4150           pNext = p->pNextLoop;
  4135   4151           break;
  4136         -      }else if( p->nOut>pTemplate->nOut
  4137         -       && p->rSetup==pTemplate->rSetup
  4138         -       && p->rRun==pTemplate->rRun
  4139         -      ){
  4140         -        /* Overwrite an existing WhereLoop with the same cost but more
  4141         -        ** outputs */
  4142         -        pNext = p->pNextLoop;
  4143         -        break;
  4144   4152         }else{
  4145   4153           /* pTemplate is not helpful.
  4146   4154           ** Return without changing or adding anything */
  4147   4155           goto whereLoopInsert_noop;
  4148   4156         }
  4149   4157       }
  4150         -    testcase( (p->prereq & pTemplate->prereq)==p->prereq
  4151         -              && p->rSetup<=pTemplate->rSetup
  4152         -              && p->rRun==pTemplate->rRun+1 );
  4153   4158       if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
  4154         -     && p->rSetup>=pTemplate->rSetup
  4155   4159        && p->rRun>=pTemplate->rRun
         4160  +     && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */
  4156   4161       ){
  4157   4162         /* Overwrite an existing WhereLoop with a better one: one that is
  4158   4163         ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
  4159   4164         ** and is no worse in any of those categories. */
  4160         -      testcase( p->rSetup==pTemplate->rSetup );
  4161         -      testcase( p->rRun==pTemplate->rRun );
  4162   4165         pNext = p->pNextLoop;
  4163   4166         break;
  4164   4167       }
  4165         -    testcase( (p->prereq & pTemplate->prereq)==pTemplate->prereq
  4166         -              && p->rSetup>=pTemplate->rSetup
  4167         -              && p->rRun==pTemplate->rRun-1 );
  4168   4168     }
  4169   4169   
  4170   4170     /* If we reach this point it means that either p[] should be overwritten
  4171   4171     ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
  4172   4172     ** WhereLoop and insert it.
  4173   4173     */
  4174   4174   #if WHERETRACE_ENABLED