Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -1038,25 +1038,29 @@ if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); if( p->pRight ){ + assert( !ExprHasProperty(p, (EP_WinFunc|EP_Filter)) ); sqlite3ExprDeleteNN(db, p->pRight); }else if( ExprHasProperty(p, EP_xIsSelect) ){ + assert( !ExprHasProperty(p, (EP_WinFunc|EP_Filter)) ); sqlite3SelectDelete(db, p->x.pSelect); }else{ sqlite3ExprListDelete(db, p->x.pList); - } #ifndef SQLITE_OMIT_WINDOWFUNC - if( ExprHasProperty(p, EP_WinFunc) ){ - assert( p->op==TK_FUNCTION && !ExprHasProperty(p, EP_Filter) ); - sqlite3WindowDelete(db, p->y.pWin); - }else if( ExprHasProperty(p, EP_Filter) ){ - assert( p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION ); - sqlite3ExprDelete(db, p->y.pFilter); - } + if( ExprHasProperty(p, (EP_WinFunc|EP_Filter)) ){ + if( ExprHasProperty(p, EP_WinFunc) ){ + assert( p->op==TK_FUNCTION && !ExprHasProperty(p, EP_Filter) ); + sqlite3WindowDelete(db, p->y.pWin); + }else{ + assert( p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION ); + sqlite3ExprDeleteNN(db, p->y.pFilter); + } + } #endif + } } if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ sqlite3DbFreeNN(db, p); } Index: src/resolve.c ================================================================== --- src/resolve.c +++ src/resolve.c @@ -824,27 +824,27 @@ } } if( 0==IN_RENAME_OBJECT ){ #ifndef SQLITE_OMIT_WINDOWFUNC - int is_win = ExprHasProperty(pExpr, EP_WinFunc); + Window *pWin = (ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0); assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX) || (pDef->xValue==0 && pDef->xInverse==0) || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) ); - if( pDef && pDef->xValue==0 && is_win ){ + if( pDef && pDef->xValue==0 && pWin ){ 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) && !is_win) - || (is_agg && is_win && (pNC->ncFlags & NC_AllowWin)==0) + || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin) + || (is_agg && pWin && (pNC->ncFlags & NC_AllowWin)==0) ){ const char *zType; - if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || is_win ){ + if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){ zType = "window"; }else{ zType = "aggregate"; } sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); @@ -879,11 +879,11 @@ if( is_agg ){ /* Window functions may not be arguments of aggregate functions. ** Or arguments of other window functions. But aggregate functions ** may be arguments for window functions. */ #ifndef SQLITE_OMIT_WINDOWFUNC - pNC->ncFlags &= ~(NC_AllowWin | (!is_win ? NC_AllowAgg : 0)); + pNC->ncFlags &= ~(NC_AllowWin | (!pWin ? NC_AllowAgg : 0)); #else pNC->ncFlags &= ~NC_AllowAgg; #endif } } Index: src/walker.c ================================================================== --- src/walker.c +++ src/walker.c @@ -61,25 +61,30 @@ if( rc ) return rc & WRC_Abort; if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; assert( pExpr->x.pList==0 || pExpr->pRight==0 ); if( pExpr->pRight ){ + assert( !ExprHasProperty(pExpr, EP_WinFunc|EP_Filter) ); pExpr = pExpr->pRight; continue; }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + assert( !ExprHasProperty(pExpr, EP_WinFunc|EP_Filter) ); if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; - }else if( pExpr->x.pList ){ - if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; - } + }else{ + if( pExpr->x.pList ){ + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + } #ifndef SQLITE_OMIT_WINDOWFUNC - if( ExprHasProperty(pExpr, EP_WinFunc) ){ - if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort; - } - if( ExprHasProperty(pExpr, EP_Filter) ){ - if( walkExpr(pWalker, pExpr->y.pFilter) ) return WRC_Abort; - } + if( ExprHasProperty(pExpr, EP_WinFunc|EP_Filter) ){ + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort; + }else if( ExprHasProperty(pExpr, EP_Filter) ){ + if( walkExpr(pWalker, pExpr->y.pFilter) ) return WRC_Abort; + } + } #endif + } } break; } return WRC_Continue; }