aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/path/allpaths.c44
-rw-r--r--src/backend/optimizer/plan/planmain.c5
-rw-r--r--src/include/nodes/relation.h4
3 files changed, 49 insertions, 4 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 4b09f03e6e7..25bd55dadf3 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.133 2005/06/09 04:18:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.134 2005/06/10 03:32:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -353,6 +353,28 @@ set_inherited_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
set_cheapest(rel);
}
+/* quick-and-dirty test to see if any joining is needed */
+static bool
+has_multiple_baserels(PlannerInfo *root)
+{
+ int num_base_rels = 0;
+ Index rti;
+
+ for (rti = 1; rti < root->base_rel_array_size; rti++)
+ {
+ RelOptInfo *brel = root->base_rel_array[rti];
+
+ if (brel == NULL)
+ continue;
+
+ /* ignore RTEs that are "other rels" */
+ if (brel->reloptkind == RELOPT_BASEREL)
+ if (++num_base_rels > 1)
+ return true;
+ }
+ return false;
+}
+
/*
* set_subquery_pathlist
* Build the (single) access path for a subquery RTE
@@ -361,8 +383,10 @@ static void
set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
Index rti, RangeTblEntry *rte)
{
+ Query *parse = root->parse;
Query *subquery = rte->subquery;
bool *differentTypes;
+ double tuple_fraction;
List *pathkeys;
List *subquery_pathkeys;
@@ -416,8 +440,24 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
pfree(differentTypes);
+ /*
+ * We can safely pass the outer tuple_fraction down to the subquery
+ * if the outer level has no joining, aggregation, or sorting to do.
+ * Otherwise we'd better tell the subquery to plan for full retrieval.
+ * (XXX This could probably be made more intelligent ...)
+ */
+ if (parse->hasAggs ||
+ parse->groupClause ||
+ parse->havingQual ||
+ parse->distinctClause ||
+ parse->sortClause ||
+ has_multiple_baserels(root))
+ tuple_fraction = 0.0; /* default case */
+ else
+ tuple_fraction = root->tuple_fraction;
+
/* Generate the plan for the subquery */
- rel->subplan = subquery_planner(subquery, 0.0 /* default case */,
+ rel->subplan = subquery_planner(subquery, tuple_fraction,
&subquery_pathkeys);
/* Copy number of output rows from subplan */
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c
index 50e1bc5ea8c..788fd2f3249 100644
--- a/src/backend/optimizer/plan/planmain.c
+++ b/src/backend/optimizer/plan/planmain.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.84 2005/06/08 23:02:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.85 2005/06/10 03:32:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -79,6 +79,9 @@ query_planner(PlannerInfo *root, List *tlist, double tuple_fraction,
Path *cheapestpath;
Path *sortedpath;
+ /* Make tuple_fraction accessible to lower-level routines */
+ root->tuple_fraction = tuple_fraction;
+
/*
* If the query has an empty join tree, then it's something easy like
* "SELECT 2+2;" or "INSERT ... VALUES()". Fall through quickly.
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index ec839d7d3f6..687ef367841 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.113 2005/06/09 04:19:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.114 2005/06/10 03:32:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -92,6 +92,8 @@ typedef struct PlannerInfo
List *query_pathkeys; /* desired pathkeys for query_planner(),
* and actual pathkeys afterwards */
+ double tuple_fraction; /* tuple_fraction passed to query_planner */
+
bool hasJoinRTEs; /* true if any RTEs are RTE_JOIN kind */
bool hasHavingQual; /* true if havingQual was non-null */
} PlannerInfo;