]> granicus.if.org Git - postgresql/commitdiff
Remove Query->qry_aggs and qry_numaggs and replace with Query->hasAggs.
authorBruce Momjian <bruce@momjian.us>
Thu, 15 Jan 1998 19:00:16 +0000 (19:00 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 15 Jan 1998 19:00:16 +0000 (19:00 +0000)
Pass List* of Aggregs into executor, and create needed array there.
No longer need to double-processs Aggregs with second copy in Query.

Fix crash when doing:

select sum(x+1) from test where 1 > 0;

20 files changed:
src/backend/executor/nodeAgg.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/list.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/planmain.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/prep/prepunion.c
src/backend/parser/analyze.c
src/backend/parser/parse_agg.c
src/backend/parser/parse_func.c
src/backend/parser/parse_node.c
src/backend/rewrite/locks.c
src/backend/rewrite/rewriteManip.c
src/include/nodes/parsenodes.h
src/include/nodes/plannodes.h
src/include/optimizer/planmain.h
src/include/parser/parse_node.h

index e268bf3423f9571e0271b9865894e5758c132b8f..62970db8c7bdaa75671cb1515ba329f0ae22c749 100644 (file)
@@ -105,6 +105,7 @@ ExecAgg(Agg *node)
        ProjectionInfo *projInfo;
        TupleTableSlot *resultSlot;
        HeapTuple       oneTuple;
+       List       *alist;
        char       *nulls;
        bool            isDone;
        bool            isNull = FALSE,
@@ -121,8 +122,17 @@ ExecAgg(Agg *node)
 
        estate = node->plan.state;
        econtext = aggstate->csstate.cstate.cs_ExprContext;
-       aggregates = node->aggs;
-       nagg = node->numAgg;
+       nagg = length(node->aggs);
+
+       aggregates = (Aggreg **)palloc(sizeof(Aggreg *) * nagg);
+
+       /* take List* and make it an array that can be quickly indexed */
+       alist = node->aggs;
+       for (i = 0; i < nagg; i++)
+       {
+               aggregates[i] = lfirst(alist);
+               alist = lnext(alist);
+       }
 
        value1 = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_values;
        nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls;
@@ -540,10 +550,10 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
 
        econtext = aggstate->csstate.cstate.cs_ExprContext;
        econtext->ecxt_values =
-               (Datum *) palloc(sizeof(Datum) * node->numAgg);
-       MemSet(econtext->ecxt_values, 0, sizeof(Datum) * node->numAgg);
-       econtext->ecxt_nulls = (char *) palloc(node->numAgg);
-       MemSet(econtext->ecxt_nulls, 0, node->numAgg);
+               (Datum *) palloc(sizeof(Datum) * length(node->aggs));
+       MemSet(econtext->ecxt_values, 0, sizeof(Datum) * length(node->aggs));
+       econtext->ecxt_nulls = (char *) palloc(length(node->aggs));
+       MemSet(econtext->ecxt_nulls, 0, length(node->aggs));
 
        /*
         * initializes child nodes
index 28dc982abbf3ec0ea59041efc7681c5a358c13bb..e0ccc63f3504c8dd4ea257d9816b2671f3f7d3ae 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.29 1998/01/11 20:01:53 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.30 1998/01/15 18:59:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -493,15 +493,10 @@ static Agg *
 _copyAgg(Agg *from)
 {
        Agg                *newnode = makeNode(Agg);
-       int                     i;
 
        CopyPlanFields((Plan *) from, (Plan *) newnode);
 
-       newnode->numAgg = from->numAgg;
-    newnode->aggs = palloc(sizeof(Aggreg *));
-       for (i = 0; i < from->numAgg; i++)
-               newnode->aggs[i] = copyObject(from->aggs[i]);
-
+       Node_Copy(from, newnode, aggs);
        Node_Copy(from, newnode, aggstate);
 
        return newnode;
@@ -1495,7 +1490,6 @@ static Query *
 _copyQuery(Query *from)
 {
        Query      *newnode = makeNode(Query);
-       int i;
        
        newnode->commandType = from->commandType;
        if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
@@ -1522,14 +1516,7 @@ _copyQuery(Query *from)
        Node_Copy(from, newnode, groupClause);
        Node_Copy(from, newnode, havingQual);
 
-       newnode->qry_numAgg = from->qry_numAgg;
-       if (from->qry_numAgg > 0)
-       {
-               newnode->qry_aggs =
-                       (Aggreg **) palloc(sizeof(Aggreg *) * from->qry_numAgg);
-               for (i=0; i < from->qry_numAgg; i++)
-                       newnode->qry_aggs[i] = _copyAggreg(from->qry_aggs[i]);
-       }
+       newnode->hasAggs = from->hasAggs;
 
        if (from->unionClause)
        {
index e68c10284697ca77af8f17d07c4f7fa60583972b..6a7b7e12be6d907e5517e5c2214490c70e7adf33 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.10 1998/01/07 21:03:29 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.11 1998/01/15 18:59:23 momjian Exp $
  *
  * NOTES
  *       XXX a few of the following functions are duplicated to handle
@@ -89,6 +89,48 @@ lappendi(List *list, int datum)
        return nconc(list, lconsi(datum, NIL));
 }
 
+List      *
+nconc(List *l1, List *l2)
+{
+       List       *temp;
+
+       if (l1 == NIL)
+               return l2;
+       if (l2 == NIL)
+               return l1;
+       if (l1 == l2)
+               elog(ERROR, "tryout to nconc a list to itself");
+
+       for (temp = l1; lnext(temp) != NULL; temp = lnext(temp))
+               ;
+
+       lnext(temp) = l2;
+       return (l1);                            /* list1 is now list1[]list2  */
+}
+
+
+List      *
+nreverse(List *list)
+{
+       List       *rlist = NIL;
+       List       *p = NIL;
+
+       if (list == NULL)
+               return (NIL);
+
+       if (length(list) == 1)
+               return (list);
+
+       for (p = list; p != NULL; p = lnext(p))
+       {
+               rlist = lcons(lfirst(p), rlist);
+       }
+
+       lfirst(list) = lfirst(rlist);
+       lnext(list) = lnext(rlist);
+       return (list);
+}
+
 Value     *
 makeInteger(long i)
 {
@@ -227,48 +269,6 @@ intAppend(List *l1, List *l2)
        return newlist;
 }
 
