Variable name changes in the query optimizer for disambiguation and
clarification.  Clear space in boolean vectors for new bit values to
encode new query plan templates. (CVS 5980)

FossilOrigin-Name: 81bd0b5ce8a1cf057064c44e9b5371502cb8c58c
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 0cd41f8..c03b6b4 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.800 2008/12/04 20:40:10 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.801 2008/12/05 02:36:34 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1517,7 +1517,7 @@
 */
 struct WhereLevel {
   int iFrom;            /* Which entry in the FROM clause */
-  int flags;            /* Flags associated with this level */
+  int wsFlags;          /* "Where-Scan Flags" associated with this level */
   int iMem;             /* First memory cell used by this level */
   int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
   Index *pIdx;          /* Index used.  NULL if no index */
@@ -1544,7 +1544,7 @@
 };
 
 /*
-** Flags appropriate for the wflags parameter of sqlite3WhereBegin().
+** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin().
 */
 #define WHERE_ORDERBY_NORMAL     0   /* No-op */
 #define WHERE_ORDERBY_MIN        1   /* ORDER BY processing for min() func */
diff --git a/src/where.c b/src/where.c
index dae66c8..6a56eca 100644
--- a/src/where.c
+++ b/src/where.c
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.330 2008/11/17 19:18:55 danielk1977 Exp $
+** $Id: where.c,v 1.331 2008/12/05 02:36:34 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -72,20 +72,20 @@
 */
 typedef struct WhereTerm WhereTerm;
 struct WhereTerm {
-  Expr *pExpr;            /* Pointer to the subexpression */
+  Expr *pExpr;            /* Pointer to the subexpression that is this term */
   i16 iParent;            /* Disable pWC->a[iParent] when this term disabled */
   i16 leftCursor;         /* Cursor number of X in "X <op> <expr>" */
   i16 leftColumn;         /* Column number of X in "X <op> <expr>" */
   u16 eOperator;          /* A WO_xx value describing <op> */
-  u8 flags;               /* Bit flags.  See below */
+  u8 wtFlags;             /* TERM_xxx bit flags.  See below */
   u8 nChild;              /* Number of children that must disable us */
   WhereClause *pWC;       /* The clause this term is part of */
-  Bitmask prereqRight;    /* Bitmask of tables used by pRight */
-  Bitmask prereqAll;      /* Bitmask of tables referenced by p */
+  Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
+  Bitmask prereqAll;      /* Bitmask of tables referenced by pExpr */
 };
 
 /*
-** Allowed values of WhereTerm.flags
+** Allowed values of WhereTerm.wtFlags
 */
 #define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(db, pExpr) */
 #define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
@@ -143,38 +143,41 @@
 ** OR-ed combination of these values can be used when searching for
 ** terms in the where clause.
 */
-#define WO_IN     1
-#define WO_EQ     2
+#define WO_IN     0x001
+#define WO_EQ     0x002
 #define WO_LT     (WO_EQ<<(TK_LT-TK_EQ))
 #define WO_LE     (WO_EQ<<(TK_LE-TK_EQ))
 #define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
 #define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))
-#define WO_MATCH  64
-#define WO_ISNULL 128
+#define WO_MATCH  0x040
+#define WO_ISNULL 0x080
+#define WO_OR     0x100
 
 /*
-** Value for flags returned by bestIndex().  
+** Value for wsFlags returned by bestIndex().  These flags determine which
+** search strategies are appropriate.
 **
-** The least significant byte is reserved as a mask for WO_ values above.
-** The WhereLevel.flags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
-** But if the table is the right table of a left join, WhereLevel.flags
-** is set to WO_IN|WO_EQ.  The WhereLevel.flags field can then be used as
+** The least significant 12 bits is reserved as a mask for WO_ values above.
+** The WhereLevel.wtFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
+** But if the table is the right table of a left join, WhereLevel.wtFlags
+** is set to WO_IN|WO_EQ.  The WhereLevel.wtFlags field can then be used as
 ** the "op" parameter to findTerm when we are resolving equality constraints.
 ** ISNULL constraints will then not be used on the right table of a left
 ** join.  Tickets #2177 and #2189.
 */
