aboutsummaryrefslogtreecommitdiff
path: root/src/resolve.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve.c')
-rw-r--r--src/resolve.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/src/resolve.c b/src/resolve.c
index 8dac077ee..872d04f57 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -749,7 +749,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
-
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
+#endif
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
@@ -830,18 +832,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|| (pDef->xValue==0 && pDef->xInverse==0)
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
);
- if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
+ 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) && !pExpr->y.pWin)
- || (is_agg && pExpr->y.pWin && (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) || pExpr->y.pWin ){
+ if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
zType = "window";
}else{
zType = "aggregate";
@@ -849,6 +851,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
pNC->nErr++;
is_agg = 0;
+ }else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
+ assert( !IsWindowFunc(pExpr) );
+ sqlite3ErrorMsg(pParse,
+ "filter clause may not be used with non-aggregate %.*s()",
+ nId, zId
+ );
+ pNC->nErr++;
}
#else
if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
@@ -874,7 +883,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
** Or arguments of other window functions. But aggregate functions
** may be arguments for window functions. */
#ifndef SQLITE_OMIT_WINDOWFUNC
- pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
+ pNC->ncFlags &= ~(NC_AllowWin | (!pWin ? NC_AllowAgg : 0));
#else
pNC->ncFlags &= ~NC_AllowAgg;
#endif
@@ -883,16 +892,16 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
sqlite3WalkExprList(pWalker, pList);
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pExpr->y.pWin ){
+ if( pWin ){
Select *pSel = pNC->pWinSelect;
if( IN_RENAME_OBJECT==0 ){
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pWin, pDef);
}
- sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
- sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
- sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
+ sqlite3WalkExprList(pWalker, pWin->pPartition);
+ sqlite3WalkExprList(pWalker, pWin->pOrderBy);
+ sqlite3WalkExpr(pWalker, pWin->pFilter);
if( 0==pSel->pWin
- || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
+ || 0==sqlite3WindowCompare(pParse, pSel->pWin, pWin, 0)
){
pExpr->y.pWin->pNextWin = pSel->pWin;
pSel->pWin = pExpr->y.pWin;
@@ -904,6 +913,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
NameContext *pNC2 = pNC;
pExpr->op = TK_AGG_FUNCTION;
pExpr->op2 = 0;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
+ }
+#endif
while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
pExpr->op2++;
pNC2 = pNC2->pNext;