Combine the Expr.pTab and Expr.pWin fields into a union named "y".  Add a new
EP_WinFunc property that is only true if Expr.y.pWin is a valid pointer.
This reduces the size of the Expr object by 8 bytes, reduces the overall
amount of code, and shaves over 1 million cycles off of the speed test.

FossilOrigin-Name: ad130bb86e74e6ce165fdbdce3a19699510f0e62071c1c7923b5a4538d888c7c
diff --git a/src/alter.c b/src/alter.c
index 08745cc..1cf778b 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -803,7 +803,7 @@
     renameTokenFind(pWalker->pParse, p, (void*)pExpr);
   }else if( pExpr->op==TK_COLUMN 
    && pExpr->iColumn==p->iCol 
-   && p->pTab==pExpr->pTab
+   && p->pTab==pExpr->y.pTab
   ){
     renameTokenFind(pWalker->pParse, p, (void*)pExpr);
   }
@@ -1341,8 +1341,8 @@
 */
 static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
   RenameCtx *p = pWalker->u.pRename;
-  if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
-    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
+  if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
+    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
   }
   return WRC_Continue;
 }
diff --git a/src/expr.c b/src/expr.c
index 4777244..1692822 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -58,8 +58,8 @@
     return sqlite3AffinityType(pExpr->u.zToken, 0);
   }
 #endif
-  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
-    return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
+    return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
   }
   if( op==TK_SELECT_COLUMN ){
     assert( pExpr->pLeft->flags&EP_xIsSelect );
@@ -143,13 +143,13 @@
     if( p->flags & EP_Generic ) break;
     if( (op==TK_AGG_COLUMN || op==TK_COLUMN
           || op==TK_REGISTER || op==TK_TRIGGER)
-     && p->pTab!=0
+     && p->y.pTab!=0
     ){
-      /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
+      /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
       ** a TK_COLUMN but was previously evaluated and cached in a register */
       int j = p->iColumn;
       if( j>=0 ){
-        const char *zColl = p->pTab->aCol[j].zColl;
+        const char *zColl = p->y.pTab->aCol[j].zColl;
         pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
       }
       break;
@@ -1052,6 +1052,10 @@
   assert( p!=0 );
   /* Sanity check: Assert that the IntValue is non-negative if it exists */
   assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
+
+  assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
+  assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
+          || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
 #ifdef SQLITE_DEBUG
   if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
     assert( p->pLeft==0 );
@@ -1070,8 +1074,9 @@
     }else{
       sqlite3ExprListDelete(db, p->x.pList);
     }
-    if( !ExprHasProperty(p, EP_Reduced) ){
-      sqlite3WindowDelete(db, p->pWin);
+    if( ExprHasProperty(p, EP_WinFunc) ){
+      assert( p->op==TK_FUNCTION );
+      sqlite3WindowDelete(db, p->y.pWin);
     }
   }
   if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
@@ -1135,7 +1140,7 @@
   assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
   if( 0==flags || p->op==TK_SELECT_COLUMN 
 #ifndef SQLITE_OMIT_WINDOWFUNC
-   || p->pWin 
+   || ExprHasProperty(p, EP_WinFunc)
 #endif
   ){
     nSize = EXPR_FULLSIZE;
@@ -1278,10 +1283,9 @@
       }
     }else{
 #ifndef SQLITE_OMIT_WINDOWFUNC
-      if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
-        pNew->pWin = 0;
-      }else{
-        pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
+      if( ExprHasProperty(p, EP_WinFunc) ){
+        pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
+        assert( ExprHasProperty(pNew, EP_WinFunc) );
       }
 #endif /* SQLITE_OMIT_WINDOWFUNC */
       if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
@@ -2089,8 +2093,8 @@
       return 0;
     case TK_COLUMN:
       return ExprHasProperty(p, EP_CanBeNull) ||
-             p->pTab==0 ||  /* Reference to column of index on expression */
-             (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
+             p->y.pTab==0 ||  /* Reference to column of index on expression */
+             (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
     default:
       return 1;
   }
@@ -3378,7 +3382,7 @@
         ** constant.
         */
         int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
-        int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+        int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
         if( aff!=SQLITE_AFF_BLOB ){
           static const char zAff[] = "B\000C\000D\000E";
           assert( SQLITE_AFF_BLOB=='A' );
@@ -3402,7 +3406,7 @@
           iTab = pParse->iSelfTab - 1;
         }
       }
-      return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+      return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
                                pExpr->iColumn, iTab, target,
                                pExpr->op2);
     }
