mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Avoid storing redundant fields in sorter records when the sort-key and data have
fields in common (as in "SELECT a FROM t1 ORDER BY 1"). FossilOrigin-Name: 0af62fdbd8e2aab14718ff8bcb5934f05463c176
This commit is contained in:
42
src/select.c
42
src/select.c
@@ -533,11 +533,11 @@ 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_REF);
|
||||
SQLITE_ECEL_DUP);
|
||||
if( bSeq ){
|
||||
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
|
||||
}
|
||||
if( nPrefixReg==0 ){
|
||||
if( nPrefixReg==0 && nData>0 ){
|
||||
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
|
||||
@@ -666,7 +666,7 @@ static void codeDistinct(
|
||||
** If srcTab is negative, then the pEList expressions
|
||||
** are evaluated in order to get the data for this row. If srcTab is
|
||||
** zero or more, then data is pulled from srcTab and pEList is used only
|
||||
** to get number columns and the datatype for each column.
|
||||
** to get the number of columns and the collation sequence for each column.
|
||||
*/
|
||||
static void selectInnerLoop(
|
||||
Parse *pParse, /* The parser context */
|
||||
@@ -734,7 +734,25 @@ static void selectInnerLoop(
|
||||
}else{
|
||||
ecelFlags = 0;
|
||||
}
|
||||
sqlite3ExprCodeExprList(pParse, pEList, regResult, 0, ecelFlags);
|
||||
if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
|
||||
/* 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
|
||||
** expression within the sort-key that pushOntoSorter() will generate.
|
||||
** This allows the pEList field to be omitted from the sorted record,
|
||||
** saving space and CPU cycles. */
|
||||
ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
|
||||
for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
|
||||
int j;
|
||||
if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
|
||||
pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
|
||||
}
|
||||
}
|
||||
|
||||
assert( eDest==SRT_Set || eDest==SRT_Mem
|
||||
|| eDest==SRT_Coroutine || eDest==SRT_Output );
|
||||
}
|
||||
nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags);
|
||||
}
|
||||
|
||||
/* If the DISTINCT keyword was present on the SELECT statement
|
||||
@@ -900,11 +918,12 @@ static void selectInnerLoop(
|
||||
** memory cells and break out of the scan loop.
|
||||
*/
|
||||
case SRT_Mem: {
|
||||
assert( nResultCol==pDest->nSdst );
|
||||
if( pSort ){
|
||||
assert( nResultCol<=pDest->nSdst );
|
||||
pushOntoSorter(
|
||||
pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg);
|
||||
}else{
|
||||
assert( nResultCol==pDest->nSdst );
|
||||
assert( regResult==iParm );
|
||||
/* The LIMIT clause will jump out of the loop for us */
|
||||
}
|
||||
@@ -1202,14 +1221,13 @@ static void generateSortTail(
|
||||
int iParm = pDest->iSDParm;
|
||||
int regRow;
|
||||
int regRowid;
|
||||
int iCol;
|
||||
int nKey;
|
||||
int iSortTab; /* Sorter cursor to read from */
|
||||
int nSortData; /* Trailing values to read from sorter */
|
||||
int i;
|
||||
int bSeq; /* True if sorter record includes seq. no. */
|
||||
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
struct ExprList_item *aOutEx = p->pEList->a;
|
||||
#endif
|
||||
|
||||
assert( addrBreak<0 );
|
||||
if( pSort->labelBkOut ){
|
||||
@@ -1247,8 +1265,14 @@ static void generateSortTail(
|
||||
iSortTab = iTab;
|
||||
bSeq = 1;
|
||||
}
|
||||
for(i=0; i<nSortData; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
|
||||
for(i=0, iCol=nKey+bSeq; i<nSortData; i++){
|
||||
int iRead;
|
||||
if( aOutEx[i].u.x.iOrderByCol ){
|
||||
iRead = aOutEx[i].u.x.iOrderByCol-1;
|
||||
}else{
|
||||
iRead = iCol++;
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
|
||||
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
|
||||
}
|
||||
switch( eDest ){
|
||||
|
||||
Reference in New Issue
Block a user