-#define WHERE_ROWID_EQ     0x000100   /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE  0x000200   /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_COLUMN_EQ    0x001000   /* x=EXPR or x IN (...) */
-#define WHERE_COLUMN_RANGE 0x002000   /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN    0x004000   /* x IN (...) */
-#define WHERE_TOP_LIMIT    0x010000   /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT    0x020000   /* x>EXPR or x>=EXPR constraint */
-#define WHERE_IDX_ONLY     0x080000   /* Use index only - omit table */
-#define WHERE_ORDERBY      0x100000   /* Output will appear in correct order */
-#define WHERE_REVERSE      0x200000   /* Scan in reverse order */
-#define WHERE_UNIQUE       0x400000   /* Selects no more than one row */
-#define WHERE_VIRTUALTABLE 0x800000   /* Use virtual-table processing */
+#define WHERE_ROWID_EQ     0x00001000  /* rowid=EXPR or rowid IN (...) */
+#define WHERE_ROWID_RANGE  0x00002000  /* rowid<EXPR and/or rowid>EXPR */
+#define WHERE_COLUMN_EQ    0x00010000  /* x=EXPR or x IN (...) */
+#define WHERE_COLUMN_RANGE 0x00020000  /* x<EXPR and/or x>EXPR */
+#define WHERE_COLUMN_IN    0x00040000  /* x IN (...) */
+#define WHERE_TOP_LIMIT    0x00100000  /* x<EXPR or x<=EXPR constraint */
+#define WHERE_BTM_LIMIT    0x00200000  /* x>EXPR or x>=EXPR constraint */
+#define WHERE_IDX_ONLY     0x00800000  /* Use index only - omit table */
+#define WHERE_ORDERBY      0x01000000  /* Output will appear in correct order */
+#define WHERE_REVERSE      0x02000000  /* Scan in reverse order */
+#define WHERE_UNIQUE       0x04000000  /* Selects no more than one row */
+#define WHERE_VIRTUALTABLE 0x08000000  /* Use virtual-table processing */
+#define WHERE_MULTI_OR     0x10000000  /* OR using multiple indices */
 
 /*
 ** Initialize a preallocated WhereClause structure.
@@ -200,7 +203,7 @@
   WhereTerm *a;
   sqlite3 *db = pWC->pParse->db;
   for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
-    if( a->flags & TERM_DYNAMIC ){
+    if( a->wtFlags & TERM_DYNAMIC ){
       sqlite3ExprDelete(db, a->pExpr);
     }
   }
@@ -213,7 +216,7 @@
 ** Add a new entries to the WhereClause structure.  Increase the allocated
 ** space as necessary.
 **
-** If the flags argument includes TERM_DYNAMIC, then responsibility
+** If the wtFlags argument includes TERM_DYNAMIC, then responsibility
 ** for freeing the expression p is assumed by the WhereClause object.
 **
 ** WARNING:  This routine might reallocate the space used to store
@@ -221,7 +224,7 @@
 ** calling this routine.  Such pointers may be reinitialized by referencing
 ** the pWC->a[] array.
 */
