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;
ProjectionInfo *projInfo;
TupleTableSlot *resultSlot;
HeapTuple oneTuple;
+ List *alist;
char *nulls;
bool isDone;
bool isNull = FALSE,
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;
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
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
_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;
_copyQuery(Query *from)
{
Query *newnode = makeNode(Query);
- int i;
newnode->commandType = from->commandType;
if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
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)
{
*
*
* 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
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)
{
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
*
*
*
* 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
_outQuery(StringInfo str, Query *node)
{
char buf[500];
- int i;
appendStringInfo(str, "QUERY");
_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);
}
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
*
*
* 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
Query *local_node;
char *token;
int length;
- int i;
local_node = makeNode(Query);
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);
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);
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
}
Agg *
-make_agg(List *tlist, int nagg, Aggreg **aggs, Plan *lefttree)
+make_agg(List *tlist, Plan *lefttree)
{
Agg *node = makeNode(Agg);
node->plan.targetlist = tlist;
node->plan.lefttree = lefttree;
node->plan.righttree = (Plan *) NULL;
- node->numAgg = nagg;
- node->aggs = aggs;
+ node->aggs = NIL;
return (node);
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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,
*/
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
* 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
subplan->targetlist = generate_fjoin(subplan->targetlist);
#endif
- return (subplan);
}
/*
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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;
* 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,
/*
* 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);
}
/*
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
/*****************************************************************************
*/
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
* 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;
{
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;
*
*/
((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))
{
*/
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
{
* Ooops! we can not handle that!
*/
elog(ERROR, "replace_agg_clause: Can not handle this tlist!\n");
+ return NIL;
}
-
}
/*
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
parse->uniqueFlag = NULL;
parse->havingQual = NULL;
- parse->qry_numAgg = 0;
- parse->qry_aggs = NULL;
+ parse->hasAggs = false;
return (make_append(union_plans,
union_rts,
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,
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
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 */
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);
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 */
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;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
}
/*
{
List *tl;
- Assert(pstate->p_numAgg > 0);
+ Assert(pstate->p_hasAggs);
/*
* aggregates never appear in WHERE clauses. (we have to check where
if (usenulls)
aggreg->usenulls = true;
+ pstate->p_hasAggs = true;
+
return aggreg;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
- }
}
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
AttrNumber attnum,
Query *parsetree)
{
- int i;
if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum))
return true;
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;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
}
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);
}
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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 */
* 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 */
*
* 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 $
*
*-------------------------------------------------------------------------
*/
typedef struct Agg
{
Plan plan;
- int numAgg;
- Aggreg **aggs;
+ List *aggs;
AggState *aggstate;
} Agg;
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
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);
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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;