diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index e268bf3423..62970db8c7 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -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 diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 28dc982abb..e0ccc63f35 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -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) { diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index e68c102846..6a7b7e12be 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -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 * diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 8f0daf3040..ba4b27f822 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -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 diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 65038f8c89..574d5c69e2 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -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); } diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 3640eabcbc..970a6a5ffb 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -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); } diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index 69186d82c0..b8b99149ce 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -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); } /* diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 77419112d7..5643b675f9 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -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); } /* diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 644ff36ee9..fe80a658f0 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -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); + aggreg_list = nconc( + replace_agg_clause(tle->expr, subplanTargetList),aggreg_list); } + return aggreg_list; } -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); - } -} - -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; } - } /* diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index e942173a74..119e054578 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -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, diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index dcb9eecb5d..45c5d1406b 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -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; diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index dfaaa99184..15413ecb73 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -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; } diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index be93156e3c..76782fc7ad 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -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; - } } } diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 503e42c825..04b40041b9 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -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; diff --git a/src/backend/rewrite/locks.c b/src/backend/rewrite/locks.c index 70dc37080e..b0557b042e 100644 --- a/src/backend/rewrite/locks.c +++ b/src/backend/rewrite/locks.c @@ -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; } diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index 122067a242..cd5f5e16a4 100644 --- a/src/backend/rewrite/rewriteManip.c +++ b/src/backend/rewrite/rewriteManip.c @@ -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); } diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 65718fc6e1..c56363ddf0 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -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 */ diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 2dc464c2a7..871afacbc4 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -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; diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 04363edd03..041a48b612 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -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); diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h index de6b03a1ad..be49fe7a0f 100644 --- a/src/include/parser/parse_node.h +++ b/src/include/parser/parse_node.h @@ -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;