summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/prep/prepunion.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/prep/prepunion.c')
-rw-r--r--src/backend/optimizer/prep/prepunion.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 9a86cb2348..10a48c666e 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.44 2000/02/15 03:37:26 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.45 2000/02/15 20:49:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -122,28 +122,35 @@ plan_union_queries(Query *parse)
/* Is this a simple one */
if (!union_all_found ||
!union_found ||
- /* A trailing UNION negates the affect of earlier UNION ALLs */
+ /* A trailing UNION negates the effect of earlier UNION ALLs */
!last_union_all_flag)
{
List *hold_unionClause = parse->unionClause;
+ double tuple_fraction = -1.0; /* default processing */
- /* we will do this later, so don't do it now */
+ /* we will do sorting later, so don't do it now */
if (!union_all_found ||
!last_union_all_flag)
{
parse->sortClause = NIL;
parse->distinctClause = NIL;
+ /*
+ * force lower-level planning to assume that all tuples will
+ * be retrieved, even if it sees a LIMIT in the query node.
+ */
+ tuple_fraction = 0.0;
}
parse->unionClause = NIL; /* prevent recursion */
- union_plans = lcons(union_planner(parse), NIL);
+ union_plans = lcons(union_planner(parse, tuple_fraction), NIL);
union_rts = lcons(parse->rtable, NIL);
foreach(ulist, hold_unionClause)
{
Query *union_query = lfirst(ulist);
- union_plans = lappend(union_plans, union_planner(union_query));
+ union_plans = lappend(union_plans,
+ union_planner(union_query, tuple_fraction));
union_rts = lappend(union_rts, union_query->rtable);
}
}
@@ -165,9 +172,12 @@ plan_union_queries(Query *parse)
/*
* Recursion, but UNION only. The last one is a UNION, so it will
- * not come here in recursion,
+ * not come here in recursion.
+ *
+ * XXX is it OK to pass default -1 to union_planner in this path,
+ * or should we force a tuple_fraction value?
*/
- union_plans = lcons(union_planner(parse), NIL);
+ union_plans = lcons(union_planner(parse, -1.0), NIL);
union_rts = lcons(parse->rtable, NIL);
/* Append the remaining UNION ALLs */
@@ -175,7 +185,8 @@ plan_union_queries(Query *parse)
{
Query *union_all_query = lfirst(ulist);
- union_plans = lappend(union_plans, union_planner(union_all_query));
+ union_plans = lappend(union_plans,
+ union_planner(union_all_query, -1.0));
union_rts = lappend(union_rts, union_all_query->rtable);
}
}
@@ -295,6 +306,7 @@ plan_inherit_query(Relids relids,
List *union_plans = NIL;
List *union_rtentries = NIL;
List *save_tlist = root->targetList;
+ double tuple_fraction;
List *i;
/*
@@ -303,6 +315,17 @@ plan_inherit_query(Relids relids,
*/
root->targetList = NIL;
+ /*
+ * If we are going to need sorting or grouping at the top level,
+ * force lower-level planners to assume that all tuples will be
+ * retrieved.
+ */
+ if (root->distinctClause || root->sortClause ||
+ root->groupClause || root->hasAggs)
+ tuple_fraction = 0.0; /* will need all tuples from each subplan */
+ else
+ tuple_fraction = -1.0; /* default behavior is OK (I think) */
+
foreach(i, relids)
{
int relid = lfirsti(i);
@@ -344,7 +367,8 @@ plan_inherit_query(Relids relids,
relid,
new_root);
- union_plans = lappend(union_plans, union_planner(new_root));
+ union_plans = lappend(union_plans,
+ union_planner(new_root, tuple_fraction));
union_rtentries = lappend(union_rtentries, new_rt_entry);
}
@@ -551,14 +575,17 @@ make_append(List *appendplans,
node->unionrtables = unionrtables;
node->inheritrelid = rt_index;
node->inheritrtable = inheritrtable;
- node->plan.cost = 0;
+ node->plan.startup_cost = 0;
+ node->plan.total_cost = 0;
node->plan.plan_rows = 0;
node->plan.plan_width = 0;
foreach(subnode, appendplans)
{
Plan *subplan = (Plan *) lfirst(subnode);
- node->plan.cost += subplan->cost;
+ if (subnode == appendplans) /* first node? */
+ node->plan.startup_cost = subplan->startup_cost;
+ node->plan.total_cost += subplan->total_cost;
node->plan.plan_rows += subplan->plan_rows;
if (node->plan.plan_width < subplan->plan_width)
node->plan.plan_width = subplan->plan_width;