-List      *
-nconc(List *l1, List *l2)
-{
-       List       *temp;
-
-       if (l1 == NIL)
-               return l2;
-       if (l2 == NIL)
-               return l1;
-       if (l1 == l2)
-               elog(ERROR, "tryout to nconc a list to itself");
-
-       for (temp = l1; lnext(temp) != NULL; temp = lnext(temp))
-               ;
-
-       lnext(temp) = l2;
-       return (l1);                            /* list1 is now list1[]list2  */
-}
-
-
-List      *
-nreverse(List *list)
-{
-       List       *rlist = NIL;
-       List       *p = NIL;
-
-       if (list == NULL)
-               return (NIL);
-
-       if (length(list) == 1)
-               return (list);
-
-       for (p = list; p != NULL; p = lnext(p))
-       {
-               rlist = lcons(lfirst(p), rlist);
-       }
-
-       lfirst(list) = lfirst(rlist);
-       lnext(list) = lnext(rlist);
-       return (list);
-}
-
 /*
  *             same
  *
index 8f0daf304052aaa0303350801fb8a7278084c07d..ba4b27f822c41108bc391e8acf9b88a51c12c2fd 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.20 1998/01/07 15:32:25 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.21 1998/01/15 18:59:26 momjian Exp $
  *
  * NOTES
  *       Every (plan) node in POSTGRES has an associated "out" routine which
@@ -163,7 +163,6 @@ static void
 _outQuery(StringInfo str, Query *node)
 {
        char            buf[500];
-       int i;
        
        appendStringInfo(str, "QUERY");
 
@@ -229,12 +228,8 @@ _outQuery(StringInfo str, Query *node)
        _outNode(str, node->groupClause);
        appendStringInfo(str, " :havingQual ");
        _outNode(str, node->havingQual);
-       appendStringInfo(str, " :qry_numAgg ");
-       sprintf(buf, " %d ", node->qry_numAgg);
-       appendStringInfo(str, buf);
-       appendStringInfo(str, " :qry_aggs ");
-       for (i=0; i < node->qry_numAgg; i++)
-               _outNode(str, node->qry_aggs[i]);
+       appendStringInfo(str, " :hasAggs ");
+       appendStringInfo(str, (node->hasAggs ? "true" : "false"));
        appendStringInfo(str, " :unionClause ");
        _outNode(str, node->unionClause);
 }
@@ -505,14 +500,12 @@ _outSort(StringInfo str, Sort *node)
 static void
 _outAgg(StringInfo str, Agg *node)
 {
-       char            buf[500];
 
        appendStringInfo(str, "AGG");
        _outPlanInfo(str, (Plan *) node);
 
-       /* the actual Agg fields */
-       sprintf(buf, " :numagg %d ", node->numAgg);
-       appendStringInfo(str, buf);
+       appendStringInfo(str, " :aggs ");
+       _outNode(str, node->aggs);
 }
 
 static void
