aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2023-10-18 22:03:48 +0000
committerdrh <>2023-10-18 22:03:48 +0000
commit20b95f8d3fc34d6fe8a049a3b2abebefce12eea1 (patch)
tree47c33c69ce9333c42eeff43e6af35ff2d5a3957e /src
parent49dc1be96f76ce01325cdb2d8b475f25a51f3605 (diff)
downloadsqlite-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.c16
-rw-r--r--src/resolve.c5
-rw-r--r--src/select.c6
-rw-r--r--src/sqliteInt.h1
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*);