@@ -3616,8 +3620,8 @@
       CollSeq *pColl = 0;    /* A collating sequence */
 
 #ifndef SQLITE_OMIT_WINDOWFUNC
-      if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
-        return pExpr->pWin->regResult;
+      if( ExprHasProperty(pExpr, EP_WinFunc) ){
+        return pExpr->y.pWin->regResult;
       }
 #endif
 
@@ -3860,7 +3864,7 @@
       **   p1==1   ->    old.a         p1==4   ->    new.a
       **   p1==2   ->    old.b         p1==5   ->    new.b       
       */
-      Table *pTab = pExpr->pTab;
+      Table *pTab = pExpr->y.pTab;
       int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
 
       assert( pExpr->iTable==0 || pExpr->iTable==1 );
@@ -3871,7 +3875,7 @@
       sqlite3VdbeAddOp2(v, OP_Param, p1, target);
       VdbeComment((v, "r[%d]=%s.%s", target,
         (pExpr->iTable ? "new" : "old"),
-        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
+        (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
       ));
 
 #ifndef SQLITE_OMIT_FLOATING_POINT
@@ -4722,6 +4726,20 @@
   if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
     if( pA->op==TK_FUNCTION ){
       if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+      /* Justification for the assert():
+      ** window functions have p->op==TK_FUNCTION but aggregate functions
+      ** have p->op==TK_AGG_FUNCTION.  So any comparison between an aggregate
+      ** function and a window function should have failed before reaching
+      ** this point.  And, it is not possible to have a window function and
+      ** a scalar function with the same name and number of arguments.  So
+      ** if we reach this point, either A and B both window functions or
+      ** neither are a window functions. */
+      assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
+      if( ExprHasProperty(pA,EP_WinFunc) ){
+        if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
+      }
+#endif
     }else if( pA->op==TK_COLLATE ){
       if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
     }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
@@ -4741,21 +4759,6 @@
       if( pA->iTable!=pB->iTable 
        && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
     }
-#ifndef SQLITE_OMIT_WINDOWFUNC
-    /* Justification for the assert():
-    ** window functions have p->op==TK_FUNCTION but aggregate functions
-    ** have p->op==TK_AGG_FUNCTION.  So any comparison between an aggregate
-    ** function and a window function should have failed before reaching
-    ** this point.  And, it is not possible to have a window function and
-    ** a scalar function with the same name and number of arguments.  So
-    ** if we reach this point, either A and B both window functions or
-    ** neither are a window functions. */
-    assert( (pA->pWin==0)==(pB->pWin==0) );
-
-    if( pA->pWin!=0 ){
-      if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
-    }
-#endif
   }
   return 0;
 }
@@ -4899,8 +4902,8 @@
       testcase( pExpr->op==TK_LE );
       testcase( pExpr->op==TK_GT );
       testcase( pExpr->op==TK_GE );
-      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
-       || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
+      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
+       || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
       ){
        return WRC_Prune;
       }
