Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3ee8f7e

Browse files
committed
Restructure planning code so that preprocessing of targetlist and quals
to simplify constant expressions and expand SubLink nodes into SubPlans is done in a separate routine subquery_planner() that calls union_planner(). We formerly did most of this work in query_planner(), but that's the wrong place because it may never see the real targetlist. Splitting union_planner into two routines also allows us to avoid redundant work when union_planner is invoked recursively for UNION and inheritance cases. Upshot is that it is now possible to do something like select float8(count(*)) / (select count(*) from int4_tbl) from int4_tbl group by f1; which has never worked before.
1 parent aafe86d commit 3ee8f7e

File tree

8 files changed

+186
-161
lines changed

8 files changed

+186
-161
lines changed

src/backend/optimizer/README

+14-7
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,28 @@ than applying a sort to the cheapest other path).
132132
Optimizer Functions
133133
-------------------
134134

135+
The primary entry point is planner().
136+
135137
planner()
136-
handle inheritance by processing separately
137-
-init_query_planner()
138-
preprocess target list
139-
preprocess qualifications(WHERE)
140-
--query_planner()
141-
simplify constant subexpressions
142-
canonicalize_qual()
138+
set up for recursive handling of subqueries
139+
do final cleanup after planning.
140+
-subquery_planner()
141+
simplify constant expressions
142+
canonicalize qual
143143
Attempt to reduce WHERE clause to either CNF or DNF canonical form.
144144
CNF (top-level-AND) is preferred, since the optimizer can then use
145145
any of the AND subclauses to filter tuples; but quals that are in
146146
or close to DNF form will suffer exponential expansion if we try to
147147
force them to CNF. In pathological cases either transform may expand
148148
the qual unreasonably; so we may have to leave it un-normalized,
149149
thereby reducing the accuracy of selectivity estimates.
150+
process sublinks
151+
convert Vars of outer query levels into Params
152+
--union_planner()
153+
handle unions and inheritance by mutual recursion with prepunion.c routines
154+
preprocess target list
155+
handle GROUP BY, HAVING, aggregates, ORDER BY, DISTINCT
156+
--query_planner()
150157
pull out constants from target list
151158
get a target list that only contains column names, no expressions
152159
if none, then return

src/backend/optimizer/plan/planmain.c

+13-65
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,31 @@
33
* planmain.c
44
* Routines to plan a single query
55
*
6+
* What's in a name, anyway? The top-level entry point of the planner/
7+
* optimizer is over in planner.c, not here as you might think from the
8+
* file name. But this is the main code for planning a basic join operation,
9+
* shorn of features like subselects, inheritance, aggregates, grouping,
10+
* and so on. (Those are the things planner.c deals with.)
11+
*
612
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
713
* Portions Copyright (c) 1994, Regents of the University of California
814
*
915
*
1016
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.52 2000/02/15 20:49:18 tgl Exp $
17+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.53 2000/03/21 05:11:58 tgl Exp $
1218
*
1319
*-------------------------------------------------------------------------
1420
*/
15-
#include <sys/types.h>
16-
1721
#include "postgres.h"
1822

23+
#include <sys/types.h>
1924

2025
#include "optimizer/clauses.h"
2126
#include "optimizer/cost.h"
2227
#include "optimizer/pathnode.h"
2328
#include "optimizer/paths.h"
2429
#include "optimizer/planmain.h"
25-
#include "optimizer/prep.h"
26-
#include "optimizer/subselect.h"
2730
#include "optimizer/tlist.h"
28-
#include "utils/lsyscache.h"
2931

3032

3133
static Plan *subplanner(Query *root, List *flat_tlist, List *qual,
@@ -34,19 +36,15 @@ static Plan *subplanner(Query *root, List *flat_tlist, List *qual,
3436

3537
/*--------------------
3638
* query_planner
37-
* Routine to create a query plan. It does so by first creating a
38-
* subplan for the topmost level of attributes in the query. Then,
39-
* it modifies all target list and qualifications to consider the next
40-
* level of nesting and creates a plan for this modified query by
41-
* recursively calling itself. The two pieces are then merged together
42-
* by creating a result node that indicates which attributes should
43-
* be placed where and any relation level qualifications to be
44-
* satisfied.
39+
* Generate a plan for a basic query, which may involve joins but
40+
* not any fancier features.
4541
*
46-
* tlist is the target list of the query (do NOT use root->targetList!)
42+
* tlist is the target list the query should produce (NOT root->targetList!)
4743
* qual is the qualification of the query (likewise!)
4844
* tuple_fraction is the fraction of tuples we expect will be retrieved
4945
*
46+
* qual must already have been converted to implicit-AND form.
47+
*
5048
* Note: the Query node now also includes a query_pathkeys field, which
5149
* is both an input and an output of query_planner(). The input value
5250
* signals query_planner that the indicated sort order is wanted in the
@@ -83,46 +81,6 @@ query_planner(Query *root,
8381
List *var_only_tlist;
8482
Plan *subplan;
8583

86-
/*
87-
* Note: union_planner should already have done constant folding
88-
* in both the tlist and qual, so we don't do it again here
89-
* (indeed, we may be getting a flattened var-only tlist anyway).
90-
*
91-
* Is there any value in re-folding the qual after canonicalize_qual?
92-
*/
93-
94-
/*
95-
* Canonicalize the qual, and convert it to implicit-AND format.
96-
*/
97-
qual = canonicalize_qual((Expr *) qual, true);
98-
#ifdef OPTIMIZER_DEBUG
99-
printf("After canonicalize_qual()\n");
100-
pprint(qual);
101-
#endif
102-
103-
/* Replace uplevel vars with Param nodes */
104-
if (PlannerQueryLevel > 1)
105-
{
106-
tlist = (List *) SS_replace_correlation_vars((Node *) tlist);
107-
qual = (List *) SS_replace_correlation_vars((Node *) qual);
108-
}
109-
110-
/* Expand SubLinks to SubPlans */
111-
if (root->hasSubLinks)
112-
{
113-
tlist = (List *) SS_process_sublinks((Node *) tlist);
114-
qual = (List *) SS_process_sublinks((Node *) qual);
115-
if (root->groupClause != NIL)
116-
{
117-
/*
118-
* Check for ungrouped variables passed to subplans.
119-
* Note we do NOT do this for subplans in WHERE; it's legal
120-
* there because WHERE is evaluated pre-GROUP.
121-
*/
122-
check_subplans_for_ungrouped_vars((Node *) tlist, root, tlist);
123-
}
124-
}
125-
12684
/*
12785
* If the query contains no relation references at all, it must be
12886
* something like "SELECT 2+2;". Build a trivial "Result" plan.
@@ -192,16 +150,6 @@ query_planner(Query *root,
192150
}
193151

194152
return subplan;
195-
196-
#ifdef NOT_USED
197-
198-
/*
199-
* Destructively modify the query plan's targetlist to add fjoin lists
200-
* to flatten functions that return sets of base types
201-
*/
202-
subplan->targetlist = generate_fjoin(subplan->targetlist);
203-
#endif
204-
205153
}
206154

207155
/*

0 commit comments

Comments
 (0)