mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Reenable the SQLITE_EXPR_REF optimization for "SELECT DISTINCT ... ORDER BY"
queries. FossilOrigin-Name: 6e2e9d383f5fc4a0cbf05fe83ec7425812c0f556
This commit is contained in:
28
src/select.c
28
src/select.c
@@ -521,7 +521,7 @@ static void pushOntoSorter(
|
||||
int iLimit; /* LIMIT counter */
|
||||
|
||||
assert( bSeq==0 || bSeq==1 );
|
||||
assert( nData==1 || regData==regOrigData );
|
||||
assert( nData==1 || regData==regOrigData || regOrigData==0 );
|
||||
if( nPrefixReg ){
|
||||
assert( nPrefixReg==nExpr+bSeq );
|
||||
regBase = regData - nExpr - bSeq;
|
||||
@@ -533,7 +533,7 @@ static void pushOntoSorter(
|
||||
iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
|
||||
pSort->labelDone = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
|
||||
SQLITE_ECEL_DUP);
|
||||
SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
|
||||
if( bSeq ){
|
||||
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
|
||||
}
|
||||
@@ -681,13 +681,20 @@ static void selectInnerLoop(
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
int hasDistinct; /* True if the DISTINCT keyword is present */
|
||||
int regResult; /* Start of memory holding result set */
|
||||
int hasDistinct; /* True if the DISTINCT keyword is present */
|
||||
int eDest = pDest->eDest; /* How to dispose of results */
|
||||
int iParm = pDest->iSDParm; /* First argument to disposal method */
|
||||
int nResultCol; /* Number of result columns */
|
||||
int nPrefixReg = 0; /* Number of extra registers before regResult */
|
||||
|
||||
/* Usually, regResult is the first cell in an array of memory cells
|
||||
** containing the current result row. In this case regOrig is set to the
|
||||
** same value. However, if the results are being sent to the sorter, the
|
||||
** values for any expressions that are also part of the sort-key are omitted
|
||||
** from this array. In this case regOrig is set to zero. */
|
||||
int regResult; /* Start of memory holding current results */
|
||||
int regOrig; /* Start of memory holding full result (or 0) */
|
||||
|
||||
assert( v );
|
||||
assert( pEList!=0 );
|
||||
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
|
||||
@@ -718,7 +725,7 @@ static void selectInnerLoop(
|
||||
pParse->nMem += nResultCol;
|
||||
}
|
||||
pDest->nSdst = nResultCol;
|
||||
regResult = pDest->iSdst;
|
||||
regOrig = regResult = pDest->iSdst;
|
||||
if( srcTab>=0 ){
|
||||
for(i=0; i<nResultCol; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
|
||||
@@ -734,7 +741,8 @@ static void selectInnerLoop(
|
||||
}else{
|
||||
ecelFlags = 0;
|
||||
}
|
||||
if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
|
||||
assert( eDest!=SRT_Table || pSort==0 );
|
||||
if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab ){
|
||||
/* For each expression in pEList that is a copy of an expression in
|
||||
** the ORDER BY clause (pSort->pOrderBy), set the associated
|
||||
** iOrderByCol value to one more than the index of the ORDER BY
|
||||
@@ -748,7 +756,7 @@ static void selectInnerLoop(
|
||||
pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
|
||||
}
|
||||
}
|
||||
|
||||
regOrig = 0;
|
||||
assert( eDest==SRT_Set || eDest==SRT_Mem
|
||||
|| eDest==SRT_Coroutine || eDest==SRT_Output );
|
||||
}
|
||||
@@ -892,7 +900,7 @@ static void selectInnerLoop(
|
||||
** does not matter. But there might be a LIMIT clause, in which
|
||||
** case the order does matter */
|
||||
pushOntoSorter(
|
||||
pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg);
|
||||
pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
|
||||
}else{
|
||||
int r1 = sqlite3GetTempReg(pParse);
|
||||
assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
|
||||
@@ -921,7 +929,7 @@ static void selectInnerLoop(
|
||||
if( pSort ){
|
||||
assert( nResultCol<=pDest->nSdst );
|
||||
pushOntoSorter(
|
||||
pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg);
|
||||
pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
|
||||
}else{
|
||||
assert( nResultCol==pDest->nSdst );
|
||||
assert( regResult==iParm );
|
||||
@@ -936,7 +944,7 @@ static void selectInnerLoop(
|
||||
testcase( eDest==SRT_Coroutine );
|
||||
testcase( eDest==SRT_Output );
|
||||
if( pSort ){
|
||||
pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol,
|
||||
pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol,
|
||||
nPrefixReg);
|
||||
}else if( eDest==SRT_Coroutine ){
|
||||
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
|
||||
|
||||
Reference in New Issue
Block a user