Changes to make the new constant expression factoring logic more general
and more testable.

FossilOrigin-Name: d10fb49a92f5f6e93093ae83544e5aec7984361a
diff --git a/src/build.c b/src/build.c
index 68d71da..27f026c 100644
--- a/src/build.c
+++ b/src/build.c
@@ -187,7 +187,7 @@
         ExprList *pEL = pParse->pConstExpr;
         pParse->cookieGoto = 0;
         for(i=0; i<pEL->nExpr; i++){
-          sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].iAlias);
+          sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
         }
       }
 
diff --git a/src/expr.c b/src/expr.c
index 15b21d1..cc2966c 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -930,8 +930,7 @@
     pItem->sortOrder = pOldItem->sortOrder;
     pItem->done = 0;
     pItem->bSpanIsTab = pOldItem->bSpanIsTab;
-    pItem->iOrderByCol = pOldItem->iOrderByCol;
-    pItem->iAlias = pOldItem->iAlias;
+    pItem->u = pOldItem->u;
   }
   return pNew;
 }
@@ -2908,7 +2907,6 @@
       if( (pX = pExpr->pLeft)!=0 ){
         tempX = *pX;
         testcase( pX->op==TK_COLUMN );
-        testcase( pX->op==TK_REGISTER );
         exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, &regFree1));
         testcase( regFree1==0 );
         opCompare.op = TK_EQ;
@@ -2932,7 +2930,6 @@
         testcase( pTest->op==TK_COLUMN );
         sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
         testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
-        testcase( aListelem[i+1].pExpr->op==TK_REGISTER );
         sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
         sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
         sqlite3ExprCachePop(pParse, 1);
@@ -3000,7 +2997,6 @@
   int r2;
   pExpr = sqlite3ExprSkipCollate(pExpr);
   if( pParse->cookieGoto>0
-   && pParse->nMem<32768
    && pExpr->op!=TK_REGISTER
    && sqlite3ExprIsConstantNotJoin(pExpr)
   ){
@@ -3010,14 +3006,14 @@
     if( p ){
       for(i=0; i<p->nExpr; i++){
         if( sqlite3ExprCompare(p->a[i].pExpr, pExpr, -1)==0 ){
-          return p->a[i].iAlias;
+          return p->a[i].u.iConstExprReg;
         }
       }
     }
     p = sqlite3ExprListAppend(pParse, p, sqlite3ExprDup(pParse->db, pExpr, 0));
     pParse->pConstExpr = p;
     r2 = ++pParse->nMem;
-    if( p ) p->a[p->nExpr-1].iAlias = r2;
+    if( p ) p->a[p->nExpr-1].u.iConstExprReg = r2;
   }else{
     int r1 = sqlite3GetTempReg(pParse);
     r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
@@ -3069,12 +3065,13 @@
   int inReg;
   inReg = sqlite3ExprCode(pParse, pExpr, target);
   assert( target>0 );
-  /* This routine is called for terms to INSERT or UPDATE.  And the only
-  ** other place where expressions can be converted into TK_REGISTER is
-  ** in WHERE clause processing.  So as currently implemented, there is
-  ** no way for a TK_REGISTER to exist here.  But it seems prudent to
-  ** keep the ALWAYS() in case the conditions above change with future
-  ** modifications or enhancements. */
+  /* The only place, other than this routine, where expressions can be
+  ** converted to TK_REGISTER is internal subexpressions in BETWEEN and
+  ** CASE operators.  Neither ever calls this routine.  And this routine
+  ** is never called twice on the same expression.  Hence it is impossible
+  ** for the input to this routine to already be a register.  Nevertheless,
+  ** it seems prudent to keep the ALWAYS() in case the conditions above
+  ** change with future modifications or enhancements. */
   if( ALWAYS(pExpr->op!=TK_REGISTER) ){  
     int iMem;
     iMem = ++pParse->nMem;
@@ -3745,7 +3742,7 @@
     }
     return 2;
   }
-  if( pA->op!=pB->op /*&& (pA->op!=TK_REGISTER || pA->op2!=pB->op)*/ ){
+  if( pA->op!=pB->op ){
     if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
       return 1;
     }
@@ -3760,8 +3757,6 @@
     }
   }
   if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
-  testcase( combinedFlags & EP_TokenOnly );
-  testcase( combinedFlags & EP_Reduced );
   if( (combinedFlags & EP_TokenOnly)==0 ){
     if( combinedFlags & EP_xIsSelect ) return 2;
     if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
@@ -3770,7 +3765,6 @@
     if( (combinedFlags & EP_Reduced)==0 ){
       if( pA->iColumn!=pB->iColumn ) return 2;
       if( pA->iTable!=pB->iTable 
-       && pA->op!=TK_REGISTER
        && (pA->iTable!=iTab || pB->iTable>=0) ) return 2;
     }
   }
diff --git a/src/resolve.c b/src/resolve.c
index b41f234..b5ba80e 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -108,10 +108,10 @@
     pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
     if( pDup==0 ) return;
     ExprSetProperty(pDup, EP_Skip);
-    if( pEList->a[iCol].iAlias==0 ){
-      pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
+    if( pEList->a[iCol].u.x.iAlias==0 ){
+      pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias);
     }
-    pDup->iTable = pEList->a[iCol].iAlias;
+    pDup->iTable = pEList->a[iCol].u.x.iAlias;
   }
   if( pExpr->op==TK_COLLATE ){
     pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
@@ -976,7 +976,7 @@
           pItem->pExpr->pLeft = pNew;
         }
         sqlite3ExprDelete(db, pE);