-static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
+static int whereClauseInsert(WhereClause *pWC, Expr *p, int wtFlags){
   WhereTerm *pTerm;
   int idx;
   if( pWC->nTerm>=pWC->nSlot ){
@@ -229,7 +232,7 @@
     sqlite3 *db = pWC->pParse->db;
     pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
     if( pWC->a==0 ){
-      if( flags & TERM_DYNAMIC ){
+      if( wtFlags & TERM_DYNAMIC ){
         sqlite3ExprDelete(db, p);
       }
       pWC->a = pOld;
@@ -244,7 +247,7 @@
   pTerm = &pWC->a[idx = pWC->nTerm];
   pWC->nTerm++;
   pTerm->pExpr = p;
-  pTerm->flags = flags;
+  pTerm->wtFlags = wtFlags;
   pTerm->pWC = pWC;
   pTerm->iParent = -1;
   return idx;
@@ -421,10 +424,13 @@
     c = WO_IN;
   }else if( op==TK_ISNULL ){
     c = WO_ISNULL;
+  }else if( op==TK_OR ){
+    c = WO_OR;
   }else{
     c = WO_EQ<<(op-TK_EQ);
   }
   assert( op!=TK_ISNULL || c==WO_ISNULL );
+  assert( op!=TK_OR || c==WO_OR );
   assert( op!=TK_IN || c==WO_IN );
   assert( op!=TK_EQ || c==WO_EQ );
   assert( op!=TK_LT || c==WO_LT );
@@ -682,13 +688,13 @@
 ** the duplicate has also been disqualified, return false.
 */
 static int orTermHasOkDuplicate(WhereClause *pOr, WhereTerm *pOrTerm){
-  if( pOrTerm->flags & TERM_COPIED ){
+  if( pOrTerm->wtFlags & TERM_COPIED ){
     /* This is the original term.  The duplicate is to the left had
     ** has not yet been analyzed and thus has not yet been disqualified. */
     return 1;
   }
-  if( (pOrTerm->flags & TERM_VIRTUAL)!=0
-     && (pOr->a[pOrTerm->iParent].flags & TERM_OR_OK)!=0 ){
+  if( (pOrTerm->wtFlags & TERM_VIRTUAL)!=0
+     && (pOr->a[pOrTerm->iParent].wtFlags & TERM_OR_OK)!=0 ){
     /* This is a duplicate term.  The original qualified so this one
     ** does not have to. */
     return 1;
@@ -781,7 +787,7 @@
         pNew->iParent = idxTerm;
         pTerm = &pWC->a[idxTerm];
         pTerm->nChild = 1;
-        pTerm->flags |= TERM_COPIED;
+        pTerm->wtFlags |= TERM_COPIED;
       }else{
         pDup = pExpr;
         pNew = pTerm;
@@ -840,7 +846,7 @@
     WhereClause sOr;
     WhereTerm *pOrTerm;
 
-    assert( (pTerm->flags & TERM_DYNAMIC)==0 );
+    assert( (pTerm->wtFlags & TERM_DYNAMIC)==0 );
     whereClauseInit(&sOr, pWC->pParse, pMaskSet);
     whereSplit(&sOr, pExpr, TK_OR);
     exprAnalyzeAll(pSrc, &sOr);
@@ -857,20 +863,20 @@
           goto or_not_possible;
         }
         if( orTermIsOptCandidate(pOrTerm, iCursor, iColumn) ){
-          pOrTerm->flags |= TERM_OR_OK;
+          pOrTerm->wtFlags |= TERM_OR_OK;
         }else if( orTermHasOkDuplicate(&sOr, pOrTerm) ){
-          pOrTerm->flags &= ~TERM_OR_OK;
+          pOrTerm->wtFlags &= ~TERM_OR_OK;
         }else{
           ok = 0;
         }
       }
-    }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<2 );
+    }while( !ok && (sOr.a[j++].wtFlags & TERM_COPIED)!=0 && j<2 );
     if( ok ){
       ExprList *pList = 0;
       Expr *pNew, *pDup;
       Expr *pLeft = 0;
       for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0; i--, pOrTerm++){
-        if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue;
+        if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
         pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight);
         pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0);
         pLeft = pOrTerm->pExpr->pLeft;
@@ -977,7 +983,7 @@
       pNewTerm->iParent = idxTerm;
       pTerm = &pWC->a[idxTerm];
       pTerm->nChild = 1;
-      pTerm->flags |= TERM_COPIED;
+      pTerm->wtFlags |= TERM_COPIED;
       pNewTerm->prereqAll = pTerm->prereqAll;
     }
   }
@@ -1486,23 +1492,23 @@
   Bitmask notReady,           /* Mask of cursors that are not available */
   ExprList *pOrderBy,         /* The order by clause */
   Index **ppIndex,            /* Make *ppIndex point to the best index */
