diff options
Diffstat (limited to 'src/select.c')
-rw-r--r-- | src/select.c | 62 |
1 files changed, 38 insertions, 24 deletions
diff --git a/src/select.c b/src/select.c index 943f0ef4e..286805e49 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.499 2009/02/09 13:19:28 drh Exp $ +** $Id: select.c,v 1.500 2009/02/19 14:39:25 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -987,8 +987,9 @@ static const char *columnType( ** statement. */ NameContext sNC; - Select *pS = pExpr->pSelect; + Select *pS = pExpr->x.pSelect; Expr *p = pS->pEList->a[0].pExpr; + assert( ExprHasProperty(pExpr, EP_xIsSelect) ); sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; @@ -2141,7 +2142,7 @@ static int multiSelectOrderBy( /* Reattach the ORDER BY clause to the query. */ p->pOrderBy = pOrderBy; - pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy); + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); /* Allocate a range of temporary registers and the KeyInfo needed ** for the logic that removes duplicate result rows when the @@ -2392,23 +2393,26 @@ static void substExpr( }else{ Expr *pNew; assert( pEList!=0 && pExpr->iColumn<pEList->nExpr ); - assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 ); + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); pNew = pEList->a[pExpr->iColumn].pExpr; assert( pNew!=0 ); pExpr->op = pNew->op; assert( pExpr->pLeft==0 ); - pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft); + pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft, 0); assert( pExpr->pRight==0 ); - pExpr->pRight = sqlite3ExprDup(db, pNew->pRight); - assert( pExpr->pList==0 ); - pExpr->pList = sqlite3ExprListDup(db, pNew->pList); + pExpr->pRight = sqlite3ExprDup(db, pNew->pRight, 0); pExpr->iTable = pNew->iTable; pExpr->pTab = pNew->pTab; pExpr->iColumn = pNew->iColumn; pExpr->iAgg = pNew->iAgg; sqlite3TokenCopy(db, &pExpr->token, &pNew->token); sqlite3TokenCopy(db, &pExpr->span, &pNew->span); - pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect); + assert( pExpr->x.pList==0 && pExpr->x.pSelect==0 ); + if( ExprHasProperty(pNew, EP_xIsSelect) ){ + pExpr->x.pSelect = sqlite3SelectDup(db, pNew->x.pSelect, 0); + }else{ + pExpr->x.pList = sqlite3ExprListDup(db, pNew->x.pList, 0); + } pExpr->flags = pNew->flags; pExpr->pAggInfo = pNew->pAggInfo; pNew->pAggInfo = 0; @@ -2416,8 +2420,11 @@ static void substExpr( }else{ substExpr(db, pExpr->pLeft, iTable, pEList); substExpr(db, pExpr->pRight, iTable, pEList); - substSelect(db, pExpr->pSelect, iTable, pEList); - substExprList(db, pExpr->pList, iTable, pEList); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + substSelect(db, pExpr->x.pSelect, iTable, pEList); + }else{ + substExprList(db, pExpr->x.pList, iTable, pEList); + } } } static void substExprList( @@ -2729,7 +2736,7 @@ static int flattenSubquery( p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; - pNew = sqlite3SelectDup(db, p); + pNew = sqlite3SelectDup(db, p, 0); p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->pSrc = pSrc; @@ -2873,7 +2880,7 @@ static int flattenSubquery( substExprList(db, pParent->pOrderBy, iParent, pSub->pEList); } if( pSub->pWhere ){ - pWhere = sqlite3ExprDup(db, pSub->pWhere); + pWhere = sqlite3ExprDup(db, pSub->pWhere, 0); }else{ pWhere = 0; } @@ -2883,9 +2890,9 @@ static int flattenSubquery( pParent->pWhere = pWhere; substExpr(db, pParent->pHaving, iParent, pSub->pEList); pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, - sqlite3ExprDup(db, pSub->pHaving)); + sqlite3ExprDup(db, pSub->pHaving, 0)); assert( pParent->pGroupBy==0 ); - pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy); + pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); }else{ substExpr(db, pParent->pWhere, iParent, pSub->pEList); pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere); @@ -2934,7 +2941,8 @@ static u8 minMaxQuery(Select *p){ if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL; pExpr = pEList->a[0].pExpr; - pEList = pExpr->pList; + if( ExprHasProperty(pExpr, EP_xIsSelect) ) return 0; + pEList = pExpr->x.pList; if( pExpr->op!=TK_AGG_FUNCTION || pEList==0 || pEList->nExpr!=1 ) return 0; if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL; if( pExpr->token.n!=3 ) return WHERE_ORDERBY_NORMAL; @@ -3065,7 +3073,7 @@ static int selectExpander(Walker *pWalker, Select *p){ ** in the inner view. */ if( pFrom->pSelect==0 ){ - pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect); + pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); sqlite3WalkSelect(pWalker, pFrom->pSelect); } } @@ -3364,12 +3372,13 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem); if( pFunc->iDistinct>=0 ){ Expr *pE = pFunc->pExpr; - if( pE->pList==0 || pE->pList->nExpr!=1 ){ + assert( !ExprHasProperty(pE, EP_xIsSelect) ); + if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " "argument"); pFunc->iDistinct = -1; }else{ - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList); + KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList); sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); } @@ -3386,7 +3395,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ int i; struct AggInfo_func *pF; for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ - ExprList *pList = pF->pExpr->pList; + ExprList *pList = pF->pExpr->x.pList; + assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0, (void*)pF->pFunc, P4_FUNCDEF); } @@ -3407,7 +3417,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ int nArg; int addrNext = 0; int regAgg; - ExprList *pList = pF->pExpr->pList; + ExprList *pList = pF->pExpr->x.pList; + assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); @@ -3657,7 +3668,7 @@ int sqlite3Select( ** GROUP BY might use an index, DISTINCT never does. */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && !p->pGroupBy ){ - p->pGroupBy = sqlite3ExprListDup(db, p->pEList); + p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); pGroupBy = p->pGroupBy; p->selFlags &= ~SF_Distinct; isDistinct = 0; @@ -3780,7 +3791,8 @@ int sqlite3Select( } sAggInfo.nAccumulator = sAggInfo.nColumn; for(i=0; i<sAggInfo.nFunc; i++){ - sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList); + assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) ); + sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList); } if( db->mallocFailed ) goto select_end; @@ -4018,7 +4030,9 @@ int sqlite3Select( */ flag = minMaxQuery(p); if( flag ){ - pDel = pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->pList); + assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) ); + pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0); + pDel = pMinMax; if( pMinMax && !db->mallocFailed ){ pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; pMinMax->a[0].pExpr->op = TK_COLUMN; |