-        pItem->iOrderByCol = (u16)iCol;
+        pItem->u.x.iOrderByCol = (u16)iCol;
         pItem->done = 1;
       }else{
         moreToDo = 1;
@@ -997,8 +997,8 @@
 /*
 ** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
 ** the SELECT statement pSelect.  If any term is reference to a
-** result set expression (as determined by the ExprList.a.iOrderByCol field)
-** then convert that term into a copy of the corresponding result set
+** result set expression (as determined by the ExprList.a.u.x.iOrderByCol
+** field) then convert that term into a copy of the corresponding result set
 ** column.
 **
 ** If any errors are detected, add an error message to pParse and
@@ -1025,12 +1025,12 @@
   pEList = pSelect->pEList;
   assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */
   for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
-    if( pItem->iOrderByCol ){
-      if( pItem->iOrderByCol>pEList->nExpr ){
+    if( pItem->u.x.iOrderByCol ){
+      if( pItem->u.x.iOrderByCol>pEList->nExpr ){
         resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
         return 1;
       }
-      resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0);
+      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
     }
   }
   return 0;
@@ -1079,7 +1079,7 @@
         ** a copy of the iCol-th result-set column.  The subsequent call to
         ** sqlite3ResolveOrderGroupBy() will convert the expression to a
         ** copy of the iCol-th result-set expression. */
-        pItem->iOrderByCol = (u16)iCol;
+        pItem->u.x.iOrderByCol = (u16)iCol;
         continue;
       }
     }
@@ -1091,18 +1091,18 @@
         resolveOutOfRangeError(pParse, zType, i+1, nResult);
         return 1;
       }
-      pItem->iOrderByCol = (u16)iCol;
+      pItem->u.x.iOrderByCol = (u16)iCol;
       continue;
     }
 
     /* Otherwise, treat the ORDER BY term as an ordinary expression */
-    pItem->iOrderByCol = 0;
+    pItem->u.x.iOrderByCol = 0;
     if( sqlite3ResolveExprNames(pNC, pE) ){
       return 1;
     }
     for(j=0; j<pSelect->pEList->nExpr; j++){
       if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
-        pItem->iOrderByCol = j+1;
+        pItem->u.x.iOrderByCol = j+1;
       }
     }
   }
diff --git a/src/select.c b/src/select.c
index 5cdef3a..04a5234 100644
--- a/src/select.c
+++ b/src/select.c
@@ -2372,8 +2372,8 @@
     for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
       struct ExprList_item *pItem;
       for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
-        assert( pItem->iOrderByCol>0 );
-        if( pItem->iOrderByCol==i ) break;
+        assert( pItem->u.x.iOrderByCol>0 );
+        if( pItem->u.x.iOrderByCol==i ) break;
       }
       if( j==nOrderBy ){
         Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
@@ -2381,7 +2381,7 @@
         pNew->flags |= EP_IntValue;
         pNew->u.iValue = i;
         pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
-        if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
+        if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
       }
     }
   }
@@ -2397,8 +2397,9 @@
   if( aPermute ){
     struct ExprList_item *pItem;
     for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
-      assert( pItem->iOrderByCol>0  && pItem->iOrderByCol<=p->pEList->nExpr );
-      aPermute[i] = pItem->iOrderByCol - 1;
+      assert( pItem->u.x.iOrderByCol>0
+          && pItem->u.x.iOrderByCol<=p->pEList->nExpr );
+      aPermute[i] = pItem->u.x.iOrderByCol - 1;
     }
     pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1);
     if( pKeyMerge ){
@@ -2978,7 +2979,7 @@
     if( p->pOrderBy ){
       int ii;
       for(ii=0; ii<p->pOrderBy->nExpr; ii++){
-        if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0;
+        if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
       }
     }
   }
@@ -4385,10 +4386,10 @@
       struct ExprList_item *pItem;  /* For looping over expression in a list */
 
       for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){
-        pItem->iAlias = 0;
+        pItem->u.x.iAlias = 0;
       }
       for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
-        pItem->iAlias = 0;
+        pItem->u.x.iAlias = 0;
       }
       if( p->nSelectRow>100 ) p->nSelectRow = 100;
     }else{
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 9c4a9cc..e6385e2 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1900,8 +1900,13 @@
     u8 sortOrder;           /* 1 for DESC or 0 for ASC */
     unsigned done :1;       /* A flag to indicate when processing is finished */
     unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
-    u16 iOrderByCol;        /* For ORDER BY, column number in result set */
-    u16 iAlias;             /* Index into Parse.aAlias[] for zName */
+    union {
+      struct {
+        u16 iOrderByCol;      /* For ORDER BY, column number in result set */
+        u16 iAlias;           /* Index into Parse.aAlias[] for zName */
+      } x;
+      int iConstExprReg;      /* Register in which Expr value is cached */
+    } u;
   } *a;                  /* Alloc a power of two greater or equal to nExpr */
 };
 
diff --git a/src/where.c b/src/where.c
index 9f4e23d..d9e16a1 100644
--- a/src/where.c
+++ b/src/where.c
@@ -669,9 +669,6 @@
 
   pRight = pList->a[0].pExpr;
   op = pRight->op;
-  if( op==TK_REGISTER ){
-    op = pRight->op2;
-  }
   if( op==TK_VARIABLE ){
     Vdbe *pReprepare = pParse->pReprepare;
     int iCol = pRight->iColumn;