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:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Avoid\sstoring\sredundant\sfields\sin\ssorter\srecords\swhen\sthe\ssort-key\sand\sdata\shave\nfields\sin\scommon\s(as\sin\s"SELECT\sa\sFROM\st1\sORDER\sBY\s1").
|
C Reenable\sthe\sSQLITE_EXPR_REF\soptimization\sfor\s"SELECT\sDISTINCT\s...\sORDER\sBY"\nqueries.
|
||||||
D 2016-11-10T20:14:06.787
|
D 2016-11-11T18:08:59.063
|
||||||
F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678
|
F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408
|
F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408
|
||||||
@@ -387,7 +387,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
|
|||||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||||
F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b
|
F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b
|
||||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||||
F src/select.c 64b2273747c6485638bfeb6790e3e774e0605d02
|
F src/select.c 04fd717fb99aea2110b752e2b6186b966fa13cb4
|
||||||
F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3
|
F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3
|
||||||
F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027
|
F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
@@ -1530,10 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P b4889588246c33374ff3758e21ccc4ce246380b6
|
P 0af62fdbd8e2aab14718ff8bcb5934f05463c176
|
||||||
R e8a5368c67459f65dc206ad3df15a284
|
R dccdf5cb21f8816d64d778a9f6efd1e8
|
||||||
T *branch * sorter-opt
|
|
||||||
T *sym-sorter-opt *
|
|
||||||
T -sym-trunk *
|
|
||||||
U dan
|
U dan
|
||||||
Z 220ba0a8da96dcdf18555b62136e6fa1
|
Z 74767a1cb4eda88af63e605e54888e92
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0af62fdbd8e2aab14718ff8bcb5934f05463c176
|
6e2e9d383f5fc4a0cbf05fe83ec7425812c0f556
|
||||||
28
src/select.c
28
src/select.c
@@ -521,7 +521,7 @@ static void pushOntoSorter(
|
|||||||
int iLimit; /* LIMIT counter */
|
int iLimit; /* LIMIT counter */
|
||||||
|
|
||||||
assert( bSeq==0 || bSeq==1 );
|
assert( bSeq==0 || bSeq==1 );
|
||||||
assert( nData==1 || regData==regOrigData );
|
assert( nData==1 || regData==regOrigData || regOrigData==0 );
|
||||||
if( nPrefixReg ){
|
if( nPrefixReg ){
|
||||||
assert( nPrefixReg==nExpr+bSeq );
|
assert( nPrefixReg==nExpr+bSeq );
|
||||||
regBase = regData - nExpr - bSeq;
|
regBase = regData - nExpr - bSeq;
|
||||||
@@ -533,7 +533,7 @@ static void pushOntoSorter(
|
|||||||
iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
|
iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
|
||||||
pSort->labelDone = sqlite3VdbeMakeLabel(v);
|
pSort->labelDone = sqlite3VdbeMakeLabel(v);
|
||||||
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
|
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
|
||||||
SQLITE_ECEL_DUP);
|
SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
|
||||||
if( bSeq ){
|
if( bSeq ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
|
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
|
||||||
}
|
}
|
||||||
@@ -681,13 +681,20 @@ static void selectInnerLoop(
|
|||||||
){
|
){
|
||||||
Vdbe *v = pParse->pVdbe;
|
Vdbe *v = pParse->pVdbe;
|
||||||
int i;
|
int i;
|
||||||
int hasDistinct; /* True if the DISTINCT keyword is present */
|
int hasDistinct; /* True if the DISTINCT keyword is present */
|
||||||
int regResult; /* Start of memory holding result set */
|
|
||||||
int eDest = pDest->eDest; /* How to dispose of results */
|
int eDest = pDest->eDest; /* How to dispose of results */
|
||||||
int iParm = pDest->iSDParm; /* First argument to disposal method */
|
int iParm = pDest->iSDParm; /* First argument to disposal method */
|
||||||
int nResultCol; /* Number of result columns */
|
int nResultCol; /* Number of result columns */
|
||||||
int nPrefixReg = 0; /* Number of extra registers before regResult */
|
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( v );
|
||||||
assert( pEList!=0 );
|
assert( pEList!=0 );
|
||||||
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
|
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
|
||||||
@@ -718,7 +725,7 @@ static void selectInnerLoop(
|
|||||||
pParse->nMem += nResultCol;
|
pParse->nMem += nResultCol;
|
||||||
}
|
}
|
||||||
pDest->nSdst = nResultCol;
|
pDest->nSdst = nResultCol;
|
||||||
regResult = pDest->iSdst;
|
regOrig = regResult = pDest->iSdst;
|
||||||
if( srcTab>=0 ){
|
if( srcTab>=0 ){
|
||||||
for(i=0; i<nResultCol; i++){
|
for(i=0; i<nResultCol; i++){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
|
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
|
||||||
@@ -734,7 +741,8 @@ static void selectInnerLoop(
|
|||||||
}else{
|
}else{
|
||||||
ecelFlags = 0;
|
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
|
/* For each expression in pEList that is a copy of an expression in
|
||||||
** the ORDER BY clause (pSort->pOrderBy), set the associated
|
** the ORDER BY clause (pSort->pOrderBy), set the associated
|
||||||
** iOrderByCol value to one more than the index of the ORDER BY
|
** 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;
|
pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
regOrig = 0;
|
||||||
assert( eDest==SRT_Set || eDest==SRT_Mem
|
assert( eDest==SRT_Set || eDest==SRT_Mem
|
||||||
|| eDest==SRT_Coroutine || eDest==SRT_Output );
|
|| 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
|
** does not matter. But there might be a LIMIT clause, in which
|
||||||
** case the order does matter */
|
** case the order does matter */
|
||||||
pushOntoSorter(
|
pushOntoSorter(
|
||||||
pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg);
|
pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
|
||||||
}else{
|
}else{
|
||||||
int r1 = sqlite3GetTempReg(pParse);
|
int r1 = sqlite3GetTempReg(pParse);
|
||||||
assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
|
assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
|
||||||
@@ -921,7 +929,7 @@ static void selectInnerLoop(
|
|||||||
if( pSort ){
|
if( pSort ){
|
||||||
assert( nResultCol<=pDest->nSdst );
|
assert( nResultCol<=pDest->nSdst );
|
||||||
pushOntoSorter(
|
pushOntoSorter(
|
||||||
pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg);
|
pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
|
||||||
}else{
|
}else{
|
||||||
assert( nResultCol==pDest->nSdst );
|
assert( nResultCol==pDest->nSdst );
|
||||||
assert( regResult==iParm );
|
assert( regResult==iParm );
|
||||||
@@ -936,7 +944,7 @@ static void selectInnerLoop(
|
|||||||
testcase( eDest==SRT_Coroutine );
|
testcase( eDest==SRT_Coroutine );
|
||||||
testcase( eDest==SRT_Output );
|
testcase( eDest==SRT_Output );
|
||||||
if( pSort ){
|
if( pSort ){
|
||||||
pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol,
|
pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol,
|
||||||
nPrefixReg);
|
nPrefixReg);
|
||||||
}else if( eDest==SRT_Coroutine ){
|
}else if( eDest==SRT_Coroutine ){
|
||||||
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
|
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
|
||||||
|
|||||||
Reference in New Issue
Block a user