diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2013-08-05 15:00:57 -0400 | 
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2013-08-05 15:01:09 -0400 | 
| commit | 3ced8837db2cd602422bb36102cec73289691d40 (patch) | |
| tree | 0fae9ca9ba7f5f259ef678d685717a70710ac0c4 /src/backend/optimizer/prep/prepjointree.c | |
| parent | 841c29c8b3be98ee30486ee245ebee782d4dedd4 (diff) | |
Simplify query_planner's API by having it return the top-level RelOptInfo.
Formerly, query_planner returned one or possibly two Paths for the topmost
join relation, so that grouping_planner didn't see the join RelOptInfo
(at least not directly; it didn't have any hesitation about examining
cheapest_path->parent, though).  However, correct selection of the Paths
involved a significant amount of coupling between query_planner and
grouping_planner, a problem which has gotten worse over time.  It seems
best to give up on this API choice and instead return the topmost
RelOptInfo explicitly.  Then grouping_planner can pull out the Paths it
wants from the rel's path list.  In this way we can remove all knowledge
of grouping behaviors from query_planner.
The only real benefit of the old way is that in the case of an empty
FROM clause, we never made any RelOptInfos at all, just a Path.  Now
we have to gin up a dummy RelOptInfo to represent the empty FROM clause.
That's not a very big deal though.
While at it, simplify query_planner's API a bit more by having the caller
set up root->tuple_fraction and root->limit_tuples, rather than passing
those values as separate parameters.  Since query_planner no longer does
anything with either value, requiring it to fill the PlannerInfo fields
seemed pretty arbitrary.
This patch just rearranges code; it doesn't (intentionally) change any
behaviors.  Followup patches will do more interesting things.
Diffstat (limited to 'src/backend/optimizer/prep/prepjointree.c')
| -rw-r--r-- | src/backend/optimizer/prep/prepjointree.c | 19 | 
1 files changed, 10 insertions, 9 deletions
| diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 52842931ec5..afeb6ddb8c4 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -1333,15 +1333,16 @@ is_simple_subquery(Query *subquery, RangeTblEntry *rte,  		return false;  	/* -	 * Hack: don't try to pull up a subquery with an empty jointree. -	 * query_planner() will correctly generate a Result plan for a jointree -	 * that's totally empty, but I don't think the right things happen if an -	 * empty FromExpr appears lower down in a jointree.  It would pose a -	 * problem for the PlaceHolderVar mechanism too, since we'd have no way to -	 * identify where to evaluate a PHV coming out of the subquery. Not worth -	 * working hard on this, just to collapse SubqueryScan/Result into Result; -	 * especially since the SubqueryScan can often be optimized away by -	 * setrefs.c anyway. +	 * Don't pull up a subquery with an empty jointree.  query_planner() will +	 * correctly generate a Result plan for a jointree that's totally empty, +	 * but we can't cope with an empty FromExpr appearing lower down in a +	 * jointree: we identify join rels via baserelid sets, so we couldn't +	 * distinguish a join containing such a FromExpr from one without it. +	 * This would for example break the PlaceHolderVar mechanism, since we'd +	 * have no way to identify where to evaluate a PHV coming out of the +	 * subquery.  Not worth working hard on this, just to collapse +	 * SubqueryScan/Result into Result; especially since the SubqueryScan can +	 * often be optimized away by setrefs.c anyway.  	 */  	if (subquery->jointree->fromlist == NIL)  		return false; | 