-  int *pFlags,                /* Put flags describing this choice in *pFlags */
+  int *pWsFlags,              /* Put wsFlags describing scan strategy here */
   int *pnEq                   /* Put the number of == or IN constraints here */
 ){
   WhereTerm *pTerm;
   Index *bestIdx = 0;         /* Index that gives the lowest cost */
   double lowestCost;          /* The cost of using bestIdx */
-  int bestFlags = 0;          /* Flags associated with bestIdx */
+  int bestWsFlags = 0;        /* Flags associated with bestIdx */
   int bestNEq = 0;            /* Best value for nEq */
   int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
   Index *pProbe;              /* An index we are evaluating */
   int rev;                    /* True to scan in reverse order */
-  int flags;                  /* Flags associated with pProbe */
+  int wsFlags;                /* Flags associated with pProbe */
   int nEq;                    /* Number of == or IN constraints */
   int eqTermMask;             /* Mask of valid equality operators */
   double cost;                /* Cost of using pProbe */
 
-  WHERETRACE(("bestIndex: tbl=%s notReady=%llx\n", pSrc->pTab->zName, notReady));
+  WHERETRACE(("bestIndex: tbl=%s notReady=%llx\n", pSrc->pTab->zName,notReady));
   lowestCost = SQLITE_BIG_DBL;
   pProbe = pSrc->pTab->pIndex;
   if( pSrc->notIndexed ){
@@ -1518,7 +1524,7 @@
   if( pProbe==0 &&
      findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 &&
      (pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev)) ){
-    *pFlags = 0;
+    *pWsFlags = 0;
     *ppIndex = 0;
     *pnEq = 0;
     return 0.0;
@@ -1532,11 +1538,11 @@
     if( pTerm ){
       Expr *pExpr;
       *ppIndex = 0;
-      bestFlags = WHERE_ROWID_EQ;
+      bestWsFlags = WHERE_ROWID_EQ;
       if( pTerm->eOperator & WO_EQ ){
         /* Rowid== is always the best pick.  Look no further.  Because only
         ** a single row is generated, output is always in sorted order */
-        *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
+        *pWsFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
         *pnEq = 1;
         WHERETRACE(("... best is rowid\n"));
         return 0.0;
@@ -1559,32 +1565,32 @@
     */
     cost = pProbe ? pProbe->aiRowEst[0] : 1000000;
     WHERETRACE(("... table scan base cost: %.9g\n", cost));
-    flags = WHERE_ROWID_RANGE;
+    wsFlags = WHERE_ROWID_RANGE;
   
     /* Check for constraints on a range of rowids in a table scan.
     */
     pTerm = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE|WO_GT|WO_GE, 0);
     if( pTerm ){
       if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){
-        flags |= WHERE_TOP_LIMIT;
+        wsFlags |= WHERE_TOP_LIMIT;
         cost /= 3;  /* Guess that rowid<EXPR eliminates two-thirds or rows */
       }
       if( findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0) ){
-        flags |= WHERE_BTM_LIMIT;
+        wsFlags |= WHERE_BTM_LIMIT;
         cost /= 3;  /* Guess that rowid>EXPR eliminates two-thirds of rows */
       }
       WHERETRACE(("... rowid range reduces cost to %.9g\n", cost));
     }else{
-      flags = 0;
+      wsFlags = 0;
     }
   
     /* If the table scan does not satisfy the ORDER BY clause, increase
     ** the cost by NlogN to cover the expense of sorting. */
     if( pOrderBy ){
       if( sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev) ){
-        flags |= WHERE_ORDERBY|WHERE_ROWID_RANGE;
+        wsFlags |= WHERE_ORDERBY|WHERE_ROWID_RANGE;
         if( rev ){
-          flags |= WHERE_REVERSE;
+          wsFlags |= WHERE_REVERSE;
         }
       }else{
         cost += cost*estLog(cost);
@@ -1593,7 +1599,7 @@
     }
     if( cost<lowestCost ){
       lowestCost = cost;
-      bestFlags = flags;
+      bestWsFlags = wsFlags;
     }
   }
 
@@ -1622,15 +1628,15 @@
     /* Count the number of columns in the index that are satisfied
     ** by x=EXPR constraints or x IN (...) constraints.
     */
-    flags = 0;
+    wsFlags = 0;
     for(i=0; i<pProbe->nColumn; i++){
       int j = pProbe->aiColumn[i];
       pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe);
       if( pTerm==0 ) break;
