-C Remove\san\sunnecessary\stemporary\sregister\sallocation.
-D 2014-03-24T09:34:58.396
+C Avoid\sunnecessary\smoving\sof\scontent\sbetween\sregisters\sduring\san\sORDER\sBY.
+D 2014-03-24T18:08:15.960
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
-F src/select.c a088183774c4efae4105076355ac4010c62390a8
+F src/select.c 7f4a1ef9c9e893ee6da160441cd773c951f3d44e
F src/shell.c cee9f46f2688a261601b1fd3d7f4b3cddf9b5cdf
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P e6c59d23316c83b318b1a94d9b28a5d321737fa5
-R ab9aa4f9f7d5ea8c370ac77061403538
-U dan
-Z 631d6a70f4aeb5d6a455a81761c8aefd
+P 5d506743f541b022cde04a9606baa4680cdfd70b
+R edfc832bbac864fb9d0e2cb38ae7f098
+U drh
+Z a04be0daeb9646c039a07b2f019c65a9
SortCtx *pSort, /* Information about the ORDER BY clause */
Select *pSelect, /* The whole SELECT statement */
int regData, /* First register holding data to be sorted */
- int nData /* Number of elements in the data array */
+ int nData, /* Number of elements in the data array */
+ int nPrefixReg /* No. of reg prior to regData available for use */
){
Vdbe *v = pParse->pVdbe; /* Stmt under construction */
int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */
int nBase = nExpr + 1 + nData; /* Fields in sorter record */
- int regBase = sqlite3GetTempRange(pParse, nBase); /* Regs for sorter record */
+ int regBase; /* Regs for sorter record */
int regRecord = sqlite3GetTempReg(pParse); /* Assemblied sorter record */
int nOBSat = pSort->nOBSat; /* No. ORDER BY terms to skip */
int op; /* Opcode to add sorter record to sorter */
+ if( nPrefixReg ){
+ assert( nPrefixReg==nExpr+1 );
+ regBase = regData - nExpr - 1;
+ }else{
+ regBase = sqlite3GetTempRange(pParse, nBase);
+ }
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP);
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
- sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+1, nData);
+ if( nPrefixReg==0 ){
+ sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+1, nData);
+ }
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
if( nOBSat>0 ){
int regPrevKey; /* The first nOBSat columns of the previous row */
sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
if( nOBSat==0 ){
sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3ReleaseTempRange(pParse, regBase, nBase);
+ if( nPrefixReg==0 ){
+ sqlite3ReleaseTempRange(pParse, regBase, nBase);
+ }
}
if( pSelect->iLimit ){
int addr1, addr2;
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 */
assert( v );
assert( pEList!=0 );
nResultCol = pEList->nExpr;
if( pDest->iSdst==0 ){
+ if( pSort ){
+ nPrefixReg = pSort->pOrderBy->nExpr + 1;
+ pParse->nMem += nPrefixReg;
+ }
pDest->iSdst = pParse->nMem+1;
pParse->nMem += nResultCol;
}else if( pDest->iSdst+nResultCol > pParse->nMem ){
case SRT_DistFifo:
case SRT_Table:
case SRT_EphemTab: {
- int r1 = sqlite3GetTempReg(pParse);
+ int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
#ifndef SQLITE_OMIT_CTE
if( eDest==SRT_DistFifo ){
/* If the destination is DistFifo, then cursor (iParm+1) is open
}
#endif
if( pSort ){
- pushOntoSorter(pParse, pSort, p, r1, 1);
+ pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg);
}else{
int r2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3ReleaseTempReg(pParse, r2);
}
- sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1);
break;
}
** ORDER BY in this case since the order of entries in the set
** does not matter. But there might be a LIMIT clause, in which
** case the order does matter */
- pushOntoSorter(pParse, pSort, p, regResult, 1);
+ pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
case SRT_Mem: {
assert( nResultCol==1 );
if( pSort ){
- pushOntoSorter(pParse, pSort, p, regResult, 1);
+ pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
}else{
sqlite3ExprCodeMove(pParse, regResult, iParm, 1);
/* The LIMIT clause will jump out of the loop for us */
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pSort ){
- pushOntoSorter(pParse, pSort, p, regResult, nResultCol);
+ pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{