aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c133
1 files changed, 53 insertions, 80 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 9cdbcc2e5e5..5a2acbd2763 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.119 2002/09/18 21:35:21 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.120 2002/11/06 00:00:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,6 +34,7 @@
static Scan *create_scan_plan(Query *root, Path *best_path);
static Join *create_join_plan(Query *root, JoinPath *best_path);
static Append *create_append_plan(Query *root, AppendPath *best_path);
+static Result *create_result_plan(Query *root, ResultPath *best_path);
static SeqScan *create_seqscan_plan(Path *best_path, List *tlist,
List *scan_clauses);
static IndexScan *create_indexscan_plan(Query *root, IndexPath *best_path,
@@ -135,6 +136,10 @@ create_plan(Query *root, Path *best_path)
plan = (Plan *) create_append_plan(root,
(AppendPath *) best_path);
break;
+ case T_Result:
+ plan = (Plan *) create_result_plan(root,
+ (ResultPath *) best_path);
+ break;
default:
elog(ERROR, "create_plan: unknown pathtype %d",
best_path->pathtype);
@@ -342,6 +347,35 @@ create_append_plan(Query *root, AppendPath *best_path)
return plan;
}
+/*
+ * create_result_plan
+ * Create a Result plan for 'best_path' and (recursively) plans
+ * for its subpaths.
+ *
+ * Returns a Plan node.
+ */
+static Result *
+create_result_plan(Query *root, ResultPath *best_path)
+{
+ Result *plan;
+ List *tlist;
+ Plan *subplan;
+
+ if (best_path->path.parent)
+ tlist = best_path->path.parent->targetlist;
+ else
+ tlist = NIL; /* will be filled in later */
+
+ if (best_path->subpath)
+ subplan = create_plan(root, best_path->subpath);
+ else
+ subplan = NULL;
+
+ plan = make_result(tlist, (Node *) best_path->constantqual, subplan);
+
+ return plan;
+}
+
/*****************************************************************************
*
@@ -1605,11 +1639,16 @@ make_material(List *tlist, Plan *lefttree)
}
Agg *
-make_agg(List *tlist, List *qual, Plan *lefttree)
+make_agg(List *tlist, List *qual, AggStrategy aggstrategy,
+ int ngrp, AttrNumber *grpColIdx, Plan *lefttree)
{
Agg *node = makeNode(Agg);
Plan *plan = &node->plan;
+ node->aggstrategy = aggstrategy;
+ node->numCols = ngrp;
+ node->grpColIdx = grpColIdx;
+
copy_plan_costsize(plan, lefttree);
/*
@@ -1621,22 +1660,21 @@ make_agg(List *tlist, List *qual, Plan *lefttree)
length(pull_agg_clause((Node *) qual)));
/*
- * We will produce a single output tuple if the input is not a Group,
+ * We will produce a single output tuple if not grouping,
* and a tuple per group otherwise. For now, estimate the number of
* groups as 10% of the number of tuples --- bogus, but how to do
- * better? (Note we assume the input Group node is in "tuplePerGroup"
- * mode, so it didn't reduce its row count already.)
+ * better?
*/
- if (IsA(lefttree, Group))
+ if (aggstrategy == AGG_PLAIN)
{
- plan->plan_rows *= 0.1;
- if (plan->plan_rows < 1)
- plan->plan_rows = 1;
+ plan->plan_rows = 1;
+ plan->startup_cost = plan->total_cost;
}
else
{
- plan->plan_rows = 1;
- plan->startup_cost = plan->total_cost;
+ plan->plan_rows *= 0.1;
+ if (plan->plan_rows < 1)
+ plan->plan_rows = 1;
}
plan->state = (EState *) NULL;
@@ -1650,7 +1688,6 @@ make_agg(List *tlist, List *qual, Plan *lefttree)
Group *
make_group(List *tlist,
- bool tuplePerGroup,
int ngrp,
AttrNumber *grpColIdx,
Plan *lefttree)
@@ -1667,25 +1704,18 @@ make_group(List *tlist,
plan->total_cost += cpu_operator_cost * plan->plan_rows * ngrp;
/*
- * If tuplePerGroup (which is named exactly backwards) is true, we
- * will return all the input tuples, so the input node's row count is
- * OK. Otherwise, we'll return only one tuple from each group. For
- * now, estimate the number of groups as 10% of the number of tuples
+ * Estimate the number of groups as 10% of the number of tuples
* --- bogus, but how to do better?
*/
- if (!tuplePerGroup)
- {
- plan->plan_rows *= 0.1;
- if (plan->plan_rows < 1)
- plan->plan_rows = 1;
- }
+ plan->plan_rows *= 0.1;
+ if (plan->plan_rows < 1)
+ plan->plan_rows = 1;
plan->state = (EState *) NULL;
plan->qual = NULL;
plan->targetlist = tlist;
plan->lefttree = lefttree;
plan->righttree = (Plan *) NULL;
- node->tuplePerGroup = tuplePerGroup;
node->numCols = ngrp;
node->grpColIdx = grpColIdx;
@@ -1883,9 +1913,6 @@ make_result(List *tlist,
Result *node = makeNode(Result);
Plan *plan = &node->plan;
-#ifdef NOT_USED
- tlist = generate_fjoin(tlist);
-#endif
if (subplan)
copy_plan_costsize(plan, subplan);
else
@@ -1906,57 +1933,3 @@ make_result(List *tlist,
return node;
}
-
-#ifdef NOT_USED
-List *
-generate_fjoin(List *tlist)
-{
- List tlistP;
- List newTlist = NIL;
- List fjoinList = NIL;
- int nIters = 0;
-
- /*
- * Break the target list into elements with Iter nodes, and those
- * without them.
- */
- foreach(tlistP, tlist)
- {
- List tlistElem;
-
- tlistElem = lfirst(tlistP);
- if (IsA(lsecond(tlistElem), Iter))
- {
- nIters++;
- fjoinList = lappend(fjoinList, tlistElem);
- }
- else
- newTlist = lappend(newTlist, tlistElem);
- }
-
- /*
- * if we have an Iter node then we need to flatten.
- */
- if (nIters > 0)
- {
- List *inner;
- List *tempList;
- Fjoin *fjoinNode;
- DatumPtr results = (DatumPtr) palloc(nIters * sizeof(Datum));
- BoolPtr alwaysDone = (BoolPtr) palloc(nIters * sizeof(bool));
-
- inner = lfirst(fjoinList);
- fjoinList = lnext(fjoinList);
- fjoinNode = (Fjoin) MakeFjoin(false,
- nIters,
- inner,
- results,
- alwaysDone);
- tempList = lcons(fjoinNode, fjoinList);
- newTlist = lappend(newTlist, tempList);
- }
- return newTlist;
- return tlist; /* do nothing for now - ay 10/94 */
-}
-
-#endif