-      flags |= WHERE_COLUMN_EQ;
+      wsFlags |= WHERE_COLUMN_EQ;
       if( pTerm->eOperator & WO_IN ){
         Expr *pExpr = pTerm->pExpr;
-        flags |= WHERE_COLUMN_IN;
+        wsFlags |= WHERE_COLUMN_IN;
         if( pExpr->pSelect!=0 ){
           inMultiplier *= 25;
         }else if( ALWAYS(pExpr->pList) ){
@@ -1640,9 +1646,9 @@
     }
     cost = pProbe->aiRowEst[i] * inMultiplier * estLog(inMultiplier);
     nEq = i;
-    if( pProbe->onError!=OE_None && (flags & WHERE_COLUMN_IN)==0
+    if( pProbe->onError!=OE_None && (wsFlags & WHERE_COLUMN_IN)==0
          && nEq==pProbe->nColumn ){
-      flags |= WHERE_UNIQUE;
+      wsFlags |= WHERE_UNIQUE;
     }
     WHERETRACE(("...... nEq=%d inMult=%.9g cost=%.9g\n",nEq,inMultiplier,cost));
 
@@ -1652,13 +1658,13 @@
       int j = pProbe->aiColumn[nEq];
       pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe);
       if( pTerm ){
-        flags |= WHERE_COLUMN_RANGE;
+        wsFlags |= WHERE_COLUMN_RANGE;
         if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){
-          flags |= WHERE_TOP_LIMIT;
+          wsFlags |= WHERE_TOP_LIMIT;
           cost /= 3;
         }
         if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){
-          flags |= WHERE_BTM_LIMIT;
+          wsFlags |= WHERE_BTM_LIMIT;
           cost /= 3;
         }
         WHERETRACE(("...... range reduces cost to %.9g\n", cost));
