From a87ee007edfa3d71e31cea4adad396888adbcd5a Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 10 Jun 2005 03:32:25 +0000 Subject: [PATCH] Quick hack to allow the outer query's tuple_fraction to be passed down to a subquery if the outer query is simple enough that the LIMIT can be reflected directly to the subquery. This didn't use to be very interesting, because a subquery that couldn't have been flattened into the upper query was usually not going to be very responsive to tuple_fraction anyway. But with new code that allows UNION ALL subqueries to pay attention to tuple_fraction, this is useful to do. In particular this lets the optimization occur when the UNION ALL is directly inside a view. --- src/backend/optimizer/path/allpaths.c | 44 +++++++++++++++++++++++++-- src/backend/optimizer/plan/planmain.c | 5 ++- src/include/nodes/relation.h | 4 ++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 4b09f03e6e..25bd55dadf 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 50e1bc5ea8..788fd2f324 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 ec839d7d3f..687ef36784 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; -- 2.40.0