aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c94
1 files changed, 82 insertions, 12 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 40e9cc50a63..381c609493b 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.13 1997/12/18 19:41:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.14 1997/12/20 07:59:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -47,6 +47,8 @@
#include "executor/executor.h"
static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);
+extern Plan *make_groupPlan(List **tlist, bool tuplePerGroup,
+ List *groupClause, Plan *subplan);
/*****************************************************************************
*
@@ -72,13 +74,13 @@ planner(Query *parse)
List *rangetable = parse->rtable;
char *uniqueflag = parse->uniqueFlag;
List *sortclause = parse->sortClause;
- Plan *special_plans = (Plan *) NULL;
+ Agg *aggplan = NULL;
Plan *result_plan = (Plan *) NULL;
- List *preprocessed_tlist = NIL;
List *primary_qual;
int rt_index;
+
/*
* plan inheritance
@@ -86,29 +88,97 @@ planner(Query *parse)
rt_index = first_matching_rt_entry(rangetable, INHERITS_FLAG);
if (rt_index != -1)
{
- special_plans = (Plan *) plan_union_queries((Index) rt_index,
+ result_plan = (Plan *) plan_union_queries((Index) rt_index,
parse,
INHERITS_FLAG);
+ /* XXX do we need to do this? bjm 12/19/97 */
+ tlist = preprocess_targetlist(tlist,
+ parse->commandType,
+ parse->resultRelation,
+ parse->rtable);
}
-
- if (special_plans)
- result_plan = special_plans;
else
{
- preprocessed_tlist = preprocess_targetlist(tlist,
- parse->commandType,
- parse->resultRelation,
- parse->rtable);
+ tlist = preprocess_targetlist(tlist,
+ parse->commandType,
+ parse->resultRelation,
+ parse->rtable);
primary_qual = cnfify((Expr *) parse->qual, true);
result_plan = query_planner(parse,
parse->commandType,
- preprocessed_tlist,
+ tlist,
primary_qual);
}
/*
+ * If we have a GROUP BY clause, insert a group node (with the
+ * appropriate sort node.)
+ */
+ if (parse->groupClause != NULL)
+ {
+ bool tuplePerGroup;
+
+ /*
+ * decide whether how many tuples per group the Group node needs
+ * to return. (Needs only one tuple per group if no aggregate is
+ * present. Otherwise, need every tuple from the group to do the
+ * aggregation.)
+ */
+ tuplePerGroup = (parse->qry_aggs) ? TRUE : FALSE;
+
+ result_plan =
+ make_groupPlan( &tlist,
+ tuplePerGroup,
+ parse->groupClause,
+ result_plan);
+
+ }
+
+ /*
+ * If aggregate is present, insert the agg node
+ */
+ if (parse->qry_aggs)
+ {
+ aggplan = make_agg(tlist,
+ parse->qry_numAgg,
+ parse->qry_aggs,
+ 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.)
+ */
+ set_agg_tlist_references(aggplan);
+ set_agg_agglist_references(aggplan);
+
+ result_plan = (Plan *) aggplan;
+ }
+
+ /*
+ * fix up the flattened target list of the plan root node so that
+ * expressions are evaluated. this forces expression evaluations that
+ * may involve expensive function calls to be delayed to the very last
+ * stage of query execution. this could be bad. but it is joey's
+ * responsibility to optimally push these expressions down the plan
+ * tree. -- Wei
+ *
+ * But now nothing to do if there are GroupBy and/or Aggregates: 1.
+ * make_groupPlan fixes tlist; 2. flatten_tlist_vars does nothing with
+ * aggregates fixing only other entries (i.e. - GroupBy-ed and so
+ * fixed by make_groupPlan). - vadim 04/05/97
+ */
+ if (parse->groupClause == NULL && aggplan == NULL)
+ {
+ result_plan->targetlist = flatten_tlist_vars(tlist,
+ result_plan->targetlist);
+ }
+
+ /*
* For now, before we hand back the plan, check to see if there is a
* user-specified sort that needs to be done. Eventually, this will
* be moved into the guts of the planner s.t. user specified sorts