diff options
Diffstat (limited to 'src/select.c')
-rw-r--r-- | src/select.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/src/select.c b/src/select.c index 98b64e52c..2280cf687 100644 --- a/src/select.c +++ b/src/select.c @@ -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.389 2008/01/05 18:48:24 drh Exp $ +** $Id: select.c,v 1.390 2008/01/06 00:25:22 drh Exp $ */ #include "sqliteInt.h" @@ -33,6 +33,16 @@ static void clearSelect(Select *p){ sqlite3ExprDelete(p->pOffset); } +/* +** Initialize a SelectDest structure. +*/ +void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ + pDest->eDest = eDest; + pDest->iParm = iParm; + pDest->affinity = 0; + pDest->iMem = 0; +} + /* ** Allocate a new Select structure and return a pointer to that @@ -542,8 +552,12 @@ static int selectInnerLoop( }else{ n = pEList->nExpr; } - iMem = pParse->nMem+1; - pParse->nMem += n; + if( pDest->iMem>0 ){ + iMem = pDest->iMem; + }else{ + pDest->iMem = iMem = pParse->nMem+1; + pParse->nMem += n; + } if( nColumn>0 ){ for(i=0; i<nColumn; i++){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i); @@ -679,7 +693,6 @@ static int selectInnerLoop( sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn); pushOntoSorter(pParse, pOrderBy, p); }else if( eDest==SRT_Subroutine ){ - for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_SCopy, iMem+i, 0); sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); }else{ sqlite3VdbeAddOp2(v, OP_ResultRow, iMem, nColumn); @@ -816,10 +829,10 @@ static void generateSortTail( int i; sqlite3CodeInsert(pParse, pseudoTab, 0); for(i=0; i<nColumn; i++){ - sqlite3VdbeAddOp2(v, OP_Column, pseudoTab, i); + sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); } if( eDest==SRT_Callback ){ - sqlite3VdbeAddOp2(v, OP_Callback, nColumn, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); }else{ sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); } @@ -1867,11 +1880,9 @@ static int multiSelect( ExprList *pOrderBy; /* The ORDER BY clause on p */ int aSetP2[2]; /* Set P2 value of these op to number of columns */ int nSetP2 = 0; /* Number of slots in aSetP2[] used */ + SelectDest dest; /* Alternative data destination */ - SelectDest dest; - dest.eDest = pDest->eDest; - dest.iParm = pDest->iParm; - dest.affinity = pDest->affinity; + dest = *pDest; /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. @@ -1988,8 +1999,7 @@ static int multiSelect( /* Code the SELECT statements to our left */ assert( !pPrior->pOrderBy ); - uniondest.eDest = priorOp; - uniondest.iParm = unionTab; + sqlite3SelectDestInit(&uniondest, priorOp, unionTab); rc = sqlite3Select(pParse, pPrior, &uniondest, 0, 0, 0, aff); if( rc ){ goto multi_select_end; @@ -2060,7 +2070,7 @@ static int multiSelect( int iCont, iBreak, iStart; Expr *pLimit, *pOffset; int addr; - SelectDest intersectdest = {SRT_Union, 0, 0}; + SelectDest intersectdest; /* INTERSECT is different from the others since it requires ** two temporary tables. Hence it has its own case. Begin @@ -2082,7 +2092,7 @@ static int multiSelect( /* Code the SELECTs to our left into temporary table "tab1". */ - intersectdest.iParm = tab1; + sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); rc = sqlite3Select(pParse, pPrior, &intersectdest, 0, 0, 0, aff); if( rc ){ goto multi_select_end; @@ -2256,6 +2266,7 @@ static int multiSelect( } multi_select_end: + pDest->iMem = dest.iMem; return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ @@ -3252,7 +3263,7 @@ int sqlite3Select( const char *zSavedAuthContext = 0; int needRestoreContext; struct SrcList_item *pItem = &pTabList->a[i]; - SelectDest dest = {SRT_EphemTab, 0, 0}; + SelectDest dest; if( pItem->pSelect==0 || pItem->isPopulated ) continue; if( pItem->zName!=0 ){ @@ -3272,7 +3283,7 @@ int sqlite3Select( */ pParse->nHeight += sqlite3SelectExprHeight(p); #endif - dest.iParm = pItem->iCursor; + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); sqlite3Select(pParse, pItem->pSelect, &dest, p, i, &isAgg, 0); if( db->mallocFailed ){ goto select_end; @@ -3647,8 +3658,8 @@ int sqlite3Select( if( pMinMax ){ pMinMax->a[0].sortOrder = ((flag==ORDERBY_MIN)?0:1); pMinMax->a[0].pExpr->op = TK_COLUMN; + pDel = pMinMax; } - pDel = pMinMax; } /* This case runs if the aggregate has no GROUP BY clause. The @@ -3658,7 +3669,7 @@ int sqlite3Select( resetAccumulator(pParse, &sAggInfo); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag); if( pWInfo==0 ){ - sqlite3ExprListDelete(pMinMax); + sqlite3ExprListDelete(pDel); goto select_end; } updateAccumulator(pParse, &sAggInfo); |