mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Experimental implementation of FILTER clause for aggregate functions.
FossilOrigin-Name: 1f1ae2d6ac8dcbb62e5aa3dc17bc67d559cb565fc0d0a8c00a596075d35f8130
This commit is contained in:
24
src/select.c
24
src/select.c
@@ -4406,7 +4406,9 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
|
||||
|
||||
assert( *ppMinMax==0 );
|
||||
assert( pFunc->op==TK_AGG_FUNCTION );
|
||||
if( pEList==0 || pEList->nExpr!=1 ) return eRet;
|
||||
if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_Filter) ){
|
||||
return eRet;
|
||||
}
|
||||
zFunc = pFunc->u.zToken;
|
||||
if( sqlite3StrICmp(zFunc, "min")==0 ){
|
||||
eRet = WHERE_ORDERBY_MIN;
|
||||
@@ -4453,7 +4455,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
|
||||
if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
|
||||
if( NEVER(pAggInfo->nFunc==0) ) return 0;
|
||||
if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
|
||||
if( pExpr->flags&EP_Distinct ) return 0;
|
||||
if( ExprHasProperty(pExpr, EP_Distinct|EP_Filter) ) return 0;
|
||||
|
||||
return pTab;
|
||||
}
|
||||
@@ -5333,6 +5335,11 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
|
||||
int regAgg;
|
||||
ExprList *pList = pF->pExpr->x.pList;
|
||||
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
|
||||
if( ExprHasProperty(pF->pExpr, EP_Filter) ){
|
||||
Expr *pFilter = pF->pExpr->y.pFilter;
|
||||
addrNext = sqlite3VdbeMakeLabel(pParse);
|
||||
sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
if( pList ){
|
||||
nArg = pList->nExpr;
|
||||
regAgg = sqlite3GetTempRange(pParse, nArg);
|
||||
@@ -5342,7 +5349,9 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
|
||||
regAgg = 0;
|
||||
}
|
||||
if( pF->iDistinct>=0 ){
|
||||
addrNext = sqlite3VdbeMakeLabel(pParse);
|
||||
if( addrNext==0 ){
|
||||
addrNext = sqlite3VdbeMakeLabel(pParse);
|
||||
}
|
||||
testcase( nArg==0 ); /* Error condition */
|
||||
testcase( nArg>1 ); /* Also an error */
|
||||
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
|
||||
@@ -6225,9 +6234,14 @@ int sqlite3Select(
|
||||
minMaxFlag = WHERE_ORDERBY_NORMAL;
|
||||
}
|
||||
for(i=0; i<sAggInfo.nFunc; i++){
|
||||
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
|
||||
Expr *pExpr = sAggInfo.aFunc[i].pExpr;
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
sNC.ncFlags |= NC_InAggFunc;
|
||||
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
|
||||
sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
|
||||
sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pFilter);
|
||||
#endif
|
||||
sNC.ncFlags &= ~NC_InAggFunc;
|
||||
}
|
||||
sAggInfo.mxReg = pParse->nMem;
|
||||
|
||||
Reference in New Issue
Block a user