Minor code enhancements. (CVS 2642)

FossilOrigin-Name: 4ab994a87ee844f453d693555abd61b51bb44a0e
diff --git a/src/expr.c b/src/expr.c
index 10283ef..3d3655d 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 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 @@
     }
     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 @@
           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 @@
   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 33c5f24..bb8c06e 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 @@
   ** 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 @@
 
     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 8042ae0..b391eb3 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 @@
     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 sqliteFuncId(Token*);
 int sqlite3ExprResolveNames(NameContext *, Expr *);
 int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
+int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
 Vdbe *sqlite3GetVdbe(Parse*);
 void sqlite3Randomness(int, void*);
 void sqlite3RollbackAll(sqlite3*);