1 /*-------------------------------------------------------------------------
4 * Routines to plan a single query
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.48 1999/12/09 05:58:52 tgl Exp $
12 *-------------------------------------------------------------------------
14 #include <sys/types.h>
19 #include "optimizer/clauses.h"
20 #include "optimizer/cost.h"
21 #include "optimizer/paths.h"
22 #include "optimizer/planmain.h"
23 #include "optimizer/prep.h"
24 #include "optimizer/subselect.h"
25 #include "optimizer/tlist.h"
26 #include "utils/lsyscache.h"
29 static Plan *subplanner(Query *root, List *flat_tlist, List *qual);
34 * Routine to create a query plan. It does so by first creating a
35 * subplan for the topmost level of attributes in the query. Then,
36 * it modifies all target list and qualifications to consider the next
37 * level of nesting and creates a plan for this modified query by
38 * recursively calling itself. The two pieces are then merged together
39 * by creating a result node that indicates which attributes should
40 * be placed where and any relation level qualifications to be
43 * tlist is the target list of the query (do NOT use root->targetList!)
44 * qual is the qualification of the query (likewise!)
46 * Note: the Query node now also includes a query_pathkeys field, which
47 * is both an input and an output of query_planner(). The input value
48 * signals query_planner that the indicated sort order is wanted in the
49 * final output plan. The output value is the actual pathkeys of the
50 * selected path. This might not be the same as what the caller requested;
51 * the caller must do pathkeys_contained_in() to decide whether an
52 * explicit sort is still needed. (The main reason query_pathkeys is a
53 * Query field and not a passed parameter is that the low-level routines
54 * in indxpath.c need to see it.)
56 * Returns a query plan.
59 query_planner(Query *root,
63 List *constant_qual = NIL;
68 * Note: union_planner should already have done constant folding
69 * in both the tlist and qual, so we don't do it again here
70 * (indeed, we may be getting a flattened var-only tlist anyway).
72 * Is there any value in re-folding the qual after canonicalize_qual?
76 * Canonicalize the qual, and convert it to implicit-AND format.
78 qual = canonicalize_qual((Expr *) qual, true);
79 #ifdef OPTIMIZER_DEBUG
80 printf("After canonicalize_qual()\n");
84 /* Replace uplevel vars with Param nodes */
85 if (PlannerQueryLevel > 1)
87 tlist = (List *) SS_replace_correlation_vars((Node *) tlist);
88 qual = (List *) SS_replace_correlation_vars((Node *) qual);
91 /* Expand SubLinks to SubPlans */
92 if (root->hasSubLinks)
94 tlist = (List *) SS_process_sublinks((Node *) tlist);
95 qual = (List *) SS_process_sublinks((Node *) qual);
96 if (root->groupClause != NIL)
99 * Check for ungrouped variables passed to subplans.
100 * Note we do NOT do this for subplans in WHERE; it's legal
101 * there because WHERE is evaluated pre-GROUP.
103 check_subplans_for_ungrouped_vars((Node *) tlist, root, tlist);
108 * If the query contains no relation references at all, it must be
109 * something like "SELECT 2+2;". Build a trivial "Result" plan.
111 if (root->rtable == NIL)
113 /* If it's not a select, it should have had a target relation... */
114 if (root->commandType != CMD_SELECT)
115 elog(ERROR, "Empty range table for non-SELECT query");
117 root->query_pathkeys = NIL; /* signal unordered result */
119 /* Make childless Result node to evaluate given tlist. */
120 return (Plan *) make_result(tlist, (Node *) qual, (Plan *) NULL);
124 * Pull out any non-variable qual clauses so these can be put in a
125 * toplevel "Result" node, where they will gate execution of the whole
126 * plan (the Result will not invoke its descendant plan unless the
127 * quals are true). Note that any *really* non-variable quals will
128 * have been optimized away by eval_const_expressions(). What we're
129 * mostly interested in here is quals that depend only on outer-level
130 * vars, although if the qual reduces to "WHERE FALSE" this path will
133 qual = pull_constant_clauses(qual, &constant_qual);
136 * Create a target list that consists solely of (resdom var) target
137 * list entries, i.e., contains no arbitrary expressions.
139 * All subplan nodes will have "flat" (var-only) tlists.
141 * This implies that all expression evaluations are done at the root
142 * of the plan tree. Once upon a time there was code to try to push
143 * expensive function calls down to lower plan nodes, but that's dead
144 * code and has been for a long time...
146 var_only_tlist = flatten_tlist(tlist);
149 * Choose the best access path and build a plan for it.
151 subplan = subplanner(root, var_only_tlist, qual);
154 * Build a result node to control the plan if we have constant quals.
159 * The result node will also be responsible for evaluating
160 * the originally requested tlist.
162 subplan = (Plan *) make_result(tlist,
163 (Node *) constant_qual,
169 * Replace the toplevel plan node's flattened target list with the
170 * targetlist given by my caller, so that expressions are evaluated.
172 subplan->targetlist = tlist;
180 * Destructively modify the query plan's targetlist to add fjoin lists
181 * to flatten functions that return sets of base types
183 subplan->targetlist = generate_fjoin(subplan->targetlist);
191 * Subplanner creates an entire plan consisting of joins and scans
192 * for processing a single level of attributes.
194 * flat_tlist is the flattened target list
195 * qual is the qualification to be satisfied
201 subplanner(Query *root,
205 RelOptInfo *final_rel;
210 * Initialize the targetlist and qualification, adding entries to
211 * base_rel_list as relation references are found (e.g., in the
212 * qualification, the targetlist, etc.)
214 root->base_rel_list = NIL;
215 root->join_rel_list = NIL;
217 make_var_only_tlist(root, flat_tlist);
218 add_restrict_and_join_to_rels(root, qual);
219 add_missing_rels_to_query(root);
221 set_joininfo_mergeable_hashable(root->base_rel_list);
223 final_rel = make_one_rel(root, root->base_rel_list);
228 * We expect to end up here for a trivial INSERT ... VALUES query
229 * (which will have a target relation, so it gets past query_planner's
230 * check for empty range table; but the target rel is unreferenced
231 * and not marked inJoinSet, so we find there is nothing to join).
233 * It's also possible to get here if the query was rewritten by the
234 * rule processor (creating rangetable entries not marked inJoinSet)
235 * but the rules either did nothing or were simplified to nothing
236 * by constant-expression folding. So, don't complain.
238 root->query_pathkeys = NIL; /* signal unordered result */
240 /* Make childless Result node to evaluate given tlist. */
241 return (Plan *) make_result(flat_tlist, (Node *) qual, (Plan *) NULL);
244 #ifdef NOT_USED /* fix xfunc */
247 * Perform Predicate Migration on each path, to optimize and correctly
248 * assess the cost of each before choosing the cheapest one. -- JMH,
251 * Needn't do so if the top rel is pruneable: that means there's no
252 * expensive functions left to pull up. -- JMH, 11/22/92
254 if (XfuncMode != XFUNC_OFF && XfuncMode != XFUNC_NOPM &&
255 XfuncMode != XFUNC_NOPULL && !final_rel->pruneable)
259 foreach(pathnode, final_rel->pathlist)
261 if (xfunc_do_predmig((Path *) lfirst(pathnode)))
262 set_cheapest(final_rel, final_rel->pathlist);
268 * Determine the cheapest path and create a subplan to execute it.
270 * If no special sort order is wanted, or if the cheapest path is
271 * already appropriately ordered, just use the cheapest path.
273 if (root->query_pathkeys == NIL ||
274 pathkeys_contained_in(root->query_pathkeys,
275 final_rel->cheapestpath->pathkeys))
277 root->query_pathkeys = final_rel->cheapestpath->pathkeys;
278 return create_plan(final_rel->cheapestpath);
282 * Otherwise, look to see if we have an already-ordered path that is
283 * cheaper than doing an explicit sort on cheapestpath.
285 cheapest_cost = final_rel->cheapestpath->path_cost +
286 cost_sort(root->query_pathkeys, final_rel->size, final_rel->width);
288 sortedpath = get_cheapest_path_for_pathkeys(final_rel->pathlist,
289 root->query_pathkeys,
293 if (sortedpath->path_cost <= cheapest_cost)
295 /* Found a better presorted path, use it */
296 root->query_pathkeys = sortedpath->pathkeys;
297 return create_plan(sortedpath);
299 /* otherwise, doing it the hard way is still cheaper */
304 * If we found no usable presorted path at all, it is possible
305 * that the user asked for descending sort order. Check to see
306 * if we can satisfy the pathkeys by using a backwards indexscan.
307 * To do this, we commute all the operators in the pathkeys and
308 * then look for a matching path that is an IndexPath.
310 List *commuted_pathkeys = copyObject(root->query_pathkeys);
312 if (commute_pathkeys(commuted_pathkeys))
314 /* pass 'true' to force only IndexPaths to be considered */
315 sortedpath = get_cheapest_path_for_pathkeys(final_rel->pathlist,
318 if (sortedpath && sortedpath->path_cost <= cheapest_cost)
321 * Kluge here: since IndexPath has no representation for
322 * backwards scan, we have to convert to Plan format and
323 * then poke the result.
325 Plan *sortedplan = create_plan(sortedpath);
326 List *sortedpathkeys;
328 Assert(IsA(sortedplan, IndexScan));
329 ((IndexScan *) sortedplan)->indxorderdir = BackwardScanDirection;
331 * Need to generate commuted keys representing the actual
332 * sort order. This should succeed, probably, but just in
333 * case it does not, use the original root->query_pathkeys
334 * as a conservative approximation.
336 sortedpathkeys = copyObject(sortedpath->pathkeys);
337 if (commute_pathkeys(sortedpathkeys))
338 root->query_pathkeys = sortedpathkeys;
346 * Nothing for it but to sort the cheapestpath --- but we let the
347 * caller do that. union_planner has to be able to add a sort node
348 * anyway, so no need for extra code here. (Furthermore, the given
349 * pathkeys might involve something we can't compute here, such as
350 * an aggregate function...)
352 root->query_pathkeys = final_rel->cheapestpath->pathkeys;
353 return create_plan(final_rel->cheapestpath);