diff options
author | Bruce Momjian <bruce@momjian.us> | 1998-01-15 19:00:16 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1998-01-15 19:00:16 +0000 |
commit | 763ff8aef848d71da079049890786edffc3302d6 (patch) | |
tree | a1aed2a633c409071dd6d724b6db2bc7bf4fcb75 /src/backend/optimizer | |
parent | f22d8e6668e36a5855c35b04cc21a4d1593298d9 (diff) | |
download | postgresql-763ff8aef848d71da079049890786edffc3302d6.tar.gz postgresql-763ff8aef848d71da079049890786edffc3302d6.zip |
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;
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 7 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planmain.c | 32 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 22 | ||||
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 76 | ||||
-rw-r--r-- | src/backend/optimizer/prep/prepunion.c | 11 |
5 files changed, 70 insertions, 78 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 3640eabcbcc..970a6a5ffb7 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 69186d82c00..b8b99149ce5 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 77419112d74..5643b675f96 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 644ff36ee90..fe80a658f0a 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); - } -} - -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; } - } /* diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index e942173a745..119e054578f 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, |