diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 53 | ||||
-rw-r--r-- | src/select.c | 32 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 |
3 files changed, 51 insertions, 38 deletions
diff --git a/src/expr.c b/src/expr.c index 10283ef2e..3d3655d7e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.221 2005/08/25 12:45:04 drh Exp $ +** $Id: expr.c,v 1.222 2005/08/30 00:54:02 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -2071,28 +2071,30 @@ static int appendAggInfo(Parse *pParse){ */ static int analyzeAggregate(void *pArg, Expr *pExpr){ int i; - AggExpr *aAgg; + AggExpr *pAgg; NameContext *pNC = (NameContext *)pArg; Parse *pParse = pNC->pParse; SrcList *pSrcList = pNC->pSrcList; + Expr *pAggExpr; switch( pExpr->op ){ case TK_COLUMN: { for(i=0; pSrcList && i<pSrcList->nSrc; i++){ if( pExpr->iTable==pSrcList->a[i].iCursor ){ - aAgg = pParse->aAgg; - for(i=0; i<pParse->nAgg; i++){ - if( aAgg[i].isAgg ) continue; - if( aAgg[i].pExpr->iTable==pExpr->iTable - && aAgg[i].pExpr->iColumn==pExpr->iColumn ){ + pAgg = pParse->aAgg; + for(i=0; i<pParse->nAgg; i++, pAgg++){ + if( pAgg->isAgg ) continue; + if( (pAggExpr = pAgg->pExpr)->iTable==pExpr->iTable + && pAggExpr->iColumn==pExpr->iColumn ){ break; } } if( i>=pParse->nAgg ){ i = appendAggInfo(pParse); if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 0; - pParse->aAgg[i].pExpr = pExpr; + pAgg = &pParse->aAgg[i]; + pAgg->isAgg = 0; + pAgg->pExpr = pExpr; } pExpr->iAgg = i; pExpr->iAggCtx = pNC->nDepth; @@ -2103,10 +2105,10 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){ } case TK_AGG_FUNCTION: { if( pNC->nDepth==0 ){ - aAgg = pParse->aAgg; - for(i=0; i<pParse->nAgg; i++){ - if( !aAgg[i].isAgg ) continue; - if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){ + pAgg = pParse->aAgg; + for(i=0; i<pParse->nAgg; i++, pAgg++){ + if( !pAgg->isAgg ) continue; + if( sqlite3ExprCompare(pAgg->pExpr, pExpr) ){ break; } } @@ -2114,9 +2116,10 @@ static int analyzeAggregate(void *pArg, Expr *pExpr){ u8 enc = pParse->db->enc; i = appendAggInfo(pParse); if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 1; - pParse->aAgg[i].pExpr = pExpr; - pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db, + pAgg = &pParse->aAgg[i]; + pAgg->isAgg = 1; + pAgg->pExpr = pExpr; + pAgg->pFunc = sqlite3FindFunction(pParse->db, pExpr->token.z, pExpr->token.n, pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); } @@ -2149,3 +2152,21 @@ int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ walkExprTree(pExpr, analyzeAggregate, pNC); return pNC->pParse->nErr - nErr; } + +/* +** Call sqlite3ExprAnalyzeAggregates() for every expression in an +** expression list. Return the number of errors. +** +** If an error is found, the analysis is cut short. +*/ +int sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ + struct ExprList_item *pItem; + int i; + int nErr = 0; + if( pList ){ + for(pItem=pList->a, i=0; nErr==0 && i<pList->nExpr; i++, pItem++){ + nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); + } + } + return nErr; +} diff --git a/src/select.c b/src/select.c index 33c5f2449..bb8c06e86 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.255 2005/08/28 01:34:22 drh Exp $ +** $Id: select.c,v 1.256 2005/08/30 00:54:03 drh Exp $ */ #include "sqliteInt.h" @@ -2632,10 +2632,10 @@ int sqlite3Select( ** names that have been explicitly specified. */ if( pOrderBy ){ - for(i=0; i<pOrderBy->nExpr; i++){ - if( pOrderBy->a[i].zName ){ - pOrderBy->a[i].pExpr->pColl = - sqlite3LocateCollSeq(pParse, pOrderBy->a[i].zName, -1); + struct ExprList_item *pTerm; + for(i=0, pTerm=pOrderBy->a; i<pOrderBy->nExpr; i++, pTerm++){ + if( pTerm->zName ){ + pTerm->pExpr->pColl = sqlite3LocateCollSeq(pParse, pTerm->zName, -1); } } if( pParse->nErr ){ @@ -2664,27 +2664,17 @@ int sqlite3Select( assert( pParse->nAgg==0 ); isAgg = 1; - for(i=0; i<pEList->nExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(&sNC, pEList->a[i].pExpr) ){ - goto select_end; - } + if( sqlite3ExprAnalyzeAggList(&sNC, pEList) ){ + goto select_end; } - if( pGroupBy ){ - for(i=0; i<pGroupBy->nExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(&sNC, pGroupBy->a[i].pExpr) ){ - goto select_end; - } - } + if( sqlite3ExprAnalyzeAggList(&sNC, pGroupBy) ){ + goto select_end; } if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){ goto select_end; } - if( pOrderBy ){ - for(i=0; i<pOrderBy->nExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(&sNC, pOrderBy->a[i].pExpr) ){ - goto select_end; - } - } + if( sqlite3ExprAnalyzeAggList(&sNC, pOrderBy) ){ + goto select_end; } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8042ae047..b391eb3bf 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.405 2005/08/29 23:00:04 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.406 2005/08/30 00:54:03 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -892,6 +892,7 @@ struct ExprList { u8 sortOrder; /* 1 for DESC or 0 for ASC */ u8 isAgg; /* True if this is an aggregate like count(*) */ u8 done; /* A flag to indicate when processing is finished */ + u8 orderByDup[2]; /* Corresponding term in OrderBy/GroupBy clause */ } *a; /* One entry for each expression */ }; @@ -1452,6 +1453,7 @@ int sqlite3ExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); int sqlite3ExprResolveNames(NameContext *, Expr *); int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); +int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*); void sqlite3Randomness(int, void*); void sqlite3RollbackAll(sqlite3*); |