mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
Remove Query->qry_aggs and qry_numaggs and replace with Query->hasAggs.
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;
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user