aboutsummaryrefslogtreecommitdiff
path: root/src/select.c
diff options
context:
space:
mode:
authordrh <>2023-12-14 13:58:50 +0000
committerdrh <>2023-12-14 13:58:50 +0000
commit07117f8118f0f7858126c36ee4d202196f541330 (patch)
tree259e34c802201d16ca3a4ce648325235048dc9a1 /src/select.c
parent3e4195c60db744c69bb24e71236631a80f2ef547 (diff)
downloadsqlite-07117f8118f0f7858126c36ee4d202196f541330.tar.gz
sqlite-07117f8118f0f7858126c36ee4d202196f541330.zip
Pass subtype information through the aggregate ORDER BY sorter for
aggregate functions that use subtype information. FossilOrigin-Name: 3536f4030eab6d650b7ed729d2f71eb6cc3b5fbe16b4e96b99008d66522aaccb
Diffstat (limited to 'src/select.c')
-rw-r--r--src/select.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/select.c b/src/select.c
index 1beaf5307..d5b94e2da 100644
--- a/src/select.c
+++ b/src/select.c
@@ -6659,6 +6659,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
assert( pFunc->pFExpr->pLeft!=0 );
assert( pFunc->pFExpr->pLeft->op==TK_ORDER );
assert( ExprUseXList(pFunc->pFExpr->pLeft) );
+ assert( pFunc->pFunc!=0 );
pOBList = pFunc->pFExpr->pLeft->x.pList;
if( !pFunc->bOBUnique ){
nExtra++; /* One extra column for the OP_Sequence */
@@ -6668,6 +6669,9 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
assert( ExprUseXList(pFunc->pFExpr) );
nExtra += pFunc->pFExpr->x.pList->nExpr;
}
+ if( pFunc->bUseSubtype ){
+ nExtra += pFunc->pFExpr->x.pList->nExpr;
+ }
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra);
if( !pFunc->bOBUnique && pParse->nErr==0 ){
pKeyInfo->nKeyField++;
@@ -6694,16 +6698,17 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
assert( ExprUseXList(pF->pFExpr) );
pList = pF->pFExpr->x.pList;
if( pF->iOBTab>=0 ){
- /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and
- ** all content was stored in emphermal table pF->iOBTab. Extract that
- ** content now (in ORDER BY order) and make all calls to OP_AggStep
+ /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs
+ ** were stored in emphermal table pF->iOBTab. Here, we extract those
+ ** inputs (in ORDER BY order) and make all calls to OP_AggStep
** before doing the OP_AggFinal call. */
int iTop; /* Start of loop for extracting columns */
int nArg; /* Number of columns to extract */
int nKey; /* Key columns to be skipped */
int regAgg; /* Extract into this array */
int j; /* Loop counter */
-
+
+ assert( pF->pFunc!=0 );
nArg = pList->nExpr;
regAgg = sqlite3GetTempRange(pParse, nArg);
@@ -6720,6 +6725,15 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
for(j=nArg-1; j>=0; j--){
sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j);
}
+ if( pF->bUseSubtype ){
+ int regSubtype = sqlite3GetTempReg(pParse);
+ int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0);
+ for(j=nArg-1; j>=0; j--){
+ sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype);
+ sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j);
+ }
+ sqlite3ReleaseTempReg(pParse, regSubtype);
+ }
sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
@@ -6774,6 +6788,7 @@ static void updateAccumulator(
ExprList *pList;
assert( ExprUseXList(pF->pFExpr) );
assert( !IsWindowFunc(pF->pFExpr) );
+ assert( pF->pFunc!=0 );
pList = pF->pFExpr->x.pList;
if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
@@ -6818,6 +6833,9 @@ static void updateAccumulator(
if( pF->bOBPayload ){
regAggSz += nArg;
}
+ if( pF->bUseSubtype ){
+ regAggSz += nArg;
+ }
regAggSz++; /* One extra register to hold result of MakeRecord */
regAgg = sqlite3GetTempRange(pParse, regAggSz);
regDistinct = regAgg;
@@ -6830,6 +6848,14 @@ static void updateAccumulator(
if( pF->bOBPayload ){
regDistinct = regAgg+jj;
sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP);
+ jj += nArg;
+ }
+ if( pF->bUseSubtype ){
+ int kk;
+ int regBase = pF->bOBPayload ? regDistinct : regAgg;
+ for(kk=0; kk<nArg; kk++, jj++){
+ sqlite3VdbeAddOp2(v, OP_GetSubtype, regBase+kk, regAgg+jj);
+ }
}
}else if( pList ){
nArg = pList->nExpr;