mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Use OP_SorterOpen instead of OP_OpenEphemeral to implement GROUP BY.
FossilOrigin-Name: ebf819aaa555bd79fddfc0a6f9827a2539095d6c
This commit is contained in:
21
src/select.c
21
src/select.c
@@ -4033,6 +4033,8 @@ int sqlite3Select(
|
||||
int iAbortFlag; /* Mem address which causes query abort if positive */
|
||||
int groupBySort; /* Rows come from source in GROUP BY order */
|
||||
int addrEnd; /* End of processing for this SELECT */
|
||||
int sortPTab = 0; /* Pseudotable used to decode sorting results */
|
||||
int sortOut = 0; /* Output register from the sorter */
|
||||
|
||||
/* Remove any and all aliases between the result set and the
|
||||
** GROUP BY clause.
|
||||
@@ -4094,12 +4096,12 @@ int sqlite3Select(
|
||||
|
||||
/* If there is a GROUP BY clause we might need a sorting index to
|
||||
** implement it. Allocate that sorting index now. If it turns out
|
||||
** that we do not need it after all, the OpenEphemeral instruction
|
||||
** that we do not need it after all, the OP_SorterOpen instruction
|
||||
** will be converted into a Noop.
|
||||
*/
|
||||
sAggInfo.sortingIdx = pParse->nTab++;
|
||||
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
|
||||
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
|
||||
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
|
||||
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
|
||||
0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||
|
||||
@@ -4180,11 +4182,14 @@ int sqlite3Select(
|
||||
}
|
||||
regRecord = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
|
||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord);
|
||||
sqlite3ReleaseTempReg(pParse, regRecord);
|
||||
sqlite3ReleaseTempRange(pParse, regBase, nCol);
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
|
||||
sortPTab = pParse->nTab++;
|
||||
sortOut = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
|
||||
VdbeComment((v, "GROUP BY sort"));
|
||||
sAggInfo.useSortingIdx = 1;
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
@@ -4197,9 +4202,13 @@ int sqlite3Select(
|
||||
*/
|
||||
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
if( groupBySort ){
|
||||
sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
|
||||
}
|
||||
for(j=0; j<pGroupBy->nExpr; j++){
|
||||
if( groupBySort ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, sAggInfo.sortingIdx, j, iBMem+j);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
|
||||
if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
|
||||
}else{
|
||||
sAggInfo.directMode = 1;
|
||||
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
|
||||
@@ -4238,7 +4247,7 @@ int sqlite3Select(
|
||||
/* End of the loop
|
||||
*/
|
||||
if( groupBySort ){
|
||||
sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
|
||||
sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
|
||||
}else{
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1);
|
||||
|
||||
Reference in New Issue
Block a user