1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Avoid duplicate OP_Column opcodes by remembering prior results.

This is similar to CSE, but only applies to columns. (CVS 4943)

FossilOrigin-Name: c29ee0fed23dcdbd9dde6b1e42b603100ea2389c
This commit is contained in:
drh
2008-03-31 23:48:03 +00:00
parent 678ccce8b3
commit e55cbd7228
9 changed files with 209 additions and 47 deletions

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.423 2008/03/31 17:41:18 danielk1977 Exp $
** $Id: select.c,v 1.424 2008/03/31 23:48:05 drh Exp $
*/
#include "sqliteInt.h"
@@ -241,7 +241,6 @@ Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){
return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy);
}
/*
** Add a term to the WHERE expression in *ppExpr that requires the
** zCol column to be equal in the two tables pTab1 and pTab2.
@@ -425,7 +424,7 @@ static void pushOntoSorter(
int regRecord = sqlite3GetTempReg(pParse);
sqlite3ExprCodeExprList(pParse, pOrderBy, regBase);
sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
sqlite3VdbeAddOp2(v, OP_Move, regData, regBase+nExpr+1);
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -670,6 +669,7 @@ static void selectInnerLoop(
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
sqlite3ExprExpireColumnCacheLines(pParse, regResult, regResult);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
}
@@ -694,7 +694,7 @@ static void selectInnerLoop(
if( pOrderBy ){
pushOntoSorter(pParse, pOrderBy, p, regResult);
}else{
sqlite3VdbeAddOp2(v, OP_Move, regResult, iParm);
sqlite3ExprCodeMove(pParse, regResult, iParm);
/* The LIMIT clause will jump out of the loop for us */
}
break;
@@ -716,6 +716,7 @@ static void selectInnerLoop(
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
}else{
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
sqlite3ExprExpireColumnCacheLines(pParse,regResult,regResult+nColumn-1);
}
break;
}
@@ -834,13 +835,14 @@ static void generateSortTail(
assert( nColumn==1 );
j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regRow);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
sqlite3ExprExpireColumnCacheLines(pParse, regRow, regRow);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
sqlite3VdbeJumpHere(v, j1);
break;
}
case SRT_Mem: {
assert( nColumn==1 );
sqlite3VdbeAddOp2(v, OP_Move, regRow, iParm);
sqlite3ExprCodeMove(pParse, regRow, iParm);
/* The LIMIT clause will terminate the loop for us */
break;
}
@@ -856,6 +858,8 @@ static void generateSortTail(
}
if( eDest==SRT_Callback ){
sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
sqlite3ExprExpireColumnCacheLines(pParse, pDest->iMem,
pDest->iMem+nColumn-1);
}else{
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
}
@@ -2926,6 +2930,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
(void*)pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, nArg);
sqlite3ReleaseTempRange(pParse, regAgg, nArg);
sqlite3ExprExpireColumnCacheLines(pParse, regAgg, regAgg+nArg-1);
if( addrNext ){
sqlite3VdbeResolveLabel(v, addrNext);
}
@@ -3434,8 +3439,12 @@ int sqlite3Select(
for(i=0; i<sAggInfo.nColumn; i++){
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
if( pCol->iSorterColumn>=j ){
sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable,
j + regBase);
int r1 = j + regBase;
int r2 = sqlite3ExprCodeGetColumn(pParse,
pCol->pTab, pCol->iColumn, pCol->iTable, r1);
if( r1!=r2 ){
sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
}
j++;
}
}
@@ -3485,7 +3494,7 @@ int sqlite3Select(
*/
sqlite3VdbeResolveLabel(v, addrGroupByChange);
for(j=0; j<pGroupBy->nExpr; j++){
sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j);
sqlite3ExprCodeMove(pParse, iBMem+j, iAMem+j);
}
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
VdbeComment((v, "output one row"));