aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.c6
-rw-r--r--src/select.c14
-rw-r--r--src/sqliteInt.h1
3 files changed, 17 insertions, 4 deletions
diff --git a/src/expr.c b/src/expr.c
index 7cd50e660..4bab38363 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -4243,7 +4243,7 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
** register iReg. The caller must ensure that iReg already contains
** the correct value for the expression.
*/
-static void exprToRegister(Expr *pExpr, int iReg){
+void sqlite3ExprToRegister(Expr *pExpr, int iReg){
Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
if( NEVER(p==0) ) return;
p->op2 = p->op;
@@ -5252,7 +5252,7 @@ expr_code_doover:
break;
}
testcase( pX->op==TK_COLUMN );
- exprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1));
+ sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1));
testcase( regFree1==0 );
memset(&opCompare, 0, sizeof(opCompare));
opCompare.op = TK_EQ;
@@ -5602,7 +5602,7 @@ static void exprCodeBetween(
compRight.op = TK_LE;
compRight.pLeft = pDel;
compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1));
+ sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1));
if( xJump ){
xJump(pParse, &exprAnd, dest, jumpIfNull);
}else{
diff --git a/src/select.c b/src/select.c
index 9278ea18b..9ff5c6c53 100644
--- a/src/select.c
+++ b/src/select.c
@@ -7847,12 +7847,18 @@ int sqlite3Select(
*/
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
&& sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
+ && OptimizationEnabled(db, SQLITE_GroupByOrder)
#ifndef SQLITE_OMIT_WINDOWFUNC
&& p->pWin==0
#endif
){
p->selFlags &= ~SF_Distinct;
pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0);
+ if( pGroupBy ){
+ for(i=0; i<pGroupBy->nExpr; i++){
+ pGroupBy->a[i].u.x.iOrderByCol = i+1;
+ }
+ }
p->selFlags |= SF_Aggregate;
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
** the sDistinct.isTnct is still set. Hence, isTnct represents the
@@ -8315,12 +8321,18 @@ int sqlite3Select(
sortOut, sortPTab);
}
for(j=0; j<pGroupBy->nExpr; j++){
+ int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol;
+
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
}else{
pAggInfo->directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
+
+ if( iOrderByCol ){
+ sqlite3ExprToRegister(p->pEList->a[iOrderByCol-1].pExpr, iAMem+j);
+ }
}
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
@@ -8336,9 +8348,9 @@ int sqlite3Select(
** and resets the aggregate accumulator registers in preparation
** for the next GROUP BY batch.
*/
- sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output one row"));
+ sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
VdbeComment((v, "check abort flag"));
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index d98a4f7f0..f4f8fc5e4 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -5025,6 +5025,7 @@ void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
void sqlite3ExprCodeMove(Parse*, int, int, int);
+void sqlite3ExprToRegister(Expr *pExpr, int iReg);
void sqlite3ExprCode(Parse*, Expr*, int);
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int);