index 65038f8c89410ab4981980fcc888970066bc86bc..574d5c69e2c99028339cacf8c14316e39618ec0f 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.17 1998/01/07 21:03:37 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.18 1998/01/15 18:59:31 momjian Exp $
  *
  * NOTES
  *       Most of the read functions for plan nodes are tested. (In fact, they
@@ -76,7 +76,6 @@ _readQuery()
        Query      *local_node;
        char       *token;
        int                     length;
-       int                     i;
        
        local_node = makeNode(Query);
 
@@ -153,19 +152,9 @@ _readQuery()
        token = lsptok(NULL, &length);          /* skip :havingQual */
        local_node->havingQual = nodeRead(true);
 
-       token = lsptok(NULL, &length);          /* skip the :qry_numAgg */
-       token = lsptok(NULL, &length);          /* get qry_numAgg */
-       local_node->qry_numAgg = atoi(token);
-
-       token = lsptok(NULL, &length);          /* skip the :qry_Aggs */
-       if (local_node->qry_numAgg == 0)
-               local_node->qry_aggs = NULL;
-       else
-       {
-               local_node->qry_aggs = palloc(sizeof(Aggreg *) * local_node->qry_numAgg);
-               for (i=0; i < local_node->qry_numAgg; i++)
-                       local_node->qry_aggs[i] = nodeRead(true);
-       }
+       token = lsptok(NULL, &length);          /* skip the :hasAggs */
+       token = lsptok(NULL, &length);          /* get hasAggs */
+       local_node->hasAggs = (token[0] == 't') ? true : false;
 
        token = lsptok(NULL, &length);          /* skip :unionClause */
        local_node->unionClause = nodeRead(true);
@@ -618,9 +607,8 @@ _readAgg()
        local_node = makeNode(Agg);
        _getPlan((Plan *) local_node);
 
-       token = lsptok(NULL, &length);          /* eat :numagg */
-       token = lsptok(NULL, &length);          /* get numagg */
-       local_node->numAgg = atoi(token);
+       token = lsptok(NULL, &length);          /* eat :agg */
+       local_node->aggs = nodeRead(true);      /* now read it */
 
        return (local_node);
 }
index 3640eabcbccbbfe247e2e783b66b5d5e83c0be97..970a6a5ffb7dd47db93ab44e3c5d16695662f327 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.22 1998/01/07 21:04:01 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.23 1998/01/15 18:59:37 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1106,7 +1106,7 @@ make_material(List *tlist,
 }
 
 Agg               *
-make_agg(List *tlist, int nagg, Aggreg **aggs, Plan *lefttree)
+make_agg(List *tlist, Plan *lefttree)
 {
        Agg                *node = makeNode(Agg);
 
@@ -1116,8 +1116,7 @@ make_agg(List *tlist, int nagg, Aggreg **aggs, Plan *lefttree)
        node->plan.targetlist = tlist;
        node->plan.lefttree = lefttree;
        node->plan.righttree = (Plan *) NULL;
-       node->numAgg = nagg;
-       node->aggs = aggs;
+       node->aggs = NIL;
 
        return (node);
 }