@@ -5131,7 +5134,7 @@
              && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 
             ){
               pCol = &pAggInfo->aCol[k];
-              pCol->pTab = pExpr->pTab;
+              pCol->pTab = pExpr->y.pTab;
               pCol->iTable = pExpr->iTable;
               pCol->iColumn = pExpr->iColumn;
               pCol->iMem = ++pParse->nMem;
diff --git a/src/fkey.c b/src/fkey.c
index 0f5248f..6777d71 100644
--- a/src/fkey.c
+++ b/src/fkey.c
@@ -502,7 +502,7 @@
 ){
   Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
   if( pExpr ){
-    pExpr->pTab = pTab;
+    pExpr->y.pTab = pTab;
     pExpr->iTable = iCursor;
     pExpr->iColumn = iCol;
   }
diff --git a/src/parse.y b/src/parse.y
index f2cb072..b150c73 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -941,13 +941,10 @@
       p->pLeft = p->pRight = 0;
       p->x.pList = 0;
       p->pAggInfo = 0;
-      p->pTab = 0;
+      p->y.pTab = 0;
       p->op2 = 0;
       p->iTable = 0;
       p->iColumn = 0;
-#ifndef SQLITE_OMIT_WINDOWFUNC
-      p->pWin = 0;
-#endif
       p->u.zToken = (char*)&p[1];
       memcpy(p->u.zToken, t.z, t.n);
       p->u.zToken[t.n] = 0;
diff --git a/src/resolve.c b/src/resolve.c
index 9fb4d4c..da9ead6 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -159,7 +159,7 @@
 **                         (even if X is implied).
 **    pExpr->iTable        Set to the cursor number for the table obtained
 **                         from pSrcList.
-**    pExpr->pTab          Points to the Table structure of X.Y (even if
+**    pExpr->y.pTab        Points to the Table structure of X.Y (even if
 **                         X and/or Y are implied.)
 **    pExpr->iColumn       Set to the column number within the table.
 **    pExpr->op            Set to TK_COLUMN.
@@ -203,7 +203,6 @@
 
   /* Initialize the node to no-match */
   pExpr->iTable = -1;
-  pExpr->pTab = 0;
   ExprSetVVAProperty(pExpr, EP_NoReduce);
 
   /* Translate the schema name in zDb into a pointer to the corresponding
@@ -265,7 +264,7 @@
             continue;
           }
           if( IN_RENAME_OBJECT && pItem->zAlias ){
-            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
+            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
           }
         }
         if( 0==(cntTab++) ){
@@ -291,13 +290,13 @@
       }
       if( pMatch ){
         pExpr->iTable = pMatch->iCursor;
-        pExpr->pTab = pMatch->pTab;
+        pExpr->y.pTab = pMatch->pTab;
         /* RIGHT JOIN not (yet) supported */
         assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
         if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
           ExprSetProperty(pExpr, EP_CanBeNull);
         }
-        pSchema = pExpr->pTab->pSchema;
+        pSchema = pExpr->y.pTab->pSchema;
       }
     } /* if( pSrcList ) */
 
@@ -354,7 +353,7 @@
             testcase( iCol==(-1) );
             if( IN_RENAME_OBJECT ){
               pExpr->iColumn = iCol;
-              pExpr->pTab = pTab;
+              pExpr->y.pTab = pTab;
               eNewExprOp = TK_COLUMN;
             }else{
               pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
@@ -376,7 +375,7 @@
               testcase( iCol==32 );
               pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
             }
-            pExpr->pTab = pTab;
+            pExpr->y.pTab = pTab;
             pExpr->iColumn = (i16)iCol;
             eNewExprOp = TK_TRIGGER;
 #endif /* SQLITE_OMIT_TRIGGER */