@@ -1668,14 +1674,14 @@
     /* Add the additional cost of sorting if that is a factor.
     */
     if( pOrderBy ){
-      if( (flags & WHERE_COLUMN_IN)==0 &&
+      if( (wsFlags & WHERE_COLUMN_IN)==0 &&
            isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev) ){
-        if( flags==0 ){
-          flags = WHERE_COLUMN_RANGE;
+        if( wsFlags==0 ){
+          wsFlags = WHERE_COLUMN_RANGE;
         }
-        flags |= WHERE_ORDERBY;
+        wsFlags |= WHERE_ORDERBY;
         if( rev ){
-          flags |= WHERE_REVERSE;
+          wsFlags |= WHERE_REVERSE;
         }
       }else{
         cost += cost*estLog(cost);
@@ -1687,7 +1693,7 @@
     ** ever reading the table.  If that is the case, then halve the
     ** cost of this index.
     */
-    if( flags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){
+    if( wsFlags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){
       Bitmask m = pSrc->colUsed;
       int j;
       for(j=0; j<pProbe->nColumn; j++){
@@ -1697,7 +1703,7 @@
         }
       }
       if( m==0 ){
-        flags |= WHERE_IDX_ONLY;
+        wsFlags |= WHERE_IDX_ONLY;
         cost /= 2;
         WHERETRACE(("...... idx-only reduces cost to %.9g\n", cost));
       }
@@ -1705,10 +1711,10 @@
 
     /* If this index has achieved the lowest cost so far, then use it.
     */
-    if( flags && cost < lowestCost ){
+    if( wsFlags && cost < lowestCost ){
       bestIdx = pProbe;
       lowestCost = cost;
-      bestFlags = flags;
+      bestWsFlags = wsFlags;
       bestNEq = nEq;
     }
   }
@@ -1716,9 +1722,9 @@
   /* Report the best result
   */
   *ppIndex = bestIdx;
-  WHERETRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
-        bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq));
-  *pFlags = bestFlags | eqTermMask;
+  WHERETRACE(("best index is %s, cost=%.9g, wsFlags=%x, nEq=%d\n",
+        bestIdx ? bestIdx->zName : "(none)", lowestCost, bestWsFlags, bestNEq));
+  *pWsFlags = bestWsFlags | eqTermMask;
   *pnEq = bestNEq;
   return lowestCost;
 }
@@ -1749,10 +1755,10 @@
 */
 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
   if( pTerm
-      && ALWAYS((pTerm->flags & TERM_CODED)==0)
+      && ALWAYS((pTerm->wtFlags & TERM_CODED)==0)
       && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
   ){
-    pTerm->flags |= TERM_CODED;
+    pTerm->wtFlags |= TERM_CODED;
     if( pTerm->iParent>=0 ){
       WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
       if( (--pOther->nChild)==0 ){
@@ -1894,9 +1900,9 @@
   for(j=0; j<nEq; j++){
     int r1;
     int k = pIdx->aiColumn[j];
-    pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx);
+    pTerm = findTerm(pWC, iCur, k, notReady, pLevel->wsFlags, pIdx);
     if( NEVER(pTerm==0) ) break;
-    assert( (pTerm->flags & TERM_CODED)==0 );
+    assert( (pTerm->wtFlags & TERM_CODED)==0 );
     r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
     if( r1!=regBase+j ){
       sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
@@ -2034,7 +2040,7 @@
   SrcList *pTabList,    /* A list of all tables to be scanned */
   Expr *pWhere,         /* The WHERE clause */
   ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
-  u8 wflags             /* One of the WHERE_* flags defined in sqliteInt.h */
+  u8 wctrlFlags         /* One of the WHERE_* flags defined in sqliteInt.h */
 ){
   int i;                     /* Loop counter */
   WhereInfo *pWInfo;         /* Will become the return value of this function */
@@ -2047,7 +2053,7 @@
   struct SrcList_item *pTabItem;  /* A single entry from pTabList */
   WhereLevel *pLevel;             /* A single level in the pWInfo list */
   int iFrom;                      /* First unused FROM clause element */
-  int andFlags;              /* AND-ed combination of all wc.a[].flags */
+  int andFlags;              /* AND-ed combination of all wc.a[].wtFlags */
   sqlite3 *db;               /* Database connection */
   ExprList *pOrderBy = 0;
 
@@ -2133,7 +2139,7 @@
   ** This loop fills in the following fields:
   **
   **   pWInfo->a[].pIdx      The index to use for this level of the loop.
-  **   pWInfo->a[].flags     WHERE_xxx flags associated with pIdx
+  **   pWInfo->a[].wsFlags   WHERE_xxx flags associated with pIdx
   **   pWInfo->a[].nEq       The number of == and IN constraints
   **   pWInfo->a[].iFrom     Which term of the FROM clause is being coded
   **   pWInfo->a[].iTabCur   The VDBE cursor for the database table
@@ -2149,12 +2155,12 @@
   WHERETRACE(("*** Optimizer Start ***\n"));
   for(i=iFrom=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
     Index *pIdx;                /* Index for FROM table at pTabItem */
-    int flags;                  /* Flags asssociated with pIdx */
+    int wsFlags;                /* Flags describing scan strategy */
     int nEq;                    /* Number of == or IN constraints */
     double cost;                /* The cost for pIdx */
     int j;                      /* For looping over FROM tables */
     Index *pBest = 0;           /* The best index seen so far */
-    int bestFlags = 0;          /* Flags associated with pBest */
+    int bestWsFlags = 0;        /* Flags associated with pBest */
     int bestNEq = 0;            /* nEq associated with pBest */
     double lowestCost;          /* Cost of the pBest */
     int bestJ = 0;              /* The value of j */
@@ -2180,10 +2186,10 @@
         cost = bestVirtualIndex(pParse, &wc, pTabItem, notReady,
                                 ppOrderBy ? *ppOrderBy : 0, i==0,
                                 ppIdxInfo);
-        flags = WHERE_VIRTUALTABLE;
+        wsFlags = WHERE_VIRTUALTABLE;
         pIndex = *ppIdxInfo;
         if( pIndex && pIndex->orderByConsumed ){
-          flags = WHERE_VIRTUALTABLE | WHERE_ORDERBY;
+          wsFlags = WHERE_VIRTUALTABLE | WHERE_ORDERBY;
         }
         pIdx = 0;
         nEq = 0;
@@ -2200,14 +2206,14 @@
       {
         cost = bestIndex(pParse, &wc, pTabItem, notReady,
                          (i==0 && ppOrderBy) ? *ppOrderBy : 0,
-                         &pIdx, &flags, &nEq);
+                         &pIdx, &wsFlags, &nEq);
         pIndex = 0;
       }
       if( cost<lowestCost ){
         once = 1;
         lowestCost = cost;
         pBest = pIdx;
-        bestFlags = flags;
+        bestWsFlags = wsFlags;
         bestNEq = nEq;
         bestJ = j;
         pLevel->pBestIdx = pIndex;
@@ -2216,11 +2222,11 @@
     }
     WHERETRACE(("*** Optimizer selects table %d for loop %d\n", bestJ,
            pLevel-pWInfo->a));
-    if( (bestFlags & WHERE_ORDERBY)!=0 ){
+    if( (bestWsFlags & WHERE_ORDERBY)!=0 ){
       *ppOrderBy = 0;
     }
-    andFlags &= bestFlags;
-    pLevel->flags = bestFlags;
+    andFlags &= bestWsFlags;
+    pLevel->wsFlags = bestWsFlags;
     pLevel->pIdx = pBest;
     pLevel->nEq = bestNEq;
     pLevel->aInLoop = 0;
@@ -2259,10 +2265,10 @@
   ** The one-pass algorithm only works if the WHERE clause constraints
   ** the statement to update a single row.
   */
-  assert( (wflags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
-  if( (wflags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
+  assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
+  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
     pWInfo->okOnePass = 1;
-    pWInfo->a[0].flags &= ~WHERE_IDX_ONLY;
+    pWInfo->a[0].wsFlags &= ~WHERE_IDX_ONLY;
   }
 
   /* Open all tables in the pTabList and any indices selected for
@@ -2285,7 +2291,7 @@
       }
       if( (pIx = pLevel->pIdx)!=0 ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s WITH INDEX %s", zMsg, pIx->zName);
-      }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+      }else if( pLevel->wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s USING PRIMARY KEY", zMsg);
       }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -2295,7 +2301,7 @@
                     pBestIdx->idxNum, pBestIdx->idxStr);
       }
 #endif
-      if( pLevel->flags & WHERE_ORDERBY ){
+      if( pLevel->wsFlags & WHERE_ORDERBY ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg);
       }
       sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
@@ -2312,7 +2318,7 @@
                         (const char*)pTab->pVtab, P4_VTAB);
     }else
 #endif
-    if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
+    if( (pLevel->wsFlags & WHERE_IDX_ONLY)==0 ){
       int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
       sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
       if( !pWInfo->okOnePass && pTab->nCol<BMS ){
@@ -2356,8 +2362,8 @@
     iCur = pTabItem->iCursor;
     pIdx = pLevel->pIdx;
     iIdxCur = pLevel->iIdxCur;
-    bRev = (pLevel->flags & WHERE_REVERSE)!=0;
-    omitTable = (pLevel->flags & WHERE_IDX_ONLY)!=0;
+    bRev = (pLevel->wsFlags & WHERE_REVERSE)!=0;
+    omitTable = (pLevel->wsFlags & WHERE_IDX_ONLY)!=0;
 
     /* Create labels for the "break" and "continue" instructions
     ** for the current loop.  Jump to brk to break out of a loop.
@@ -2430,7 +2436,7 @@
     }else
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
-    if( pLevel->flags & WHERE_ROWID_EQ ){
+    if( pLevel->wsFlags & WHERE_ROWID_EQ ){
       /* Case 1:  We can directly reference a single row using an
       **          equality comparison against the ROWID field.  Or
       **          we reference multiple rows using a "rowid IN (...)"
@@ -2450,7 +2456,7 @@
       sqlite3ReleaseTempReg(pParse, rtmp);
       VdbeComment((v, "pk"));
       pLevel->op = OP_Noop;
-    }else if( pLevel->flags & WHERE_ROWID_RANGE ){
+    }else if( pLevel->wsFlags & WHERE_ROWID_RANGE ){
       /* Case 2:  We have an inequality comparison against the ROWID field.
       */
       int testOp = OP_Noop;
@@ -2517,7 +2523,7 @@
         sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
         sqlite3ReleaseTempReg(pParse, r1);
       }
-    }else if( pLevel->flags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
+    }else if( pLevel->wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
       /* Case 3: A scan using an index.
       **
       **         The WHERE clause may contain zero or more equality 
@@ -2592,8 +2598,8 @@
       ** the first one after the nEq equality constraints in the index,
       ** this requires some special handling.
       */
-      if( (wflags&WHERE_ORDERBY_MIN)!=0
-       && (pLevel->flags&WHERE_ORDERBY)
+      if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
+       && (pLevel->wsFlags&WHERE_ORDERBY)
        && (pIdx->nColumn>nEq)
       ){
         assert( pOrderBy->nExpr==1 );
@@ -2604,10 +2610,10 @@
       /* Find any inequality constraint terms for the start and end 
       ** of the range. 
       */
-      if( pLevel->flags & WHERE_TOP_LIMIT ){
+      if( pLevel->wsFlags & WHERE_TOP_LIMIT ){
         pRangeEnd = findTerm(&wc, iCur, k, notReady, (WO_LT|WO_LE), pIdx);
       }
-      if( pLevel->flags & WHERE_BTM_LIMIT ){
+      if( pLevel->wsFlags & WHERE_BTM_LIMIT ){
         pRangeStart = findTerm(&wc, iCur, k, notReady, (WO_GT|WO_GE), pIdx);
       }
 
@@ -2684,9 +2690,9 @@
       ** If it is, jump to the next iteration of the loop.
       */
       r1 = sqlite3GetTempReg(pParse);
-      testcase( pLevel->flags & WHERE_BTM_LIMIT );
-      testcase( pLevel->flags & WHERE_TOP_LIMIT );
-      if( pLevel->flags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
+      testcase( pLevel->wsFlags & WHERE_BTM_LIMIT );
+      testcase( pLevel->wsFlags & WHERE_TOP_LIMIT );
+      if( pLevel->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT) ){
         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
         sqlite3VdbeAddOp2(v, OP_IsNull, r1, cont);
       }
@@ -2724,9 +2730,9 @@
     k = 0;
     for(pTerm=wc.a, j=wc.nTerm; j>0; j--, pTerm++){
       Expr *pE;
-      testcase( pTerm->flags & TERM_VIRTUAL );
-      testcase( pTerm->flags & TERM_CODED );
-      if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+      testcase( pTerm->wtFlags & TERM_VIRTUAL );
+      testcase( pTerm->wtFlags & TERM_CODED );
+      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
       if( (pTerm->prereqAll & notReady)!=0 ) continue;
       pE = pTerm->pExpr;
       assert( pE!=0 );
@@ -2737,7 +2743,7 @@
       sqlite3ExprIfFalse(pParse, pE, cont, SQLITE_JUMPIFNULL);
       pParse->disableColCache -= k;
       k = 1;
-      pTerm->flags |= TERM_CODED;
+      pTerm->wtFlags |= TERM_CODED;
     }
 
     /* For a LEFT OUTER JOIN, generate code that will record the fact that
@@ -2750,13 +2756,13 @@
       sqlite3ExprClearColumnCache(pParse, pLevel->iTabCur);
       sqlite3ExprClearColumnCache(pParse, pLevel->iIdxCur);
       for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
-        testcase( pTerm->flags & TERM_VIRTUAL );
-        testcase( pTerm->flags & TERM_CODED );
-        if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+        testcase( pTerm->wtFlags & TERM_VIRTUAL );
+        testcase( pTerm->wtFlags & TERM_CODED );
+        if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
         if( (pTerm->prereqAll & notReady)!=0 ) continue;
         assert( pTerm->pExpr );
         sqlite3ExprIfFalse(pParse, pTerm->pExpr, cont, SQLITE_JUMPIFNULL);
-        pTerm->flags |= TERM_CODED;
+        pTerm->wtFlags |= TERM_CODED;
       }
     }
   }
@@ -2777,7 +2783,7 @@
     if( z==0 ) z = pTabItem->pTab->zName;
     n = strlen(z);
     if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
-      if( pLevel->flags & WHERE_IDX_ONLY ){
+      if( pLevel->wsFlags & WHERE_IDX_ONLY ){
         memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
         nQPlan += 2;
       }else{
@@ -2786,9 +2792,9 @@
       }
       sqlite3_query_plan[nQPlan++] = ' ';
     }
-    testcase( pLevel->flags & WHERE_ROWID_EQ );
-    testcase( pLevel->flags & WHERE_ROWID_RANGE );
-    if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+    testcase( pLevel->wsFlags & WHERE_ROWID_EQ );
+    testcase( pLevel->wsFlags & WHERE_ROWID_RANGE );
+    if( pLevel->wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
       memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
       nQPlan += 2;
     }else if( pLevel->pIdx==0 ){
@@ -2882,7 +2888,7 @@
     Table *pTab = pTabItem->pTab;
     assert( pTab!=0 );
     if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue;
-    if( !pWInfo->okOnePass && (pLevel->flags & WHERE_IDX_ONLY)==0 ){
+    if( !pWInfo->okOnePass && (pLevel->wsFlags & WHERE_IDX_ONLY)==0 ){
       sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
     }
     if( pLevel->pIdx!=0 ){
@@ -2906,7 +2912,7 @@
       int k, j, last;
       VdbeOp *pOp;
       Index *pIdx = pLevel->pIdx;
-      int useIndexOnly = pLevel->flags & WHERE_IDX_ONLY;
+      int useIndexOnly = pLevel->wsFlags & WHERE_IDX_ONLY;
 
       assert( pIdx!=0 );
       pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);