diff options
author | drh <> | 2023-10-18 22:03:48 +0000 |
---|---|---|
committer | drh <> | 2023-10-18 22:03:48 +0000 |
commit | 20b95f8d3fc34d6fe8a049a3b2abebefce12eea1 (patch) | |
tree | 47c33c69ce9333c42eeff43e6af35ff2d5a3957e /src | |
parent | 49dc1be96f76ce01325cdb2d8b475f25a51f3605 (diff) | |
download | sqlite-20b95f8d3fc34d6fe8a049a3b2abebefce12eea1.tar.gz sqlite-20b95f8d3fc34d6fe8a049a3b2abebefce12eea1.zip |
Make sure all terms of the ORDER BY within an aggregate go through aggregate
analysis. Do not attach an aggregate ORDER BY to a window function.
FossilOrigin-Name: 16f3805514a741405f70e0ee3b5a6b67720bc75719372e82daa4136fe411ea2b
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 16 | ||||
-rw-r--r-- | src/resolve.c | 5 | ||||
-rw-r--r-- | src/select.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 |
4 files changed, 24 insertions, 4 deletions
diff --git a/src/expr.c b/src/expr.c index 26f0b4c5c..72a5fae7d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1182,6 +1182,16 @@ Expr *sqlite3ExprFunction( } /* +** Report an error when attempting to use an ORDER BY clause within +** the arguments of a non-aggregate function. +*/ +void sqlite3ExprOrderByAggregateError(Parse *pParse, Expr *p){ + sqlite3ErrorMsg(pParse, + "ORDER BY may not be used with non-aggregate %#T()", p + ); +} + +/* ** Attach an ORDER BY clause to a function call. ** ** functionname( arguments ORDER BY sortlist ) @@ -1215,6 +1225,12 @@ void sqlite3ExprAddFunctionOrderBy( sqlite3ExprListDelete(db, pOrderBy); return; } + if( IsWindowFunc(pExpr) ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); if( pOB==0 ){ sqlite3ExprListDelete(db, pOrderBy); diff --git a/src/resolve.c b/src/resolve.c index 532306e9c..7eba26938 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1195,10 +1195,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } #endif else if( is_agg==0 && pExpr->pLeft ){ - sqlite3ErrorMsg(pParse, - "ORDER BY may not be used with non-aggregate %#T()", - pExpr - ); + sqlite3ExprOrderByAggregateError(pParse, pExpr); pNC->nNcErr++; } if( is_agg ){ diff --git a/src/select.c b/src/select.c index 60583b20a..05aeb42e0 100644 --- a/src/select.c +++ b/src/select.c @@ -6490,8 +6490,14 @@ static void analyzeAggFuncArgs( pNC->ncFlags |= NC_InAggFunc; for(i=0; i<pAggInfo->nFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index cb90fba4a..4becf9222 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4790,6 +4790,7 @@ Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*); +void sqlite3ExprOrderByAggregateError(Parse*,Expr*); void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); |