index 69186d82c00234db9d1dcbb3f7babc5158999297..b8b99149ce5a8e0440426b741c21614e2fe0e404 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.15 1998/01/07 21:04:04 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.16 1998/01/15 18:59:44 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -71,7 +71,7 @@ query_planner(Query *root,
        List       *constant_qual = NIL;
        List       *var_only_tlist = NIL;
        List       *level_tlist = NIL;
-       Plan       *subplan = (Plan *) NULL;
+       Plan       *subplan = NULL;
 
        /*
         * A command without a target list or qualification is an error,
@@ -174,20 +174,19 @@ query_planner(Query *root,
         */
        if (constant_qual)
        {
-               Plan       *plan;
-
-               plan = (Plan *) make_result(tlist,
-                                                                       (Node *) constant_qual,
-                                                                       subplan);
+               subplan = (Plan *)make_result((!root->hasAggs && !root->groupClause)
+                                                                                       ? tlist : subplan->targetlist,
+                                                                               (Node *) constant_qual,
+                                                                               subplan);
 
                /*
                 * Change all varno's of the Result's node target list.
                 */
-               set_result_tlist_references((Result *) plan);
+               if (!root->hasAggs && !root->groupClause)
+                       set_tlist_references(subplan);
 
-               return (plan);
+               return subplan;
        }
-
        /*
         * fix up the flattened target list of the plan root node so that
         * expressions are evaluated.  this forces expression evaluations that
@@ -201,12 +200,14 @@ query_planner(Query *root,
         * aggregates fixing only other entries (i.e. - GroupBy-ed and so
         * fixed by make_groupPlan).     - vadim 04/05/97
         */
-       if (root->groupClause == NULL && root->qry_aggs == NULL)
-       {
-               subplan->targetlist = flatten_tlist_vars(tlist,
+        else
+        {
+               if (!root->hasAggs && !root->groupClause)
+                       subplan->targetlist = flatten_tlist_vars(tlist,
                                                                                                 subplan->targetlist);
-       }
-
+               return subplan;
+        }
+        
 #ifdef NOT_USED
        /*
         * Destructively modify the query plan's targetlist to add fjoin lists
@@ -215,7 +216,6 @@ query_planner(Query *root,
        subplan->targetlist = generate_fjoin(subplan->targetlist);
 #endif
 
-       return (subplan);
 }
 
 /*
index 77419112d7433d871974c08eacbc17be929230da..5643b675f96392f5ba1e97737124bf199346914c 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.20 1998/01/07 21:04:05 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.21 1998/01/15 18:59:48 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -117,7 +117,7 @@ planner(Query *parse)
         * If we have a GROUP BY clause, insert a group node (with the
         * appropriate sort node.)
         */
-       if (parse->groupClause != NULL)
+       if (parse->groupClause)
        {
                bool            tuplePerGroup;
 
@@ -127,7 +127,7 @@ planner(Query *parse)
                 * present. Otherwise, need every tuple from the group to do the
                 * aggregation.)
                 */
-               tuplePerGroup = (parse->qry_aggs) ? TRUE : FALSE;
+               tuplePerGroup = parse->hasAggs;
 
                result_plan =
                        make_groupPlan( &tlist,
@@ -140,22 +140,16 @@ planner(Query *parse)
        /*
         * If aggregate is present, insert the agg node
         */
-       if (parse->qry_aggs)
+       if (parse->hasAggs)
        {
-               result_plan = (Plan *)make_agg(tlist,
-                                                       parse->qry_numAgg,
-                                                       parse->qry_aggs,
-                                                       result_plan);
+               result_plan = (Plan *)make_agg(tlist, result_plan);
 
                /*
                 * set the varno/attno entries to the appropriate references to
-                * the result tuple of the subplans. (We need to set those in the
-                * array of aggreg's in the Agg node also. Even though they're
-                * pointers, after a few dozen's of copying, they're not the same
-                * as those in the target list.)
+                * the result tuple of the subplans.
                 */
-               set_agg_tlist_references((Agg *)result_plan);
-               set_agg_agglist_references((Agg *)result_plan);
+               ((Agg *)result_plan)->aggs =
+                       set_agg_tlist_references((Agg *)result_plan);
        }
 
        /*
index 644ff36ee908869b6c893a41dc9b8f4ee12d0fcb..fe80a658f0a1f08838f3ae33723719178937934a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.14 1998/01/14 19:55:53 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.15 1998/01/15 18:59:50 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,7 +44,7 @@ static Var *replace_joinvar_refs(Var *var, List *outer_tlist, List *inner_tlist)
 static List *tlist_temp_references(Oid tempid, List *tlist);
 static void replace_result_clause(Node *clause, List *subplanTargetList);
 static bool OperandIsInner(Node *opnd, int inner_relid);
-static void replace_agg_clause(Node *expr, List *targetlist);
+static List *replace_agg_clause(Node *expr, List *targetlist);
 static Node *del_agg_clause(Node *clause);
 
 /*****************************************************************************
@@ -536,13 +536,9 @@ set_result_tlist_references(Result *resultNode)
         */
        subplan = ((Plan *) resultNode)->lefttree;
        if (subplan != NULL)
-       {
                subplanTargetList = subplan->targetlist;
-       }
        else
-       {
                subplanTargetList = NIL;
-       }
 
        /*
         * now for traverse all the entris of the target list. These should be
@@ -695,13 +691,16 @@ OperandIsInner(Node *opnd, int inner_relid)
  *       changes the target list of an Agg node so that it points to
  *       the tuples returned by its left tree subplan.
  *
+ *     We now also generate a linked list of Aggreg pointers for Agg.
+ *
  */
-void
+List *
 set_agg_tlist_references(Agg *aggNode)
 {
        List       *aggTargetList;
        List       *subplanTargetList;
        List       *tl;
+       List       *aggreg_list = NIL;
 
        aggTargetList = aggNode->plan.targetlist;
        subplanTargetList = aggNode->plan.lefttree->targetlist;
@@ -710,30 +709,18 @@ set_agg_tlist_references(Agg *aggNode)
        {
                TargetEntry *tle = lfirst(tl);
 
-               replace_agg_clause(tle->expr, subplanTargetList);
-       }
-}
-
-void
-set_agg_agglist_references(Agg *aggNode)
-{
-       List       *subplanTargetList;
-       Aggreg    **aggs;
-       int                     i;
-
-       aggs = aggNode->aggs;
-       subplanTargetList = aggNode->plan.lefttree->targetlist;
-
-       for (i = 0; i < aggNode->numAgg; i++)
-       {
-               replace_agg_clause(aggs[i]->target, subplanTargetList);
+               aggreg_list = nconc(
+                       replace_agg_clause(tle->expr, subplanTargetList),aggreg_list);
        }
+       return aggreg_list;
 }
 
-static void
+static List *
 replace_agg_clause(Node *clause, List *subplanTargetList)
 {
        List       *t;
+       List *agg_list = NIL;
+
        if (IsA(clause, Var))
        {
                TargetEntry *subplanVar;
@@ -748,41 +735,51 @@ replace_agg_clause(Node *clause, List *subplanTargetList)
                 *
                 */
                ((Var *) clause)->varattno = subplanVar->resdom->resno;
+
+               return NIL;
        }
        else if (is_funcclause(clause))
        {
-
                /*
                 * This is a function. Recursively call this routine for its
                 * arguments...
                 */
                foreach(t, ((Expr *) clause)->args)
                {
-                       replace_agg_clause(lfirst(t), subplanTargetList);
+                       agg_list = nconc(agg_list,
+                               replace_agg_clause(lfirst(t), subplanTargetList));
                }
+               return agg_list;
        }
        else if (IsA(clause, Aggreg))
        {
-               replace_agg_clause(((Aggreg *) clause)->target, subplanTargetList);
+               return lcons(clause,
+                       replace_agg_clause(((Aggreg *) clause)->target, subplanTargetList));
        }
        else if (IsA(clause, ArrayRef))
        {
                ArrayRef   *aref = (ArrayRef *) clause;
-
+               
                /*
                 * This is an arrayref. Recursively call this routine for its
                 * expression and its index expression...
                 */
                foreach(t, aref->refupperindexpr)
                {
-                       replace_agg_clause(lfirst(t), subplanTargetList);
+                       agg_list = nconc(agg_list,
+                               replace_agg_clause(lfirst(t), subplanTargetList));
                }
                foreach(t, aref->reflowerindexpr)
                {
-                       replace_agg_clause(lfirst(t), subplanTargetList);
+                       agg_list = nconc(agg_list,
+                               replace_agg_clause(lfirst(t), subplanTargetList));
                }
-               replace_agg_clause(aref->refexpr, subplanTargetList);
-               replace_agg_clause(aref->refassgnexpr, subplanTargetList);
+               agg_list = nconc(agg_list,
+                       replace_agg_clause(aref->refexpr, subplanTargetList));
+               agg_list = nconc(agg_list,
+                       replace_agg_clause(aref->refassgnexpr, subplanTargetList));
+
+               return agg_list;
        }
        else if (is_opclause(clause))
        {
@@ -792,15 +789,20 @@ replace_agg_clause(Node *clause, List *subplanTargetList)
                 */
                Node       *left = (Node *) get_leftop((Expr *) clause);
                Node       *right = (Node *) get_rightop((Expr *) clause);
-
+               
                if (left != (Node *) NULL)
-                       replace_agg_clause(left, subplanTargetList);
+                       agg_list = nconc(agg_list,
+                               replace_agg_clause(left, subplanTargetList));
                if (right != (Node *) NULL)
-                       replace_agg_clause(right, subplanTargetList);
+                       agg_list = nconc(agg_list,
+                               replace_agg_clause(right, subplanTargetList));
+
+               return agg_list;
        }
        else if (IsA(clause, Param) ||IsA(clause, Const))
        {
                /* do nothing! */
+               return NIL;
        }
        else
        {
@@ -809,8 +811,8 @@ replace_agg_clause(Node *clause, List *subplanTargetList)
                 * Ooops! we can not handle that!
                 */
                elog(ERROR, "replace_agg_clause: Can not handle this tlist!\n");
+               return NIL;
        }
-
 }
 
 /*
index e942173a74548b6bba658244c4158e2b89bd960d..119e054578f691c94d038bd47af57870fb64b18b 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.17 1997/12/29 04:31:23 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.18 1998/01/15 18:59:53 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -185,8 +185,7 @@ plan_union_queries(Query *parse)
                parse->uniqueFlag = NULL;
 
        parse->havingQual = NULL;
-       parse->qry_numAgg = 0;
-       parse->qry_aggs = NULL;
+       parse->hasAggs = false;
 
        return (make_append(union_plans,
                                                union_rts,
@@ -267,11 +266,9 @@ plan_inherit_query(List *relids,
                new_root->uniqueFlag = NULL;
                new_root->sortClause = NULL;
                new_root->groupClause = NULL;
-               if (new_root->qry_numAgg != 0)
+               if (new_root->hasAggs)
                {
-                       new_root->qry_numAgg = 0;
-                       pfree(new_root->qry_aggs);
-                       new_root->qry_aggs = NULL;
+                       new_root->hasAggs = false;
                        del_agg_tlist_references(new_root->targetList);
                }
                fix_parsetree_attnums(rt_index,
index dcb9eecb5db5cb01420c9b204f24a357e8b0410b..45c5d1406ba9e333bd158dc1d221c840b14b8798 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.64 1998/01/11 03:41:35 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.65 1998/01/15 18:59:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -219,7 +219,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
        qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
        /* make sure we don't have aggregates in the where clause */
-       if (pstate->p_numAgg > 0)
+       if (pstate->p_hasAggs)
                parseCheckAggregates(pstate, qry);
 
        return (Query *) qry;
@@ -334,7 +334,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
                                                                                  qry->targetList,
                                                                                  qry->uniqueFlag);
 
-       if (pstate->p_numAgg > 0)
+       if (pstate->p_hasAggs)
                finalizeAggregates(pstate, qry);
 
        qry->unionall = stmt->unionall; /* in child, so unionClause may be false */
@@ -796,8 +796,7 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
 
                pstate->p_last_resno = 1;
                pstate->p_is_rule = true;               /* for expand all */
-               pstate->p_numAgg = 0;
-               pstate->p_aggs = NULL;
+               pstate->p_hasAggs = false;
 
                lfirst(actions) = transformStmt(pstate, lfirst(actions));
                actions = lnext(actions);
@@ -853,7 +852,7 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
                                                                                        qry->targetList);
        qry->rtable = pstate->p_rtable;
 
-       if (pstate->p_numAgg > 0)
+       if (pstate->p_hasAggs)
                finalizeAggregates(pstate, qry);
 
        qry->unionall = stmt->unionall; /* in child, so unionClause may be false */
@@ -890,11 +889,11 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
        qry->rtable = pstate->p_rtable;
        qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
-       if (pstate->p_numAgg > 0)
+       if (pstate->p_hasAggs)
                finalizeAggregates(pstate, qry);
 
        /* make sure we don't have aggregates in the where clause */
-       if (pstate->p_numAgg > 0)
+       if (pstate->p_hasAggs)
                parseCheckAggregates(pstate, qry);
 
        return (Query *) qry;
index dfaaa991843c50058940a35a758e34f829deb9e1..15413ecb7390873f121612d373ad0c8ebf38a0ba 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.6 1998/01/05 03:32:25 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.7 1998/01/15 18:59:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,64 +34,17 @@ static bool contain_agg_clause(Node *clause);
 static bool exprIsAggOrGroupCol(Node *expr, List *groupClause);
 static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause);
 