@@ -476,7 +475,7 @@
     assert( pExpr->op==TK_ID );
     if( ExprHasProperty(pExpr,EP_DblQuoted) ){
       pExpr->op = TK_STRING;
-      pExpr->pTab = 0;
+      pExpr->y.pTab = 0;
       return WRC_Prune;
     }
     if( sqlite3ExprIdToTrueFalse(pExpr) ){
@@ -554,9 +553,9 @@
   Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
   if( p ){
     struct SrcList_item *pItem = &pSrc->a[iSrc];
-    p->pTab = pItem->pTab;
+    p->y.pTab = pItem->pTab;
     p->iTable = pItem->iCursor;
-    if( p->pTab->iPKey==iCol ){
+    if( p->y.pTab->iPKey==iCol ){
       p->iColumn = -1;
     }else{
       p->iColumn = (ynVar)iCol;
@@ -646,7 +645,7 @@
       pItem = pSrcList->a;
       assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
       pExpr->op = TK_COLUMN;
-      pExpr->pTab = pItem->pTab;
+      pExpr->y.pTab = pItem->pTab;
       pExpr->iTable = pItem->iCursor;
       pExpr->iColumn = -1;
       pExpr->affinity = SQLITE_AFF_INTEGER;
@@ -692,7 +691,7 @@
           sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
         }
         if( IN_RENAME_OBJECT ){
-          sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
+          sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
         }
       }
       return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
@@ -782,18 +781,18 @@
           || (pDef->xValue==0 && pDef->xInverse==0)
           || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
         );
-        if( pDef && pDef->xValue==0 && pExpr->pWin ){
+        if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
           sqlite3ErrorMsg(pParse, 
               "%.*s() may not be used as a window function", nId, zId
           );
           pNC->nErr++;
         }else if( 
               (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
-           || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
-           || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
+           || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
+           || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
         ){
           const char *zType;
-          if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
+          if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
             zType = "window";
           }else{
             zType = "aggregate";
@@ -823,7 +822,7 @@
         }
         if( is_agg ){
 #ifndef SQLITE_OMIT_WINDOWFUNC
-          pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
+          pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
 #else
           pNC->ncFlags &= ~NC_AllowAgg;
 #endif
@@ -832,17 +831,17 @@
       sqlite3WalkExprList(pWalker, pList);
       if( is_agg ){
 #ifndef SQLITE_OMIT_WINDOWFUNC
-        if( pExpr->pWin ){
+        if( pExpr->y.pWin ){
           Select *pSel = pNC->pWinSelect;
-          sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
-          sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
-          sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
-          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
+          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
+          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
+          sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
+          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
           if( 0==pSel->pWin 
-           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin) 
+           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) 
           ){
-            pExpr->pWin->pNextWin = pSel->pWin;
-            pSel->pWin = pExpr->pWin;
+            pExpr->y.pWin->pNextWin = pSel->pWin;
+            pSel->pWin = pExpr->y.pWin;
           }
           pNC->ncFlags |= NC_AllowWin;
         }else
@@ -1265,13 +1264,13 @@
     for(j=0; j<pSelect->pEList->nExpr; j++){
       if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
 #ifndef SQLITE_OMIT_WINDOWFUNC
-        if( pE->pWin ){
+        if( ExprHasProperty(pE, EP_WinFunc) ){
           /* Since this window function is being changed into a reference
           ** to the same window function the result set, remove the instance
           ** of this window function from the Select.pWin list. */
           Window **pp;
           for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
-            if( *pp==pE->pWin ){
+            if( *pp==pE->y.pWin ){
               *pp = (*pp)->pNextWin;
             }    
           }
diff --git a/src/select.c b/src/select.c
index bc5960f..d300798 100644
--- a/src/select.c
+++ b/src/select.c
@@ -803,7 +803,7 @@
     struct ExprList_item *pItem = &pEList->a[i];
     if( pItem->u.x.iOrderByCol==0 ){
       Expr *pExpr = pItem->pExpr;
-      Table *pTab = pExpr->pTab;
+      Table *pTab = pExpr->y.pTab;
       if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
        && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
       ){
@@ -826,12 +826,12 @@
               Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
               if( pNew ){
                 pNew->iTable = pExpr->iTable;
-                pNew->pTab = pExpr->pTab;
+                pNew->y.pTab = pExpr->y.pTab;
                 pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
                 pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
               }
             }
-            pSort->aDefer[nDefer].pTab = pExpr->pTab;
+            pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
             pSort->aDefer[nDefer].iCsr = pExpr->iTable;
             pSort->aDefer[nDefer].nKey = nKey;
             nDefer++;
@@ -1680,7 +1680,7 @@
         break;
       }
 
-      assert( pTab && pExpr->pTab==pTab );
+      assert( pTab && pExpr->y.pTab==pTab );
       if( pS ){
         /* The "table" is actually a sub-select or a view in the FROM clause
         ** of the SELECT statement. Return the declaration type and origin
@@ -1865,7 +1865,7 @@
 
     assert( p!=0 );
     assert( p->op!=TK_AGG_COLUMN );  /* Agg processing has not run yet */
-    assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
+    assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
     if( pEList->a[i].zName ){
       /* An AS clause always takes first priority */
       char *zName = pEList->a[i].zName;
@@ -1873,7 +1873,7 @@
     }else if( srcName && p->op==TK_COLUMN ){
       char *zCol;
       int iCol = p->iColumn;
-      pTab = p->pTab;
+      pTab = p->y.pTab;
       assert( pTab!=0 );
       if( iCol<0 ) iCol = pTab->iPKey;
       assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
@@ -1964,7 +1964,7 @@
       if( pColExpr->op==TK_COLUMN ){
         /* For columns use the column name name */
         int iCol = pColExpr->iColumn;
-        Table *pTab = pColExpr->pTab;
+        Table *pTab = pColExpr->y.pTab;
         assert( pTab!=0 );
         if( iCol<0 ) iCol = pTab->iPKey;
         zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 74438b5..ba24c07 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2459,11 +2459,11 @@
                          ** TK_COLUMN: the value of p5 for OP_Column
                          ** TK_AGG_FUNCTION: nesting depth */
   AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
-  Table *pTab;           /* Table for TK_COLUMN expressions.  Can be NULL
-                         ** for a column of an index on an expression */
-#ifndef SQLITE_OMIT_WINDOWFUNC
-  Window *pWin;          /* Window definition for window functions */
-#endif
+  union {
+    Table *pTab;           /* TK_COLUMN: Table containing column. Can be NULL
+                           ** for a column of an index on an expression */
+    Window *pWin;          /* TK_FUNCTION: Window definition for the func */
+  } y;
 };
 
 /*
@@ -2493,6 +2493,7 @@
 #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
 #define EP_Alias     0x400000 /* Is an alias for a result set column */
 #define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
+#define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
 
 /*
 ** The EP_Propagate mask is a set of properties that automatically propagate
diff --git a/src/treeview.c b/src/treeview.c
index cde776d..c8c3b90 100644
--- a/src/treeview.c
+++ b/src/treeview.c
@@ -497,7 +497,7 @@
       }else{
         pFarg = pExpr->x.pList;
 #ifndef SQLITE_OMIT_WINDOWFUNC
-        pWin = pExpr->pWin;
+        pWin = pExpr->y.pWin;
 #else
         pWin = 0;
 #endif 
diff --git a/src/vtab.c b/src/vtab.c
index 7b459be..f5501e1 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -1053,7 +1053,7 @@
   /* Check to see the left operand is a column in a virtual table */
   if( NEVER(pExpr==0) ) return pDef;
   if( pExpr->op!=TK_COLUMN ) return pDef;
-  pTab = pExpr->pTab;
+  pTab = pExpr->y.pTab;
   if( pTab==0 ) return pDef;
   if( !IsVirtual(pTab) ) return pDef;
   pVtab = sqlite3GetVTable(db, pTab)->pVtab;
diff --git a/src/walker.c b/src/walker.c
index b3d4cd8..c31d94f 100644
--- a/src/walker.c
+++ b/src/walker.c
@@ -55,8 +55,8 @@
         if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
       }
 #ifndef SQLITE_OMIT_WINDOWFUNC
-      if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
-        Window *pWin = pExpr->pWin;
+      if( ExprHasProperty(pExpr, EP_WinFunc) ){
+        Window *pWin = pExpr->y.pWin;
         if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
         if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
         if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
diff --git a/src/wherecode.c b/src/wherecode.c
index 65cbc4c..f337006 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -1117,7 +1117,7 @@
     pExpr->op = TK_COLUMN;
     pExpr->iTable = pX->iIdxCur;
     pExpr->iColumn = pX->iIdxCol;
-    pExpr->pTab = 0;
+    pExpr->y.pTab = 0;
     return WRC_Prune;
   }else{
     return WRC_Continue;
diff --git a/src/whereexpr.c b/src/whereexpr.c
index 808c0d2..8f3791e 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -281,7 +281,7 @@
         ){
           if( pLeft->op!=TK_COLUMN 
            || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
-           || IsVirtual(pLeft->pTab)  /* Value might be numeric */
+           || IsVirtual(pLeft->y.pTab)  /* Value might be numeric */
           ){
             sqlite3ExprDelete(db, pPrefix);
             sqlite3ValueFree(pVal);
@@ -382,7 +382,7 @@
     **       MATCH(expression,vtab_column)
     */
     pCol = pList->a[1].pExpr;
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
       for(i=0; i<ArraySize(aOp); i++){
         if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
           *peOp2 = aOp[i].eOp2;
@@ -404,12 +404,12 @@
     ** with function names in an arbitrary case.
     */
     pCol = pList->a[0].pExpr;
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
       sqlite3_vtab *pVtab;
       sqlite3_module *pMod;
       void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
       void *pNotUsed;
-      pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
+      pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
       assert( pVtab!=0 );
       assert( pVtab->pModule!=0 );
       pMod = (sqlite3_module *)pVtab->pModule;
@@ -427,10 +427,10 @@
     int res = 0;
     Expr *pLeft = pExpr->pLeft;
     Expr *pRight = pExpr->pRight;
-    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
+    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
       res++;
     }
-    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
+    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
       res++;
       SWAP(Expr*, pLeft, pRight);
     }
@@ -1583,7 +1583,7 @@
     if( pColRef==0 ) return;
     pColRef->iTable = pItem->iCursor;
     pColRef->iColumn = k++;
-    pColRef->pTab = pTab;
+    pColRef->y.pTab = pTab;
     pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
                          sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
     whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
diff --git a/src/window.c b/src/window.c
index ce51de7..36cfc1c 100644
--- a/src/window.c
+++ b/src/window.c
@@ -624,12 +624,12 @@
   switch( pExpr->op ){
 
     case TK_FUNCTION:
-      if( pExpr->pWin==0 ){
+      if( !ExprHasProperty(pExpr, EP_WinFunc) ){
         break;
       }else{
         Window *pWin;
         for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
-          if( pExpr->pWin==pWin ){
+          if( pExpr->y.pWin==pWin ){
             assert( pWin->pOwner==pExpr );
             return WRC_Prune;
           }
@@ -959,11 +959,13 @@
 */
 void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
   if( p ){
+    assert( p->op==TK_FUNCTION );
     /* This routine is only called for the parser.  If pWin was not
     ** allocated due to an OOM, then the parser would fail before ever
     ** invoking this routine */
     if( ALWAYS(pWin) ){
-      p->pWin = pWin;
+      p->y.pWin = pWin;
+      ExprSetProperty(p, EP_WinFunc);
       pWin->pOwner = p;
       if( p->flags & EP_Distinct ){
         sqlite3ErrorMsg(pParse,
@@ -2126,7 +2128,7 @@
 */
 Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
   Window *pNew = 0;
-  if( p ){
+  if( ALWAYS(p) ){
     pNew = sqlite3DbMallocZero(db, sizeof(Window));
     if( pNew ){
       pNew->zName = sqlite3DbStrDup(db, p->zName);