|
20 | 20 | */ |
21 | 21 | #include"postgres.h" |
22 | 22 |
|
23 | | -#include"miscadmin.h" |
24 | | -#include"optimizer/cost.h" |
25 | 23 | #include"optimizer/pathnode.h" |
26 | 24 | #include"optimizer/paths.h" |
27 | 25 | #include"optimizer/placeholder.h" |
28 | 26 | #include"optimizer/planmain.h" |
29 | | -#include"optimizer/tlist.h" |
30 | | -#include"utils/selfuncs.h" |
31 | 27 |
|
32 | 28 |
|
33 | 29 | /* |
|
36 | 32 | * which may involve joins but not any fancier features. |
37 | 33 | * |
38 | 34 | * Since query_planner does not handle the toplevel processing (grouping, |
39 | | - * sorting, etc) it cannot select the best path by itself.It selects |
40 | | - * two paths: the cheapest path that produces all the required tuples, |
41 | | - * independent of any ordering considerations, and the cheapest path that |
42 | | - * produces the expected fraction of the required tuples in the required |
43 | | - * ordering, if there is a path that is cheaper for this than just sorting |
44 | | - * the output of the cheapest overall path. The caller (grouping_planner) |
45 | | - * will make the final decision about which to use. |
| 35 | + * sorting, etc) it cannot select the best path by itself.Instead, it |
| 36 | + * returns the RelOptInfo for the top level of joining, and the caller |
| 37 | + * (grouping_planner) can choose one of the surviving paths for the rel. |
| 38 | + * Normally it would choose either the rel's cheapest path, or the cheapest |
| 39 | + * path for the desired sort order. |
46 | 40 | * |
47 | | - * Input parameters: |
48 | 41 | * root describes the query to plan |
49 | 42 | * tlist is the target list the query should produce |
50 | 43 | *(this is NOT necessarily root->parse->targetList!) |
51 | | - * tuple_fraction is the fraction of tuples we expect will be retrieved |
52 | | - * limit_tuples is a hard limit on number of tuples to retrieve, |
53 | | - *or -1 if no limit |
54 | 44 | * qp_callback is a function to compute query_pathkeys once it's safe to do so |
55 | 45 | * qp_extra is optional extra data to pass to qp_callback |
56 | 46 | * |
57 | | - * Output parameters: |
58 | | - * *cheapest_path receives the overall-cheapest path for the query |
59 | | - * *sorted_path receives the cheapest presorted path for the query, |
60 | | - *if any (NULL if there is no useful presorted path) |
61 | | - * *num_groups receives the estimated number of groups, or 1 if query |
62 | | - *does not use grouping |
63 | | - * |
64 | 47 | * Note: the PlannerInfo node also includes a query_pathkeys field, which |
65 | 48 | * tells query_planner the sort order that is desired in the final output |
66 | 49 | * plan. This value is *not* available at call time, but is computed by |
67 | 50 | * qp_callback once we have completed merging the query's equivalence classes. |
68 | 51 | * (We cannot construct canonical pathkeys until that's done.) |
69 | | - * |
70 | | - * tuple_fraction is interpreted as follows: |
71 | | - * 0: expect all tuples to be retrieved (normal case) |
72 | | - * 0 < tuple_fraction < 1: expect the given fraction of tuples available |
73 | | - *from the plan to be retrieved |
74 | | - * tuple_fraction >= 1: tuple_fraction is the absolute number of tuples |
75 | | - *expected to be retrieved (ie, a LIMIT specification) |
76 | | - * Note that a nonzero tuple_fraction could come from outer context; it is |
77 | | - * therefore not redundant with limit_tuples. We use limit_tuples to determine |
78 | | - * whether a bounded sort can be used at runtime. |
79 | 52 | */ |
80 | | -void |
| 53 | +RelOptInfo* |
81 | 54 | query_planner(PlannerInfo*root,List*tlist, |
82 | | -doubletuple_fraction,doublelimit_tuples, |
83 | | -query_pathkeys_callbackqp_callback,void*qp_extra, |
84 | | -Path**cheapest_path,Path**sorted_path, |
85 | | -double*num_groups) |
| 55 | +query_pathkeys_callbackqp_callback,void*qp_extra) |
86 | 56 | { |
87 | 57 | Query*parse=root->parse; |
88 | 58 | List*joinlist; |
89 | 59 | RelOptInfo*final_rel; |
90 | | -Path*cheapestpath; |
91 | | -Path*sortedpath; |
92 | 60 | Indexrti; |
93 | 61 | doubletotal_pages; |
94 | 62 |
|
95 | | -/* Make tuple_fraction, limit_tuples accessible to lower-level routines */ |
96 | | -root->tuple_fraction=tuple_fraction; |
97 | | -root->limit_tuples=limit_tuples; |
98 | | - |
99 | | -*num_groups=1;/* default result */ |
100 | | - |
101 | 63 | /* |
102 | 64 | * If the query has an empty join tree, then it's something easy like |
103 | 65 | * "SELECT 2+2;" or "INSERT ... VALUES()".Fall through quickly. |
104 | 66 | */ |
105 | 67 | if (parse->jointree->fromlist==NIL) |
106 | 68 | { |
107 | | -/* We need a trivial path result */ |
108 | | -*cheapest_path= (Path*) |
109 | | -create_result_path((List*)parse->jointree->quals); |
110 | | -*sorted_path=NULL; |
| 69 | +/* We need a dummy joinrel to describe the empty set of baserels */ |
| 70 | +final_rel=build_empty_join_rel(root); |
| 71 | + |
| 72 | +/* The only path for it is a trivial Result path */ |
| 73 | +add_path(final_rel, (Path*) |
| 74 | +create_result_path((List*)parse->jointree->quals)); |
| 75 | + |
| 76 | +/* Select cheapest path (pretty easy in this case...) */ |
| 77 | +set_cheapest(final_rel); |
111 | 78 |
|
112 | 79 | /* |
113 | 80 | * We still are required to call qp_callback, in case it's something |
114 | 81 | * like "SELECT 2+2 ORDER BY 1". |
115 | 82 | */ |
116 | 83 | root->canon_pathkeys=NIL; |
117 | 84 | (*qp_callback) (root,qp_extra); |
118 | | -return; |
| 85 | + |
| 86 | +returnfinal_rel; |
119 | 87 | } |
120 | 88 |
|
121 | 89 | /* |
@@ -259,165 +227,10 @@ query_planner(PlannerInfo *root, List *tlist, |
259 | 227 | */ |
260 | 228 | final_rel=make_one_rel(root,joinlist); |
261 | 229 |
|
| 230 | +/* Check that we got at least one usable path */ |
262 | 231 | if (!final_rel|| !final_rel->cheapest_total_path|| |
263 | 232 | final_rel->cheapest_total_path->param_info!=NULL) |
264 | 233 | elog(ERROR,"failed to construct the join relation"); |
265 | 234 |
|
266 | | -/* |
267 | | - * If there's grouping going on, estimate the number of result groups. We |
268 | | - * couldn't do this any earlier because it depends on relation size |
269 | | - * estimates that were set up above. |
270 | | - * |
271 | | - * Then convert tuple_fraction to fractional form if it is absolute, and |
272 | | - * adjust it based on the knowledge that grouping_planner will be doing |
273 | | - * grouping or aggregation work with our result. |
274 | | - * |
275 | | - * This introduces some undesirable coupling between this code and |
276 | | - * grouping_planner, but the alternatives seem even uglier; we couldn't |
277 | | - * pass back completed paths without making these decisions here. |
278 | | - */ |
279 | | -if (parse->groupClause) |
280 | | -{ |
281 | | -List*groupExprs; |
282 | | - |
283 | | -groupExprs=get_sortgrouplist_exprs(parse->groupClause, |
284 | | -parse->targetList); |
285 | | -*num_groups=estimate_num_groups(root, |
286 | | -groupExprs, |
287 | | -final_rel->rows); |
288 | | - |
289 | | -/* |
290 | | - * In GROUP BY mode, an absolute LIMIT is relative to the number of |
291 | | - * groups not the number of tuples. If the caller gave us a fraction, |
292 | | - * keep it as-is. (In both cases, we are effectively assuming that |
293 | | - * all the groups are about the same size.) |
294 | | - */ |
295 | | -if (tuple_fraction >=1.0) |
296 | | -tuple_fraction /=*num_groups; |
297 | | - |
298 | | -/* |
299 | | - * If both GROUP BY and ORDER BY are specified, we will need two |
300 | | - * levels of sort --- and, therefore, certainly need to read all the |
301 | | - * tuples --- unless ORDER BY is a subset of GROUP BY.Likewise if we |
302 | | - * have both DISTINCT and GROUP BY, or if we have a window |
303 | | - * specification not compatible with the GROUP BY. |
304 | | - */ |
305 | | -if (!pathkeys_contained_in(root->sort_pathkeys,root->group_pathkeys)|| |
306 | | -!pathkeys_contained_in(root->distinct_pathkeys,root->group_pathkeys)|| |
307 | | - !pathkeys_contained_in(root->window_pathkeys,root->group_pathkeys)) |
308 | | -tuple_fraction=0.0; |
309 | | - |
310 | | -/* In any case, limit_tuples shouldn't be specified here */ |
311 | | -Assert(limit_tuples<0); |
312 | | -} |
313 | | -elseif (parse->hasAggs||root->hasHavingQual) |
314 | | -{ |
315 | | -/* |
316 | | - * Ungrouped aggregate will certainly want to read all the tuples, and |
317 | | - * it will deliver a single result row (so leave *num_groups 1). |
318 | | - */ |
319 | | -tuple_fraction=0.0; |
320 | | - |
321 | | -/* limit_tuples shouldn't be specified here */ |
322 | | -Assert(limit_tuples<0); |
323 | | -} |
324 | | -elseif (parse->distinctClause) |
325 | | -{ |
326 | | -/* |
327 | | - * Since there was no grouping or aggregation, it's reasonable to |
328 | | - * assume the UNIQUE filter has effects comparable to GROUP BY. Return |
329 | | - * the estimated number of output rows for use by caller. (If DISTINCT |
330 | | - * is used with grouping, we ignore its effects for rowcount |
331 | | - * estimation purposes; this amounts to assuming the grouped rows are |
332 | | - * distinct already.) |
333 | | - */ |
334 | | -List*distinctExprs; |
335 | | - |
336 | | -distinctExprs=get_sortgrouplist_exprs(parse->distinctClause, |
337 | | -parse->targetList); |
338 | | -*num_groups=estimate_num_groups(root, |
339 | | -distinctExprs, |
340 | | -final_rel->rows); |
341 | | - |
342 | | -/* |
343 | | - * Adjust tuple_fraction the same way as for GROUP BY, too. |
344 | | - */ |
345 | | -if (tuple_fraction >=1.0) |
346 | | -tuple_fraction /=*num_groups; |
347 | | - |
348 | | -/* limit_tuples shouldn't be specified here */ |
349 | | -Assert(limit_tuples<0); |
350 | | -} |
351 | | -else |
352 | | -{ |
353 | | -/* |
354 | | - * Plain non-grouped, non-aggregated query: an absolute tuple fraction |
355 | | - * can be divided by the number of tuples. |
356 | | - */ |
357 | | -if (tuple_fraction >=1.0) |
358 | | -tuple_fraction /=final_rel->rows; |
359 | | -} |
360 | | - |
361 | | -/* |
362 | | - * Pick out the cheapest-total path and the cheapest presorted path for |
363 | | - * the requested pathkeys (if there is one). We should take the tuple |
364 | | - * fraction into account when selecting the cheapest presorted path, but |
365 | | - * not when selecting the cheapest-total path, since if we have to sort |
366 | | - * then we'll have to fetch all the tuples. (But there's a special case: |
367 | | - * if query_pathkeys is NIL, meaning order doesn't matter, then the |
368 | | - * "cheapest presorted" path will be the cheapest overall for the tuple |
369 | | - * fraction.) |
370 | | - * |
371 | | - * The cheapest-total path is also the one to use if grouping_planner |
372 | | - * decides to use hashed aggregation, so we return it separately even if |
373 | | - * this routine thinks the presorted path is the winner. |
374 | | - */ |
375 | | -cheapestpath=final_rel->cheapest_total_path; |
376 | | - |
377 | | -sortedpath= |
378 | | -get_cheapest_fractional_path_for_pathkeys(final_rel->pathlist, |
379 | | -root->query_pathkeys, |
380 | | -NULL, |
381 | | -tuple_fraction); |
382 | | - |
383 | | -/* Don't return same path in both guises; just wastes effort */ |
384 | | -if (sortedpath==cheapestpath) |
385 | | -sortedpath=NULL; |
386 | | - |
387 | | -/* |
388 | | - * Forget about the presorted path if it would be cheaper to sort the |
389 | | - * cheapest-total path. Here we need consider only the behavior at the |
390 | | - * tuple fraction point. |
391 | | - */ |
392 | | -if (sortedpath) |
393 | | -{ |
394 | | -Pathsort_path;/* dummy for result of cost_sort */ |
395 | | - |
396 | | -if (root->query_pathkeys==NIL|| |
397 | | -pathkeys_contained_in(root->query_pathkeys, |
398 | | -cheapestpath->pathkeys)) |
399 | | -{ |
400 | | -/* No sort needed for cheapest path */ |
401 | | -sort_path.startup_cost=cheapestpath->startup_cost; |
402 | | -sort_path.total_cost=cheapestpath->total_cost; |
403 | | -} |
404 | | -else |
405 | | -{ |
406 | | -/* Figure cost for sorting */ |
407 | | -cost_sort(&sort_path,root,root->query_pathkeys, |
408 | | -cheapestpath->total_cost, |
409 | | -final_rel->rows,final_rel->width, |
410 | | -0.0,work_mem,limit_tuples); |
411 | | -} |
412 | | - |
413 | | -if (compare_fractional_path_costs(sortedpath,&sort_path, |
414 | | -tuple_fraction)>0) |
415 | | -{ |
416 | | -/* Presorted path is a loser */ |
417 | | -sortedpath=NULL; |
418 | | -} |
419 | | -} |
420 | | - |
421 | | -*cheapest_path=cheapestpath; |
422 | | -*sorted_path=sortedpath; |
| 235 | +returnfinal_rel; |
423 | 236 | } |