Index: src/resolve.c ================================================================== --- src/resolve.c +++ src/resolve.c @@ -389,16 +389,16 @@ && cnt==0 ){ for(j=0; jnExpr; j++){ char *zAs = pEList->a[j].zName; if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ - Expr *pOrig; assert( pExpr->pLeft==0 && pExpr->pRight==0 ); assert( pExpr->x.pList==0 ); assert( pExpr->x.pSelect==0 ); - pOrig = pEList->a[j].pExpr; - if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ + if( (pNC->ncFlags&NC_AllowAgg)==0 + && ExprHasProperty(pEList->a[j].pExpr, EP_Agg) + ){ sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); return WRC_Abort; } resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); cnt = 1; @@ -712,15 +712,20 @@ ** sqlite_version() that might change over time cannot be used ** in an index. */ notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr); } } +#if 0 + /* This error condition will be caught later, during code + ** generation */ if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); pNC->nErr++; is_agg = 0; - }else if( no_such_func && pParse->db->init.busy==0 ){ + }else +#endif + if( no_such_func && pParse->db->init.busy==0 ){ sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); pNC->nErr++; }else if( wrong_num_args ){ sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", nId, zId); @@ -1206,24 +1211,13 @@ sNC.pNext = pOuterNC; /* Resolve names in the result set. */ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; - /* If there are no aggregate functions in the result-set, and no GROUP BY - ** expression, do not allow aggregates in any of the other expressions. - */ - assert( (p->selFlags & SF_Aggregate)==0 ); - pGroupBy = p->pGroupBy; - if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ - assert( NC_MinMaxAgg==SF_MinMaxAgg ); - p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg); - }else{ - sNC.ncFlags &= ~NC_AllowAgg; - } - /* If a HAVING clause is present, then there must be a GROUP BY clause. */ + pGroupBy = p->pGroupBy; if( p->pHaving && !pGroupBy ){ sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); return WRC_Abort; } @@ -1234,12 +1228,24 @@ ** ** Minor point: If this is the case, then the expression will be ** re-evaluated for each reference to it. */ sNC.pEList = p->pEList; - if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; + + /* If there are no aggregate functions in the result-set, and no GROUP BY + ** expression, do not allow aggregates in any of the other expressions. + */ + assert( (p->selFlags & SF_Aggregate)==0 ); + if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ + assert( NC_MinMaxAgg==SF_MinMaxAgg ); + assert( NC_HasAgg==SF_HasAgg ); + p->selFlags |= SF_Aggregate | (sNC.ncFlags&(NC_MinMaxAgg|NC_HasAgg)); + }else{ + sNC.ncFlags &= ~NC_AllowAgg; + } /* Resolve names in table-valued-function arguments */ for(i=0; ipSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; if( pItem->fg.isTabFunc Index: src/select.c ================================================================== --- src/select.c +++ src/select.c @@ -4897,16 +4897,16 @@ sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", pTab->nCol, pTab->zName, pSub->pEList->nExpr); goto select_end; } - isAggSub = (pSub->selFlags & SF_Aggregate)!=0; + isAggSub = pSub->selFlags & (SF_Aggregate|SF_HasAgg); if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ /* This subquery can be absorbed into its parent. */ if( isAggSub ){ isAgg = 1; - p->selFlags |= SF_Aggregate; + p->selFlags |= isAggSub; } i = -1; } pTabList = p->pSrc; if( db->mallocFailed ) goto select_end; @@ -5060,10 +5060,11 @@ pEList = p->pEList; pWhere = p->pWhere; pGroupBy = p->pGroupBy; pHaving = p->pHaving; sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; + assert( (p->selFlags & SF_HasAgg)==0 || (p->selFlags & SF_Aggregate)!=0 ); #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); @@ -5268,10 +5269,13 @@ sNC.ncFlags &= ~NC_InAggFunc; } sAggInfo.mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; + /* Not true if there are errors in the input SQL!: + ** assert( (sAggInfo.nFunc>0)==((p->selFlags&SF_HasAgg)!=0) ); */ + /* Processing for aggregates with GROUP BY is very different and ** much more complex than aggregates without a GROUP BY. */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ @@ -5654,10 +5658,11 @@ sqlite3VdbeResolveLabel(v, iEnd); /* The SELECT has been coded. If there is an error in the Parse structure, ** set the return code to 1. Otherwise 0. */ rc = (pParse->nErr>0); + assert( (sAggInfo.nFunc>0)==((p->selFlags&SF_HasAgg)!=0) || rc!=SQLITE_OK ); /* Control jumps to here if an error is encountered above, or upon ** successful coding of the SELECT. */ select_end: Index: test/aggnested.test ================================================================== --- test/aggnested.test +++ test/aggnested.test @@ -216,17 +216,16 @@ FROM t1 WHERE value1 IN (SELECT max(value1) FROM t1 GROUP BY id1); } } {12 2 34 4} do_test aggnested-3.15 { - # FIXME: If case 3.16 works, then this case really ought to work too... catchsql { SELECT max(value1), (SELECT sum(value2=max(value1)) FROM t2) FROM t1 GROUP BY id1; } -} {1 {misuse of aggregate function max()}} +} {0 {12 2 34 4}} do_test aggnested-3.16 { db eval { SELECT max(value1), (SELECT sum(value2=value1) FROM t2) FROM t1 GROUP BY id1; Index: test/select1.test ================================================================== --- test/select1.test +++ test/select1.test @@ -221,11 +221,11 @@ lappend v $msg } {0 44} do_test select1-2.20 { set v [catch {execsql {SELECT SUM(min(f1)) FROM test1}} msg] lappend v $msg -} {1 {misuse of aggregate function min()}} +} {1 {misuse of aggregate: min()}} # Ticket #2526 # do_test select1-2.21 { catchsql {