-/*
- * AddAggToParseState -
- *       add the aggregate to the list of unique aggregates in pstate.
- *
- * SIDE EFFECT: aggno in target list entry will be modified
- */
-void
-AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
-{
-       List       *ag;
-       int                     i;
-
-       /*
-        * see if we have the aggregate already (we only need to record the
-        * aggregate once)
-        */
-       i = 0;
-       foreach(ag, pstate->p_aggs)
-       {
-               Aggreg     *a = lfirst(ag);
-
-               if (!strcmp(a->aggname, aggreg->aggname) &&
-                       equal(a->target, aggreg->target))
-               {
-
-                       /* fill in the aggno and we're done */
-                       aggreg->aggno = i;
-                       return;
-               }
-               i++;
-       }
-
-       /* not found, new aggregate */
-       aggreg->aggno = i;
-       pstate->p_numAgg++;
-       pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
-       return;
-}
-
 /*
  * finalizeAggregates -
- *       fill in qry_aggs from pstate. Also checks to make sure that aggregates
+ *       fill in hasAggs from pstate. Also checks to make sure that aggregates
  *       are used in the proper place.
  */
 void
 finalizeAggregates(ParseState *pstate, Query *qry)
 {
-       List       *l;
-       int                     i;
-
        parseCheckAggregates(pstate, qry);
 
-       qry->qry_numAgg = pstate->p_numAgg;
-       qry->qry_aggs =
-               (Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
-       i = 0;
-       foreach(l, pstate->p_aggs)
-               qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
+       qry->hasAggs = pstate->p_hasAggs;
 }
 
 /*
@@ -240,7 +193,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 {
        List       *tl;
 
-       Assert(pstate->p_numAgg > 0);
+       Assert(pstate->p_hasAggs);
 
        /*
         * aggregates never appear in WHERE clauses. (we have to check where
@@ -393,6 +346,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
        if (usenulls)
                aggreg->usenulls = true;
 
+       pstate->p_hasAggs = true;
+
        return aggreg;
 }
 
index be93156e3c12271c1d76b1bae464b21330865ceb..76782fc7ad90f406b7b278bc813b089a8db4de61 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.5 1998/01/05 03:32:28 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.6 1998/01/15 19:00:02 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -221,13 +221,8 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs,
                                                                        PointerGetDatum(funcname),
                                                                        ObjectIdGetDatum(basetype),
                                                                        0, 0))
-                       {
-                               Aggreg     *aggreg = ParseAgg(pstate, funcname, basetype,
+                               return (Node *)ParseAgg(pstate, funcname, basetype,
                                                                                fargs, precedence);
-
-                               AddAggToParseState(pstate, aggreg);
-                               return (Node *) aggreg;
-                       }
                }
        }
 
index 503e42c8250d82e9e5044a54819d3ec38586da72..04b40041b9df3629817a1298ae80d5fcac75e830 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.5 1998/01/05 03:32:29 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.6 1998/01/15 19:00:04 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,8 +49,7 @@ make_parsestate(void)
        pstate = palloc(sizeof(ParseState));
        pstate->p_last_resno = 1;
        pstate->p_rtable = NIL;
-       pstate->p_numAgg = 0;
-       pstate->p_aggs = NIL;
+       pstate->p_hasAggs = false;
        pstate->p_is_insert = false;
        pstate->p_insert_columns = NIL;
        pstate->p_is_update = false;
index 70dc37080e2a5d098accbc08d17d3d5d7fdec8c9..b0557b042e1ed1f782c67749efd9a94cb886e65a 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.6 1998/01/04 04:31:27 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.7 1998/01/15 19:00:06 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -95,7 +95,6 @@ thisLockWasTriggered(int varno,
                                         AttrNumber attnum,
                                         Query *parsetree)
 {
-       int i;
        
        if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum))
                return true;
@@ -103,10 +102,6 @@ thisLockWasTriggered(int varno,
        if (nodeThisLockWasTriggered((Node *) parsetree->targetList, varno, attnum))
                return true;
 
-       for(i=0; i < parsetree->qry_numAgg; i++)
-               if (nodeThisLockWasTriggered(parsetree->qry_aggs[i]->target,
-                                       varno, attnum))
-                       return true;
        return false;
                
 }
index 122067a2424feb91ef9ca3a877656131b869cfce..cd5f5e16a4d73c365adbfca5e1e515073ae9b1ce 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.9 1998/01/04 04:31:29 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.10 1998/01/15 19:00:07 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -420,16 +420,12 @@ HandleRIRAttributeRule(Query *parsetree,
                                           int *modified,
                                           int *badsql)
 {
-       int i;
        
        nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
                                                           targetlist, rt_index, attr_num,
                                                           modified, badsql);
        nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
                                                           rt_index, attr_num, modified, badsql);
-       for(i=0; i < parsetree->qry_numAgg; i++)
-               nodeHandleRIRAttributeRule(&parsetree->qry_aggs[i]->target, rtable,
-                                       targetlist, rt_index, attr_num, modified, badsql);
 }
 
 
@@ -521,13 +517,9 @@ HandleViewRule(Query *parsetree,
                           int rt_index,
                           int *modified)
 {
-       int i;
-       
+
        nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
                                           modified);
        nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
                                           rt_index, modified);
-       for(i=0; i < parsetree->qry_numAgg; i++)
-               nodeHandleViewRule(&parsetree->qry_aggs[i]->target, rtable, targetlist, rt_index,
-                                          modified);
 }
index 65718fc6e16d47f308994ff1a3b0b7266fcc86a7..c56363ddf0c8a80fe679529f742c8afdb174de01 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.43 1998/01/11 03:41:49 momjian Exp $
+ * $Id: parsenodes.h,v 1.44 1998/01/15 19:00:11 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,6 +44,7 @@ typedef struct Query
        bool            isPortal;               /* is this a retrieve into portal? */
        bool            isBinary;               /* binary portal? */
        bool            unionall;               /* union without unique sort */
+       bool            hasAggs;                /* has aggregates in target list */
        
        char       *uniqueFlag;         /* NULL, '*', or Unique attribute name */
        List       *sortClause;         /* a list of SortClause's */
@@ -56,9 +57,6 @@ typedef struct Query
                                                                 * BY */
        Node       *havingQual;         /* qualification of each group */
 
-       int                     qry_numAgg;             /* number of aggregates in the target list */
-       Aggreg    **qry_aggs;           /* the aggregates */
-
        List       *unionClause;        /* unions are linked under the previous query */
 
        /* internal to planner */
index 2dc464c2a7af104299a498bca52bc7f9ba707129..871afacbc4b71a91a4c7791c21e4a107df5553b0 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: plannodes.h,v 1.12 1997/12/27 06:41:41 momjian Exp $
+ * $Id: plannodes.h,v 1.13 1998/01/15 19:00:13 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -214,8 +214,7 @@ typedef struct HashJoin
 typedef struct Agg
 {
        Plan            plan;
-       int                     numAgg;
-       Aggreg    **aggs;
+       List            *aggs;
        AggState   *aggstate;
 } Agg;
 
index 04363edd03e94627eba276f47f0bb1c42eb8b330..041a48b612ad5b648aabab6b5886d12628d9bb5f 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: planmain.h,v 1.9 1997/12/20 07:59:43 momjian Exp $
+ * $Id: planmain.h,v 1.10 1998/01/15 19:00:15 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,7 +33,7 @@ extern SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid,
                         Plan *lefttree);
 extern Sort *make_sort(List *tlist, Oid tempid, Plan *lefttree,
                  int keycount);
-extern Agg *make_agg(List *tlist, int nagg, Aggreg **aggs, Plan *lefttree);
+extern Agg *make_agg(List *tlist, Plan *lefttree);
 extern Group *make_group(List *tlist, bool tuplePerGroup, int ngrp,
                   AttrNumber *grpColIdx, Sort *lefttree);
 extern Unique *make_unique(List *tlist, Plan *lefttree, char *uniqueAttr);
@@ -55,7 +55,7 @@ extern List *join_references(List *clauses, List *outer_tlist,
 extern List *index_outerjoin_references(List *inner_indxqual,
                                                   List *outer_tlist, Index inner_relid);
 extern void set_result_tlist_references(Result *resultNode);
-extern void set_agg_tlist_references(Agg *aggNode);
+extern List *set_agg_tlist_references(Agg *aggNode);
 extern void set_agg_agglist_references(Agg *aggNode);
 extern void del_agg_tlist_references(List *tlist);
 
index de6b03a1ad01b9e8aeade1ab06532db567c99bbf..be49fe7a0fa421f08130e80e3b49270575c87e06 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_node.h,v 1.3 1997/11/26 03:43:13 momjian Exp $
+ * $Id: parse_node.h,v 1.4 1998/01/15 19:00:16 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,10 +30,9 @@ typedef struct ParseState
 {
        int                     p_last_resno;
        List       *p_rtable;
-       int                     p_numAgg;
-       List       *p_aggs;
-       bool            p_is_insert;
        List       *p_insert_columns;
+       bool            p_hasAggs;
+       bool            p_is_insert;
        bool            p_is_update;
        bool            p_is_rule;
        bool            p_in_where_clause;