1/*-------------------------------------------------------------------------
2 *
3 * createplan.c
4 * Routines to create the desired plan for processing a query.
5 * Planning is complete, we just need to convert the selected
6 * Path into a Plan.
7 *
8 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
10 *
11 *
12 * IDENTIFICATION
13 * src/backend/optimizer/plan/createplan.c
14 *
15 *-------------------------------------------------------------------------
16 */
17#include "postgres.h"
18
19#include <limits.h>
20#include <math.h>
21
22#include "access/sysattr.h"
23#include "catalog/pg_class.h"
24#include "foreign/fdwapi.h"
25#include "miscadmin.h"
26#include "nodes/extensible.h"
27#include "nodes/makefuncs.h"
28#include "nodes/nodeFuncs.h"
29#include "optimizer/clauses.h"
30#include "optimizer/cost.h"
31#include "optimizer/optimizer.h"
32#include "optimizer/paramassign.h"
33#include "optimizer/paths.h"
34#include "optimizer/placeholder.h"
35#include "optimizer/plancat.h"
36#include "optimizer/planmain.h"
37#include "optimizer/restrictinfo.h"
38#include "optimizer/subselect.h"
39#include "optimizer/tlist.h"
40#include "parser/parse_clause.h"
41#include "parser/parsetree.h"
42#include "partitioning/partprune.h"
43#include "utils/lsyscache.h"
44
45
46/*
47 * Flag bits that can appear in the flags argument of create_plan_recurse().
48 * These can be OR-ed together.
49 *
50 * CP_EXACT_TLIST specifies that the generated plan node must return exactly
51 * the tlist specified by the path's pathtarget (this overrides both
52 * CP_SMALL_TLIST and CP_LABEL_TLIST, if those are set). Otherwise, the
53 * plan node is allowed to return just the Vars and PlaceHolderVars needed
54 * to evaluate the pathtarget.
55 *
56 * CP_SMALL_TLIST specifies that a narrower tlist is preferred. This is
57 * passed down by parent nodes such as Sort and Hash, which will have to
58 * store the returned tuples.
59 *
60 * CP_LABEL_TLIST specifies that the plan node must return columns matching
61 * any sortgrouprefs specified in its pathtarget, with appropriate
62 * ressortgroupref labels. This is passed down by parent nodes such as Sort
63 * and Group, which need these values to be available in their inputs.
64 *
65 * CP_IGNORE_TLIST specifies that the caller plans to replace the targetlist,
66 * and therefore it doesn't matter a bit what target list gets generated.
67 */
68#define CP_EXACT_TLIST 0x0001 /* Plan must return specified tlist */
69#define CP_SMALL_TLIST 0x0002 /* Prefer narrower tlists */
70#define CP_LABEL_TLIST 0x0004 /* tlist must contain sortgrouprefs */
71#define CP_IGNORE_TLIST 0x0008 /* caller will replace tlist */
72
73
74static Plan *create_plan_recurse(PlannerInfo *root, Path *best_path,
75 int flags);
76static Plan *create_scan_plan(PlannerInfo *root, Path *best_path,
77 int flags);
78static List *build_path_tlist(PlannerInfo *root, Path *path);
79static bool use_physical_tlist(PlannerInfo *root, Path *path, int flags);
80static List *get_gating_quals(PlannerInfo *root, List *quals);
81static Plan *create_gating_plan(PlannerInfo *root, Path *path, Plan *plan,
82 List *gating_quals);
83static Plan *create_join_plan(PlannerInfo *root, JoinPath *best_path);
84static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path,
85 int flags);
86static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
87 int flags);
88static Result *create_group_result_plan(PlannerInfo *root,
89 GroupResultPath *best_path);
90static ProjectSet *create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path);
91static Material *create_material_plan(PlannerInfo *root, MaterialPath *best_path,
92 int flags);
93static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path,
94 int flags);
95static Gather *create_gather_plan(PlannerInfo *root, GatherPath *best_path);
96static Plan *create_projection_plan(PlannerInfo *root,
97 ProjectionPath *best_path,
98 int flags);
99static Plan *inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe);
100static Sort *create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags);
101static Group *create_group_plan(PlannerInfo *root, GroupPath *best_path);
102static Unique *create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path,
103 int flags);
104static Agg *create_agg_plan(PlannerInfo *root, AggPath *best_path);
105static Plan *create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path);
106static Result *create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path);
107static WindowAgg *create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path);
108static SetOp *create_setop_plan(PlannerInfo *root, SetOpPath *best_path,
109 int flags);
110static RecursiveUnion *create_recursiveunion_plan(PlannerInfo *root, RecursiveUnionPath *best_path);
111static LockRows *create_lockrows_plan(PlannerInfo *root, LockRowsPath *best_path,
112 int flags);
113static ModifyTable *create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path);
114static Limit *create_limit_plan(PlannerInfo *root, LimitPath *best_path,
115 int flags);
116static SeqScan *create_seqscan_plan(PlannerInfo *root, Path *best_path,
117 List *tlist, List *scan_clauses);
118static SampleScan *create_samplescan_plan(PlannerInfo *root, Path *best_path,
119 List *tlist, List *scan_clauses);
120static Scan *create_indexscan_plan(PlannerInfo *root, IndexPath *best_path,
121 List *tlist, List *scan_clauses, bool indexonly);
122static BitmapHeapScan *create_bitmap_scan_plan(PlannerInfo *root,
123 BitmapHeapPath *best_path,
124 List *tlist, List *scan_clauses);
125static Plan *create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
126 List **qual, List **indexqual, List **indexECs);
127static void bitmap_subplan_mark_shared(Plan *plan);
128static TidScan *create_tidscan_plan(PlannerInfo *root, TidPath *best_path,
129 List *tlist, List *scan_clauses);
130static SubqueryScan *create_subqueryscan_plan(PlannerInfo *root,
131 SubqueryScanPath *best_path,
132 List *tlist, List *scan_clauses);
133static FunctionScan *create_functionscan_plan(PlannerInfo *root, Path *best_path,
134 List *tlist, List *scan_clauses);
135static ValuesScan *create_valuesscan_plan(PlannerInfo *root, Path *best_path,
136 List *tlist, List *scan_clauses);
137static TableFuncScan *create_tablefuncscan_plan(PlannerInfo *root, Path *best_path,
138 List *tlist, List *scan_clauses);
139static CteScan *create_ctescan_plan(PlannerInfo *root, Path *best_path,
140 List *tlist, List *scan_clauses);
141static NamedTuplestoreScan *create_namedtuplestorescan_plan(PlannerInfo *root,
142 Path *best_path, List *tlist, List *scan_clauses);
143static Result *create_resultscan_plan(PlannerInfo *root, Path *best_path,
144 List *tlist, List *scan_clauses);
145static WorkTableScan *create_worktablescan_plan(PlannerInfo *root, Path *best_path,
146 List *tlist, List *scan_clauses);
147static ForeignScan *create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
148 List *tlist, List *scan_clauses);
149static CustomScan *create_customscan_plan(PlannerInfo *root,
150 CustomPath *best_path,
151 List *tlist, List *scan_clauses);
152static NestLoop *create_nestloop_plan(PlannerInfo *root, NestPath *best_path);
153static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path);
154static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path);
155static Node *replace_nestloop_params(PlannerInfo *root, Node *expr);
156static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root);
157static void fix_indexqual_references(PlannerInfo *root, IndexPath *index_path,
158 List **stripped_indexquals_p,
159 List **fixed_indexquals_p);
160static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
161static Node *fix_indexqual_clause(PlannerInfo *root,
162 IndexOptInfo *index, int indexcol,
163 Node *clause, List *indexcolnos);
164static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
165static List *get_switched_clauses(List *clauses, Relids outerrelids);
166static List *order_qual_clauses(PlannerInfo *root, List *clauses);
167static void copy_generic_path_info(Plan *dest, Path *src);
168static void copy_plan_costsize(Plan *dest, Plan *src);
169static void label_sort_with_costsize(PlannerInfo *root, Sort *plan,
170 double limit_tuples);
171static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
172static SampleScan *make_samplescan(List *qptlist, List *qpqual, Index scanrelid,
173 TableSampleClause *tsc);
174static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
175 Oid indexid, List *indexqual, List *indexqualorig,
176 List *indexorderby, List *indexorderbyorig,
177 List *indexorderbyops,
178 ScanDirection indexscandir);
179static IndexOnlyScan *make_indexonlyscan(List *qptlist, List *qpqual,
180 Index scanrelid, Oid indexid,
181 List *indexqual, List *indexorderby,
182 List *indextlist,
183 ScanDirection indexscandir);
184static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid,
185 List *indexqual,
186 List *indexqualorig);
187static BitmapHeapScan *make_bitmap_heapscan(List *qptlist,
188 List *qpqual,
189 Plan *lefttree,
190 List *bitmapqualorig,
191 Index scanrelid);
192static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
193 List *tidquals);
194static SubqueryScan *make_subqueryscan(List *qptlist,
195 List *qpqual,
196 Index scanrelid,
197 Plan *subplan);
198static FunctionScan *make_functionscan(List *qptlist, List *qpqual,
199 Index scanrelid, List *functions, bool funcordinality);
200static ValuesScan *make_valuesscan(List *qptlist, List *qpqual,
201 Index scanrelid, List *values_lists);
202static TableFuncScan *make_tablefuncscan(List *qptlist, List *qpqual,
203 Index scanrelid, TableFunc *tablefunc);
204static CteScan *make_ctescan(List *qptlist, List *qpqual,
205 Index scanrelid, int ctePlanId, int cteParam);
206static NamedTuplestoreScan *make_namedtuplestorescan(List *qptlist, List *qpqual,
207 Index scanrelid, char *enrname);
208static WorkTableScan *make_worktablescan(List *qptlist, List *qpqual,
209 Index scanrelid, int wtParam);
210static RecursiveUnion *make_recursive_union(List *tlist,
211 Plan *lefttree,
212 Plan *righttree,
213 int wtParam,
214 List *distinctList,
215 long numGroups);
216static BitmapAnd *make_bitmap_and(List *bitmapplans);
217static BitmapOr *make_bitmap_or(List *bitmapplans);
218static NestLoop *make_nestloop(List *tlist,
219 List *joinclauses, List *otherclauses, List *nestParams,
220 Plan *lefttree, Plan *righttree,
221 JoinType jointype, bool inner_unique);
222static HashJoin *make_hashjoin(List *tlist,
223 List *joinclauses, List *otherclauses,
224 List *hashclauses,
225 List *hashoperators, List *hashcollations,
226 List *hashkeys,
227 Plan *lefttree, Plan *righttree,
228 JoinType jointype, bool inner_unique);
229static Hash *make_hash(Plan *lefttree,
230 List *hashkeys,
231 Oid skewTable,
232 AttrNumber skewColumn,
233 bool skewInherit);
234static MergeJoin *make_mergejoin(List *tlist,
235 List *joinclauses, List *otherclauses,
236 List *mergeclauses,
237 Oid *mergefamilies,
238 Oid *mergecollations,
239 int *mergestrategies,
240 bool *mergenullsfirst,
241 Plan *lefttree, Plan *righttree,
242 JoinType jointype, bool inner_unique,
243 bool skip_mark_restore);
244static Sort *make_sort(Plan *lefttree, int numCols,
245 AttrNumber *sortColIdx, Oid *sortOperators,
246 Oid *collations, bool *nullsFirst);
247static Plan *prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
248 Relids relids,
249 const AttrNumber *reqColIdx,
250 bool adjust_tlist_in_place,
251 int *p_numsortkeys,
252 AttrNumber **p_sortColIdx,
253 Oid **p_sortOperators,
254 Oid **p_collations,
255 bool **p_nullsFirst);
256static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec,
257 TargetEntry *tle,
258 Relids relids);
259static Sort *make_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
260 Relids relids);
261static Sort *make_sort_from_groupcols(List *groupcls,
262 AttrNumber *grpColIdx,
263 Plan *lefttree);
264static Material *make_material(Plan *lefttree);
265static WindowAgg *make_windowagg(List *tlist, Index winref,
266 int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,
267 int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,
268 int frameOptions, Node *startOffset, Node *endOffset,
269 Oid startInRangeFunc, Oid endInRangeFunc,
270 Oid inRangeColl, bool inRangeAsc, bool inRangeNullsFirst,
271 Plan *lefttree);
272static Group *make_group(List *tlist, List *qual, int numGroupCols,
273 AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,
274 Plan *lefttree);
275static Unique *make_unique_from_sortclauses(Plan *lefttree, List *distinctList);
276static Unique *make_unique_from_pathkeys(Plan *lefttree,
277 List *pathkeys, int numCols);
278static Gather *make_gather(List *qptlist, List *qpqual,
279 int nworkers, int rescan_param, bool single_copy, Plan *subplan);
280static SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree,
281 List *distinctList, AttrNumber flagColIdx, int firstFlag,
282 long numGroups);
283static LockRows *make_lockrows(Plan *lefttree, List *rowMarks, int epqParam);
284static Result *make_result(List *tlist, Node *resconstantqual, Plan *subplan);
285static ProjectSet *make_project_set(List *tlist, Plan *subplan);
286static ModifyTable *make_modifytable(PlannerInfo *root,
287 CmdType operation, bool canSetTag,
288 Index nominalRelation, Index rootRelation,
289 bool partColsUpdated,
290 List *resultRelations, List *subplans, List *subroots,
291 List *withCheckOptionLists, List *returningLists,
292 List *rowMarks, OnConflictExpr *onconflict, int epqParam);
293static GatherMerge *create_gather_merge_plan(PlannerInfo *root,
294 GatherMergePath *best_path);
295
296
297/*
298 * create_plan
299 * Creates the access plan for a query by recursively processing the
300 * desired tree of pathnodes, starting at the node 'best_path'. For
301 * every pathnode found, we create a corresponding plan node containing
302 * appropriate id, target list, and qualification information.
303 *
304 * The tlists and quals in the plan tree are still in planner format,
305 * ie, Vars still correspond to the parser's numbering. This will be
306 * fixed later by setrefs.c.
307 *
308 * best_path is the best access path
309 *
310 * Returns a Plan tree.
311 */
312Plan *
313create_plan(PlannerInfo *root, Path *best_path)
314{
315 Plan *plan;
316
317 /* plan_params should not be in use in current query level */
318 Assert(root->plan_params == NIL);
319
320 /* Initialize this module's workspace in PlannerInfo */
321 root->curOuterRels = NULL;
322 root->curOuterParams = NIL;
323
324 /* Recursively process the path tree, demanding the correct tlist result */
325 plan = create_plan_recurse(root, best_path, CP_EXACT_TLIST);
326
327 /*
328 * Make sure the topmost plan node's targetlist exposes the original
329 * column names and other decorative info. Targetlists generated within
330 * the planner don't bother with that stuff, but we must have it on the
331 * top-level tlist seen at execution time. However, ModifyTable plan
332 * nodes don't have a tlist matching the querytree targetlist.
333 */
334 if (!IsA(plan, ModifyTable))
335 apply_tlist_labeling(plan->targetlist, root->processed_tlist);
336
337 /*
338 * Attach any initPlans created in this query level to the topmost plan
339 * node. (In principle the initplans could go in any plan node at or
340 * above where they're referenced, but there seems no reason to put them
341 * any lower than the topmost node for the query level. Also, see
342 * comments for SS_finalize_plan before you try to change this.)
343 */
344 SS_attach_initplans(root, plan);
345
346 /* Check we successfully assigned all NestLoopParams to plan nodes */
347 if (root->curOuterParams != NIL)
348 elog(ERROR, "failed to assign all NestLoopParams to plan nodes");
349
350 /*
351 * Reset plan_params to ensure param IDs used for nestloop params are not
352 * re-used later
353 */
354 root->plan_params = NIL;
355
356 return plan;
357}
358
359/*
360 * create_plan_recurse
361 * Recursive guts of create_plan().
362 */
363static Plan *
364create_plan_recurse(PlannerInfo *root, Path *best_path, int flags)
365{
366 Plan *plan;
367
368 /* Guard against stack overflow due to overly complex plans */
369 check_stack_depth();
370
371 switch (best_path->pathtype)
372 {
373 case T_SeqScan:
374 case T_SampleScan:
375 case T_IndexScan:
376 case T_IndexOnlyScan:
377 case T_BitmapHeapScan:
378 case T_TidScan:
379 case T_SubqueryScan:
380 case T_FunctionScan:
381 case T_TableFuncScan:
382 case T_ValuesScan:
383 case T_CteScan:
384 case T_WorkTableScan:
385 case T_NamedTuplestoreScan:
386 case T_ForeignScan:
387 case T_CustomScan:
388 plan = create_scan_plan(root, best_path, flags);
389 break;
390 case T_HashJoin:
391 case T_MergeJoin:
392 case T_NestLoop:
393 plan = create_join_plan(root,
394 (JoinPath *) best_path);
395 break;
396 case T_Append:
397 plan = create_append_plan(root,
398 (AppendPath *) best_path,
399 flags);
400 break;
401 case T_MergeAppend:
402 plan = create_merge_append_plan(root,
403 (MergeAppendPath *) best_path,
404 flags);
405 break;
406 case T_Result:
407 if (IsA(best_path, ProjectionPath))
408 {
409 plan = create_projection_plan(root,
410 (ProjectionPath *) best_path,
411 flags);
412 }
413 else if (IsA(best_path, MinMaxAggPath))
414 {
415 plan = (Plan *) create_minmaxagg_plan(root,
416 (MinMaxAggPath *) best_path);
417 }
418 else if (IsA(best_path, GroupResultPath))
419 {
420 plan = (Plan *) create_group_result_plan(root,
421 (GroupResultPath *) best_path);
422 }
423 else
424 {
425 /* Simple RTE_RESULT base relation */
426 Assert(IsA(best_path, Path));
427 plan = create_scan_plan(root, best_path, flags);
428 }
429 break;
430 case T_ProjectSet:
431 plan = (Plan *) create_project_set_plan(root,
432 (ProjectSetPath *) best_path);
433 break;
434 case T_Material:
435 plan = (Plan *) create_material_plan(root,
436 (MaterialPath *) best_path,
437 flags);
438 break;
439 case T_Unique:
440 if (IsA(best_path, UpperUniquePath))
441 {
442 plan = (Plan *) create_upper_unique_plan(root,
443 (UpperUniquePath *) best_path,
444 flags);
445 }
446 else
447 {
448 Assert(IsA(best_path, UniquePath));
449 plan = create_unique_plan(root,
450 (UniquePath *) best_path,
451 flags);
452 }
453 break;
454 case T_Gather:
455 plan = (Plan *) create_gather_plan(root,
456 (GatherPath *) best_path);
457 break;
458 case T_Sort:
459 plan = (Plan *) create_sort_plan(root,
460 (SortPath *) best_path,
461 flags);
462 break;
463 case T_Group:
464 plan = (Plan *) create_group_plan(root,
465 (GroupPath *) best_path);
466 break;
467 case T_Agg:
468 if (IsA(best_path, GroupingSetsPath))
469 plan = create_groupingsets_plan(root,
470 (GroupingSetsPath *) best_path);
471 else
472 {
473 Assert(IsA(best_path, AggPath));
474 plan = (Plan *) create_agg_plan(root,
475 (AggPath *) best_path);
476 }
477 break;
478 case T_WindowAgg:
479 plan = (Plan *) create_windowagg_plan(root,
480 (WindowAggPath *) best_path);
481 break;
482 case T_SetOp:
483 plan = (Plan *) create_setop_plan(root,
484 (SetOpPath *) best_path,
485 flags);
486 break;
487 case T_RecursiveUnion:
488 plan = (Plan *) create_recursiveunion_plan(root,
489 (RecursiveUnionPath *) best_path);
490 break;
491 case T_LockRows:
492 plan = (Plan *) create_lockrows_plan(root,
493 (LockRowsPath *) best_path,
494 flags);
495 break;
496 case T_ModifyTable:
497 plan = (Plan *) create_modifytable_plan(root,
498 (ModifyTablePath *) best_path);
499 break;
500 case T_Limit:
501 plan = (Plan *) create_limit_plan(root,
502 (LimitPath *) best_path,
503 flags);
504 break;
505 case T_GatherMerge:
506 plan = (Plan *) create_gather_merge_plan(root,
507 (GatherMergePath *) best_path);
508 break;
509 default:
510 elog(ERROR, "unrecognized node type: %d",
511 (int) best_path->pathtype);
512 plan = NULL; /* keep compiler quiet */
513 break;
514 }
515
516 return plan;
517}
518
519/*
520 * create_scan_plan
521 * Create a scan plan for the parent relation of 'best_path'.
522 */
523static Plan *
524create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
525{
526 RelOptInfo *rel = best_path->parent;
527 List *scan_clauses;
528 List *gating_clauses;
529 List *tlist;
530 Plan *plan;
531
532 /*
533 * Extract the relevant restriction clauses from the parent relation. The
534 * executor must apply all these restrictions during the scan, except for
535 * pseudoconstants which we'll take care of below.
536 *
537 * If this is a plain indexscan or index-only scan, we need not consider
538 * restriction clauses that are implied by the index's predicate, so use
539 * indrestrictinfo not baserestrictinfo. Note that we can't do that for
540 * bitmap indexscans, since there's not necessarily a single index
541 * involved; but it doesn't matter since create_bitmap_scan_plan() will be
542 * able to get rid of such clauses anyway via predicate proof.
543 */
544 switch (best_path->pathtype)
545 {
546 case T_IndexScan:
547 case T_IndexOnlyScan:
548 scan_clauses = castNode(IndexPath, best_path)->indexinfo->indrestrictinfo;
549 break;
550 default:
551 scan_clauses = rel->baserestrictinfo;
552 break;
553 }
554
555 /*
556 * If this is a parameterized scan, we also need to enforce all the join
557 * clauses available from the outer relation(s).
558 *
559 * For paranoia's sake, don't modify the stored baserestrictinfo list.
560 */
561 if (best_path->param_info)
562 scan_clauses = list_concat(list_copy(scan_clauses),
563 best_path->param_info->ppi_clauses);
564
565 /*
566 * Detect whether we have any pseudoconstant quals to deal with. Then, if
567 * we'll need a gating Result node, it will be able to project, so there
568 * are no requirements on the child's tlist.
569 */
570 gating_clauses = get_gating_quals(root, scan_clauses);
571 if (gating_clauses)
572 flags = 0;
573
574 /*
575 * For table scans, rather than using the relation targetlist (which is
576 * only those Vars actually needed by the query), we prefer to generate a
577 * tlist containing all Vars in order. This will allow the executor to
578 * optimize away projection of the table tuples, if possible.
579 *
580 * But if the caller is going to ignore our tlist anyway, then don't
581 * bother generating one at all. We use an exact equality test here, so
582 * that this only applies when CP_IGNORE_TLIST is the only flag set.
583 */
584 if (flags == CP_IGNORE_TLIST)
585 {
586 tlist = NULL;
587 }
588 else if (use_physical_tlist(root, best_path, flags))
589 {
590 if (best_path->pathtype == T_IndexOnlyScan)
591 {
592 /* For index-only scan, the preferred tlist is the index's */
593 tlist = copyObject(((IndexPath *) best_path)->indexinfo->indextlist);
594
595 /*
596 * Transfer sortgroupref data to the replacement tlist, if
597 * requested (use_physical_tlist checked that this will work).
598 */
599 if (flags & CP_LABEL_TLIST)
600 apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
601 }
602 else
603 {
604 tlist = build_physical_tlist(root, rel);
605 if (tlist == NIL)
606 {
607 /* Failed because of dropped cols, so use regular method */
608 tlist = build_path_tlist(root, best_path);
609 }
610 else
611 {
612 /* As above, transfer sortgroupref data to replacement tlist */
613 if (flags & CP_LABEL_TLIST)
614 apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
615 }
616 }
617 }
618 else
619 {
620 tlist = build_path_tlist(root, best_path);
621 }
622
623 switch (best_path->pathtype)
624 {
625 case T_SeqScan:
626 plan = (Plan *) create_seqscan_plan(root,
627 best_path,
628 tlist,
629 scan_clauses);
630 break;
631
632 case T_SampleScan:
633 plan = (Plan *) create_samplescan_plan(root,
634 best_path,
635 tlist,
636 scan_clauses);
637 break;
638
639 case T_IndexScan:
640 plan = (Plan *) create_indexscan_plan(root,
641 (IndexPath *) best_path,
642 tlist,
643 scan_clauses,
644 false);
645 break;
646
647 case T_IndexOnlyScan:
648 plan = (Plan *) create_indexscan_plan(root,
649 (IndexPath *) best_path,
650 tlist,
651 scan_clauses,
652 true);
653 break;
654
655 case T_BitmapHeapScan:
656 plan = (Plan *) create_bitmap_scan_plan(root,
657 (BitmapHeapPath *) best_path,
658 tlist,
659 scan_clauses);
660 break;
661
662 case T_TidScan:
663 plan = (Plan *) create_tidscan_plan(root,
664 (TidPath *) best_path,
665 tlist,
666 scan_clauses);
667 break;
668
669 case T_SubqueryScan:
670 plan = (Plan *) create_subqueryscan_plan(root,
671 (SubqueryScanPath *) best_path,
672 tlist,
673 scan_clauses);
674 break;
675
676 case T_FunctionScan:
677 plan = (Plan *) create_functionscan_plan(root,
678 best_path,
679 tlist,
680 scan_clauses);
681 break;
682
683 case T_TableFuncScan:
684 plan = (Plan *) create_tablefuncscan_plan(root,
685 best_path,
686 tlist,
687 scan_clauses);
688 break;
689
690 case T_ValuesScan:
691 plan = (Plan *) create_valuesscan_plan(root,
692 best_path,
693 tlist,
694 scan_clauses);
695 break;
696
697 case T_CteScan:
698 plan = (Plan *) create_ctescan_plan(root,
699 best_path,
700 tlist,
701 scan_clauses);
702 break;
703
704 case T_NamedTuplestoreScan:
705 plan = (Plan *) create_namedtuplestorescan_plan(root,
706 best_path,
707 tlist,
708 scan_clauses);
709 break;
710
711 case T_Result:
712 plan = (Plan *) create_resultscan_plan(root,
713 best_path,
714 tlist,
715 scan_clauses);
716 break;
717
718 case T_WorkTableScan:
719 plan = (Plan *) create_worktablescan_plan(root,
720 best_path,
721 tlist,
722 scan_clauses);
723 break;
724
725 case T_ForeignScan:
726 plan = (Plan *) create_foreignscan_plan(root,
727 (ForeignPath *) best_path,
728 tlist,
729 scan_clauses);
730 break;
731
732 case T_CustomScan:
733 plan = (Plan *) create_customscan_plan(root,
734 (CustomPath *) best_path,
735 tlist,
736 scan_clauses);
737 break;
738
739 default:
740 elog(ERROR, "unrecognized node type: %d",
741 (int) best_path->pathtype);
742 plan = NULL; /* keep compiler quiet */
743 break;
744 }
745
746 /*
747 * If there are any pseudoconstant clauses attached to this node, insert a
748 * gating Result node that evaluates the pseudoconstants as one-time
749 * quals.
750 */
751 if (gating_clauses)
752 plan = create_gating_plan(root, best_path, plan, gating_clauses);
753
754 return plan;
755}
756
757/*
758 * Build a target list (ie, a list of TargetEntry) for the Path's output.
759 *
760 * This is almost just make_tlist_from_pathtarget(), but we also have to
761 * deal with replacing nestloop params.
762 */
763static List *
764build_path_tlist(PlannerInfo *root, Path *path)
765{
766 List *tlist = NIL;
767 Index *sortgrouprefs = path->pathtarget->sortgrouprefs;
768 int resno = 1;
769 ListCell *v;
770
771 foreach(v, path->pathtarget->exprs)
772 {
773 Node *node = (Node *) lfirst(v);
774 TargetEntry *tle;
775
776 /*
777 * If it's a parameterized path, there might be lateral references in
778 * the tlist, which need to be replaced with Params. There's no need
779 * to remake the TargetEntry nodes, so apply this to each list item
780 * separately.
781 */
782 if (path->param_info)
783 node = replace_nestloop_params(root, node);
784
785 tle = makeTargetEntry((Expr *) node,
786 resno,
787 NULL,
788 false);
789 if (sortgrouprefs)
790 tle->ressortgroupref = sortgrouprefs[resno - 1];
791
792 tlist = lappend(tlist, tle);
793 resno++;
794 }
795 return tlist;
796}
797
798/*
799 * use_physical_tlist
800 * Decide whether to use a tlist matching relation structure,
801 * rather than only those Vars actually referenced.
802 */
803static bool
804use_physical_tlist(PlannerInfo *root, Path *path, int flags)
805{
806 RelOptInfo *rel = path->parent;
807 int i;
808 ListCell *lc;
809
810 /*
811 * Forget it if either exact tlist or small tlist is demanded.
812 */
813 if (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST))
814 return false;
815
816 /*
817 * We can do this for real relation scans, subquery scans, function scans,
818 * tablefunc scans, values scans, and CTE scans (but not for, eg, joins).
819 */
820 if (rel->rtekind != RTE_RELATION &&
821 rel->rtekind != RTE_SUBQUERY &&
822 rel->rtekind != RTE_FUNCTION &&
823 rel->rtekind != RTE_TABLEFUNC &&
824 rel->rtekind != RTE_VALUES &&
825 rel->rtekind != RTE_CTE)
826 return false;
827
828 /*
829 * Can't do it with inheritance cases either (mainly because Append
830 * doesn't project; this test may be unnecessary now that
831 * create_append_plan instructs its children to return an exact tlist).
832 */
833 if (rel->reloptkind != RELOPT_BASEREL)
834 return false;
835
836 /*
837 * Also, don't do it to a CustomPath; the premise that we're extracting
838 * columns from a simple physical tuple is unlikely to hold for those.
839 * (When it does make sense, the custom path creator can set up the path's
840 * pathtarget that way.)
841 */
842 if (IsA(path, CustomPath))
843 return false;
844
845 /*
846 * If a bitmap scan's tlist is empty, keep it as-is. This may allow the
847 * executor to skip heap page fetches, and in any case, the benefit of
848 * using a physical tlist instead would be minimal.
849 */
850 if (IsA(path, BitmapHeapPath) &&
851 path->pathtarget->exprs == NIL)
852 return false;
853
854 /*
855 * Can't do it if any system columns or whole-row Vars are requested.
856 * (This could possibly be fixed but would take some fragile assumptions
857 * in setrefs.c, I think.)
858 */
859 for (i = rel->min_attr; i <= 0; i++)
860 {
861 if (!bms_is_empty(rel->attr_needed[i - rel->min_attr]))
862 return false;
863 }
864
865 /*
866 * Can't do it if the rel is required to emit any placeholder expressions,
867 * either.
868 */
869 foreach(lc, root->placeholder_list)
870 {
871 PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
872
873 if (bms_nonempty_difference(phinfo->ph_needed, rel->relids) &&
874 bms_is_subset(phinfo->ph_eval_at, rel->relids))
875 return false;
876 }
877
878 /*
879 * Also, can't do it if CP_LABEL_TLIST is specified and path is requested
880 * to emit any sort/group columns that are not simple Vars. (If they are
881 * simple Vars, they should appear in the physical tlist, and
882 * apply_pathtarget_labeling_to_tlist will take care of getting them
883 * labeled again.) We also have to check that no two sort/group columns
884 * are the same Var, else that element of the physical tlist would need
885 * conflicting ressortgroupref labels.
886 */
887 if ((flags & CP_LABEL_TLIST) && path->pathtarget->sortgrouprefs)
888 {
889 Bitmapset *sortgroupatts = NULL;
890
891 i = 0;
892 foreach(lc, path->pathtarget->exprs)
893 {
894 Expr *expr = (Expr *) lfirst(lc);
895
896 if (path->pathtarget->sortgrouprefs[i])
897 {
898 if (expr && IsA(expr, Var))
899 {
900 int attno = ((Var *) expr)->varattno;
901
902 attno -= FirstLowInvalidHeapAttributeNumber;
903 if (bms_is_member(attno, sortgroupatts))
904 return false;
905 sortgroupatts = bms_add_member(sortgroupatts, attno);
906 }
907 else
908 return false;
909 }
910 i++;
911 }
912 }
913
914 return true;
915}
916
917/*
918 * get_gating_quals
919 * See if there are pseudoconstant quals in a node's quals list
920 *
921 * If the node's quals list includes any pseudoconstant quals,
922 * return just those quals.
923 */
924static List *
925get_gating_quals(PlannerInfo *root, List *quals)
926{
927 /* No need to look if we know there are no pseudoconstants */
928 if (!root->hasPseudoConstantQuals)
929 return NIL;
930
931 /* Sort into desirable execution order while still in RestrictInfo form */
932 quals = order_qual_clauses(root, quals);
933
934 /* Pull out any pseudoconstant quals from the RestrictInfo list */
935 return extract_actual_clauses(quals, true);
936}
937
938/*
939 * create_gating_plan
940 * Deal with pseudoconstant qual clauses
941 *
942 * Add a gating Result node atop the already-built plan.
943 */
944static Plan *
945create_gating_plan(PlannerInfo *root, Path *path, Plan *plan,
946 List *gating_quals)
947{
948 Plan *gplan;
949 Plan *splan;
950
951 Assert(gating_quals);
952
953 /*
954 * We might have a trivial Result plan already. Stacking one Result atop
955 * another is silly, so if that applies, just discard the input plan.
956 * (We're assuming its targetlist is uninteresting; it should be either
957 * the same as the result of build_path_tlist, or a simplified version.)
958 */
959 splan = plan;
960 if (IsA(plan, Result))
961 {
962 Result *rplan = (Result *) plan;
963
964 if (rplan->plan.lefttree == NULL &&
965 rplan->resconstantqual == NULL)
966 splan = NULL;
967 }
968
969 /*
970 * Since we need a Result node anyway, always return the path's requested
971 * tlist; that's never a wrong choice, even if the parent node didn't ask
972 * for CP_EXACT_TLIST.
973 */
974 gplan = (Plan *) make_result(build_path_tlist(root, path),
975 (Node *) gating_quals,
976 splan);
977
978 /*
979 * Notice that we don't change cost or size estimates when doing gating.
980 * The costs of qual eval were already included in the subplan's cost.
981 * Leaving the size alone amounts to assuming that the gating qual will
982 * succeed, which is the conservative estimate for planning upper queries.
983 * We certainly don't want to assume the output size is zero (unless the
984 * gating qual is actually constant FALSE, and that case is dealt with in
985 * clausesel.c). Interpolating between the two cases is silly, because it
986 * doesn't reflect what will really happen at runtime, and besides which
987 * in most cases we have only a very bad idea of the probability of the
988 * gating qual being true.
989 */
990 copy_plan_costsize(gplan, plan);
991
992 /* Gating quals could be unsafe, so better use the Path's safety flag */
993 gplan->parallel_safe = path->parallel_safe;
994
995 return gplan;
996}
997
998/*
999 * create_join_plan
1000 * Create a join plan for 'best_path' and (recursively) plans for its
1001 * inner and outer paths.
1002 */
1003static Plan *
1004create_join_plan(PlannerInfo *root, JoinPath *best_path)
1005{
1006 Plan *plan;
1007 List *gating_clauses;
1008
1009 switch (best_path->path.pathtype)
1010 {
1011 case T_MergeJoin:
1012 plan = (Plan *) create_mergejoin_plan(root,
1013 (MergePath *) best_path);
1014 break;
1015 case T_HashJoin:
1016 plan = (Plan *) create_hashjoin_plan(root,
1017 (HashPath *) best_path);
1018 break;
1019 case T_NestLoop:
1020 plan = (Plan *) create_nestloop_plan(root,
1021 (NestPath *) best_path);
1022 break;
1023 default:
1024 elog(ERROR, "unrecognized node type: %d",
1025 (int) best_path->path.pathtype);
1026 plan = NULL; /* keep compiler quiet */
1027 break;
1028 }
1029
1030 /*
1031 * If there are any pseudoconstant clauses attached to this node, insert a
1032 * gating Result node that evaluates the pseudoconstants as one-time
1033 * quals.
1034 */
1035 gating_clauses = get_gating_quals(root, best_path->joinrestrictinfo);
1036 if (gating_clauses)
1037 plan = create_gating_plan(root, (Path *) best_path, plan,
1038 gating_clauses);
1039
1040#ifdef NOT_USED
1041
1042 /*
1043 * * Expensive function pullups may have pulled local predicates * into
1044 * this path node. Put them in the qpqual of the plan node. * JMH,
1045 * 6/15/92
1046 */
1047 if (get_loc_restrictinfo(best_path) != NIL)
1048 set_qpqual((Plan) plan,
1049 list_concat(get_qpqual((Plan) plan),
1050 get_actual_clauses(get_loc_restrictinfo(best_path))));
1051#endif
1052
1053 return plan;
1054}
1055
1056/*
1057 * create_append_plan
1058 * Create an Append plan for 'best_path' and (recursively) plans
1059 * for its subpaths.
1060 *
1061 * Returns a Plan node.
1062 */
1063static Plan *
1064create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
1065{
1066 Append *plan;
1067 List *tlist = build_path_tlist(root, &best_path->path);
1068 int orig_tlist_length = list_length(tlist);
1069 bool tlist_was_changed = false;
1070 List *pathkeys = best_path->path.pathkeys;
1071 List *subplans = NIL;
1072 ListCell *subpaths;
1073 RelOptInfo *rel = best_path->path.parent;
1074 PartitionPruneInfo *partpruneinfo = NULL;
1075 int nodenumsortkeys = 0;
1076 AttrNumber *nodeSortColIdx = NULL;
1077 Oid *nodeSortOperators = NULL;
1078 Oid *nodeCollations = NULL;
1079 bool *nodeNullsFirst = NULL;
1080
1081 /*
1082 * The subpaths list could be empty, if every child was proven empty by
1083 * constraint exclusion. In that case generate a dummy plan that returns
1084 * no rows.
1085 *
1086 * Note that an AppendPath with no members is also generated in certain
1087 * cases where there was no appending construct at all, but we know the
1088 * relation is empty (see set_dummy_rel_pathlist and mark_dummy_rel).
1089 */
1090 if (best_path->subpaths == NIL)
1091 {
1092 /* Generate a Result plan with constant-FALSE gating qual */
1093 Plan *plan;
1094
1095 plan = (Plan *) make_result(tlist,
1096 (Node *) list_make1(makeBoolConst(false,
1097 false)),
1098 NULL);
1099
1100 copy_generic_path_info(plan, (Path *) best_path);
1101
1102 return plan;
1103 }
1104
1105 /*
1106 * Otherwise build an Append plan. Note that if there's just one child,
1107 * the Append is pretty useless; but we wait till setrefs.c to get rid of
1108 * it. Doing so here doesn't work because the varno of the child scan
1109 * plan won't match the parent-rel Vars it'll be asked to emit.
1110 *
1111 * We don't have the actual creation of the Append node split out into a
1112 * separate make_xxx function. This is because we want to run
1113 * prepare_sort_from_pathkeys on it before we do so on the individual
1114 * child plans, to make cross-checking the sort info easier.
1115 */
1116 plan = makeNode(Append);
1117 plan->plan.targetlist = tlist;
1118 plan->plan.qual = NIL;
1119 plan->plan.lefttree = NULL;
1120 plan->plan.righttree = NULL;
1121
1122 if (pathkeys != NIL)
1123 {
1124 /*
1125 * Compute sort column info, and adjust the Append's tlist as needed.
1126 * Because we pass adjust_tlist_in_place = true, we may ignore the
1127 * function result; it must be the same plan node. However, we then
1128 * need to detect whether any tlist entries were added.
1129 */
1130 (void) prepare_sort_from_pathkeys((Plan *) plan, pathkeys,
1131 best_path->path.parent->relids,
1132 NULL,
1133 true,
1134 &nodenumsortkeys,
1135 &nodeSortColIdx,
1136 &nodeSortOperators,
1137 &nodeCollations,
1138 &nodeNullsFirst);
1139 tlist_was_changed = (orig_tlist_length != list_length(plan->plan.targetlist));
1140 }
1141
1142 /* Build the plan for each child */
1143 foreach(subpaths, best_path->subpaths)
1144 {
1145 Path *subpath = (Path *) lfirst(subpaths);
1146 Plan *subplan;
1147
1148 /* Must insist that all children return the same tlist */
1149 subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST);
1150
1151 /*
1152 * For ordered Appends, we must insert a Sort node if subplan isn't
1153 * sufficiently ordered.
1154 */
1155 if (pathkeys != NIL)
1156 {
1157 int numsortkeys;
1158 AttrNumber *sortColIdx;
1159 Oid *sortOperators;
1160 Oid *collations;
1161 bool *nullsFirst;
1162
1163 /*
1164 * Compute sort column info, and adjust subplan's tlist as needed.
1165 * We must apply prepare_sort_from_pathkeys even to subplans that
1166 * don't need an explicit sort, to make sure they are returning
1167 * the same sort key columns the Append expects.
1168 */
1169 subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
1170 subpath->parent->relids,
1171 nodeSortColIdx,
1172 false,
1173 &numsortkeys,
1174 &sortColIdx,
1175 &sortOperators,
1176 &collations,
1177 &nullsFirst);
1178
1179 /*
1180 * Check that we got the same sort key information. We just
1181 * Assert that the sortops match, since those depend only on the
1182 * pathkeys; but it seems like a good idea to check the sort
1183 * column numbers explicitly, to ensure the tlists match up.
1184 */
1185 Assert(numsortkeys == nodenumsortkeys);
1186 if (memcmp(sortColIdx, nodeSortColIdx,
1187 numsortkeys * sizeof(AttrNumber)) != 0)
1188 elog(ERROR, "Append child's targetlist doesn't match Append");
1189 Assert(memcmp(sortOperators, nodeSortOperators,
1190 numsortkeys * sizeof(Oid)) == 0);
1191 Assert(memcmp(collations, nodeCollations,
1192 numsortkeys * sizeof(Oid)) == 0);
1193 Assert(memcmp(nullsFirst, nodeNullsFirst,
1194 numsortkeys * sizeof(bool)) == 0);
1195
1196 /* Now, insert a Sort node if subplan isn't sufficiently ordered */
1197 if (!pathkeys_contained_in(pathkeys, subpath->pathkeys))
1198 {
1199 Sort *sort = make_sort(subplan, numsortkeys,
1200 sortColIdx, sortOperators,
1201 collations, nullsFirst);
1202
1203 label_sort_with_costsize(root, sort, best_path->limit_tuples);
1204 subplan = (Plan *) sort;
1205 }
1206 }
1207
1208 subplans = lappend(subplans, subplan);
1209 }
1210
1211 /*
1212 * If any quals exist, they may be useful to perform further partition
1213 * pruning during execution. Gather information needed by the executor to
1214 * do partition pruning.
1215 */
1216 if (enable_partition_pruning &&
1217 rel->reloptkind == RELOPT_BASEREL &&
1218 best_path->partitioned_rels != NIL)
1219 {
1220 List *prunequal;
1221
1222 prunequal = extract_actual_clauses(rel->baserestrictinfo, false);
1223
1224 if (best_path->path.param_info)
1225 {
1226 List *prmquals = best_path->path.param_info->ppi_clauses;
1227
1228 prmquals = extract_actual_clauses(prmquals, false);
1229 prmquals = (List *) replace_nestloop_params(root,
1230 (Node *) prmquals);
1231
1232 prunequal = list_concat(prunequal, prmquals);
1233 }
1234
1235 if (prunequal != NIL)
1236 partpruneinfo =
1237 make_partition_pruneinfo(root, rel,
1238 best_path->subpaths,
1239 best_path->partitioned_rels,
1240 prunequal);
1241 }
1242
1243 plan->appendplans = subplans;
1244 plan->first_partial_plan = best_path->first_partial_path;
1245 plan->part_prune_info = partpruneinfo;
1246
1247 copy_generic_path_info(&plan->plan, (Path *) best_path);
1248
1249 /*
1250 * If prepare_sort_from_pathkeys added sort columns, but we were told to
1251 * produce either the exact tlist or a narrow tlist, we should get rid of
1252 * the sort columns again. We must inject a projection node to do so.
1253 */
1254 if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST)))
1255 {
1256 tlist = list_truncate(list_copy(plan->plan.targetlist),
1257 orig_tlist_length);
1258 return inject_projection_plan((Plan *) plan, tlist,
1259 plan->plan.parallel_safe);
1260 }
1261 else
1262 return (Plan *) plan;
1263}
1264
1265/*
1266 * create_merge_append_plan
1267 * Create a MergeAppend plan for 'best_path' and (recursively) plans
1268 * for its subpaths.
1269 *
1270 * Returns a Plan node.
1271 */
1272static Plan *
1273create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
1274 int flags)
1275{
1276 MergeAppend *node = makeNode(MergeAppend);
1277 Plan *plan = &node->plan;
1278 List *tlist = build_path_tlist(root, &best_path->path);
1279 int orig_tlist_length = list_length(tlist);
1280 bool tlist_was_changed;
1281 List *pathkeys = best_path->path.pathkeys;
1282 List *subplans = NIL;
1283 ListCell *subpaths;
1284 RelOptInfo *rel = best_path->path.parent;
1285 PartitionPruneInfo *partpruneinfo = NULL;
1286
1287 /*
1288 * We don't have the actual creation of the MergeAppend node split out
1289 * into a separate make_xxx function. This is because we want to run
1290 * prepare_sort_from_pathkeys on it before we do so on the individual
1291 * child plans, to make cross-checking the sort info easier.
1292 */
1293 copy_generic_path_info(plan, (Path *) best_path);
1294 plan->targetlist = tlist;
1295 plan->qual = NIL;
1296 plan->lefttree = NULL;
1297 plan->righttree = NULL;
1298
1299 /*
1300 * Compute sort column info, and adjust MergeAppend's tlist as needed.
1301 * Because we pass adjust_tlist_in_place = true, we may ignore the
1302 * function result; it must be the same plan node. However, we then need
1303 * to detect whether any tlist entries were added.
1304 */
1305 (void) prepare_sort_from_pathkeys(plan, pathkeys,
1306 best_path->path.parent->relids,
1307 NULL,
1308 true,
1309 &node->numCols,
1310 &node->sortColIdx,
1311 &node->sortOperators,
1312 &node->collations,
1313 &node->nullsFirst);
1314 tlist_was_changed = (orig_tlist_length != list_length(plan->targetlist));
1315
1316 /*
1317 * Now prepare the child plans. We must apply prepare_sort_from_pathkeys
1318 * even to subplans that don't need an explicit sort, to make sure they
1319 * are returning the same sort key columns the MergeAppend expects.
1320 */
1321 foreach(subpaths, best_path->subpaths)
1322 {
1323 Path *subpath = (Path *) lfirst(subpaths);
1324 Plan *subplan;
1325 int numsortkeys;
1326 AttrNumber *sortColIdx;
1327 Oid *sortOperators;
1328 Oid *collations;
1329 bool *nullsFirst;
1330
1331 /* Build the child plan */
1332 /* Must insist that all children return the same tlist */
1333 subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST);
1334
1335 /* Compute sort column info, and adjust subplan's tlist as needed */
1336 subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
1337 subpath->parent->relids,
1338 node->sortColIdx,
1339 false,
1340 &numsortkeys,
1341 &sortColIdx,
1342 &sortOperators,
1343 &collations,
1344 &nullsFirst);
1345
1346 /*
1347 * Check that we got the same sort key information. We just Assert
1348 * that the sortops match, since those depend only on the pathkeys;
1349 * but it seems like a good idea to check the sort column numbers
1350 * explicitly, to ensure the tlists really do match up.
1351 */
1352 Assert(numsortkeys == node->numCols);
1353 if (memcmp(sortColIdx, node->sortColIdx,
1354 numsortkeys * sizeof(AttrNumber)) != 0)
1355 elog(ERROR, "MergeAppend child's targetlist doesn't match MergeAppend");
1356 Assert(memcmp(sortOperators, node->sortOperators,
1357 numsortkeys * sizeof(Oid)) == 0);
1358 Assert(memcmp(collations, node->collations,
1359 numsortkeys * sizeof(Oid)) == 0);
1360 Assert(memcmp(nullsFirst, node->nullsFirst,
1361 numsortkeys * sizeof(bool)) == 0);
1362
1363 /* Now, insert a Sort node if subplan isn't sufficiently ordered */
1364 if (!pathkeys_contained_in(pathkeys, subpath->pathkeys))
1365 {
1366 Sort *sort = make_sort(subplan, numsortkeys,
1367 sortColIdx, sortOperators,
1368 collations, nullsFirst);
1369
1370 label_sort_with_costsize(root, sort, best_path->limit_tuples);
1371 subplan = (Plan *) sort;
1372 }
1373
1374 subplans = lappend(subplans, subplan);
1375 }
1376
1377 /*
1378 * If any quals exist, they may be useful to perform further partition
1379 * pruning during execution. Gather information needed by the executor to
1380 * do partition pruning.
1381 */
1382 if (enable_partition_pruning &&
1383 rel->reloptkind == RELOPT_BASEREL &&
1384 best_path->partitioned_rels != NIL)
1385 {
1386 List *prunequal;
1387
1388 prunequal = extract_actual_clauses(rel->baserestrictinfo, false);
1389
1390 if (best_path->path.param_info)
1391 {
1392 List *prmquals = best_path->path.param_info->ppi_clauses;
1393
1394 prmquals = extract_actual_clauses(prmquals, false);
1395 prmquals = (List *) replace_nestloop_params(root,
1396 (Node *) prmquals);
1397
1398 prunequal = list_concat(prunequal, prmquals);
1399 }
1400
1401 if (prunequal != NIL)
1402 partpruneinfo = make_partition_pruneinfo(root, rel,
1403 best_path->subpaths,
1404 best_path->partitioned_rels,
1405 prunequal);
1406 }
1407
1408 node->mergeplans = subplans;
1409 node->part_prune_info = partpruneinfo;
1410
1411 /*
1412 * If prepare_sort_from_pathkeys added sort columns, but we were told to
1413 * produce either the exact tlist or a narrow tlist, we should get rid of
1414 * the sort columns again. We must inject a projection node to do so.
1415 */
1416 if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST)))
1417 {
1418 tlist = list_truncate(list_copy(plan->targetlist), orig_tlist_length);
1419 return inject_projection_plan(plan, tlist, plan->parallel_safe);
1420 }
1421 else
1422 return plan;
1423}
1424
1425/*
1426 * create_group_result_plan
1427 * Create a Result plan for 'best_path'.
1428 * This is only used for degenerate grouping cases.
1429 *
1430 * Returns a Plan node.
1431 */
1432static Result *
1433create_group_result_plan(PlannerInfo *root, GroupResultPath *best_path)
1434{
1435 Result *plan;
1436 List *tlist;
1437 List *quals;
1438
1439 tlist = build_path_tlist(root, &best_path->path);
1440
1441 /* best_path->quals is just bare clauses */
1442 quals = order_qual_clauses(root, best_path->quals);
1443
1444 plan = make_result(tlist, (Node *) quals, NULL);
1445
1446 copy_generic_path_info(&plan->plan, (Path *) best_path);
1447
1448 return plan;
1449}
1450
1451/*
1452 * create_project_set_plan
1453 * Create a ProjectSet plan for 'best_path'.
1454 *
1455 * Returns a Plan node.
1456 */
1457static ProjectSet *
1458create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path)
1459{
1460 ProjectSet *plan;
1461 Plan *subplan;
1462 List *tlist;
1463
1464 /* Since we intend to project, we don't need to constrain child tlist */
1465 subplan = create_plan_recurse(root, best_path->subpath, 0);
1466
1467 tlist = build_path_tlist(root, &best_path->path);
1468
1469 plan = make_project_set(tlist, subplan);
1470
1471 copy_generic_path_info(&plan->plan, (Path *) best_path);
1472
1473 return plan;
1474}
1475
1476/*
1477 * create_material_plan
1478 * Create a Material plan for 'best_path' and (recursively) plans
1479 * for its subpaths.
1480 *
1481 * Returns a Plan node.
1482 */
1483static Material *
1484create_material_plan(PlannerInfo *root, MaterialPath *best_path, int flags)
1485{
1486 Material *plan;
1487 Plan *subplan;
1488
1489 /*
1490 * We don't want any excess columns in the materialized tuples, so request
1491 * a smaller tlist. Otherwise, since Material doesn't project, tlist
1492 * requirements pass through.
1493 */
1494 subplan = create_plan_recurse(root, best_path->subpath,
1495 flags | CP_SMALL_TLIST);
1496
1497 plan = make_material(subplan);
1498
1499 copy_generic_path_info(&plan->plan, (Path *) best_path);
1500
1501 return plan;
1502}
1503
1504/*
1505 * create_unique_plan
1506 * Create a Unique plan for 'best_path' and (recursively) plans
1507 * for its subpaths.
1508 *
1509 * Returns a Plan node.
1510 */
1511static Plan *
1512create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags)
1513{
1514 Plan *plan;
1515 Plan *subplan;
1516 List *in_operators;
1517 List *uniq_exprs;
1518 List *newtlist;
1519 int nextresno;
1520 bool newitems;
1521 int numGroupCols;
1522 AttrNumber *groupColIdx;
1523 Oid *groupCollations;
1524 int groupColPos;
1525 ListCell *l;
1526
1527 /* Unique doesn't project, so tlist requirements pass through */
1528 subplan = create_plan_recurse(root, best_path->subpath, flags);
1529
1530 /* Done if we don't need to do any actual unique-ifying */
1531 if (best_path->umethod == UNIQUE_PATH_NOOP)
1532 return subplan;
1533
1534 /*
1535 * As constructed, the subplan has a "flat" tlist containing just the Vars
1536 * needed here and at upper levels. The values we are supposed to
1537 * unique-ify may be expressions in these variables. We have to add any
1538 * such expressions to the subplan's tlist.
1539 *
1540 * The subplan may have a "physical" tlist if it is a simple scan plan. If
1541 * we're going to sort, this should be reduced to the regular tlist, so
1542 * that we don't sort more data than we need to. For hashing, the tlist
1543 * should be left as-is if we don't need to add any expressions; but if we
1544 * do have to add expressions, then a projection step will be needed at
1545 * runtime anyway, so we may as well remove unneeded items. Therefore
1546 * newtlist starts from build_path_tlist() not just a copy of the
1547 * subplan's tlist; and we don't install it into the subplan unless we are
1548 * sorting or stuff has to be added.
1549 */
1550 in_operators = best_path->in_operators;
1551 uniq_exprs = best_path->uniq_exprs;
1552
1553 /* initialize modified subplan tlist as just the "required" vars */
1554 newtlist = build_path_tlist(root, &best_path->path);
1555 nextresno = list_length(newtlist) + 1;
1556 newitems = false;
1557
1558 foreach(l, uniq_exprs)
1559 {
1560 Expr *uniqexpr = lfirst(l);
1561 TargetEntry *tle;
1562
1563 tle = tlist_member(uniqexpr, newtlist);
1564 if (!tle)
1565 {
1566 tle = makeTargetEntry((Expr *) uniqexpr,
1567 nextresno,
1568 NULL,
1569 false);
1570 newtlist = lappend(newtlist, tle);
1571 nextresno++;
1572 newitems = true;
1573 }
1574 }
1575
1576 /* Use change_plan_targetlist in case we need to insert a Result node */
1577 if (newitems || best_path->umethod == UNIQUE_PATH_SORT)
1578 subplan = change_plan_targetlist(subplan, newtlist,
1579 best_path->path.parallel_safe);
1580
1581 /*
1582 * Build control information showing which subplan output columns are to
1583 * be examined by the grouping step. Unfortunately we can't merge this
1584 * with the previous loop, since we didn't then know which version of the
1585 * subplan tlist we'd end up using.
1586 */
1587 newtlist = subplan->targetlist;
1588 numGroupCols = list_length(uniq_exprs);
1589 groupColIdx = (AttrNumber *) palloc(numGroupCols * sizeof(AttrNumber));
1590 groupCollations = (Oid *) palloc(numGroupCols * sizeof(Oid));
1591
1592 groupColPos = 0;
1593 foreach(l, uniq_exprs)
1594 {
1595 Expr *uniqexpr = lfirst(l);
1596 TargetEntry *tle;
1597
1598 tle = tlist_member(uniqexpr, newtlist);
1599 if (!tle) /* shouldn't happen */
1600 elog(ERROR, "failed to find unique expression in subplan tlist");
1601 groupColIdx[groupColPos] = tle->resno;
1602 groupCollations[groupColPos] = exprCollation((Node *) tle->expr);
1603 groupColPos++;
1604 }
1605
1606 if (best_path->umethod == UNIQUE_PATH_HASH)
1607 {
1608 Oid *groupOperators;
1609
1610 /*
1611 * Get the hashable equality operators for the Agg node to use.
1612 * Normally these are the same as the IN clause operators, but if
1613 * those are cross-type operators then the equality operators are the
1614 * ones for the IN clause operators' RHS datatype.
1615 */
1616 groupOperators = (Oid *) palloc(numGroupCols * sizeof(Oid));
1617 groupColPos = 0;
1618 foreach(l, in_operators)
1619 {
1620 Oid in_oper = lfirst_oid(l);
1621 Oid eq_oper;
1622
1623 if (!get_compatible_hash_operators(in_oper, NULL, &eq_oper))
1624 elog(ERROR, "could not find compatible hash operator for operator %u",
1625 in_oper);
1626 groupOperators[groupColPos++] = eq_oper;
1627 }
1628
1629 /*
1630 * Since the Agg node is going to project anyway, we can give it the
1631 * minimum output tlist, without any stuff we might have added to the
1632 * subplan tlist.
1633 */
1634 plan = (Plan *) make_agg(build_path_tlist(root, &best_path->path),
1635 NIL,
1636 AGG_HASHED,
1637 AGGSPLIT_SIMPLE,
1638 numGroupCols,
1639 groupColIdx,
1640 groupOperators,
1641 groupCollations,
1642 NIL,
1643 NIL,
1644 best_path->path.rows,
1645 subplan);
1646 }
1647 else
1648 {
1649 List *sortList = NIL;
1650 Sort *sort;
1651
1652 /* Create an ORDER BY list to sort the input compatibly */
1653 groupColPos = 0;
1654 foreach(l, in_operators)
1655 {
1656 Oid in_oper = lfirst_oid(l);
1657 Oid sortop;
1658 Oid eqop;
1659 TargetEntry *tle;
1660 SortGroupClause *sortcl;
1661
1662 sortop = get_ordering_op_for_equality_op(in_oper, false);
1663 if (!OidIsValid(sortop)) /* shouldn't happen */
1664 elog(ERROR, "could not find ordering operator for equality operator %u",
1665 in_oper);
1666
1667 /*
1668 * The Unique node will need equality operators. Normally these
1669 * are the same as the IN clause operators, but if those are
1670 * cross-type operators then the equality operators are the ones
1671 * for the IN clause operators' RHS datatype.
1672 */
1673 eqop = get_equality_op_for_ordering_op(sortop, NULL);
1674 if (!OidIsValid(eqop)) /* shouldn't happen */
1675 elog(ERROR, "could not find equality operator for ordering operator %u",
1676 sortop);
1677
1678 tle = get_tle_by_resno(subplan->targetlist,
1679 groupColIdx[groupColPos]);
1680 Assert(tle != NULL);
1681
1682 sortcl = makeNode(SortGroupClause);
1683 sortcl->tleSortGroupRef = assignSortGroupRef(tle,
1684 subplan->targetlist);
1685 sortcl->eqop = eqop;
1686 sortcl->sortop = sortop;
1687 sortcl->nulls_first = false;
1688 sortcl->hashable = false; /* no need to make this accurate */
1689 sortList = lappend(sortList, sortcl);
1690 groupColPos++;
1691 }
1692 sort = make_sort_from_sortclauses(sortList, subplan);
1693 label_sort_with_costsize(root, sort, -1.0);
1694 plan = (Plan *) make_unique_from_sortclauses((Plan *) sort, sortList);
1695 }
1696
1697 /* Copy cost data from Path to Plan */
1698 copy_generic_path_info(plan, &best_path->path);
1699
1700 return plan;
1701}
1702
1703/*
1704 * create_gather_plan
1705 *
1706 * Create a Gather plan for 'best_path' and (recursively) plans
1707 * for its subpaths.
1708 */
1709static Gather *
1710create_gather_plan(PlannerInfo *root, GatherPath *best_path)
1711{
1712 Gather *gather_plan;
1713 Plan *subplan;
1714 List *tlist;
1715
1716 /*
1717 * Although the Gather node can project, we prefer to push down such work
1718 * to its child node, so demand an exact tlist from the child.
1719 */
1720 subplan = create_plan_recurse(root, best_path->subpath, CP_EXACT_TLIST);
1721
1722 tlist = build_path_tlist(root, &best_path->path);
1723
1724 gather_plan = make_gather(tlist,
1725 NIL,
1726 best_path->num_workers,
1727 assign_special_exec_param(root),
1728 best_path->single_copy,
1729 subplan);
1730
1731 copy_generic_path_info(&gather_plan->plan, &best_path->path);
1732
1733 /* use parallel mode for parallel plans. */
1734 root->glob->parallelModeNeeded = true;
1735
1736 return gather_plan;
1737}
1738
1739/*
1740 * create_gather_merge_plan
1741 *
1742 * Create a Gather Merge plan for 'best_path' and (recursively)
1743 * plans for its subpaths.
1744 */
1745static GatherMerge *
1746create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)
1747{
1748 GatherMerge *gm_plan;
1749 Plan *subplan;
1750 List *pathkeys = best_path->path.pathkeys;
1751 List *tlist = build_path_tlist(root, &best_path->path);
1752
1753 /* As with Gather, it's best to project away columns in the workers. */
1754 subplan = create_plan_recurse(root, best_path->subpath, CP_EXACT_TLIST);
1755
1756 /* Create a shell for a GatherMerge plan. */
1757 gm_plan = makeNode(GatherMerge);
1758 gm_plan->plan.targetlist = tlist;
1759 gm_plan->num_workers = best_path->num_workers;
1760 copy_generic_path_info(&gm_plan->plan, &best_path->path);
1761
1762 /* Assign the rescan Param. */
1763 gm_plan->rescan_param = assign_special_exec_param(root);
1764
1765 /* Gather Merge is pointless with no pathkeys; use Gather instead. */
1766 Assert(pathkeys != NIL);
1767
1768 /* Compute sort column info, and adjust subplan's tlist as needed */
1769 subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
1770 best_path->subpath->parent->relids,
1771 gm_plan->sortColIdx,
1772 false,
1773 &gm_plan->numCols,
1774 &gm_plan->sortColIdx,
1775 &gm_plan->sortOperators,
1776 &gm_plan->collations,
1777 &gm_plan->nullsFirst);
1778
1779
1780 /* Now, insert a Sort node if subplan isn't sufficiently ordered */
1781 if (!pathkeys_contained_in(pathkeys, best_path->subpath->pathkeys))
1782 subplan = (Plan *) make_sort(subplan, gm_plan->numCols,
1783 gm_plan->sortColIdx,
1784 gm_plan->sortOperators,
1785 gm_plan->collations,
1786 gm_plan->nullsFirst);
1787
1788 /* Now insert the subplan under GatherMerge. */
1789 gm_plan->plan.lefttree = subplan;
1790
1791 /* use parallel mode for parallel plans. */
1792 root->glob->parallelModeNeeded = true;
1793
1794 return gm_plan;
1795}
1796
1797/*
1798 * create_projection_plan
1799 *
1800 * Create a plan tree to do a projection step and (recursively) plans
1801 * for its subpaths. We may need a Result node for the projection,
1802 * but sometimes we can just let the subplan do the work.
1803 */
1804static Plan *
1805create_projection_plan(PlannerInfo *root, ProjectionPath *best_path, int flags)
1806{
1807 Plan *plan;
1808 Plan *subplan;
1809 List *tlist;
1810 bool needs_result_node = false;
1811
1812 /*
1813 * Convert our subpath to a Plan and determine whether we need a Result
1814 * node.
1815 *
1816 * In most cases where we don't need to project, creation_projection_path
1817 * will have set dummypp, but not always. First, some createplan.c
1818 * routines change the tlists of their nodes. (An example is that
1819 * create_merge_append_plan might add resjunk sort columns to a
1820 * MergeAppend.) Second, create_projection_path has no way of knowing
1821 * what path node will be placed on top of the projection path and
1822 * therefore can't predict whether it will require an exact tlist. For
1823 * both of these reasons, we have to recheck here.
1824 */
1825 if (use_physical_tlist(root, &best_path->path, flags))
1826 {
1827 /*
1828 * Our caller doesn't really care what tlist we return, so we don't
1829 * actually need to project. However, we may still need to ensure
1830 * proper sortgroupref labels, if the caller cares about those.
1831 */
1832 subplan = create_plan_recurse(root, best_path->subpath, 0);
1833 tlist = subplan->targetlist;
1834 if (flags & CP_LABEL_TLIST)
1835 apply_pathtarget_labeling_to_tlist(tlist,
1836 best_path->path.pathtarget);
1837 }
1838 else if (is_projection_capable_path(best_path->subpath))
1839 {
1840 /*
1841 * Our caller requires that we return the exact tlist, but no separate
1842 * result node is needed because the subpath is projection-capable.
1843 * Tell create_plan_recurse that we're going to ignore the tlist it
1844 * produces.
1845 */
1846 subplan = create_plan_recurse(root, best_path->subpath,
1847 CP_IGNORE_TLIST);
1848 tlist = build_path_tlist(root, &best_path->path);
1849 }
1850 else
1851 {
1852 /*
1853 * It looks like we need a result node, unless by good fortune the
1854 * requested tlist is exactly the one the child wants to produce.
1855 */
1856 subplan = create_plan_recurse(root, best_path->subpath, 0);
1857 tlist = build_path_tlist(root, &best_path->path);
1858 needs_result_node = !tlist_same_exprs(tlist, subplan->targetlist);
1859 }
1860
1861 /*
1862 * If we make a different decision about whether to include a Result node
1863 * than create_projection_path did, we'll have made slightly wrong cost
1864 * estimates; but label the plan with the cost estimates we actually used,
1865 * not "corrected" ones. (XXX this could be cleaned up if we moved more
1866 * of the sortcolumn setup logic into Path creation, but that would add
1867 * expense to creating Paths we might end up not using.)
1868 */
1869 if (!needs_result_node)
1870 {
1871 /* Don't need a separate Result, just assign tlist to subplan */
1872 plan = subplan;
1873 plan->targetlist = tlist;
1874
1875 /* Label plan with the estimated costs we actually used */
1876 plan->startup_cost = best_path->path.startup_cost;
1877 plan->total_cost = best_path->path.total_cost;
1878 plan->plan_rows = best_path->path.rows;
1879 plan->plan_width = best_path->path.pathtarget->width;
1880 plan->parallel_safe = best_path->path.parallel_safe;
1881 /* ... but don't change subplan's parallel_aware flag */
1882 }
1883 else
1884 {
1885 /* We need a Result node */
1886 plan = (Plan *) make_result(tlist, NULL, subplan);
1887
1888 copy_generic_path_info(plan, (Path *) best_path);
1889 }
1890
1891 return plan;
1892}
1893
1894/*
1895 * inject_projection_plan
1896 * Insert a Result node to do a projection step.
1897 *
1898 * This is used in a few places where we decide on-the-fly that we need a
1899 * projection step as part of the tree generated for some Path node.
1900 * We should try to get rid of this in favor of doing it more honestly.
1901 *
1902 * One reason it's ugly is we have to be told the right parallel_safe marking
1903 * to apply (since the tlist might be unsafe even if the child plan is safe).
1904 */
1905static Plan *
1906inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe)
1907{
1908 Plan *plan;
1909
1910 plan = (Plan *) make_result(tlist, NULL, subplan);
1911
1912 /*
1913 * In principle, we should charge tlist eval cost plus cpu_per_tuple per
1914 * row for the Result node. But the former has probably been factored in
1915 * already and the latter was not accounted for during Path construction,
1916 * so being formally correct might just make the EXPLAIN output look less
1917 * consistent not more so. Hence, just copy the subplan's cost.
1918 */
1919 copy_plan_costsize(plan, subplan);
1920 plan->parallel_safe = parallel_safe;
1921
1922 return plan;
1923}
1924
1925/*
1926 * change_plan_targetlist
1927 * Externally available wrapper for inject_projection_plan.
1928 *
1929 * This is meant for use by FDW plan-generation functions, which might
1930 * want to adjust the tlist computed by some subplan tree. In general,
1931 * a Result node is needed to compute the new tlist, but we can optimize
1932 * some cases.
1933 *
1934 * In most cases, tlist_parallel_safe can just be passed as the parallel_safe
1935 * flag of the FDW's own Path node.
1936 */
1937Plan *
1938change_plan_targetlist(Plan *subplan, List *tlist, bool tlist_parallel_safe)
1939{
1940 /*
1941 * If the top plan node can't do projections and its existing target list
1942 * isn't already what we need, we need to add a Result node to help it
1943 * along.
1944 */
1945 if (!is_projection_capable_plan(subplan) &&
1946 !tlist_same_exprs(tlist, subplan->targetlist))
1947 subplan = inject_projection_plan(subplan, tlist,
1948 subplan->parallel_safe &&
1949 tlist_parallel_safe);
1950 else
1951 {
1952 /* Else we can just replace the plan node's tlist */
1953 subplan->targetlist = tlist;
1954 subplan->parallel_safe &= tlist_parallel_safe;
1955 }
1956 return subplan;
1957}
1958
1959/*
1960 * create_sort_plan
1961 *
1962 * Create a Sort plan for 'best_path' and (recursively) plans
1963 * for its subpaths.
1964 */
1965static Sort *
1966create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags)
1967{
1968 Sort *plan;
1969 Plan *subplan;
1970
1971 /*
1972 * We don't want any excess columns in the sorted tuples, so request a
1973 * smaller tlist. Otherwise, since Sort doesn't project, tlist
1974 * requirements pass through.
1975 */
1976 subplan = create_plan_recurse(root, best_path->subpath,
1977 flags | CP_SMALL_TLIST);
1978
1979 /*
1980 * make_sort_from_pathkeys() indirectly calls find_ec_member_for_tle(),
1981 * which will ignore any child EC members that don't belong to the given
1982 * relids. Thus, if this sort path is based on a child relation, we must
1983 * pass its relids.
1984 */
1985 plan = make_sort_from_pathkeys(subplan, best_path->path.pathkeys,
1986 IS_OTHER_REL(best_path->subpath->parent) ?
1987 best_path->path.parent->relids : NULL);
1988
1989 copy_generic_path_info(&plan->plan, (Path *) best_path);
1990
1991 return plan;
1992}
1993
1994/*
1995 * create_group_plan
1996 *
1997 * Create a Group plan for 'best_path' and (recursively) plans
1998 * for its subpaths.
1999 */
2000static Group *
2001create_group_plan(PlannerInfo *root, GroupPath *best_path)
2002{
2003 Group *plan;
2004 Plan *subplan;
2005 List *tlist;
2006 List *quals;
2007
2008 /*
2009 * Group can project, so no need to be terribly picky about child tlist,
2010 * but we do need grouping columns to be available
2011 */
2012 subplan = create_plan_recurse(root, best_path->subpath, CP_LABEL_TLIST);
2013
2014 tlist = build_path_tlist(root, &best_path->path);
2015
2016 quals = order_qual_clauses(root, best_path->qual);
2017
2018 plan = make_group(tlist,
2019 quals,
2020 list_length(best_path->groupClause),
2021 extract_grouping_cols(best_path->groupClause,
2022 subplan->targetlist),
2023 extract_grouping_ops(best_path->groupClause),
2024 extract_grouping_collations(best_path->groupClause,
2025 subplan->targetlist),
2026 subplan);
2027
2028 copy_generic_path_info(&plan->plan, (Path *) best_path);
2029
2030 return plan;
2031}
2032
2033/*
2034 * create_upper_unique_plan
2035 *
2036 * Create a Unique plan for 'best_path' and (recursively) plans
2037 * for its subpaths.
2038 */
2039static Unique *
2040create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path, int flags)
2041{
2042 Unique *plan;
2043 Plan *subplan;
2044
2045 /*
2046 * Unique doesn't project, so tlist requirements pass through; moreover we
2047 * need grouping columns to be labeled.
2048 */
2049 subplan = create_plan_recurse(root, best_path->subpath,
2050 flags | CP_LABEL_TLIST);
2051
2052 plan = make_unique_from_pathkeys(subplan,
2053 best_path->path.pathkeys,
2054 best_path->numkeys);
2055
2056 copy_generic_path_info(&plan->plan, (Path *) best_path);
2057
2058 return plan;
2059}
2060
2061/*
2062 * create_agg_plan
2063 *
2064 * Create an Agg plan for 'best_path' and (recursively) plans
2065 * for its subpaths.
2066 */
2067static Agg *
2068create_agg_plan(PlannerInfo *root, AggPath *best_path)
2069{
2070 Agg *plan;
2071 Plan *subplan;
2072 List *tlist;
2073 List *quals;
2074
2075 /*
2076 * Agg can project, so no need to be terribly picky about child tlist, but
2077 * we do need grouping columns to be available
2078 */
2079 subplan = create_plan_recurse(root, best_path->subpath, CP_LABEL_TLIST);
2080
2081 tlist = build_path_tlist(root, &best_path->path);
2082
2083 quals = order_qual_clauses(root, best_path->qual);
2084
2085 plan = make_agg(tlist, quals,
2086 best_path->aggstrategy,
2087 best_path->aggsplit,
2088 list_length(best_path->groupClause),
2089 extract_grouping_cols(best_path->groupClause,
2090 subplan->targetlist),
2091 extract_grouping_ops(best_path->groupClause),
2092 extract_grouping_collations(best_path->groupClause,
2093 subplan->targetlist),
2094 NIL,
2095 NIL,
2096 best_path->numGroups,
2097 subplan);
2098
2099 copy_generic_path_info(&plan->plan, (Path *) best_path);
2100
2101 return plan;
2102}
2103
2104/*
2105 * Given a groupclause for a collection of grouping sets, produce the
2106 * corresponding groupColIdx.
2107 *
2108 * root->grouping_map maps the tleSortGroupRef to the actual column position in
2109 * the input tuple. So we get the ref from the entries in the groupclause and
2110 * look them up there.
2111 */
2112static AttrNumber *
2113remap_groupColIdx(PlannerInfo *root, List *groupClause)
2114{
2115 AttrNumber *grouping_map = root->grouping_map;
2116 AttrNumber *new_grpColIdx;
2117 ListCell *lc;
2118 int i;
2119
2120 Assert(grouping_map);
2121
2122 new_grpColIdx = palloc0(sizeof(AttrNumber) * list_length(groupClause));
2123
2124 i = 0;
2125 foreach(lc, groupClause)
2126 {
2127 SortGroupClause *clause = lfirst(lc);
2128
2129 new_grpColIdx[i++] = grouping_map[clause->tleSortGroupRef];
2130 }
2131
2132 return new_grpColIdx;
2133}
2134
2135/*
2136 * create_groupingsets_plan
2137 * Create a plan for 'best_path' and (recursively) plans
2138 * for its subpaths.
2139 *
2140 * What we emit is an Agg plan with some vestigial Agg and Sort nodes
2141 * hanging off the side. The top Agg implements the last grouping set
2142 * specified in the GroupingSetsPath, and any additional grouping sets
2143 * each give rise to a subsidiary Agg and Sort node in the top Agg's
2144 * "chain" list. These nodes don't participate in the plan directly,
2145 * but they are a convenient way to represent the required data for
2146 * the extra steps.
2147 *
2148 * Returns a Plan node.
2149 */
2150static Plan *
2151create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path)
2152{
2153 Agg *plan;
2154 Plan *subplan;
2155 List *rollups = best_path->rollups;
2156 AttrNumber *grouping_map;
2157 int maxref;
2158 List *chain;
2159 ListCell *lc;
2160
2161 /* Shouldn't get here without grouping sets */
2162 Assert(root->parse->groupingSets);
2163 Assert(rollups != NIL);
2164
2165 /*
2166 * Agg can project, so no need to be terribly picky about child tlist, but
2167 * we do need grouping columns to be available
2168 */
2169 subplan = create_plan_recurse(root, best_path->subpath, CP_LABEL_TLIST);
2170
2171 /*
2172 * Compute the mapping from tleSortGroupRef to column index in the child's
2173 * tlist. First, identify max SortGroupRef in groupClause, for array
2174 * sizing.
2175 */
2176 maxref = 0;
2177 foreach(lc, root->parse->groupClause)
2178 {
2179 SortGroupClause *gc = (SortGroupClause *) lfirst(lc);
2180
2181 if (gc->tleSortGroupRef > maxref)
2182 maxref = gc->tleSortGroupRef;
2183 }
2184
2185 grouping_map = (AttrNumber *) palloc0((maxref + 1) * sizeof(AttrNumber));
2186
2187 /* Now look up the column numbers in the child's tlist */
2188 foreach(lc, root->parse->groupClause)
2189 {
2190 SortGroupClause *gc = (SortGroupClause *) lfirst(lc);
2191 TargetEntry *tle = get_sortgroupclause_tle(gc, subplan->targetlist);
2192
2193 grouping_map[gc->tleSortGroupRef] = tle->resno;
2194 }
2195
2196 /*
2197 * During setrefs.c, we'll need the grouping_map to fix up the cols lists
2198 * in GroupingFunc nodes. Save it for setrefs.c to use.
2199 *
2200 * This doesn't work if we're in an inheritance subtree (see notes in
2201 * create_modifytable_plan). Fortunately we can't be because there would
2202 * never be grouping in an UPDATE/DELETE; but let's Assert that.
2203 */
2204 Assert(root->inhTargetKind == INHKIND_NONE);
2205 Assert(root->grouping_map == NULL);
2206 root->grouping_map = grouping_map;
2207
2208 /*
2209 * Generate the side nodes that describe the other sort and group
2210 * operations besides the top one. Note that we don't worry about putting
2211 * accurate cost estimates in the side nodes; only the topmost Agg node's
2212 * costs will be shown by EXPLAIN.
2213 */
2214 chain = NIL;
2215 if (list_length(rollups) > 1)
2216 {
2217 ListCell *lc2 = lnext(list_head(rollups));
2218 bool is_first_sort = ((RollupData *) linitial(rollups))->is_hashed;
2219
2220 for_each_cell(lc, lc2)
2221 {
2222 RollupData *rollup = lfirst(lc);
2223 AttrNumber *new_grpColIdx;
2224 Plan *sort_plan = NULL;
2225 Plan *agg_plan;
2226 AggStrategy strat;
2227
2228 new_grpColIdx = remap_groupColIdx(root, rollup->groupClause);
2229
2230 if (!rollup->is_hashed && !is_first_sort)
2231 {
2232 sort_plan = (Plan *)
2233 make_sort_from_groupcols(rollup->groupClause,
2234 new_grpColIdx,
2235 subplan);
2236 }
2237
2238 if (!rollup->is_hashed)
2239 is_first_sort = false;
2240
2241 if (rollup->is_hashed)
2242 strat = AGG_HASHED;
2243 else if (list_length(linitial(rollup->gsets)) == 0)
2244 strat = AGG_PLAIN;
2245 else
2246 strat = AGG_SORTED;
2247
2248 agg_plan = (Plan *) make_agg(NIL,
2249 NIL,
2250 strat,
2251 AGGSPLIT_SIMPLE,
2252 list_length((List *) linitial(rollup->gsets)),
2253 new_grpColIdx,
2254 extract_grouping_ops(rollup->groupClause),
2255 extract_grouping_collations(rollup->groupClause, subplan->targetlist),
2256 rollup->gsets,
2257 NIL,
2258 rollup->numGroups,
2259 sort_plan);
2260
2261 /*
2262 * Remove stuff we don't need to avoid bloating debug output.
2263 */
2264 if (sort_plan)
2265 {
2266 sort_plan->targetlist = NIL;
2267 sort_plan->lefttree = NULL;
2268 }
2269
2270 chain = lappend(chain, agg_plan);
2271 }
2272 }
2273
2274 /*
2275 * Now make the real Agg node
2276 */
2277 {
2278 RollupData *rollup = linitial(rollups);
2279 AttrNumber *top_grpColIdx;
2280 int numGroupCols;
2281
2282 top_grpColIdx = remap_groupColIdx(root, rollup->groupClause);
2283
2284 numGroupCols = list_length((List *) linitial(rollup->gsets));
2285
2286 plan = make_agg(build_path_tlist(root, &best_path->path),
2287 best_path->qual,
2288 best_path->aggstrategy,
2289 AGGSPLIT_SIMPLE,
2290 numGroupCols,
2291 top_grpColIdx,
2292 extract_grouping_ops(rollup->groupClause),
2293 extract_grouping_collations(rollup->groupClause, subplan->targetlist),
2294 rollup->gsets,
2295 chain,
2296 rollup->numGroups,
2297 subplan);
2298
2299 /* Copy cost data from Path to Plan */
2300 copy_generic_path_info(&plan->plan, &best_path->path);
2301 }
2302
2303 return (Plan *) plan;
2304}
2305
2306/*
2307 * create_minmaxagg_plan
2308 *
2309 * Create a Result plan for 'best_path' and (recursively) plans
2310 * for its subpaths.
2311 */
2312static Result *
2313create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path)
2314{
2315 Result *plan;
2316 List *tlist;
2317 ListCell *lc;
2318
2319 /* Prepare an InitPlan for each aggregate's subquery. */
2320 foreach(lc, best_path->mmaggregates)
2321 {
2322 MinMaxAggInfo *mminfo = (MinMaxAggInfo *) lfirst(lc);
2323 PlannerInfo *subroot = mminfo->subroot;
2324 Query *subparse = subroot->parse;
2325 Plan *plan;
2326
2327 /*
2328 * Generate the plan for the subquery. We already have a Path, but we
2329 * have to convert it to a Plan and attach a LIMIT node above it.
2330 * Since we are entering a different planner context (subroot),
2331 * recurse to create_plan not create_plan_recurse.
2332 */
2333 plan = create_plan(subroot, mminfo->path);
2334
2335 plan = (Plan *) make_limit(plan,
2336 subparse->limitOffset,
2337 subparse->limitCount);
2338
2339 /* Must apply correct cost/width data to Limit node */
2340 plan->startup_cost = mminfo->path->startup_cost;
2341 plan->total_cost = mminfo->pathcost;
2342 plan->plan_rows = 1;
2343 plan->plan_width = mminfo->path->pathtarget->width;
2344 plan->parallel_aware = false;
2345 plan->parallel_safe = mminfo->path->parallel_safe;
2346
2347 /* Convert the plan into an InitPlan in the outer query. */
2348 SS_make_initplan_from_plan(root, subroot, plan, mminfo->param);
2349 }
2350
2351 /* Generate the output plan --- basically just a Result */
2352 tlist = build_path_tlist(root, &best_path->path);
2353
2354 plan = make_result(tlist, (Node *) best_path->quals, NULL);
2355
2356 copy_generic_path_info(&plan->plan, (Path *) best_path);
2357
2358 /*
2359 * During setrefs.c, we'll need to replace references to the Agg nodes
2360 * with InitPlan output params. (We can't just do that locally in the
2361 * MinMaxAgg node, because path nodes above here may have Agg references
2362 * as well.) Save the mmaggregates list to tell setrefs.c to do that.
2363 *
2364 * This doesn't work if we're in an inheritance subtree (see notes in
2365 * create_modifytable_plan). Fortunately we can't be because there would
2366 * never be aggregates in an UPDATE/DELETE; but let's Assert that.
2367 */
2368 Assert(root->inhTargetKind == INHKIND_NONE);
2369 Assert(root->minmax_aggs == NIL);
2370 root->minmax_aggs = best_path->mmaggregates;
2371
2372 return plan;
2373}
2374
2375/*
2376 * create_windowagg_plan
2377 *
2378 * Create a WindowAgg plan for 'best_path' and (recursively) plans
2379 * for its subpaths.
2380 */
2381static WindowAgg *
2382create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path)
2383{
2384 WindowAgg *plan;
2385 WindowClause *wc = best_path->winclause;
2386 int numPart = list_length(wc->partitionClause);
2387 int numOrder = list_length(wc->orderClause);
2388 Plan *subplan;
2389 List *tlist;
2390 int partNumCols;
2391 AttrNumber *partColIdx;
2392 Oid *partOperators;
2393 Oid *partCollations;
2394 int ordNumCols;
2395 AttrNumber *ordColIdx;
2396 Oid *ordOperators;
2397 Oid *ordCollations;
2398 ListCell *lc;
2399
2400 /*
2401 * WindowAgg can project, so no need to be terribly picky about child
2402 * tlist, but we do need grouping columns to be available
2403 */
2404 subplan = create_plan_recurse(root, best_path->subpath, CP_LABEL_TLIST);
2405
2406 tlist = build_path_tlist(root, &best_path->path);
2407
2408 /*
2409 * Convert SortGroupClause lists into arrays of attr indexes and equality
2410 * operators, as wanted by executor. (Note: in principle, it's possible
2411 * to drop some of the sort columns, if they were proved redundant by
2412 * pathkey logic. However, it doesn't seem worth going out of our way to
2413 * optimize such cases. In any case, we must *not* remove the ordering
2414 * column for RANGE OFFSET cases, as the executor needs that for in_range
2415 * tests even if it's known to be equal to some partitioning column.)
2416 */
2417 partColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numPart);
2418 partOperators = (Oid *) palloc(sizeof(Oid) * numPart);
2419 partCollations = (Oid *) palloc(sizeof(Oid) * numPart);
2420
2421 partNumCols = 0;
2422 foreach(lc, wc->partitionClause)
2423 {
2424 SortGroupClause *sgc = (SortGroupClause *) lfirst(lc);
2425 TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist);
2426
2427 Assert(OidIsValid(sgc->eqop));
2428 partColIdx[partNumCols] = tle->resno;
2429 partOperators[partNumCols] = sgc->eqop;
2430 partCollations[partNumCols] = exprCollation((Node *) tle->expr);
2431 partNumCols++;
2432 }
2433
2434 ordColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numOrder);
2435 ordOperators = (Oid *) palloc(sizeof(Oid) * numOrder);
2436 ordCollations = (Oid *) palloc(sizeof(Oid) * numOrder);
2437
2438 ordNumCols = 0;
2439 foreach(lc, wc->orderClause)
2440 {
2441 SortGroupClause *sgc = (SortGroupClause *) lfirst(lc);
2442 TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist);
2443
2444 Assert(OidIsValid(sgc->eqop));
2445 ordColIdx[ordNumCols] = tle->resno;
2446 ordOperators[ordNumCols] = sgc->eqop;
2447 ordCollations[ordNumCols] = exprCollation((Node *) tle->expr);
2448 ordNumCols++;
2449 }
2450
2451 /* And finally we can make the WindowAgg node */
2452 plan = make_windowagg(tlist,
2453 wc->winref,
2454 partNumCols,
2455 partColIdx,
2456 partOperators,
2457 partCollations,
2458 ordNumCols,
2459 ordColIdx,
2460 ordOperators,
2461 ordCollations,
2462 wc->frameOptions,
2463 wc->startOffset,
2464 wc->endOffset,
2465 wc->startInRangeFunc,
2466 wc->endInRangeFunc,
2467 wc->inRangeColl,
2468 wc->inRangeAsc,
2469 wc->inRangeNullsFirst,
2470 subplan);
2471
2472 copy_generic_path_info(&plan->plan, (Path *) best_path);
2473
2474 return plan;
2475}
2476
2477/*
2478 * create_setop_plan
2479 *
2480 * Create a SetOp plan for 'best_path' and (recursively) plans
2481 * for its subpaths.
2482 */
2483static SetOp *
2484create_setop_plan(PlannerInfo *root, SetOpPath *best_path, int flags)
2485{
2486 SetOp *plan;
2487 Plan *subplan;
2488 long numGroups;
2489
2490 /*
2491 * SetOp doesn't project, so tlist requirements pass through; moreover we
2492 * need grouping columns to be labeled.
2493 */
2494 subplan = create_plan_recurse(root, best_path->subpath,
2495 flags | CP_LABEL_TLIST);
2496
2497 /* Convert numGroups to long int --- but 'ware overflow! */
2498 numGroups = (long) Min(best_path->numGroups, (double) LONG_MAX);
2499
2500 plan = make_setop(best_path->cmd,
2501 best_path->strategy,
2502 subplan,
2503 best_path->distinctList,
2504 best_path->flagColIdx,
2505 best_path->firstFlag,
2506 numGroups);
2507
2508 copy_generic_path_info(&plan->plan, (Path *) best_path);
2509
2510 return plan;
2511}
2512
2513/*
2514 * create_recursiveunion_plan
2515 *
2516 * Create a RecursiveUnion plan for 'best_path' and (recursively) plans
2517 * for its subpaths.
2518 */
2519static RecursiveUnion *
2520create_recursiveunion_plan(PlannerInfo *root, RecursiveUnionPath *best_path)
2521{
2522 RecursiveUnion *plan;
2523 Plan *leftplan;
2524 Plan *rightplan;
2525 List *tlist;
2526 long numGroups;
2527
2528 /* Need both children to produce same tlist, so force it */
2529 leftplan = create_plan_recurse(root, best_path->leftpath, CP_EXACT_TLIST);
2530 rightplan = create_plan_recurse(root, best_path->rightpath, CP_EXACT_TLIST);
2531
2532 tlist = build_path_tlist(root, &best_path->path);
2533
2534 /* Convert numGroups to long int --- but 'ware overflow! */
2535 numGroups = (long) Min(best_path->numGroups, (double) LONG_MAX);
2536
2537 plan = make_recursive_union(tlist,
2538 leftplan,
2539 rightplan,
2540 best_path->wtParam,
2541 best_path->distinctList,
2542 numGroups);
2543
2544 copy_generic_path_info(&plan->plan, (Path *) best_path);
2545
2546 return plan;
2547}
2548
2549/*
2550 * create_lockrows_plan
2551 *
2552 * Create a LockRows plan for 'best_path' and (recursively) plans
2553 * for its subpaths.
2554 */
2555static LockRows *
2556create_lockrows_plan(PlannerInfo *root, LockRowsPath *best_path,
2557 int flags)
2558{
2559 LockRows *plan;
2560 Plan *subplan;
2561
2562 /* LockRows doesn't project, so tlist requirements pass through */
2563 subplan = create_plan_recurse(root, best_path->subpath, flags);
2564
2565 plan = make_lockrows(subplan, best_path->rowMarks, best_path->epqParam);
2566
2567 copy_generic_path_info(&plan->plan, (Path *) best_path);
2568
2569 return plan;
2570}
2571
2572/*
2573 * create_modifytable_plan
2574 * Create a ModifyTable plan for 'best_path'.
2575 *
2576 * Returns a Plan node.
2577 */
2578static ModifyTable *
2579create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path)
2580{
2581 ModifyTable *plan;
2582 List *subplans = NIL;
2583 ListCell *subpaths,
2584 *subroots;
2585
2586 /* Build the plan for each input path */
2587 forboth(subpaths, best_path->subpaths,
2588 subroots, best_path->subroots)
2589 {
2590 Path *subpath = (Path *) lfirst(subpaths);
2591 PlannerInfo *subroot = (PlannerInfo *) lfirst(subroots);
2592 Plan *subplan;
2593
2594 /*
2595 * In an inherited UPDATE/DELETE, reference the per-child modified
2596 * subroot while creating Plans from Paths for the child rel. This is
2597 * a kluge, but otherwise it's too hard to ensure that Plan creation
2598 * functions (particularly in FDWs) don't depend on the contents of
2599 * "root" matching what they saw at Path creation time. The main
2600 * downside is that creation functions for Plans that might appear
2601 * below a ModifyTable cannot expect to modify the contents of "root"
2602 * and have it "stick" for subsequent processing such as setrefs.c.
2603 * That's not great, but it seems better than the alternative.
2604 */
2605 subplan = create_plan_recurse(subroot, subpath, CP_EXACT_TLIST);
2606
2607 /* Transfer resname/resjunk labeling, too, to keep executor happy */
2608 apply_tlist_labeling(subplan->targetlist, subroot->processed_tlist);
2609
2610 subplans = lappend(subplans, subplan);
2611 }
2612
2613 plan = make_modifytable(root,
2614 best_path->operation,
2615 best_path->canSetTag,
2616 best_path->nominalRelation,
2617 best_path->rootRelation,
2618 best_path->partColsUpdated,
2619 best_path->resultRelations,
2620 subplans,
2621 best_path->subroots,
2622 best_path->withCheckOptionLists,
2623 best_path->returningLists,
2624 best_path->rowMarks,
2625 best_path->onconflict,
2626 best_path->epqParam);
2627
2628 copy_generic_path_info(&plan->plan, &best_path->path);
2629
2630 return plan;
2631}
2632
2633/*
2634 * create_limit_plan
2635 *
2636 * Create a Limit plan for 'best_path' and (recursively) plans
2637 * for its subpaths.
2638 */
2639static Limit *
2640create_limit_plan(PlannerInfo *root, LimitPath *best_path, int flags)
2641{
2642 Limit *plan;
2643 Plan *subplan;
2644
2645 /* Limit doesn't project, so tlist requirements pass through */
2646 subplan = create_plan_recurse(root, best_path->subpath, flags);
2647
2648 plan = make_limit(subplan,
2649 best_path->limitOffset,
2650 best_path->limitCount);
2651
2652 copy_generic_path_info(&plan->plan, (Path *) best_path);
2653
2654 return plan;
2655}
2656
2657
2658/*****************************************************************************
2659 *
2660 * BASE-RELATION SCAN METHODS
2661 *
2662 *****************************************************************************/
2663
2664
2665/*
2666 * create_seqscan_plan
2667 * Returns a seqscan plan for the base relation scanned by 'best_path'
2668 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
2669 */
2670static SeqScan *
2671create_seqscan_plan(PlannerInfo *root, Path *best_path,
2672 List *tlist, List *scan_clauses)
2673{
2674 SeqScan *scan_plan;
2675 Index scan_relid = best_path->parent->relid;
2676
2677 /* it should be a base rel... */
2678 Assert(scan_relid > 0);
2679 Assert(best_path->parent->rtekind == RTE_RELATION);
2680
2681 /* Sort clauses into best execution order */
2682 scan_clauses = order_qual_clauses(root, scan_clauses);
2683
2684 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
2685 scan_clauses = extract_actual_clauses(scan_clauses, false);
2686
2687 /* Replace any outer-relation variables with nestloop params */
2688 if (best_path->param_info)
2689 {
2690 scan_clauses = (List *)
2691 replace_nestloop_params(root, (Node *) scan_clauses);
2692 }
2693
2694 scan_plan = make_seqscan(tlist,
2695 scan_clauses,
2696 scan_relid);
2697
2698 copy_generic_path_info(&scan_plan->plan, best_path);
2699
2700 return scan_plan;
2701}
2702
2703/*
2704 * create_samplescan_plan
2705 * Returns a samplescan plan for the base relation scanned by 'best_path'
2706 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
2707 */
2708static SampleScan *
2709create_samplescan_plan(PlannerInfo *root, Path *best_path,
2710 List *tlist, List *scan_clauses)
2711{
2712 SampleScan *scan_plan;
2713 Index scan_relid = best_path->parent->relid;
2714 RangeTblEntry *rte;
2715 TableSampleClause *tsc;
2716
2717 /* it should be a base rel with a tablesample clause... */
2718 Assert(scan_relid > 0);
2719 rte = planner_rt_fetch(scan_relid, root);
2720 Assert(rte->rtekind == RTE_RELATION);
2721 tsc = rte->tablesample;
2722 Assert(tsc != NULL);
2723
2724 /* Sort clauses into best execution order */
2725 scan_clauses = order_qual_clauses(root, scan_clauses);
2726
2727 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
2728 scan_clauses = extract_actual_clauses(scan_clauses, false);
2729
2730 /* Replace any outer-relation variables with nestloop params */
2731 if (best_path->param_info)
2732 {
2733 scan_clauses = (List *)
2734 replace_nestloop_params(root, (Node *) scan_clauses);
2735 tsc = (TableSampleClause *)
2736 replace_nestloop_params(root, (Node *) tsc);
2737 }
2738
2739 scan_plan = make_samplescan(tlist,
2740 scan_clauses,
2741 scan_relid,
2742 tsc);
2743
2744 copy_generic_path_info(&scan_plan->scan.plan, best_path);
2745
2746 return scan_plan;
2747}
2748
2749/*
2750 * create_indexscan_plan
2751 * Returns an indexscan plan for the base relation scanned by 'best_path'
2752 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
2753 *
2754 * We use this for both plain IndexScans and IndexOnlyScans, because the
2755 * qual preprocessing work is the same for both. Note that the caller tells
2756 * us which to build --- we don't look at best_path->path.pathtype, because
2757 * create_bitmap_subplan needs to be able to override the prior decision.
2758 */
2759static Scan *
2760create_indexscan_plan(PlannerInfo *root,
2761 IndexPath *best_path,
2762 List *tlist,
2763 List *scan_clauses,
2764 bool indexonly)
2765{
2766 Scan *scan_plan;
2767 List *indexclauses = best_path->indexclauses;
2768 List *indexorderbys = best_path->indexorderbys;
2769 Index baserelid = best_path->path.parent->relid;
2770 Oid indexoid = best_path->indexinfo->indexoid;
2771 List *qpqual;
2772 List *stripped_indexquals;
2773 List *fixed_indexquals;
2774 List *fixed_indexorderbys;
2775 List *indexorderbyops = NIL;
2776 ListCell *l;
2777
2778 /* it should be a base rel... */
2779 Assert(baserelid > 0);
2780 Assert(best_path->path.parent->rtekind == RTE_RELATION);
2781
2782 /*
2783 * Extract the index qual expressions (stripped of RestrictInfos) from the
2784 * IndexClauses list, and prepare a copy with index Vars substituted for
2785 * table Vars. (This step also does replace_nestloop_params on the
2786 * fixed_indexquals.)
2787 */
2788 fix_indexqual_references(root, best_path,
2789 &stripped_indexquals,
2790 &fixed_indexquals);
2791
2792 /*
2793 * Likewise fix up index attr references in the ORDER BY expressions.
2794 */
2795 fixed_indexorderbys = fix_indexorderby_references(root, best_path);
2796
2797 /*
2798 * The qpqual list must contain all restrictions not automatically handled
2799 * by the index, other than pseudoconstant clauses which will be handled
2800 * by a separate gating plan node. All the predicates in the indexquals
2801 * will be checked (either by the index itself, or by nodeIndexscan.c),
2802 * but if there are any "special" operators involved then they must be
2803 * included in qpqual. The upshot is that qpqual must contain
2804 * scan_clauses minus whatever appears in indexquals.
2805 *
2806 * is_redundant_with_indexclauses() detects cases where a scan clause is
2807 * present in the indexclauses list or is generated from the same
2808 * EquivalenceClass as some indexclause, and is therefore redundant with
2809 * it, though not equal. (The latter happens when indxpath.c prefers a
2810 * different derived equality than what generate_join_implied_equalities
2811 * picked for a parameterized scan's ppi_clauses.) Note that it will not
2812 * match to lossy index clauses, which is critical because we have to
2813 * include the original clause in qpqual in that case.
2814 *
2815 * In some situations (particularly with OR'd index conditions) we may
2816 * have scan_clauses that are not equal to, but are logically implied by,
2817 * the index quals; so we also try a predicate_implied_by() check to see
2818 * if we can discard quals that way. (predicate_implied_by assumes its
2819 * first input contains only immutable functions, so we have to check
2820 * that.)
2821 *
2822 * Note: if you change this bit of code you should also look at
2823 * extract_nonindex_conditions() in costsize.c.
2824 */
2825 qpqual = NIL;
2826 foreach(l, scan_clauses)
2827 {
2828 RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
2829
2830 if (rinfo->pseudoconstant)
2831 continue; /* we may drop pseudoconstants here */
2832 if (is_redundant_with_indexclauses(rinfo, indexclauses))
2833 continue; /* dup or derived from same EquivalenceClass */
2834 if (!contain_mutable_functions((Node *) rinfo->clause) &&
2835 predicate_implied_by(list_make1(rinfo->clause), stripped_indexquals,
2836 false))
2837 continue; /* provably implied by indexquals */
2838 qpqual = lappend(qpqual, rinfo);
2839 }
2840
2841 /* Sort clauses into best execution order */
2842 qpqual = order_qual_clauses(root, qpqual);
2843
2844 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
2845 qpqual = extract_actual_clauses(qpqual, false);
2846
2847 /*
2848 * We have to replace any outer-relation variables with nestloop params in
2849 * the indexqualorig, qpqual, and indexorderbyorig expressions. A bit
2850 * annoying to have to do this separately from the processing in
2851 * fix_indexqual_references --- rethink this when generalizing the inner
2852 * indexscan support. But note we can't really do this earlier because
2853 * it'd break the comparisons to predicates above ... (or would it? Those
2854 * wouldn't have outer refs)
2855 */
2856 if (best_path->path.param_info)
2857 {
2858 stripped_indexquals = (List *)
2859 replace_nestloop_params(root, (Node *) stripped_indexquals);
2860 qpqual = (List *)
2861 replace_nestloop_params(root, (Node *) qpqual);
2862 indexorderbys = (List *)
2863 replace_nestloop_params(root, (Node *) indexorderbys);
2864 }
2865
2866 /*
2867 * If there are ORDER BY expressions, look up the sort operators for their
2868 * result datatypes.
2869 */
2870 if (indexorderbys)
2871 {
2872 ListCell *pathkeyCell,
2873 *exprCell;
2874
2875 /*
2876 * PathKey contains OID of the btree opfamily we're sorting by, but
2877 * that's not quite enough because we need the expression's datatype
2878 * to look up the sort operator in the operator family.
2879 */
2880 Assert(list_length(best_path->path.pathkeys) == list_length(indexorderbys));
2881 forboth(pathkeyCell, best_path->path.pathkeys, exprCell, indexorderbys)
2882 {
2883 PathKey *pathkey = (PathKey *) lfirst(pathkeyCell);
2884 Node *expr = (Node *) lfirst(exprCell);
2885 Oid exprtype = exprType(expr);
2886 Oid sortop;
2887
2888 /* Get sort operator from opfamily */
2889 sortop = get_opfamily_member(pathkey->pk_opfamily,
2890 exprtype,
2891 exprtype,
2892 pathkey->pk_strategy);
2893 if (!OidIsValid(sortop))
2894 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
2895 pathkey->pk_strategy, exprtype, exprtype, pathkey->pk_opfamily);
2896 indexorderbyops = lappend_oid(indexorderbyops, sortop);
2897 }
2898 }
2899
2900 /* Finally ready to build the plan node */
2901 if (indexonly)
2902 scan_plan = (Scan *) make_indexonlyscan(tlist,
2903 qpqual,
2904 baserelid,
2905 indexoid,
2906 fixed_indexquals,
2907 fixed_indexorderbys,
2908 best_path->indexinfo->indextlist,
2909 best_path->indexscandir);
2910 else
2911 scan_plan = (Scan *) make_indexscan(tlist,
2912 qpqual,
2913 baserelid,
2914 indexoid,
2915 fixed_indexquals,
2916 stripped_indexquals,
2917 fixed_indexorderbys,
2918 indexorderbys,
2919 indexorderbyops,
2920 best_path->indexscandir);
2921
2922 copy_generic_path_info(&scan_plan->plan, &best_path->path);
2923
2924 return scan_plan;
2925}
2926
2927/*
2928 * create_bitmap_scan_plan
2929 * Returns a bitmap scan plan for the base relation scanned by 'best_path'
2930 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
2931 */
2932static BitmapHeapScan *
2933create_bitmap_scan_plan(PlannerInfo *root,
2934 BitmapHeapPath *best_path,
2935 List *tlist,
2936 List *scan_clauses)
2937{
2938 Index baserelid = best_path->path.parent->relid;
2939 Plan *bitmapqualplan;
2940 List *bitmapqualorig;
2941 List *indexquals;
2942 List *indexECs;
2943 List *qpqual;
2944 ListCell *l;
2945 BitmapHeapScan *scan_plan;
2946
2947 /* it should be a base rel... */
2948 Assert(baserelid > 0);
2949 Assert(best_path->path.parent->rtekind == RTE_RELATION);
2950
2951 /* Process the bitmapqual tree into a Plan tree and qual lists */
2952 bitmapqualplan = create_bitmap_subplan(root, best_path->bitmapqual,
2953 &bitmapqualorig, &indexquals,
2954 &indexECs);
2955
2956 if (best_path->path.parallel_aware)
2957 bitmap_subplan_mark_shared(bitmapqualplan);
2958
2959 /*
2960 * The qpqual list must contain all restrictions not automatically handled
2961 * by the index, other than pseudoconstant clauses which will be handled
2962 * by a separate gating plan node. All the predicates in the indexquals
2963 * will be checked (either by the index itself, or by
2964 * nodeBitmapHeapscan.c), but if there are any "special" operators
2965 * involved then they must be added to qpqual. The upshot is that qpqual
2966 * must contain scan_clauses minus whatever appears in indexquals.
2967 *
2968 * This loop is similar to the comparable code in create_indexscan_plan(),
2969 * but with some differences because it has to compare the scan clauses to
2970 * stripped (no RestrictInfos) indexquals. See comments there for more
2971 * info.
2972 *
2973 * In normal cases simple equal() checks will be enough to spot duplicate
2974 * clauses, so we try that first. We next see if the scan clause is
2975 * redundant with any top-level indexqual by virtue of being generated
2976 * from the same EC. After that, try predicate_implied_by().
2977 *
2978 * Unlike create_indexscan_plan(), the predicate_implied_by() test here is
2979 * useful for getting rid of qpquals that are implied by index predicates,
2980 * because the predicate conditions are included in the "indexquals"
2981 * returned by create_bitmap_subplan(). Bitmap scans have to do it that
2982 * way because predicate conditions need to be rechecked if the scan
2983 * becomes lossy, so they have to be included in bitmapqualorig.
2984 */
2985 qpqual = NIL;
2986 foreach(l, scan_clauses)
2987 {
2988 RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
2989 Node *clause = (Node *) rinfo->clause;
2990
2991 if (rinfo->pseudoconstant)
2992 continue; /* we may drop pseudoconstants here */
2993 if (list_member(indexquals, clause))
2994 continue; /* simple duplicate */
2995 if (rinfo->parent_ec && list_member_ptr(indexECs, rinfo->parent_ec))
2996 continue; /* derived from same EquivalenceClass */
2997 if (!contain_mutable_functions(clause) &&
2998 predicate_implied_by(list_make1(clause), indexquals, false))
2999 continue; /* provably implied by indexquals */
3000 qpqual = lappend(qpqual, rinfo);
3001 }
3002
3003 /* Sort clauses into best execution order */
3004 qpqual = order_qual_clauses(root, qpqual);
3005
3006 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3007 qpqual = extract_actual_clauses(qpqual, false);
3008
3009 /*
3010 * When dealing with special operators, we will at this point have
3011 * duplicate clauses in qpqual and bitmapqualorig. We may as well drop
3012 * 'em from bitmapqualorig, since there's no point in making the tests
3013 * twice.
3014 */
3015 bitmapqualorig = list_difference_ptr(bitmapqualorig, qpqual);
3016
3017 /*
3018 * We have to replace any outer-relation variables with nestloop params in
3019 * the qpqual and bitmapqualorig expressions. (This was already done for
3020 * expressions attached to plan nodes in the bitmapqualplan tree.)
3021 */
3022 if (best_path->path.param_info)
3023 {
3024 qpqual = (List *)
3025 replace_nestloop_params(root, (Node *) qpqual);
3026 bitmapqualorig = (List *)
3027 replace_nestloop_params(root, (Node *) bitmapqualorig);
3028 }
3029
3030 /* Finally ready to build the plan node */
3031 scan_plan = make_bitmap_heapscan(tlist,
3032 qpqual,
3033 bitmapqualplan,
3034 bitmapqualorig,
3035 baserelid);
3036
3037 copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
3038
3039 return scan_plan;
3040}
3041
3042/*
3043 * Given a bitmapqual tree, generate the Plan tree that implements it
3044 *
3045 * As byproducts, we also return in *qual and *indexqual the qual lists
3046 * (in implicit-AND form, without RestrictInfos) describing the original index
3047 * conditions and the generated indexqual conditions. (These are the same in
3048 * simple cases, but when special index operators are involved, the former
3049 * list includes the special conditions while the latter includes the actual
3050 * indexable conditions derived from them.) Both lists include partial-index
3051 * predicates, because we have to recheck predicates as well as index
3052 * conditions if the bitmap scan becomes lossy.
3053 *
3054 * In addition, we return a list of EquivalenceClass pointers for all the
3055 * top-level indexquals that were possibly-redundantly derived from ECs.
3056 * This allows removal of scan_clauses that are redundant with such quals.
3057 * (We do not attempt to detect such redundancies for quals that are within
3058 * OR subtrees. This could be done in a less hacky way if we returned the
3059 * indexquals in RestrictInfo form, but that would be slower and still pretty
3060 * messy, since we'd have to build new RestrictInfos in many cases.)
3061 */
3062static Plan *
3063create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
3064 List **qual, List **indexqual, List **indexECs)
3065{
3066 Plan *plan;
3067
3068 if (IsA(bitmapqual, BitmapAndPath))
3069 {
3070 BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
3071 List *subplans = NIL;
3072 List *subquals = NIL;
3073 List *subindexquals = NIL;
3074 List *subindexECs = NIL;
3075 ListCell *l;
3076
3077 /*
3078 * There may well be redundant quals among the subplans, since a
3079 * top-level WHERE qual might have gotten used to form several
3080 * different index quals. We don't try exceedingly hard to eliminate
3081 * redundancies, but we do eliminate obvious duplicates by using
3082 * list_concat_unique.
3083 */
3084 foreach(l, apath->bitmapquals)
3085 {
3086 Plan *subplan;
3087 List *subqual;
3088 List *subindexqual;
3089 List *subindexEC;
3090
3091 subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
3092 &subqual, &subindexqual,
3093 &subindexEC);
3094 subplans = lappend(subplans, subplan);
3095 subquals = list_concat_unique(subquals, subqual);
3096 subindexquals = list_concat_unique(subindexquals, subindexqual);
3097 /* Duplicates in indexECs aren't worth getting rid of */
3098 subindexECs = list_concat(subindexECs, subindexEC);
3099 }
3100 plan = (Plan *) make_bitmap_and(subplans);
3101 plan->startup_cost = apath->path.startup_cost;
3102 plan->total_cost = apath->path.total_cost;
3103 plan->plan_rows =
3104 clamp_row_est(apath->bitmapselectivity * apath->path.parent->tuples);
3105 plan->plan_width = 0; /* meaningless */
3106 plan->parallel_aware = false;
3107 plan->parallel_safe = apath->path.parallel_safe;
3108 *qual = subquals;
3109 *indexqual = subindexquals;
3110 *indexECs = subindexECs;
3111 }
3112 else if (IsA(bitmapqual, BitmapOrPath))
3113 {
3114 BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
3115 List *subplans = NIL;
3116 List *subquals = NIL;
3117 List *subindexquals = NIL;
3118 bool const_true_subqual = false;
3119 bool const_true_subindexqual = false;
3120 ListCell *l;
3121
3122 /*
3123 * Here, we only detect qual-free subplans. A qual-free subplan would
3124 * cause us to generate "... OR true ..." which we may as well reduce
3125 * to just "true". We do not try to eliminate redundant subclauses
3126 * because (a) it's not as likely as in the AND case, and (b) we might
3127 * well be working with hundreds or even thousands of OR conditions,
3128 * perhaps from a long IN list. The performance of list_append_unique
3129 * would be unacceptable.
3130 */
3131 foreach(l, opath->bitmapquals)
3132 {
3133 Plan *subplan;
3134 List *subqual;
3135 List *subindexqual;
3136 List *subindexEC;
3137
3138 subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
3139 &subqual, &subindexqual,
3140 &subindexEC);
3141 subplans = lappend(subplans, subplan);
3142 if (subqual == NIL)
3143 const_true_subqual = true;
3144 else if (!const_true_subqual)
3145 subquals = lappend(subquals,
3146 make_ands_explicit(subqual));
3147 if (subindexqual == NIL)
3148 const_true_subindexqual = true;
3149 else if (!const_true_subindexqual)
3150 subindexquals = lappend(subindexquals,
3151 make_ands_explicit(subindexqual));
3152 }
3153
3154 /*
3155 * In the presence of ScalarArrayOpExpr quals, we might have built
3156 * BitmapOrPaths with just one subpath; don't add an OR step.
3157 */
3158 if (list_length(subplans) == 1)
3159 {
3160 plan = (Plan *) linitial(subplans);
3161 }
3162 else
3163 {
3164 plan = (Plan *) make_bitmap_or(subplans);
3165 plan->startup_cost = opath->path.startup_cost;
3166 plan->total_cost = opath->path.total_cost;
3167 plan->plan_rows =
3168 clamp_row_est(opath->bitmapselectivity * opath->path.parent->tuples);
3169 plan->plan_width = 0; /* meaningless */
3170 plan->parallel_aware = false;
3171 plan->parallel_safe = opath->path.parallel_safe;
3172 }
3173
3174 /*
3175 * If there were constant-TRUE subquals, the OR reduces to constant
3176 * TRUE. Also, avoid generating one-element ORs, which could happen
3177 * due to redundancy elimination or ScalarArrayOpExpr quals.
3178 */
3179 if (const_true_subqual)
3180 *qual = NIL;
3181 else if (list_length(subquals) <= 1)
3182 *qual = subquals;
3183 else
3184 *qual = list_make1(make_orclause(subquals));
3185 if (const_true_subindexqual)
3186 *indexqual = NIL;
3187 else if (list_length(subindexquals) <= 1)
3188 *indexqual = subindexquals;
3189 else
3190 *indexqual = list_make1(make_orclause(subindexquals));
3191 *indexECs = NIL;
3192 }
3193 else if (IsA(bitmapqual, IndexPath))
3194 {
3195 IndexPath *ipath = (IndexPath *) bitmapqual;
3196 IndexScan *iscan;
3197 List *subquals;
3198 List *subindexquals;
3199 List *subindexECs;
3200 ListCell *l;
3201
3202 /* Use the regular indexscan plan build machinery... */
3203 iscan = castNode(IndexScan,
3204 create_indexscan_plan(root, ipath,
3205 NIL, NIL, false));
3206 /* then convert to a bitmap indexscan */
3207 plan = (Plan *) make_bitmap_indexscan(iscan->scan.scanrelid,
3208 iscan->indexid,
3209 iscan->indexqual,
3210 iscan->indexqualorig);
3211 /* and set its cost/width fields appropriately */
3212 plan->startup_cost = 0.0;
3213 plan->total_cost = ipath->indextotalcost;
3214 plan->plan_rows =
3215 clamp_row_est(ipath->indexselectivity * ipath->path.parent->tuples);
3216 plan->plan_width = 0; /* meaningless */
3217 plan->parallel_aware = false;
3218 plan->parallel_safe = ipath->path.parallel_safe;
3219 /* Extract original index clauses, actual index quals, relevant ECs */
3220 subquals = NIL;
3221 subindexquals = NIL;
3222 subindexECs = NIL;
3223 foreach(l, ipath->indexclauses)
3224 {
3225 IndexClause *iclause = (IndexClause *) lfirst(l);
3226 RestrictInfo *rinfo = iclause->rinfo;
3227
3228 Assert(!rinfo->pseudoconstant);
3229 subquals = lappend(subquals, rinfo->clause);
3230 subindexquals = list_concat(subindexquals,
3231 get_actual_clauses(iclause->indexquals));
3232 if (rinfo->parent_ec)
3233 subindexECs = lappend(subindexECs, rinfo->parent_ec);
3234 }
3235 /* We can add any index predicate conditions, too */
3236 foreach(l, ipath->indexinfo->indpred)
3237 {
3238 Expr *pred = (Expr *) lfirst(l);
3239
3240 /*
3241 * We know that the index predicate must have been implied by the
3242 * query condition as a whole, but it may or may not be implied by
3243 * the conditions that got pushed into the bitmapqual. Avoid
3244 * generating redundant conditions.
3245 */
3246 if (!predicate_implied_by(list_make1(pred), subquals, false))
3247 {
3248 subquals = lappend(subquals, pred);
3249 subindexquals = lappend(subindexquals, pred);
3250 }
3251 }
3252 *qual = subquals;
3253 *indexqual = subindexquals;
3254 *indexECs = subindexECs;
3255 }
3256 else
3257 {
3258 elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
3259 plan = NULL; /* keep compiler quiet */
3260 }
3261
3262 return plan;
3263}
3264
3265/*
3266 * create_tidscan_plan
3267 * Returns a tidscan plan for the base relation scanned by 'best_path'
3268 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3269 */
3270static TidScan *
3271create_tidscan_plan(PlannerInfo *root, TidPath *best_path,
3272 List *tlist, List *scan_clauses)
3273{
3274 TidScan *scan_plan;
3275 Index scan_relid = best_path->path.parent->relid;
3276 List *tidquals = best_path->tidquals;
3277
3278 /* it should be a base rel... */
3279 Assert(scan_relid > 0);
3280 Assert(best_path->path.parent->rtekind == RTE_RELATION);
3281
3282 /*
3283 * The qpqual list must contain all restrictions not enforced by the
3284 * tidquals list. Since tidquals has OR semantics, we have to be careful
3285 * about matching it up to scan_clauses. It's convenient to handle the
3286 * single-tidqual case separately from the multiple-tidqual case. In the
3287 * single-tidqual case, we look through the scan_clauses while they are
3288 * still in RestrictInfo form, and drop any that are redundant with the
3289 * tidqual.
3290 *
3291 * In normal cases simple pointer equality checks will be enough to spot
3292 * duplicate RestrictInfos, so we try that first.
3293 *
3294 * Another common case is that a scan_clauses entry is generated from the
3295 * same EquivalenceClass as some tidqual, and is therefore redundant with
3296 * it, though not equal.
3297 *
3298 * Unlike indexpaths, we don't bother with predicate_implied_by(); the
3299 * number of cases where it could win are pretty small.
3300 */
3301 if (list_length(tidquals) == 1)
3302 {
3303 List *qpqual = NIL;
3304 ListCell *l;
3305
3306 foreach(l, scan_clauses)
3307 {
3308 RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
3309
3310 if (rinfo->pseudoconstant)
3311 continue; /* we may drop pseudoconstants here */
3312 if (list_member_ptr(tidquals, rinfo))
3313 continue; /* simple duplicate */
3314 if (is_redundant_derived_clause(rinfo, tidquals))
3315 continue; /* derived from same EquivalenceClass */
3316 qpqual = lappend(qpqual, rinfo);
3317 }
3318 scan_clauses = qpqual;
3319 }
3320
3321 /* Sort clauses into best execution order */
3322 scan_clauses = order_qual_clauses(root, scan_clauses);
3323
3324 /* Reduce RestrictInfo lists to bare expressions; ignore pseudoconstants */
3325 tidquals = extract_actual_clauses(tidquals, false);
3326 scan_clauses = extract_actual_clauses(scan_clauses, false);
3327
3328 /*
3329 * If we have multiple tidquals, it's more convenient to remove duplicate
3330 * scan_clauses after stripping the RestrictInfos. In this situation,
3331 * because the tidquals represent OR sub-clauses, they could not have come
3332 * from EquivalenceClasses so we don't have to worry about matching up
3333 * non-identical clauses. On the other hand, because tidpath.c will have
3334 * extracted those sub-clauses from some OR clause and built its own list,
3335 * we will certainly not have pointer equality to any scan clause. So
3336 * convert the tidquals list to an explicit OR clause and see if we can
3337 * match it via equal() to any scan clause.
3338 */
3339 if (list_length(tidquals) > 1)
3340 scan_clauses = list_difference(scan_clauses,
3341 list_make1(make_orclause(tidquals)));
3342
3343 /* Replace any outer-relation variables with nestloop params */
3344 if (best_path->path.param_info)
3345 {
3346 tidquals = (List *)
3347 replace_nestloop_params(root, (Node *) tidquals);
3348 scan_clauses = (List *)
3349 replace_nestloop_params(root, (Node *) scan_clauses);
3350 }
3351
3352 scan_plan = make_tidscan(tlist,
3353 scan_clauses,
3354 scan_relid,
3355 tidquals);
3356
3357 copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
3358
3359 return scan_plan;
3360}
3361
3362/*
3363 * create_subqueryscan_plan
3364 * Returns a subqueryscan plan for the base relation scanned by 'best_path'
3365 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3366 */
3367static SubqueryScan *
3368create_subqueryscan_plan(PlannerInfo *root, SubqueryScanPath *best_path,
3369 List *tlist, List *scan_clauses)
3370{
3371 SubqueryScan *scan_plan;
3372 RelOptInfo *rel = best_path->path.parent;
3373 Index scan_relid = rel->relid;
3374 Plan *subplan;
3375
3376 /* it should be a subquery base rel... */
3377 Assert(scan_relid > 0);
3378 Assert(rel->rtekind == RTE_SUBQUERY);
3379
3380 /*
3381 * Recursively create Plan from Path for subquery. Since we are entering
3382 * a different planner context (subroot), recurse to create_plan not
3383 * create_plan_recurse.
3384 */
3385 subplan = create_plan(rel->subroot, best_path->subpath);
3386
3387 /* Sort clauses into best execution order */
3388 scan_clauses = order_qual_clauses(root, scan_clauses);
3389
3390 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3391 scan_clauses = extract_actual_clauses(scan_clauses, false);
3392
3393 /* Replace any outer-relation variables with nestloop params */
3394 if (best_path->path.param_info)
3395 {
3396 scan_clauses = (List *)
3397 replace_nestloop_params(root, (Node *) scan_clauses);
3398 process_subquery_nestloop_params(root,
3399 rel->subplan_params);
3400 }
3401
3402 scan_plan = make_subqueryscan(tlist,
3403 scan_clauses,
3404 scan_relid,
3405 subplan);
3406
3407 copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
3408
3409 return scan_plan;
3410}
3411
3412/*
3413 * create_functionscan_plan
3414 * Returns a functionscan plan for the base relation scanned by 'best_path'
3415 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3416 */
3417static FunctionScan *
3418create_functionscan_plan(PlannerInfo *root, Path *best_path,
3419 List *tlist, List *scan_clauses)
3420{
3421 FunctionScan *scan_plan;
3422 Index scan_relid = best_path->parent->relid;
3423 RangeTblEntry *rte;
3424 List *functions;
3425
3426 /* it should be a function base rel... */
3427 Assert(scan_relid > 0);
3428 rte = planner_rt_fetch(scan_relid, root);
3429 Assert(rte->rtekind == RTE_FUNCTION);
3430 functions = rte->functions;
3431
3432 /* Sort clauses into best execution order */
3433 scan_clauses = order_qual_clauses(root, scan_clauses);
3434
3435 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3436 scan_clauses = extract_actual_clauses(scan_clauses, false);
3437
3438 /* Replace any outer-relation variables with nestloop params */
3439 if (best_path->param_info)
3440 {
3441 scan_clauses = (List *)
3442 replace_nestloop_params(root, (Node *) scan_clauses);
3443 /* The function expressions could contain nestloop params, too */
3444 functions = (List *) replace_nestloop_params(root, (Node *) functions);
3445 }
3446
3447 scan_plan = make_functionscan(tlist, scan_clauses, scan_relid,
3448 functions, rte->funcordinality);
3449
3450 copy_generic_path_info(&scan_plan->scan.plan, best_path);
3451
3452 return scan_plan;
3453}
3454
3455/*
3456 * create_tablefuncscan_plan
3457 * Returns a tablefuncscan plan for the base relation scanned by 'best_path'
3458 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3459 */
3460static TableFuncScan *
3461create_tablefuncscan_plan(PlannerInfo *root, Path *best_path,
3462 List *tlist, List *scan_clauses)
3463{
3464 TableFuncScan *scan_plan;
3465 Index scan_relid = best_path->parent->relid;
3466 RangeTblEntry *rte;
3467 TableFunc *tablefunc;
3468
3469 /* it should be a function base rel... */
3470 Assert(scan_relid > 0);
3471 rte = planner_rt_fetch(scan_relid, root);
3472 Assert(rte->rtekind == RTE_TABLEFUNC);
3473 tablefunc = rte->tablefunc;
3474
3475 /* Sort clauses into best execution order */
3476 scan_clauses = order_qual_clauses(root, scan_clauses);
3477
3478 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3479 scan_clauses = extract_actual_clauses(scan_clauses, false);
3480
3481 /* Replace any outer-relation variables with nestloop params */
3482 if (best_path->param_info)
3483 {
3484 scan_clauses = (List *)
3485 replace_nestloop_params(root, (Node *) scan_clauses);
3486 /* The function expressions could contain nestloop params, too */
3487 tablefunc = (TableFunc *) replace_nestloop_params(root, (Node *) tablefunc);
3488 }
3489
3490 scan_plan = make_tablefuncscan(tlist, scan_clauses, scan_relid,
3491 tablefunc);
3492
3493 copy_generic_path_info(&scan_plan->scan.plan, best_path);
3494
3495 return scan_plan;
3496}
3497
3498/*
3499 * create_valuesscan_plan
3500 * Returns a valuesscan plan for the base relation scanned by 'best_path'
3501 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3502 */
3503static ValuesScan *
3504create_valuesscan_plan(PlannerInfo *root, Path *best_path,
3505 List *tlist, List *scan_clauses)
3506{
3507 ValuesScan *scan_plan;
3508 Index scan_relid = best_path->parent->relid;
3509 RangeTblEntry *rte;
3510 List *values_lists;
3511
3512 /* it should be a values base rel... */
3513 Assert(scan_relid > 0);
3514 rte = planner_rt_fetch(scan_relid, root);
3515 Assert(rte->rtekind == RTE_VALUES);
3516 values_lists = rte->values_lists;
3517
3518 /* Sort clauses into best execution order */
3519 scan_clauses = order_qual_clauses(root, scan_clauses);
3520
3521 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3522 scan_clauses = extract_actual_clauses(scan_clauses, false);
3523
3524 /* Replace any outer-relation variables with nestloop params */
3525 if (best_path->param_info)
3526 {
3527 scan_clauses = (List *)
3528 replace_nestloop_params(root, (Node *) scan_clauses);
3529 /* The values lists could contain nestloop params, too */
3530 values_lists = (List *)
3531 replace_nestloop_params(root, (Node *) values_lists);
3532 }
3533
3534 scan_plan = make_valuesscan(tlist, scan_clauses, scan_relid,
3535 values_lists);
3536
3537 copy_generic_path_info(&scan_plan->scan.plan, best_path);
3538
3539 return scan_plan;
3540}
3541
3542/*
3543 * create_ctescan_plan
3544 * Returns a ctescan plan for the base relation scanned by 'best_path'
3545 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3546 */
3547static CteScan *
3548create_ctescan_plan(PlannerInfo *root, Path *best_path,
3549 List *tlist, List *scan_clauses)
3550{
3551 CteScan *scan_plan;
3552 Index scan_relid = best_path->parent->relid;
3553 RangeTblEntry *rte;
3554 SubPlan *ctesplan = NULL;
3555 int plan_id;
3556 int cte_param_id;
3557 PlannerInfo *cteroot;
3558 Index levelsup;
3559 int ndx;
3560 ListCell *lc;
3561
3562 Assert(scan_relid > 0);
3563 rte = planner_rt_fetch(scan_relid, root);
3564 Assert(rte->rtekind == RTE_CTE);
3565 Assert(!rte->self_reference);
3566
3567 /*
3568 * Find the referenced CTE, and locate the SubPlan previously made for it.
3569 */
3570 levelsup = rte->ctelevelsup;
3571 cteroot = root;
3572 while (levelsup-- > 0)
3573 {
3574 cteroot = cteroot->parent_root;
3575 if (!cteroot) /* shouldn't happen */
3576 elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
3577 }
3578
3579 /*
3580 * Note: cte_plan_ids can be shorter than cteList, if we are still working
3581 * on planning the CTEs (ie, this is a side-reference from another CTE).
3582 * So we mustn't use forboth here.
3583 */
3584 ndx = 0;
3585 foreach(lc, cteroot->parse->cteList)
3586 {
3587 CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
3588
3589 if (strcmp(cte->ctename, rte->ctename) == 0)
3590 break;
3591 ndx++;
3592 }
3593 if (lc == NULL) /* shouldn't happen */
3594 elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
3595 if (ndx >= list_length(cteroot->cte_plan_ids))
3596 elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
3597 plan_id = list_nth_int(cteroot->cte_plan_ids, ndx);
3598 Assert(plan_id > 0);
3599 foreach(lc, cteroot->init_plans)
3600 {
3601 ctesplan = (SubPlan *) lfirst(lc);
3602 if (ctesplan->plan_id == plan_id)
3603 break;
3604 }
3605 if (lc == NULL) /* shouldn't happen */
3606 elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
3607
3608 /*
3609 * We need the CTE param ID, which is the sole member of the SubPlan's
3610 * setParam list.
3611 */
3612 cte_param_id = linitial_int(ctesplan->setParam);
3613
3614 /* Sort clauses into best execution order */
3615 scan_clauses = order_qual_clauses(root, scan_clauses);
3616
3617 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3618 scan_clauses = extract_actual_clauses(scan_clauses, false);
3619
3620 /* Replace any outer-relation variables with nestloop params */
3621 if (best_path->param_info)
3622 {
3623 scan_clauses = (List *)
3624 replace_nestloop_params(root, (Node *) scan_clauses);
3625 }
3626
3627 scan_plan = make_ctescan(tlist, scan_clauses, scan_relid,
3628 plan_id, cte_param_id);
3629
3630 copy_generic_path_info(&scan_plan->scan.plan, best_path);
3631
3632 return scan_plan;
3633}
3634
3635/*
3636 * create_namedtuplestorescan_plan
3637 * Returns a tuplestorescan plan for the base relation scanned by
3638 * 'best_path' with restriction clauses 'scan_clauses' and targetlist
3639 * 'tlist'.
3640 */
3641static NamedTuplestoreScan *
3642create_namedtuplestorescan_plan(PlannerInfo *root, Path *best_path,
3643 List *tlist, List *scan_clauses)
3644{
3645 NamedTuplestoreScan *scan_plan;
3646 Index scan_relid = best_path->parent->relid;
3647 RangeTblEntry *rte;
3648
3649 Assert(scan_relid > 0);
3650 rte = planner_rt_fetch(scan_relid, root);
3651 Assert(rte->rtekind == RTE_NAMEDTUPLESTORE);
3652
3653 /* Sort clauses into best execution order */
3654 scan_clauses = order_qual_clauses(root, scan_clauses);
3655
3656 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3657 scan_clauses = extract_actual_clauses(scan_clauses, false);
3658
3659 /* Replace any outer-relation variables with nestloop params */
3660 if (best_path->param_info)
3661 {
3662 scan_clauses = (List *)
3663 replace_nestloop_params(root, (Node *) scan_clauses);
3664 }
3665
3666 scan_plan = make_namedtuplestorescan(tlist, scan_clauses, scan_relid,
3667 rte->enrname);
3668
3669 copy_generic_path_info(&scan_plan->scan.plan, best_path);
3670
3671 return scan_plan;
3672}
3673
3674/*
3675 * create_resultscan_plan
3676 * Returns a Result plan for the RTE_RESULT base relation scanned by
3677 * 'best_path' with restriction clauses 'scan_clauses' and targetlist
3678 * 'tlist'.
3679 */
3680static Result *
3681create_resultscan_plan(PlannerInfo *root, Path *best_path,
3682 List *tlist, List *scan_clauses)
3683{
3684 Result *scan_plan;
3685 Index scan_relid = best_path->parent->relid;
3686 RangeTblEntry *rte PG_USED_FOR_ASSERTS_ONLY;
3687
3688 Assert(scan_relid > 0);
3689 rte = planner_rt_fetch(scan_relid, root);
3690 Assert(rte->rtekind == RTE_RESULT);
3691
3692 /* Sort clauses into best execution order */
3693 scan_clauses = order_qual_clauses(root, scan_clauses);
3694
3695 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3696 scan_clauses = extract_actual_clauses(scan_clauses, false);
3697
3698 /* Replace any outer-relation variables with nestloop params */
3699 if (best_path->param_info)
3700 {
3701 scan_clauses = (List *)
3702 replace_nestloop_params(root, (Node *) scan_clauses);
3703 }
3704
3705 scan_plan = make_result(tlist, (Node *) scan_clauses, NULL);
3706
3707 copy_generic_path_info(&scan_plan->plan, best_path);
3708
3709 return scan_plan;
3710}
3711
3712/*
3713 * create_worktablescan_plan
3714 * Returns a worktablescan plan for the base relation scanned by 'best_path'
3715 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3716 */
3717static WorkTableScan *
3718create_worktablescan_plan(PlannerInfo *root, Path *best_path,
3719 List *tlist, List *scan_clauses)
3720{
3721 WorkTableScan *scan_plan;
3722 Index scan_relid = best_path->parent->relid;
3723 RangeTblEntry *rte;
3724 Index levelsup;
3725 PlannerInfo *cteroot;
3726
3727 Assert(scan_relid > 0);
3728 rte = planner_rt_fetch(scan_relid, root);
3729 Assert(rte->rtekind == RTE_CTE);
3730 Assert(rte->self_reference);
3731
3732 /*
3733 * We need to find the worktable param ID, which is in the plan level
3734 * that's processing the recursive UNION, which is one level *below* where
3735 * the CTE comes from.
3736 */
3737 levelsup = rte->ctelevelsup;
3738 if (levelsup == 0) /* shouldn't happen */
3739 elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
3740 levelsup--;
3741 cteroot = root;
3742 while (levelsup-- > 0)
3743 {
3744 cteroot = cteroot->parent_root;
3745 if (!cteroot) /* shouldn't happen */
3746 elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
3747 }
3748 if (cteroot->wt_param_id < 0) /* shouldn't happen */
3749 elog(ERROR, "could not find param ID for CTE \"%s\"", rte->ctename);
3750
3751 /* Sort clauses into best execution order */
3752 scan_clauses = order_qual_clauses(root, scan_clauses);
3753
3754 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3755 scan_clauses = extract_actual_clauses(scan_clauses, false);
3756
3757 /* Replace any outer-relation variables with nestloop params */
3758 if (best_path->param_info)
3759 {
3760 scan_clauses = (List *)
3761 replace_nestloop_params(root, (Node *) scan_clauses);
3762 }
3763
3764 scan_plan = make_worktablescan(tlist, scan_clauses, scan_relid,
3765 cteroot->wt_param_id);
3766
3767 copy_generic_path_info(&scan_plan->scan.plan, best_path);
3768
3769 return scan_plan;
3770}
3771
3772/*
3773 * create_foreignscan_plan
3774 * Returns a foreignscan plan for the relation scanned by 'best_path'
3775 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3776 */
3777static ForeignScan *
3778create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
3779 List *tlist, List *scan_clauses)
3780{
3781 ForeignScan *scan_plan;
3782 RelOptInfo *rel = best_path->path.parent;
3783 Index scan_relid = rel->relid;
3784 Oid rel_oid = InvalidOid;
3785 Plan *outer_plan = NULL;
3786
3787 Assert(rel->fdwroutine != NULL);
3788
3789 /* transform the child path if any */
3790 if (best_path->fdw_outerpath)
3791 outer_plan = create_plan_recurse(root, best_path->fdw_outerpath,
3792 CP_EXACT_TLIST);
3793
3794 /*
3795 * If we're scanning a base relation, fetch its OID. (Irrelevant if
3796 * scanning a join relation.)
3797 */
3798 if (scan_relid > 0)
3799 {
3800 RangeTblEntry *rte;
3801
3802 Assert(rel->rtekind == RTE_RELATION);
3803 rte = planner_rt_fetch(scan_relid, root);
3804 Assert(rte->rtekind == RTE_RELATION);
3805 rel_oid = rte->relid;
3806 }
3807
3808 /*
3809 * Sort clauses into best execution order. We do this first since the FDW
3810 * might have more info than we do and wish to adjust the ordering.
3811 */
3812 scan_clauses = order_qual_clauses(root, scan_clauses);
3813
3814 /*
3815 * Let the FDW perform its processing on the restriction clauses and
3816 * generate the plan node. Note that the FDW might remove restriction
3817 * clauses that it intends to execute remotely, or even add more (if it
3818 * has selected some join clauses for remote use but also wants them
3819 * rechecked locally).
3820 */
3821 scan_plan = rel->fdwroutine->GetForeignPlan(root, rel, rel_oid,
3822 best_path,
3823 tlist, scan_clauses,
3824 outer_plan);
3825
3826 /* Copy cost data from Path to Plan; no need to make FDW do this */
3827 copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
3828
3829 /* Copy foreign server OID; likewise, no need to make FDW do this */
3830 scan_plan->fs_server = rel->serverid;
3831
3832 /*
3833 * Likewise, copy the relids that are represented by this foreign scan. An
3834 * upper rel doesn't have relids set, but it covers all the base relations
3835 * participating in the underlying scan, so use root's all_baserels.
3836 */
3837 if (rel->reloptkind == RELOPT_UPPER_REL)
3838 scan_plan->fs_relids = root->all_baserels;
3839 else
3840 scan_plan->fs_relids = best_path->path.parent->relids;
3841
3842 /*
3843 * If this is a foreign join, and to make it valid to push down we had to
3844 * assume that the current user is the same as some user explicitly named
3845 * in the query, mark the finished plan as depending on the current user.
3846 */
3847 if (rel->useridiscurrent)
3848 root->glob->dependsOnRole = true;
3849
3850 /*
3851 * Replace any outer-relation variables with nestloop params in the qual,
3852 * fdw_exprs and fdw_recheck_quals expressions. We do this last so that
3853 * the FDW doesn't have to be involved. (Note that parts of fdw_exprs or
3854 * fdw_recheck_quals could have come from join clauses, so doing this
3855 * beforehand on the scan_clauses wouldn't work.) We assume
3856 * fdw_scan_tlist contains no such variables.
3857 */
3858 if (best_path->path.param_info)
3859 {
3860 scan_plan->scan.plan.qual = (List *)
3861 replace_nestloop_params(root, (Node *) scan_plan->scan.plan.qual);
3862 scan_plan->fdw_exprs = (List *)
3863 replace_nestloop_params(root, (Node *) scan_plan->fdw_exprs);
3864 scan_plan->fdw_recheck_quals = (List *)
3865 replace_nestloop_params(root,
3866 (Node *) scan_plan->fdw_recheck_quals);
3867 }
3868
3869 /*
3870 * If rel is a base relation, detect whether any system columns are
3871 * requested from the rel. (If rel is a join relation, rel->relid will be
3872 * 0, but there can be no Var with relid 0 in the rel's targetlist or the
3873 * restriction clauses, so we skip this in that case. Note that any such
3874 * columns in base relations that were joined are assumed to be contained
3875 * in fdw_scan_tlist.) This is a bit of a kluge and might go away
3876 * someday, so we intentionally leave it out of the API presented to FDWs.
3877 */
3878 scan_plan->fsSystemCol = false;
3879 if (scan_relid > 0)
3880 {
3881 Bitmapset *attrs_used = NULL;
3882 ListCell *lc;
3883 int i;
3884
3885 /*
3886 * First, examine all the attributes needed for joins or final output.
3887 * Note: we must look at rel's targetlist, not the attr_needed data,
3888 * because attr_needed isn't computed for inheritance child rels.
3889 */
3890 pull_varattnos((Node *) rel->reltarget->exprs, scan_relid, &attrs_used);
3891
3892 /* Add all the attributes used by restriction clauses. */
3893 foreach(lc, rel->baserestrictinfo)
3894 {
3895 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
3896
3897 pull_varattnos((Node *) rinfo->clause, scan_relid, &attrs_used);
3898 }
3899
3900 /* Now, are any system columns requested from rel? */
3901 for (i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++)
3902 {
3903 if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber, attrs_used))
3904 {
3905 scan_plan->fsSystemCol = true;
3906 break;
3907 }
3908 }
3909
3910 bms_free(attrs_used);
3911 }
3912
3913 return scan_plan;
3914}
3915
3916/*
3917 * create_customscan_plan
3918 *
3919 * Transform a CustomPath into a Plan.
3920 */
3921static CustomScan *
3922create_customscan_plan(PlannerInfo *root, CustomPath *best_path,
3923 List *tlist, List *scan_clauses)
3924{
3925 CustomScan *cplan;
3926 RelOptInfo *rel = best_path->path.parent;
3927 List *custom_plans = NIL;
3928 ListCell *lc;
3929
3930 /* Recursively transform child paths. */
3931 foreach(lc, best_path->custom_paths)
3932 {
3933 Plan *plan = create_plan_recurse(root, (Path *) lfirst(lc),
3934 CP_EXACT_TLIST);
3935
3936 custom_plans = lappend(custom_plans, plan);
3937 }
3938
3939 /*
3940 * Sort clauses into the best execution order, although custom-scan
3941 * provider can reorder them again.
3942 */
3943 scan_clauses = order_qual_clauses(root, scan_clauses);
3944
3945 /*
3946 * Invoke custom plan provider to create the Plan node represented by the
3947 * CustomPath.
3948 */
3949 cplan = castNode(CustomScan,
3950 best_path->methods->PlanCustomPath(root,
3951 rel,
3952 best_path,
3953 tlist,
3954 scan_clauses,
3955 custom_plans));
3956
3957 /*
3958 * Copy cost data from Path to Plan; no need to make custom-plan providers
3959 * do this
3960 */
3961 copy_generic_path_info(&cplan->scan.plan, &best_path->path);
3962
3963 /* Likewise, copy the relids that are represented by this custom scan */
3964 cplan->custom_relids = best_path->path.parent->relids;
3965
3966 /*
3967 * Replace any outer-relation variables with nestloop params in the qual
3968 * and custom_exprs expressions. We do this last so that the custom-plan
3969 * provider doesn't have to be involved. (Note that parts of custom_exprs
3970 * could have come from join clauses, so doing this beforehand on the
3971 * scan_clauses wouldn't work.) We assume custom_scan_tlist contains no
3972 * such variables.
3973 */
3974 if (best_path->path.param_info)
3975 {
3976 cplan->scan.plan.qual = (List *)
3977 replace_nestloop_params(root, (Node *) cplan->scan.plan.qual);
3978 cplan->custom_exprs = (List *)
3979 replace_nestloop_params(root, (Node *) cplan->custom_exprs);
3980 }
3981
3982 return cplan;
3983}
3984
3985
3986/*****************************************************************************
3987 *
3988 * JOIN METHODS
3989 *
3990 *****************************************************************************/
3991
3992static NestLoop *
3993create_nestloop_plan(PlannerInfo *root,
3994 NestPath *best_path)
3995{
3996 NestLoop *join_plan;
3997 Plan *outer_plan;
3998 Plan *inner_plan;
3999 List *tlist = build_path_tlist(root, &best_path->path);
4000 List *joinrestrictclauses = best_path->joinrestrictinfo;
4001 List *joinclauses;
4002 List *otherclauses;
4003 Relids outerrelids;
4004 List *nestParams;
4005 Relids saveOuterRels = root->curOuterRels;
4006
4007 /* NestLoop can project, so no need to be picky about child tlists */
4008 outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0);
4009
4010 /* For a nestloop, include outer relids in curOuterRels for inner side */
4011 root->curOuterRels = bms_union(root->curOuterRels,
4012 best_path->outerjoinpath->parent->relids);
4013
4014 inner_plan = create_plan_recurse(root, best_path->innerjoinpath, 0);
4015
4016 /* Restore curOuterRels */
4017 bms_free(root->curOuterRels);
4018 root->curOuterRels = saveOuterRels;
4019
4020 /* Sort join qual clauses into best execution order */
4021 joinrestrictclauses = order_qual_clauses(root, joinrestrictclauses);
4022
4023 /* Get the join qual clauses (in plain expression form) */
4024 /* Any pseudoconstant clauses are ignored here */
4025 if (IS_OUTER_JOIN(best_path->jointype))
4026 {
4027 extract_actual_join_clauses(joinrestrictclauses,
4028 best_path->path.parent->relids,
4029 &joinclauses, &otherclauses);
4030 }
4031 else
4032 {
4033 /* We can treat all clauses alike for an inner join */
4034 joinclauses = extract_actual_clauses(joinrestrictclauses, false);
4035 otherclauses = NIL;
4036 }
4037
4038 /* Replace any outer-relation variables with nestloop params */
4039 if (best_path->path.param_info)
4040 {
4041 joinclauses = (List *)
4042 replace_nestloop_params(root, (Node *) joinclauses);
4043 otherclauses = (List *)
4044 replace_nestloop_params(root, (Node *) otherclauses);
4045 }
4046
4047 /*
4048 * Identify any nestloop parameters that should be supplied by this join
4049 * node, and remove them from root->curOuterParams.
4050 */
4051 outerrelids = best_path->outerjoinpath->parent->relids;
4052 nestParams = identify_current_nestloop_params(root, outerrelids);
4053
4054 join_plan = make_nestloop(tlist,
4055 joinclauses,
4056 otherclauses,
4057 nestParams,
4058 outer_plan,
4059 inner_plan,
4060 best_path->jointype,
4061 best_path->inner_unique);
4062
4063 copy_generic_path_info(&join_plan->join.plan, &best_path->path);
4064
4065 return join_plan;
4066}
4067
4068static MergeJoin *
4069create_mergejoin_plan(PlannerInfo *root,
4070 MergePath *best_path)
4071{
4072 MergeJoin *join_plan;
4073 Plan *outer_plan;
4074 Plan *inner_plan;
4075 List *tlist = build_path_tlist(root, &best_path->jpath.path);
4076 List *joinclauses;
4077 List *otherclauses;
4078 List *mergeclauses;
4079 List *outerpathkeys;
4080 List *innerpathkeys;
4081 int nClauses;
4082 Oid *mergefamilies;
4083 Oid *mergecollations;
4084 int *mergestrategies;
4085 bool *mergenullsfirst;
4086 PathKey *opathkey;
4087 EquivalenceClass *opeclass;
4088 int i;
4089 ListCell *lc;
4090 ListCell *lop;
4091 ListCell *lip;
4092 Path *outer_path = best_path->jpath.outerjoinpath;
4093 Path *inner_path = best_path->jpath.innerjoinpath;
4094
4095 /*
4096 * MergeJoin can project, so we don't have to demand exact tlists from the
4097 * inputs. However, if we're intending to sort an input's result, it's
4098 * best to request a small tlist so we aren't sorting more data than
4099 * necessary.
4100 */
4101 outer_plan = create_plan_recurse(root, best_path->jpath.outerjoinpath,
4102 (best_path->outersortkeys != NIL) ? CP_SMALL_TLIST : 0);
4103
4104 inner_plan = create_plan_recurse(root, best_path->jpath.innerjoinpath,
4105 (best_path->innersortkeys != NIL) ? CP_SMALL_TLIST : 0);
4106
4107 /* Sort join qual clauses into best execution order */
4108 /* NB: do NOT reorder the mergeclauses */
4109 joinclauses = order_qual_clauses(root, best_path->jpath.joinrestrictinfo);
4110
4111 /* Get the join qual clauses (in plain expression form) */
4112 /* Any pseudoconstant clauses are ignored here */
4113 if (IS_OUTER_JOIN(best_path->jpath.jointype))
4114 {
4115 extract_actual_join_clauses(joinclauses,
4116 best_path->jpath.path.parent->relids,
4117 &joinclauses, &otherclauses);
4118 }
4119 else
4120 {
4121 /* We can treat all clauses alike for an inner join */
4122 joinclauses = extract_actual_clauses(joinclauses, false);
4123 otherclauses = NIL;
4124 }
4125
4126 /*
4127 * Remove the mergeclauses from the list of join qual clauses, leaving the
4128 * list of quals that must be checked as qpquals.
4129 */
4130 mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
4131 joinclauses = list_difference(joinclauses, mergeclauses);
4132
4133 /*
4134 * Replace any outer-relation variables with nestloop params. There
4135 * should not be any in the mergeclauses.
4136 */
4137 if (best_path->jpath.path.param_info)
4138 {
4139 joinclauses = (List *)
4140 replace_nestloop_params(root, (Node *) joinclauses);
4141 otherclauses = (List *)
4142 replace_nestloop_params(root, (Node *) otherclauses);
4143 }
4144
4145 /*
4146 * Rearrange mergeclauses, if needed, so that the outer variable is always
4147 * on the left; mark the mergeclause restrictinfos with correct
4148 * outer_is_left status.
4149 */
4150 mergeclauses = get_switched_clauses(best_path->path_mergeclauses,
4151 best_path->jpath.outerjoinpath->parent->relids);
4152
4153 /*
4154 * Create explicit sort nodes for the outer and inner paths if necessary.
4155 */
4156 if (best_path->outersortkeys)
4157 {
4158 Relids outer_relids = outer_path->parent->relids;
4159 Sort *sort = make_sort_from_pathkeys(outer_plan,
4160 best_path->outersortkeys,
4161 outer_relids);
4162
4163 label_sort_with_costsize(root, sort, -1.0);
4164 outer_plan = (Plan *) sort;
4165 outerpathkeys = best_path->outersortkeys;
4166 }
4167 else
4168 outerpathkeys = best_path->jpath.outerjoinpath->pathkeys;
4169
4170 if (best_path->innersortkeys)
4171 {
4172 Relids inner_relids = inner_path->parent->relids;
4173 Sort *sort = make_sort_from_pathkeys(inner_plan,
4174 best_path->innersortkeys,
4175 inner_relids);
4176
4177 label_sort_with_costsize(root, sort, -1.0);
4178 inner_plan = (Plan *) sort;
4179 innerpathkeys = best_path->innersortkeys;
4180 }
4181 else
4182 innerpathkeys = best_path->jpath.innerjoinpath->pathkeys;
4183
4184 /*
4185 * If specified, add a materialize node to shield the inner plan from the
4186 * need to handle mark/restore.
4187 */
4188 if (best_path->materialize_inner)
4189 {
4190 Plan *matplan = (Plan *) make_material(inner_plan);
4191
4192 /*
4193 * We assume the materialize will not spill to disk, and therefore
4194 * charge just cpu_operator_cost per tuple. (Keep this estimate in
4195 * sync with final_cost_mergejoin.)
4196 */
4197 copy_plan_costsize(matplan, inner_plan);
4198 matplan->total_cost += cpu_operator_cost * matplan->plan_rows;
4199
4200 inner_plan = matplan;
4201 }
4202
4203 /*
4204 * Compute the opfamily/collation/strategy/nullsfirst arrays needed by the
4205 * executor. The information is in the pathkeys for the two inputs, but
4206 * we need to be careful about the possibility of mergeclauses sharing a
4207 * pathkey, as well as the possibility that the inner pathkeys are not in
4208 * an order matching the mergeclauses.
4209 */
4210 nClauses = list_length(mergeclauses);
4211 Assert(nClauses == list_length(best_path->path_mergeclauses));
4212 mergefamilies = (Oid *) palloc(nClauses * sizeof(Oid));
4213 mergecollations = (Oid *) palloc(nClauses * sizeof(Oid));
4214 mergestrategies = (int *) palloc(nClauses * sizeof(int));
4215 mergenullsfirst = (bool *) palloc(nClauses * sizeof(bool));
4216
4217 opathkey = NULL;
4218 opeclass = NULL;
4219 lop = list_head(outerpathkeys);
4220 lip = list_head(innerpathkeys);
4221 i = 0;
4222 foreach(lc, best_path->path_mergeclauses)
4223 {
4224 RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
4225 EquivalenceClass *oeclass;
4226 EquivalenceClass *ieclass;
4227 PathKey *ipathkey = NULL;
4228 EquivalenceClass *ipeclass = NULL;
4229 bool first_inner_match = false;
4230
4231 /* fetch outer/inner eclass from mergeclause */
4232 if (rinfo->outer_is_left)
4233 {
4234 oeclass = rinfo->left_ec;
4235 ieclass = rinfo->right_ec;
4236 }
4237 else
4238 {
4239 oeclass = rinfo->right_ec;
4240 ieclass = rinfo->left_ec;
4241 }
4242 Assert(oeclass != NULL);
4243 Assert(ieclass != NULL);
4244
4245 /*
4246 * We must identify the pathkey elements associated with this clause
4247 * by matching the eclasses (which should give a unique match, since
4248 * the pathkey lists should be canonical). In typical cases the merge
4249 * clauses are one-to-one with the pathkeys, but when dealing with
4250 * partially redundant query conditions, things are more complicated.
4251 *
4252 * lop and lip reference the first as-yet-unmatched pathkey elements.
4253 * If they're NULL then all pathkey elements have been matched.
4254 *
4255 * The ordering of the outer pathkeys should match the mergeclauses,
4256 * by construction (see find_mergeclauses_for_outer_pathkeys()). There
4257 * could be more than one mergeclause for the same outer pathkey, but
4258 * no pathkey may be entirely skipped over.
4259 */
4260 if (oeclass != opeclass) /* multiple matches are not interesting */
4261 {
4262 /* doesn't match the current opathkey, so must match the next */
4263 if (lop == NULL)
4264 elog(ERROR, "outer pathkeys do not match mergeclauses");
4265 opathkey = (PathKey *) lfirst(lop);
4266 opeclass = opathkey->pk_eclass;
4267 lop = lnext(lop);
4268 if (oeclass != opeclass)
4269 elog(ERROR, "outer pathkeys do not match mergeclauses");
4270 }
4271
4272 /*
4273 * The inner pathkeys likewise should not have skipped-over keys, but
4274 * it's possible for a mergeclause to reference some earlier inner
4275 * pathkey if we had redundant pathkeys. For example we might have
4276 * mergeclauses like "o.a = i.x AND o.b = i.y AND o.c = i.x". The
4277 * implied inner ordering is then "ORDER BY x, y, x", but the pathkey
4278 * mechanism drops the second sort by x as redundant, and this code
4279 * must cope.
4280 *
4281 * It's also possible for the implied inner-rel ordering to be like
4282 * "ORDER BY x, y, x DESC". We still drop the second instance of x as
4283 * redundant; but this means that the sort ordering of a redundant
4284 * inner pathkey should not be considered significant. So we must
4285 * detect whether this is the first clause matching an inner pathkey.
4286 */
4287 if (lip)
4288 {
4289 ipathkey = (PathKey *) lfirst(lip);
4290 ipeclass = ipathkey->pk_eclass;
4291 if (ieclass == ipeclass)
4292 {
4293 /* successful first match to this inner pathkey */
4294 lip = lnext(lip);
4295 first_inner_match = true;
4296 }
4297 }
4298 if (!first_inner_match)
4299 {
4300 /* redundant clause ... must match something before lip */
4301 ListCell *l2;
4302
4303 foreach(l2, innerpathkeys)
4304 {
4305 if (l2 == lip)
4306 break;
4307 ipathkey = (PathKey *) lfirst(l2);
4308 ipeclass = ipathkey->pk_eclass;
4309 if (ieclass == ipeclass)
4310 break;
4311 }
4312 if (ieclass != ipeclass)
4313 elog(ERROR, "inner pathkeys do not match mergeclauses");
4314 }
4315
4316 /*
4317 * The pathkeys should always match each other as to opfamily and
4318 * collation (which affect equality), but if we're considering a
4319 * redundant inner pathkey, its sort ordering might not match. In
4320 * such cases we may ignore the inner pathkey's sort ordering and use
4321 * the outer's. (In effect, we're lying to the executor about the
4322 * sort direction of this inner column, but it does not matter since
4323 * the run-time row comparisons would only reach this column when
4324 * there's equality for the earlier column containing the same eclass.
4325 * There could be only one value in this column for the range of inner
4326 * rows having a given value in the earlier column, so it does not
4327 * matter which way we imagine this column to be ordered.) But a
4328 * non-redundant inner pathkey had better match outer's ordering too.
4329 */
4330 if (opathkey->pk_opfamily != ipathkey->pk_opfamily ||
4331 opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation)
4332 elog(ERROR, "left and right pathkeys do not match in mergejoin");
4333 if (first_inner_match &&
4334 (opathkey->pk_strategy != ipathkey->pk_strategy ||
4335 opathkey->pk_nulls_first != ipathkey->pk_nulls_first))
4336 elog(ERROR, "left and right pathkeys do not match in mergejoin");
4337
4338 /* OK, save info for executor */
4339 mergefamilies[i] = opathkey->pk_opfamily;
4340 mergecollations[i] = opathkey->pk_eclass->ec_collation;
4341 mergestrategies[i] = opathkey->pk_strategy;
4342 mergenullsfirst[i] = opathkey->pk_nulls_first;
4343 i++;
4344 }
4345
4346 /*
4347 * Note: it is not an error if we have additional pathkey elements (i.e.,
4348 * lop or lip isn't NULL here). The input paths might be better-sorted
4349 * than we need for the current mergejoin.
4350 */
4351
4352 /*
4353 * Now we can build the mergejoin node.
4354 */
4355 join_plan = make_mergejoin(tlist,
4356 joinclauses,
4357 otherclauses,
4358 mergeclauses,
4359 mergefamilies,
4360 mergecollations,
4361 mergestrategies,
4362 mergenullsfirst,
4363 outer_plan,
4364 inner_plan,
4365 best_path->jpath.jointype,
4366 best_path->jpath.inner_unique,
4367 best_path->skip_mark_restore);
4368
4369 /* Costs of sort and material steps are included in path cost already */
4370 copy_generic_path_info(&join_plan->join.plan, &best_path->jpath.path);
4371
4372 return join_plan;
4373}
4374
4375static HashJoin *
4376create_hashjoin_plan(PlannerInfo *root,
4377 HashPath *best_path)
4378{
4379 HashJoin *join_plan;
4380 Hash *hash_plan;
4381 Plan *outer_plan;
4382 Plan *inner_plan;
4383 List *tlist = build_path_tlist(root, &best_path->jpath.path);
4384 List *joinclauses;
4385 List *otherclauses;
4386 List *hashclauses;
4387 List *hashoperators = NIL;
4388 List *hashcollations = NIL;
4389 List *inner_hashkeys = NIL;
4390 List *outer_hashkeys = NIL;
4391 Oid skewTable = InvalidOid;
4392 AttrNumber skewColumn = InvalidAttrNumber;
4393 bool skewInherit = false;
4394 ListCell *lc;
4395
4396 /*
4397 * HashJoin can project, so we don't have to demand exact tlists from the
4398 * inputs. However, it's best to request a small tlist from the inner
4399 * side, so that we aren't storing more data than necessary. Likewise, if
4400 * we anticipate batching, request a small tlist from the outer side so
4401 * that we don't put extra data in the outer batch files.
4402 */
4403 outer_plan = create_plan_recurse(root, best_path->jpath.outerjoinpath,
4404 (best_path->num_batches > 1) ? CP_SMALL_TLIST : 0);
4405
4406 inner_plan = create_plan_recurse(root, best_path->jpath.innerjoinpath,
4407 CP_SMALL_TLIST);
4408
4409 /* Sort join qual clauses into best execution order */
4410 joinclauses = order_qual_clauses(root, best_path->jpath.joinrestrictinfo);
4411 /* There's no point in sorting the hash clauses ... */
4412
4413 /* Get the join qual clauses (in plain expression form) */
4414 /* Any pseudoconstant clauses are ignored here */
4415 if (IS_OUTER_JOIN(best_path->jpath.jointype))
4416 {
4417 extract_actual_join_clauses(joinclauses,
4418 best_path->jpath.path.parent->relids,
4419 &joinclauses, &otherclauses);
4420 }
4421 else
4422 {
4423 /* We can treat all clauses alike for an inner join */
4424 joinclauses = extract_actual_clauses(joinclauses, false);
4425 otherclauses = NIL;
4426 }
4427
4428 /*
4429 * Remove the hashclauses from the list of join qual clauses, leaving the
4430 * list of quals that must be checked as qpquals.
4431 */
4432 hashclauses = get_actual_clauses(best_path->path_hashclauses);
4433 joinclauses = list_difference(joinclauses, hashclauses);
4434
4435 /*
4436 * Replace any outer-relation variables with nestloop params. There
4437 * should not be any in the hashclauses.
4438 */
4439 if (best_path->jpath.path.param_info)
4440 {
4441 joinclauses = (List *)
4442 replace_nestloop_params(root, (Node *) joinclauses);
4443 otherclauses = (List *)
4444 replace_nestloop_params(root, (Node *) otherclauses);
4445 }
4446
4447 /*
4448 * Rearrange hashclauses, if needed, so that the outer variable is always
4449 * on the left.
4450 */
4451 hashclauses = get_switched_clauses(best_path->path_hashclauses,
4452 best_path->jpath.outerjoinpath->parent->relids);
4453
4454 /*
4455 * If there is a single join clause and we can identify the outer variable
4456 * as a simple column reference, supply its identity for possible use in
4457 * skew optimization. (Note: in principle we could do skew optimization
4458 * with multiple join clauses, but we'd have to be able to determine the
4459 * most common combinations of outer values, which we don't currently have
4460 * enough stats for.)
4461 */
4462 if (list_length(hashclauses) == 1)
4463 {
4464 OpExpr *clause = (OpExpr *) linitial(hashclauses);
4465 Node *node;
4466
4467 Assert(is_opclause(clause));
4468 node = (Node *) linitial(clause->args);
4469 if (IsA(node, RelabelType))
4470 node = (Node *) ((RelabelType *) node)->arg;
4471 if (IsA(node, Var))
4472 {
4473 Var *var = (Var *) node;
4474 RangeTblEntry *rte;
4475
4476 rte = root->simple_rte_array[var->varno];
4477 if (rte->rtekind == RTE_RELATION)
4478 {
4479 skewTable = rte->relid;
4480 skewColumn = var->varattno;
4481 skewInherit = rte->inh;
4482 }
4483 }
4484 }
4485
4486 /*
4487 * Collect hash related information. The hashed expressions are
4488 * deconstructed into outer/inner expressions, so they can be computed
4489 * separately (inner expressions are used to build the hashtable via Hash,
4490 * outer expressions to perform lookups of tuples from HashJoin's outer
4491 * plan in the hashtable). Also collect operator information necessary to
4492 * build the hashtable.
4493 */
4494 foreach(lc, hashclauses)
4495 {
4496 OpExpr *hclause = lfirst_node(OpExpr, lc);
4497
4498 hashoperators = lappend_oid(hashoperators, hclause->opno);
4499 hashcollations = lappend_oid(hashcollations, hclause->inputcollid);
4500 outer_hashkeys = lappend(outer_hashkeys, linitial(hclause->args));
4501 inner_hashkeys = lappend(inner_hashkeys, lsecond(hclause->args));
4502 }
4503
4504 /*
4505 * Build the hash node and hash join node.
4506 */
4507 hash_plan = make_hash(inner_plan,
4508 inner_hashkeys,
4509 skewTable,
4510 skewColumn,
4511 skewInherit);
4512
4513 /*
4514 * Set Hash node's startup & total costs equal to total cost of input
4515 * plan; this only affects EXPLAIN display not decisions.
4516 */
4517 copy_plan_costsize(&hash_plan->plan, inner_plan);
4518 hash_plan->plan.startup_cost = hash_plan->plan.total_cost;
4519
4520 /*
4521 * If parallel-aware, the executor will also need an estimate of the total
4522 * number of rows expected from all participants so that it can size the
4523 * shared hash table.
4524 */
4525 if (best_path->jpath.path.parallel_aware)
4526 {
4527 hash_plan->plan.parallel_aware = true;
4528 hash_plan->rows_total = best_path->inner_rows_total;
4529 }
4530
4531 join_plan = make_hashjoin(tlist,
4532 joinclauses,
4533 otherclauses,
4534 hashclauses,
4535 hashoperators,
4536 hashcollations,
4537 outer_hashkeys,
4538 outer_plan,
4539 (Plan *) hash_plan,
4540 best_path->jpath.jointype,
4541 best_path->jpath.inner_unique);
4542
4543 copy_generic_path_info(&join_plan->join.plan, &best_path->jpath.path);
4544
4545 return join_plan;
4546}
4547
4548
4549/*****************************************************************************
4550 *
4551 * SUPPORTING ROUTINES
4552 *
4553 *****************************************************************************/
4554
4555/*
4556 * replace_nestloop_params
4557 * Replace outer-relation Vars and PlaceHolderVars in the given expression
4558 * with nestloop Params
4559 *
4560 * All Vars and PlaceHolderVars belonging to the relation(s) identified by
4561 * root->curOuterRels are replaced by Params, and entries are added to
4562 * root->curOuterParams if not already present.
4563 */
4564static Node *
4565replace_nestloop_params(PlannerInfo *root, Node *expr)
4566{
4567 /* No setup needed for tree walk, so away we go */
4568 return replace_nestloop_params_mutator(expr, root);
4569}
4570
4571static Node *
4572replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
4573{
4574 if (node == NULL)
4575 return NULL;
4576 if (IsA(node, Var))
4577 {
4578 Var *var = (Var *) node;
4579
4580 /* Upper-level Vars should be long gone at this point */
4581 Assert(var->varlevelsup == 0);
4582 /* If not to be replaced, we can just return the Var unmodified */
4583 if (!bms_is_member(var->varno, root->curOuterRels))
4584 return node;
4585 /* Replace the Var with a nestloop Param */
4586 return (Node *) replace_nestloop_param_var(root, var);
4587 }
4588 if (IsA(node, PlaceHolderVar))
4589 {
4590 PlaceHolderVar *phv = (PlaceHolderVar *) node;
4591
4592 /* Upper-level PlaceHolderVars should be long gone at this point */
4593 Assert(phv->phlevelsup == 0);
4594
4595 /*
4596 * Check whether we need to replace the PHV. We use bms_overlap as a
4597 * cheap/quick test to see if the PHV might be evaluated in the outer
4598 * rels, and then grab its PlaceHolderInfo to tell for sure.
4599 */
4600 if (!bms_overlap(phv->phrels, root->curOuterRels) ||
4601 !bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at,
4602 root->curOuterRels))
4603 {
4604 /*
4605 * We can't replace the whole PHV, but we might still need to
4606 * replace Vars or PHVs within its expression, in case it ends up
4607 * actually getting evaluated here. (It might get evaluated in
4608 * this plan node, or some child node; in the latter case we don't
4609 * really need to process the expression here, but we haven't got
4610 * enough info to tell if that's the case.) Flat-copy the PHV
4611 * node and then recurse on its expression.
4612 *
4613 * Note that after doing this, we might have different
4614 * representations of the contents of the same PHV in different
4615 * parts of the plan tree. This is OK because equal() will just
4616 * match on phid/phlevelsup, so setrefs.c will still recognize an
4617 * upper-level reference to a lower-level copy of the same PHV.
4618 */
4619 PlaceHolderVar *newphv = makeNode(PlaceHolderVar);
4620
4621 memcpy(newphv, phv, sizeof(PlaceHolderVar));
4622 newphv->phexpr = (Expr *)
4623 replace_nestloop_params_mutator((Node *) phv->phexpr,
4624 root);
4625 return (Node *) newphv;
4626 }
4627 /* Replace the PlaceHolderVar with a nestloop Param */
4628 return (Node *) replace_nestloop_param_placeholdervar(root, phv);
4629 }
4630 return expression_tree_mutator(node,
4631 replace_nestloop_params_mutator,
4632 (void *) root);
4633}
4634
4635/*
4636 * fix_indexqual_references
4637 * Adjust indexqual clauses to the form the executor's indexqual
4638 * machinery needs.
4639 *
4640 * We have three tasks here:
4641 * * Select the actual qual clauses out of the input IndexClause list,
4642 * and remove RestrictInfo nodes from the qual clauses.
4643 * * Replace any outer-relation Var or PHV nodes with nestloop Params.
4644 * (XXX eventually, that responsibility should go elsewhere?)
4645 * * Index keys must be represented by Var nodes with varattno set to the
4646 * index's attribute number, not the attribute number in the original rel.
4647 *
4648 * *stripped_indexquals_p receives a list of the actual qual clauses.
4649 *
4650 * *fixed_indexquals_p receives a list of the adjusted quals. This is a copy
4651 * that shares no substructure with the original; this is needed in case there
4652 * are subplans in it (we need two separate copies of the subplan tree, or
4653 * things will go awry).
4654 */
4655static void
4656fix_indexqual_references(PlannerInfo *root, IndexPath *index_path,
4657 List **stripped_indexquals_p, List **fixed_indexquals_p)
4658{
4659 IndexOptInfo *index = index_path->indexinfo;
4660 List *stripped_indexquals;
4661 List *fixed_indexquals;
4662 ListCell *lc;
4663
4664 stripped_indexquals = fixed_indexquals = NIL;
4665
4666 foreach(lc, index_path->indexclauses)
4667 {
4668 IndexClause *iclause = lfirst_node(IndexClause, lc);
4669 int indexcol = iclause->indexcol;
4670 ListCell *lc2;
4671
4672 foreach(lc2, iclause->indexquals)
4673 {
4674 RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
4675 Node *clause = (Node *) rinfo->clause;
4676
4677 stripped_indexquals = lappend(stripped_indexquals, clause);
4678 clause = fix_indexqual_clause(root, index, indexcol,
4679 clause, iclause->indexcols);
4680 fixed_indexquals = lappend(fixed_indexquals, clause);
4681 }
4682 }
4683
4684 *stripped_indexquals_p = stripped_indexquals;
4685 *fixed_indexquals_p = fixed_indexquals;
4686}
4687
4688/*
4689 * fix_indexorderby_references
4690 * Adjust indexorderby clauses to the form the executor's index
4691 * machinery needs.
4692 *
4693 * This is a simplified version of fix_indexqual_references. The input is
4694 * bare clauses and a separate indexcol list, instead of IndexClauses.
4695 */
4696static List *
4697fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path)
4698{
4699 IndexOptInfo *index = index_path->indexinfo;
4700 List *fixed_indexorderbys;
4701 ListCell *lcc,
4702 *lci;
4703
4704 fixed_indexorderbys = NIL;
4705
4706 forboth(lcc, index_path->indexorderbys, lci, index_path->indexorderbycols)
4707 {
4708 Node *clause = (Node *) lfirst(lcc);
4709 int indexcol = lfirst_int(lci);
4710
4711 clause = fix_indexqual_clause(root, index, indexcol, clause, NIL);
4712 fixed_indexorderbys = lappend(fixed_indexorderbys, clause);
4713 }
4714
4715 return fixed_indexorderbys;
4716}
4717
4718/*
4719 * fix_indexqual_clause
4720 * Convert a single indexqual clause to the form needed by the executor.
4721 *
4722 * We replace nestloop params here, and replace the index key variables
4723 * or expressions by index Var nodes.
4724 */
4725static Node *
4726fix_indexqual_clause(PlannerInfo *root, IndexOptInfo *index, int indexcol,
4727 Node *clause, List *indexcolnos)
4728{
4729 /*
4730 * Replace any outer-relation variables with nestloop params.
4731 *
4732 * This also makes a copy of the clause, so it's safe to modify it
4733 * in-place below.
4734 */
4735 clause = replace_nestloop_params(root, clause);
4736
4737 if (IsA(clause, OpExpr))
4738 {
4739 OpExpr *op = (OpExpr *) clause;
4740
4741 /* Replace the indexkey expression with an index Var. */
4742 linitial(op->args) = fix_indexqual_operand(linitial(op->args),
4743 index,
4744 indexcol);
4745 }
4746 else if (IsA(clause, RowCompareExpr))
4747 {
4748 RowCompareExpr *rc = (RowCompareExpr *) clause;
4749 ListCell *lca,
4750 *lcai;
4751
4752 /* Replace the indexkey expressions with index Vars. */
4753 Assert(list_length(rc->largs) == list_length(indexcolnos));
4754 forboth(lca, rc->largs, lcai, indexcolnos)
4755 {
4756 lfirst(lca) = fix_indexqual_operand(lfirst(lca),
4757 index,
4758 lfirst_int(lcai));
4759 }
4760 }
4761 else if (IsA(clause, ScalarArrayOpExpr))
4762 {
4763 ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
4764
4765 /* Replace the indexkey expression with an index Var. */
4766 linitial(saop->args) = fix_indexqual_operand(linitial(saop->args),
4767 index,
4768 indexcol);
4769 }
4770 else if (IsA(clause, NullTest))
4771 {
4772 NullTest *nt = (NullTest *) clause;
4773
4774 /* Replace the indexkey expression with an index Var. */
4775 nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg,
4776 index,
4777 indexcol);
4778 }
4779 else
4780 elog(ERROR, "unsupported indexqual type: %d",
4781 (int) nodeTag(clause));
4782
4783 return clause;
4784}
4785
4786/*
4787 * fix_indexqual_operand
4788 * Convert an indexqual expression to a Var referencing the index column.
4789 *
4790 * We represent index keys by Var nodes having varno == INDEX_VAR and varattno
4791 * equal to the index's attribute number (index column position).
4792 *
4793 * Most of the code here is just for sanity cross-checking that the given
4794 * expression actually matches the index column it's claimed to.
4795 */
4796static Node *
4797fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol)
4798{
4799 Var *result;
4800 int pos;
4801 ListCell *indexpr_item;
4802
4803 /*
4804 * Remove any binary-compatible relabeling of the indexkey
4805 */
4806 if (IsA(node, RelabelType))
4807 node = (Node *) ((RelabelType *) node)->arg;
4808
4809 Assert(indexcol >= 0 && indexcol < index->ncolumns);
4810
4811 if (index->indexkeys[indexcol] != 0)
4812 {
4813 /* It's a simple index column */
4814 if (IsA(node, Var) &&
4815 ((Var *) node)->varno == index->rel->relid &&
4816 ((Var *) node)->varattno == index->indexkeys[indexcol])
4817 {
4818 result = (Var *) copyObject(node);
4819 result->varno = INDEX_VAR;
4820 result->varattno = indexcol + 1;
4821 return (Node *) result;
4822 }
4823 else
4824 elog(ERROR, "index key does not match expected index column");
4825 }
4826
4827 /* It's an index expression, so find and cross-check the expression */
4828 indexpr_item = list_head(index->indexprs);
4829 for (pos = 0; pos < index->ncolumns; pos++)
4830 {
4831 if (index->indexkeys[pos] == 0)
4832 {
4833 if (indexpr_item == NULL)
4834 elog(ERROR, "too few entries in indexprs list");
4835 if (pos == indexcol)
4836 {
4837 Node *indexkey;
4838
4839 indexkey = (Node *) lfirst(indexpr_item);
4840 if (indexkey && IsA(indexkey, RelabelType))
4841 indexkey = (Node *) ((RelabelType *) indexkey)->arg;
4842 if (equal(node, indexkey))
4843 {
4844 result = makeVar(INDEX_VAR, indexcol + 1,
4845 exprType(lfirst(indexpr_item)), -1,
4846 exprCollation(lfirst(indexpr_item)),
4847 0);
4848 return (Node *) result;
4849 }
4850 else
4851 elog(ERROR, "index key does not match expected index column");
4852 }
4853 indexpr_item = lnext(indexpr_item);
4854 }
4855 }
4856
4857 /* Oops... */
4858 elog(ERROR, "index key does not match expected index column");
4859 return NULL; /* keep compiler quiet */
4860}
4861
4862/*
4863 * get_switched_clauses
4864 * Given a list of merge or hash joinclauses (as RestrictInfo nodes),
4865 * extract the bare clauses, and rearrange the elements within the
4866 * clauses, if needed, so the outer join variable is on the left and
4867 * the inner is on the right. The original clause data structure is not
4868 * touched; a modified list is returned. We do, however, set the transient
4869 * outer_is_left field in each RestrictInfo to show which side was which.
4870 */
4871static List *
4872get_switched_clauses(List *clauses, Relids outerrelids)
4873{
4874 List *t_list = NIL;
4875 ListCell *l;
4876
4877 foreach(l, clauses)
4878 {
4879 RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
4880 OpExpr *clause = (OpExpr *) restrictinfo->clause;
4881
4882 Assert(is_opclause(clause));
4883 if (bms_is_subset(restrictinfo->right_relids, outerrelids))
4884 {
4885 /*
4886 * Duplicate just enough of the structure to allow commuting the
4887 * clause without changing the original list. Could use
4888 * copyObject, but a complete deep copy is overkill.
4889 */
4890 OpExpr *temp = makeNode(OpExpr);
4891
4892 temp->opno = clause->opno;
4893 temp->opfuncid = InvalidOid;
4894 temp->opresulttype = clause->opresulttype;
4895 temp->opretset = clause->opretset;
4896 temp->opcollid = clause->opcollid;
4897 temp->inputcollid = clause->inputcollid;
4898 temp->args = list_copy(clause->args);
4899 temp->location = clause->location;
4900 /* Commute it --- note this modifies the temp node in-place. */
4901 CommuteOpExpr(temp);
4902 t_list = lappend(t_list, temp);
4903 restrictinfo->outer_is_left = false;
4904 }
4905 else
4906 {
4907 Assert(bms_is_subset(restrictinfo->left_relids, outerrelids));
4908 t_list = lappend(t_list, clause);
4909 restrictinfo->outer_is_left = true;
4910 }
4911 }
4912 return t_list;
4913}
4914
4915/*
4916 * order_qual_clauses
4917 * Given a list of qual clauses that will all be evaluated at the same
4918 * plan node, sort the list into the order we want to check the quals
4919 * in at runtime.
4920 *
4921 * When security barrier quals are used in the query, we may have quals with
4922 * different security levels in the list. Quals of lower security_level
4923 * must go before quals of higher security_level, except that we can grant
4924 * exceptions to move up quals that are leakproof. When security level
4925 * doesn't force the decision, we prefer to order clauses by estimated
4926 * execution cost, cheapest first.
4927 *
4928 * Ideally the order should be driven by a combination of execution cost and
4929 * selectivity, but it's not immediately clear how to account for both,
4930 * and given the uncertainty of the estimates the reliability of the decisions
4931 * would be doubtful anyway. So we just order by security level then
4932 * estimated per-tuple cost, being careful not to change the order when
4933 * (as is often the case) the estimates are identical.
4934 *
4935 * Although this will work on either bare clauses or RestrictInfos, it's
4936 * much faster to apply it to RestrictInfos, since it can re-use cost
4937 * information that is cached in RestrictInfos. XXX in the bare-clause
4938 * case, we are also not able to apply security considerations. That is
4939 * all right for the moment, because the bare-clause case doesn't occur
4940 * anywhere that barrier quals could be present, but it would be better to
4941 * get rid of it.
4942 *
4943 * Note: some callers pass lists that contain entries that will later be
4944 * removed; this is the easiest way to let this routine see RestrictInfos
4945 * instead of bare clauses. This is another reason why trying to consider
4946 * selectivity in the ordering would likely do the wrong thing.
4947 */
4948static List *
4949order_qual_clauses(PlannerInfo *root, List *clauses)
4950{
4951 typedef struct
4952 {
4953 Node *clause;
4954 Cost cost;
4955 Index security_level;
4956 } QualItem;
4957 int nitems = list_length(clauses);
4958 QualItem *items;
4959 ListCell *lc;
4960 int i;
4961 List *result;
4962
4963 /* No need to work hard for 0 or 1 clause */
4964 if (nitems <= 1)
4965 return clauses;
4966
4967 /*
4968 * Collect the items and costs into an array. This is to avoid repeated
4969 * cost_qual_eval work if the inputs aren't RestrictInfos.
4970 */
4971 items = (QualItem *) palloc(nitems * sizeof(QualItem));
4972 i = 0;
4973 foreach(lc, clauses)
4974 {
4975 Node *clause = (Node *) lfirst(lc);
4976 QualCost qcost;
4977
4978 cost_qual_eval_node(&qcost, clause, root);
4979 items[i].clause = clause;
4980 items[i].cost = qcost.per_tuple;
4981 if (IsA(clause, RestrictInfo))
4982 {
4983 RestrictInfo *rinfo = (RestrictInfo *) clause;
4984
4985 /*
4986 * If a clause is leakproof, it doesn't have to be constrained by
4987 * its nominal security level. If it's also reasonably cheap
4988 * (here defined as 10X cpu_operator_cost), pretend it has
4989 * security_level 0, which will allow it to go in front of
4990 * more-expensive quals of lower security levels. Of course, that
4991 * will also force it to go in front of cheaper quals of its own
4992 * security level, which is not so great, but we can alleviate
4993 * that risk by applying the cost limit cutoff.
4994 */
4995 if (rinfo->leakproof && items[i].cost < 10 * cpu_operator_cost)
4996 items[i].security_level = 0;
4997 else
4998 items[i].security_level = rinfo->security_level;
4999 }
5000 else
5001 items[i].security_level = 0;
5002 i++;
5003 }
5004
5005 /*
5006 * Sort. We don't use qsort() because it's not guaranteed stable for
5007 * equal keys. The expected number of entries is small enough that a
5008 * simple insertion sort should be good enough.
5009 */
5010 for (i = 1; i < nitems; i++)
5011 {
5012 QualItem newitem = items[i];
5013 int j;
5014
5015 /* insert newitem into the already-sorted subarray */
5016 for (j = i; j > 0; j--)
5017 {
5018 QualItem *olditem = &items[j - 1];
5019
5020 if (newitem.security_level > olditem->security_level ||
5021 (newitem.security_level == olditem->security_level &&
5022 newitem.cost >= olditem->cost))
5023 break;
5024 items[j] = *olditem;
5025 }
5026 items[j] = newitem;
5027 }
5028
5029 /* Convert back to a list */
5030 result = NIL;
5031 for (i = 0; i < nitems; i++)
5032 result = lappend(result, items[i].clause);
5033
5034 return result;
5035}
5036
5037/*
5038 * Copy cost and size info from a Path node to the Plan node created from it.
5039 * The executor usually won't use this info, but it's needed by EXPLAIN.
5040 * Also copy the parallel-related flags, which the executor *will* use.
5041 */
5042static void
5043copy_generic_path_info(Plan *dest, Path *src)
5044{
5045 dest->startup_cost = src->startup_cost;
5046 dest->total_cost = src->total_cost;
5047 dest->plan_rows = src->rows;
5048 dest->plan_width = src->pathtarget->width;
5049 dest->parallel_aware = src->parallel_aware;
5050 dest->parallel_safe = src->parallel_safe;
5051}
5052
5053/*
5054 * Copy cost and size info from a lower plan node to an inserted node.
5055 * (Most callers alter the info after copying it.)
5056 */
5057static void
5058copy_plan_costsize(Plan *dest, Plan *src)
5059{
5060 dest->startup_cost = src->startup_cost;
5061 dest->total_cost = src->total_cost;
5062 dest->plan_rows = src->plan_rows;
5063 dest->plan_width = src->plan_width;
5064 /* Assume the inserted node is not parallel-aware. */
5065 dest->parallel_aware = false;
5066 /* Assume the inserted node is parallel-safe, if child plan is. */
5067 dest->parallel_safe = src->parallel_safe;
5068}
5069
5070/*
5071 * Some places in this file build Sort nodes that don't have a directly
5072 * corresponding Path node. The cost of the sort is, or should have been,
5073 * included in the cost of the Path node we're working from, but since it's
5074 * not split out, we have to re-figure it using cost_sort(). This is just
5075 * to label the Sort node nicely for EXPLAIN.
5076 *
5077 * limit_tuples is as for cost_sort (in particular, pass -1 if no limit)
5078 */
5079static void
5080label_sort_with_costsize(PlannerInfo *root, Sort *plan, double limit_tuples)
5081{
5082 Plan *lefttree = plan->plan.lefttree;
5083 Path sort_path; /* dummy for result of cost_sort */
5084
5085 cost_sort(&sort_path, root, NIL,
5086 lefttree->total_cost,
5087 lefttree->plan_rows,
5088 lefttree->plan_width,
5089 0.0,
5090 work_mem,
5091 limit_tuples);
5092 plan->plan.startup_cost = sort_path.startup_cost;
5093 plan->plan.total_cost = sort_path.total_cost;
5094 plan->plan.plan_rows = lefttree->plan_rows;
5095 plan->plan.plan_width = lefttree->plan_width;
5096 plan->plan.parallel_aware = false;
5097 plan->plan.parallel_safe = lefttree->parallel_safe;
5098}
5099
5100/*
5101 * bitmap_subplan_mark_shared
5102 * Set isshared flag in bitmap subplan so that it will be created in
5103 * shared memory.
5104 */
5105static void
5106bitmap_subplan_mark_shared(Plan *plan)
5107{
5108 if (IsA(plan, BitmapAnd))
5109 bitmap_subplan_mark_shared(
5110 linitial(((BitmapAnd *) plan)->bitmapplans));
5111 else if (IsA(plan, BitmapOr))
5112 {
5113 ((BitmapOr *) plan)->isshared = true;
5114 bitmap_subplan_mark_shared(
5115 linitial(((BitmapOr *) plan)->bitmapplans));
5116 }
5117 else if (IsA(plan, BitmapIndexScan))
5118 ((BitmapIndexScan *) plan)->isshared = true;
5119 else
5120 elog(ERROR, "unrecognized node type: %d", nodeTag(plan));
5121}
5122
5123/*****************************************************************************
5124 *
5125 * PLAN NODE BUILDING ROUTINES
5126 *
5127 * In general, these functions are not passed the original Path and therefore
5128 * leave it to the caller to fill in the cost/width fields from the Path,
5129 * typically by calling copy_generic_path_info(). This convention is
5130 * somewhat historical, but it does support a few places above where we build
5131 * a plan node without having an exactly corresponding Path node. Under no
5132 * circumstances should one of these functions do its own cost calculations,
5133 * as that would be redundant with calculations done while building Paths.
5134 *
5135 *****************************************************************************/
5136
5137static SeqScan *
5138make_seqscan(List *qptlist,
5139 List *qpqual,
5140 Index scanrelid)
5141{
5142 SeqScan *node = makeNode(SeqScan);
5143 Plan *plan = &node->plan;
5144
5145 plan->targetlist = qptlist;
5146 plan->qual = qpqual;
5147 plan->lefttree = NULL;
5148 plan->righttree = NULL;
5149 node->scanrelid = scanrelid;
5150
5151 return node;
5152}
5153
5154static SampleScan *
5155make_samplescan(List *qptlist,
5156 List *qpqual,
5157 Index scanrelid,
5158 TableSampleClause *tsc)
5159{
5160 SampleScan *node = makeNode(SampleScan);
5161 Plan *plan = &node->scan.plan;
5162
5163 plan->targetlist = qptlist;
5164 plan->qual = qpqual;
5165 plan->lefttree = NULL;
5166 plan->righttree = NULL;
5167 node->scan.scanrelid = scanrelid;
5168 node->tablesample = tsc;
5169
5170 return node;
5171}
5172
5173static IndexScan *
5174make_indexscan(List *qptlist,
5175 List *qpqual,
5176 Index scanrelid,
5177 Oid indexid,
5178 List *indexqual,
5179 List *indexqualorig,
5180 List *indexorderby,
5181 List *indexorderbyorig,
5182 List *indexorderbyops,
5183 ScanDirection indexscandir)
5184{
5185 IndexScan *node = makeNode(IndexScan);
5186 Plan *plan = &node->scan.plan;
5187
5188 plan->targetlist = qptlist;
5189 plan->qual = qpqual;
5190 plan->lefttree = NULL;
5191 plan->righttree = NULL;
5192 node->scan.scanrelid = scanrelid;
5193 node->indexid = indexid;
5194 node->indexqual = indexqual;
5195 node->indexqualorig = indexqualorig;
5196 node->indexorderby = indexorderby;
5197 node->indexorderbyorig = indexorderbyorig;
5198 node->indexorderbyops = indexorderbyops;
5199 node->indexorderdir = indexscandir;
5200
5201 return node;
5202}
5203
5204static IndexOnlyScan *
5205make_indexonlyscan(List *qptlist,
5206 List *qpqual,
5207 Index scanrelid,
5208 Oid indexid,
5209 List *indexqual,
5210 List *indexorderby,
5211 List *indextlist,
5212 ScanDirection indexscandir)
5213{
5214 IndexOnlyScan *node = makeNode(IndexOnlyScan);
5215 Plan *plan = &node->scan.plan;
5216
5217 plan->targetlist = qptlist;
5218 plan->qual = qpqual;
5219 plan->lefttree = NULL;
5220 plan->righttree = NULL;
5221 node->scan.scanrelid = scanrelid;
5222 node->indexid = indexid;
5223 node->indexqual = indexqual;
5224 node->indexorderby = indexorderby;
5225 node->indextlist = indextlist;
5226 node->indexorderdir = indexscandir;
5227
5228 return node;
5229}
5230
5231static BitmapIndexScan *
5232make_bitmap_indexscan(Index scanrelid,
5233 Oid indexid,
5234 List *indexqual,
5235 List *indexqualorig)
5236{
5237 BitmapIndexScan *node = makeNode(BitmapIndexScan);
5238 Plan *plan = &node->scan.plan;
5239
5240 plan->targetlist = NIL; /* not used */
5241 plan->qual = NIL; /* not used */
5242 plan->lefttree = NULL;
5243 plan->righttree = NULL;
5244 node->scan.scanrelid = scanrelid;
5245 node->indexid = indexid;
5246 node->indexqual = indexqual;
5247 node->indexqualorig = indexqualorig;
5248
5249 return node;
5250}
5251
5252static BitmapHeapScan *
5253make_bitmap_heapscan(List *qptlist,
5254 List *qpqual,
5255 Plan *lefttree,
5256 List *bitmapqualorig,
5257 Index scanrelid)
5258{
5259 BitmapHeapScan *node = makeNode(BitmapHeapScan);
5260 Plan *plan = &node->scan.plan;
5261
5262 plan->targetlist = qptlist;
5263 plan->qual = qpqual;
5264 plan->lefttree = lefttree;
5265 plan->righttree = NULL;
5266 node->scan.scanrelid = scanrelid;
5267 node->bitmapqualorig = bitmapqualorig;
5268
5269 return node;
5270}
5271
5272static TidScan *
5273make_tidscan(List *qptlist,
5274 List *qpqual,
5275 Index scanrelid,
5276 List *tidquals)
5277{
5278 TidScan *node = makeNode(TidScan);
5279 Plan *plan = &node->scan.plan;
5280
5281 plan->targetlist = qptlist;
5282 plan->qual = qpqual;
5283 plan->lefttree = NULL;
5284 plan->righttree = NULL;
5285 node->scan.scanrelid = scanrelid;
5286 node->tidquals = tidquals;
5287
5288 return node;
5289}
5290
5291static SubqueryScan *
5292make_subqueryscan(List *qptlist,
5293 List *qpqual,
5294 Index scanrelid,
5295 Plan *subplan)
5296{
5297 SubqueryScan *node = makeNode(SubqueryScan);
5298 Plan *plan = &node->scan.plan;
5299
5300 plan->targetlist = qptlist;
5301 plan->qual = qpqual;
5302 plan->lefttree = NULL;
5303 plan->righttree = NULL;
5304 node->scan.scanrelid = scanrelid;
5305 node->subplan = subplan;
5306
5307 return node;
5308}
5309
5310static FunctionScan *
5311make_functionscan(List *qptlist,
5312 List *qpqual,
5313 Index scanrelid,
5314 List *functions,
5315 bool funcordinality)
5316{
5317 FunctionScan *node = makeNode(FunctionScan);
5318 Plan *plan = &node->scan.plan;
5319
5320 plan->targetlist = qptlist;
5321 plan->qual = qpqual;
5322 plan->lefttree = NULL;
5323 plan->righttree = NULL;
5324 node->scan.scanrelid = scanrelid;
5325 node->functions = functions;
5326 node->funcordinality = funcordinality;
5327
5328 return node;
5329}
5330
5331static TableFuncScan *
5332make_tablefuncscan(List *qptlist,
5333 List *qpqual,
5334 Index scanrelid,
5335 TableFunc *tablefunc)
5336{
5337 TableFuncScan *node = makeNode(TableFuncScan);
5338 Plan *plan = &node->scan.plan;
5339
5340 plan->targetlist = qptlist;
5341 plan->qual = qpqual;
5342 plan->lefttree = NULL;
5343 plan->righttree = NULL;
5344 node->scan.scanrelid = scanrelid;
5345 node->tablefunc = tablefunc;
5346
5347 return node;
5348}
5349
5350static ValuesScan *
5351make_valuesscan(List *qptlist,
5352 List *qpqual,
5353 Index scanrelid,
5354 List *values_lists)
5355{
5356 ValuesScan *node = makeNode(ValuesScan);
5357 Plan *plan = &node->scan.plan;
5358
5359 plan->targetlist = qptlist;
5360 plan->qual = qpqual;
5361 plan->lefttree = NULL;
5362 plan->righttree = NULL;
5363 node->scan.scanrelid = scanrelid;
5364 node->values_lists = values_lists;
5365
5366 return node;
5367}
5368
5369static CteScan *
5370make_ctescan(List *qptlist,
5371 List *qpqual,
5372 Index scanrelid,
5373 int ctePlanId,
5374 int cteParam)
5375{
5376 CteScan *node = makeNode(CteScan);
5377 Plan *plan = &node->scan.plan;
5378
5379 plan->targetlist = qptlist;
5380 plan->qual = qpqual;
5381 plan->lefttree = NULL;
5382 plan->righttree = NULL;
5383 node->scan.scanrelid = scanrelid;
5384 node->ctePlanId = ctePlanId;
5385 node->cteParam = cteParam;
5386
5387 return node;
5388}
5389
5390static NamedTuplestoreScan *
5391make_namedtuplestorescan(List *qptlist,
5392 List *qpqual,
5393 Index scanrelid,
5394 char *enrname)
5395{
5396 NamedTuplestoreScan *node = makeNode(NamedTuplestoreScan);
5397 Plan *plan = &node->scan.plan;
5398
5399 /* cost should be inserted by caller */
5400 plan->targetlist = qptlist;
5401 plan->qual = qpqual;
5402 plan->lefttree = NULL;
5403 plan->righttree = NULL;
5404 node->scan.scanrelid = scanrelid;
5405 node->enrname = enrname;
5406
5407 return node;
5408}
5409
5410static WorkTableScan *
5411make_worktablescan(List *qptlist,
5412 List *qpqual,
5413 Index scanrelid,
5414 int wtParam)
5415{
5416 WorkTableScan *node = makeNode(WorkTableScan);
5417 Plan *plan = &node->scan.plan;
5418
5419 plan->targetlist = qptlist;
5420 plan->qual = qpqual;
5421 plan->lefttree = NULL;
5422 plan->righttree = NULL;
5423 node->scan.scanrelid = scanrelid;
5424 node->wtParam = wtParam;
5425
5426 return node;
5427}
5428
5429ForeignScan *
5430make_foreignscan(List *qptlist,
5431 List *qpqual,
5432 Index scanrelid,
5433 List *fdw_exprs,
5434 List *fdw_private,
5435 List *fdw_scan_tlist,
5436 List *fdw_recheck_quals,
5437 Plan *outer_plan)
5438{
5439 ForeignScan *node = makeNode(ForeignScan);
5440 Plan *plan = &node->scan.plan;
5441
5442 /* cost will be filled in by create_foreignscan_plan */
5443 plan->targetlist = qptlist;
5444 plan->qual = qpqual;
5445 plan->lefttree = outer_plan;
5446 plan->righttree = NULL;
5447 node->scan.scanrelid = scanrelid;
5448 node->operation = CMD_SELECT;
5449 /* fs_server will be filled in by create_foreignscan_plan */
5450 node->fs_server = InvalidOid;
5451 node->fdw_exprs = fdw_exprs;
5452 node->fdw_private = fdw_private;
5453 node->fdw_scan_tlist = fdw_scan_tlist;
5454 node->fdw_recheck_quals = fdw_recheck_quals;
5455 /* fs_relids will be filled in by create_foreignscan_plan */
5456 node->fs_relids = NULL;
5457 /* fsSystemCol will be filled in by create_foreignscan_plan */
5458 node->fsSystemCol = false;
5459
5460 return node;
5461}
5462
5463static RecursiveUnion *
5464make_recursive_union(List *tlist,
5465 Plan *lefttree,
5466 Plan *righttree,
5467 int wtParam,
5468 List *distinctList,
5469 long numGroups)
5470{
5471 RecursiveUnion *node = makeNode(RecursiveUnion);
5472 Plan *plan = &node->plan;
5473 int numCols = list_length(distinctList);
5474
5475 plan->targetlist = tlist;
5476 plan->qual = NIL;
5477 plan->lefttree = lefttree;
5478 plan->righttree = righttree;
5479 node->wtParam = wtParam;
5480
5481 /*
5482 * convert SortGroupClause list into arrays of attr indexes and equality
5483 * operators, as wanted by executor
5484 */
5485 node->numCols = numCols;
5486 if (numCols > 0)
5487 {
5488 int keyno = 0;
5489 AttrNumber *dupColIdx;
5490 Oid *dupOperators;
5491 Oid *dupCollations;
5492 ListCell *slitem;
5493
5494 dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
5495 dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
5496 dupCollations = (Oid *) palloc(sizeof(Oid) * numCols);
5497
5498 foreach(slitem, distinctList)
5499 {
5500 SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
5501 TargetEntry *tle = get_sortgroupclause_tle(sortcl,
5502 plan->targetlist);
5503
5504 dupColIdx[keyno] = tle->resno;
5505 dupOperators[keyno] = sortcl->eqop;
5506 dupCollations[keyno] = exprCollation((Node *) tle->expr);
5507 Assert(OidIsValid(dupOperators[keyno]));
5508 keyno++;
5509 }
5510 node->dupColIdx = dupColIdx;
5511 node->dupOperators = dupOperators;
5512 node->dupCollations = dupCollations;
5513 }
5514 node->numGroups = numGroups;
5515
5516 return node;
5517}
5518
5519static BitmapAnd *
5520make_bitmap_and(List *bitmapplans)
5521{
5522 BitmapAnd *node = makeNode(BitmapAnd);
5523 Plan *plan = &node->plan;
5524
5525 plan->targetlist = NIL;
5526 plan->qual = NIL;
5527 plan->lefttree = NULL;
5528 plan->righttree = NULL;
5529 node->bitmapplans = bitmapplans;
5530
5531 return node;
5532}
5533
5534static BitmapOr *
5535make_bitmap_or(List *bitmapplans)
5536{
5537 BitmapOr *node = makeNode(BitmapOr);
5538 Plan *plan = &node->plan;
5539
5540 plan->targetlist = NIL;
5541 plan->qual = NIL;
5542 plan->lefttree = NULL;
5543 plan->righttree = NULL;
5544 node->bitmapplans = bitmapplans;
5545
5546 return node;
5547}
5548
5549static NestLoop *
5550make_nestloop(List *tlist,
5551 List *joinclauses,
5552 List *otherclauses,
5553 List *nestParams,
5554 Plan *lefttree,
5555 Plan *righttree,
5556 JoinType jointype,
5557 bool inner_unique)
5558{
5559 NestLoop *node = makeNode(NestLoop);
5560 Plan *plan = &node->join.plan;
5561
5562 plan->targetlist = tlist;
5563 plan->qual = otherclauses;
5564 plan->lefttree = lefttree;
5565 plan->righttree = righttree;
5566 node->join.jointype = jointype;
5567 node->join.inner_unique = inner_unique;
5568 node->join.joinqual = joinclauses;
5569 node->nestParams = nestParams;
5570
5571 return node;
5572}
5573
5574static HashJoin *
5575make_hashjoin(List *tlist,
5576 List *joinclauses,
5577 List *otherclauses,
5578 List *hashclauses,
5579 List *hashoperators,
5580 List *hashcollations,
5581 List *hashkeys,
5582 Plan *lefttree,
5583 Plan *righttree,
5584 JoinType jointype,
5585 bool inner_unique)
5586{
5587 HashJoin *node = makeNode(HashJoin);
5588 Plan *plan = &node->join.plan;
5589
5590 plan->targetlist = tlist;
5591 plan->qual = otherclauses;
5592 plan->lefttree = lefttree;
5593 plan->righttree = righttree;
5594 node->hashclauses = hashclauses;
5595 node->hashoperators = hashoperators;
5596 node->hashcollations = hashcollations;
5597 node->hashkeys = hashkeys;
5598 node->join.jointype = jointype;
5599 node->join.inner_unique = inner_unique;
5600 node->join.joinqual = joinclauses;
5601
5602 return node;
5603}
5604
5605static Hash *
5606make_hash(Plan *lefttree,
5607 List *hashkeys,
5608 Oid skewTable,
5609 AttrNumber skewColumn,
5610 bool skewInherit)
5611{
5612 Hash *node = makeNode(Hash);
5613 Plan *plan = &node->plan;
5614
5615 plan->targetlist = lefttree->targetlist;
5616 plan->qual = NIL;
5617 plan->lefttree = lefttree;
5618 plan->righttree = NULL;
5619
5620 node->hashkeys = hashkeys;
5621 node->skewTable = skewTable;
5622 node->skewColumn = skewColumn;
5623 node->skewInherit = skewInherit;
5624
5625 return node;
5626}
5627
5628static MergeJoin *
5629make_mergejoin(List *tlist,
5630 List *joinclauses,
5631 List *otherclauses,
5632 List *mergeclauses,
5633 Oid *mergefamilies,
5634 Oid *mergecollations,
5635 int *mergestrategies,
5636 bool *mergenullsfirst,
5637 Plan *lefttree,
5638 Plan *righttree,
5639 JoinType jointype,
5640 bool inner_unique,
5641 bool skip_mark_restore)
5642{
5643 MergeJoin *node = makeNode(MergeJoin);
5644 Plan *plan = &node->join.plan;
5645
5646 plan->targetlist = tlist;
5647 plan->qual = otherclauses;
5648 plan->lefttree = lefttree;
5649 plan->righttree = righttree;
5650 node->skip_mark_restore = skip_mark_restore;
5651 node->mergeclauses = mergeclauses;
5652 node->mergeFamilies = mergefamilies;
5653 node->mergeCollations = mergecollations;
5654 node->mergeStrategies = mergestrategies;
5655 node->mergeNullsFirst = mergenullsfirst;
5656 node->join.jointype = jointype;
5657 node->join.inner_unique = inner_unique;
5658 node->join.joinqual = joinclauses;
5659
5660 return node;
5661}
5662
5663/*
5664 * make_sort --- basic routine to build a Sort plan node
5665 *
5666 * Caller must have built the sortColIdx, sortOperators, collations, and
5667 * nullsFirst arrays already.
5668 */
5669static Sort *
5670make_sort(Plan *lefttree, int numCols,
5671 AttrNumber *sortColIdx, Oid *sortOperators,
5672 Oid *collations, bool *nullsFirst)
5673{
5674 Sort *node = makeNode(Sort);
5675 Plan *plan = &node->plan;
5676
5677 plan->targetlist = lefttree->targetlist;
5678 plan->qual = NIL;
5679 plan->lefttree = lefttree;
5680 plan->righttree = NULL;
5681 node->numCols = numCols;
5682 node->sortColIdx = sortColIdx;
5683 node->sortOperators = sortOperators;
5684 node->collations = collations;
5685 node->nullsFirst = nullsFirst;
5686
5687 return node;
5688}
5689
5690/*
5691 * prepare_sort_from_pathkeys
5692 * Prepare to sort according to given pathkeys
5693 *
5694 * This is used to set up for Sort, MergeAppend, and Gather Merge nodes. It
5695 * calculates the executor's representation of the sort key information, and
5696 * adjusts the plan targetlist if needed to add resjunk sort columns.
5697 *
5698 * Input parameters:
5699 * 'lefttree' is the plan node which yields input tuples
5700 * 'pathkeys' is the list of pathkeys by which the result is to be sorted
5701 * 'relids' identifies the child relation being sorted, if any
5702 * 'reqColIdx' is NULL or an array of required sort key column numbers
5703 * 'adjust_tlist_in_place' is true if lefttree must be modified in-place
5704 *
5705 * We must convert the pathkey information into arrays of sort key column
5706 * numbers, sort operator OIDs, collation OIDs, and nulls-first flags,
5707 * which is the representation the executor wants. These are returned into
5708 * the output parameters *p_numsortkeys etc.
5709 *
5710 * When looking for matches to an EquivalenceClass's members, we will only
5711 * consider child EC members if they belong to given 'relids'. This protects
5712 * against possible incorrect matches to child expressions that contain no
5713 * Vars.
5714 *
5715 * If reqColIdx isn't NULL then it contains sort key column numbers that
5716 * we should match. This is used when making child plans for a MergeAppend;
5717 * it's an error if we can't match the columns.
5718 *
5719 * If the pathkeys include expressions that aren't simple Vars, we will
5720 * usually need to add resjunk items to the input plan's targetlist to
5721 * compute these expressions, since a Sort or MergeAppend node itself won't
5722 * do any such calculations. If the input plan type isn't one that can do
5723 * projections, this means adding a Result node just to do the projection.
5724 * However, the caller can pass adjust_tlist_in_place = true to force the
5725 * lefttree tlist to be modified in-place regardless of whether the node type
5726 * can project --- we use this for fixing the tlist of MergeAppend itself.
5727 *
5728 * Returns the node which is to be the input to the Sort (either lefttree,
5729 * or a Result stacked atop lefttree).
5730 */
5731static Plan *
5732prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
5733 Relids relids,
5734 const AttrNumber *reqColIdx,
5735 bool adjust_tlist_in_place,
5736 int *p_numsortkeys,
5737 AttrNumber **p_sortColIdx,
5738 Oid **p_sortOperators,
5739 Oid **p_collations,
5740 bool **p_nullsFirst)
5741{
5742 List *tlist = lefttree->targetlist;
5743 ListCell *i;
5744 int numsortkeys;
5745 AttrNumber *sortColIdx;
5746 Oid *sortOperators;
5747 Oid *collations;
5748 bool *nullsFirst;
5749
5750 /*
5751 * We will need at most list_length(pathkeys) sort columns; possibly less
5752 */
5753 numsortkeys = list_length(pathkeys);
5754 sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
5755 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
5756 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
5757 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
5758
5759 numsortkeys = 0;
5760
5761 foreach(i, pathkeys)
5762 {
5763 PathKey *pathkey = (PathKey *) lfirst(i);
5764 EquivalenceClass *ec = pathkey->pk_eclass;
5765 EquivalenceMember *em;
5766 TargetEntry *tle = NULL;
5767 Oid pk_datatype = InvalidOid;
5768 Oid sortop;
5769 ListCell *j;
5770
5771 if (ec->ec_has_volatile)
5772 {
5773 /*
5774 * If the pathkey's EquivalenceClass is volatile, then it must
5775 * have come from an ORDER BY clause, and we have to match it to
5776 * that same targetlist entry.
5777 */
5778 if (ec->ec_sortref == 0) /* can't happen */
5779 elog(ERROR, "volatile EquivalenceClass has no sortref");
5780 tle = get_sortgroupref_tle(ec->ec_sortref, tlist);
5781 Assert(tle);
5782 Assert(list_length(ec->ec_members) == 1);
5783 pk_datatype = ((EquivalenceMember *) linitial(ec->ec_members))->em_datatype;
5784 }
5785 else if (reqColIdx != NULL)
5786 {
5787 /*
5788 * If we are given a sort column number to match, only consider
5789 * the single TLE at that position. It's possible that there is
5790 * no such TLE, in which case fall through and generate a resjunk
5791 * targetentry (we assume this must have happened in the parent
5792 * plan as well). If there is a TLE but it doesn't match the
5793 * pathkey's EC, we do the same, which is probably the wrong thing
5794 * but we'll leave it to caller to complain about the mismatch.
5795 */
5796 tle = get_tle_by_resno(tlist, reqColIdx[numsortkeys]);
5797 if (tle)
5798 {
5799 em = find_ec_member_for_tle(ec, tle, relids);
5800 if (em)
5801 {
5802 /* found expr at right place in tlist */
5803 pk_datatype = em->em_datatype;
5804 }
5805 else
5806 tle = NULL;
5807 }
5808 }
5809 else
5810 {
5811 /*
5812 * Otherwise, we can sort by any non-constant expression listed in
5813 * the pathkey's EquivalenceClass. For now, we take the first
5814 * tlist item found in the EC. If there's no match, we'll generate
5815 * a resjunk entry using the first EC member that is an expression
5816 * in the input's vars. (The non-const restriction only matters
5817 * if the EC is below_outer_join; but if it isn't, it won't
5818 * contain consts anyway, else we'd have discarded the pathkey as
5819 * redundant.)
5820 *
5821 * XXX if we have a choice, is there any way of figuring out which
5822 * might be cheapest to execute? (For example, int4lt is likely
5823 * much cheaper to execute than numericlt, but both might appear
5824 * in the same equivalence class...) Not clear that we ever will
5825 * have an interesting choice in practice, so it may not matter.
5826 */
5827 foreach(j, tlist)
5828 {
5829 tle = (TargetEntry *) lfirst(j);
5830 em = find_ec_member_for_tle(ec, tle, relids);
5831 if (em)
5832 {
5833 /* found expr already in tlist */
5834 pk_datatype = em->em_datatype;
5835 break;
5836 }
5837 tle = NULL;
5838 }
5839 }
5840
5841 if (!tle)
5842 {
5843 /*
5844 * No matching tlist item; look for a computable expression. Note
5845 * that we treat Aggrefs as if they were variables; this is
5846 * necessary when attempting to sort the output from an Agg node
5847 * for use in a WindowFunc (since grouping_planner will have
5848 * treated the Aggrefs as variables, too). Likewise, if we find a
5849 * WindowFunc in a sort expression, treat it as a variable.
5850 */
5851 Expr *sortexpr = NULL;
5852
5853 foreach(j, ec->ec_members)
5854 {
5855 EquivalenceMember *em = (EquivalenceMember *) lfirst(j);
5856 List *exprvars;
5857 ListCell *k;
5858
5859 /*
5860 * We shouldn't be trying to sort by an equivalence class that
5861 * contains a constant, so no need to consider such cases any
5862 * further.
5863 */
5864 if (em->em_is_const)
5865 continue;
5866
5867 /*
5868 * Ignore child members unless they belong to the rel being
5869 * sorted.
5870 */
5871 if (em->em_is_child &&
5872 !bms_is_subset(em->em_relids, relids))
5873 continue;
5874
5875 sortexpr = em->em_expr;
5876 exprvars = pull_var_clause((Node *) sortexpr,
5877 PVC_INCLUDE_AGGREGATES |
5878 PVC_INCLUDE_WINDOWFUNCS |
5879 PVC_INCLUDE_PLACEHOLDERS);
5880 foreach(k, exprvars)
5881 {
5882 if (!tlist_member_ignore_relabel(lfirst(k), tlist))
5883 break;
5884 }
5885 list_free(exprvars);
5886 if (!k)
5887 {
5888 pk_datatype = em->em_datatype;
5889 break; /* found usable expression */
5890 }
5891 }
5892 if (!j)
5893 elog(ERROR, "could not find pathkey item to sort");
5894
5895 /*
5896 * Do we need to insert a Result node?
5897 */
5898 if (!adjust_tlist_in_place &&
5899 !is_projection_capable_plan(lefttree))
5900 {
5901 /* copy needed so we don't modify input's tlist below */
5902 tlist = copyObject(tlist);
5903 lefttree = inject_projection_plan(lefttree, tlist,
5904 lefttree->parallel_safe);
5905 }
5906
5907 /* Don't bother testing is_projection_capable_plan again */
5908 adjust_tlist_in_place = true;
5909
5910 /*
5911 * Add resjunk entry to input's tlist
5912 */
5913 tle = makeTargetEntry(sortexpr,
5914 list_length(tlist) + 1,
5915 NULL,
5916 true);
5917 tlist = lappend(tlist, tle);
5918 lefttree->targetlist = tlist; /* just in case NIL before */
5919 }
5920
5921 /*
5922 * Look up the correct sort operator from the PathKey's slightly
5923 * abstracted representation.
5924 */
5925 sortop = get_opfamily_member(pathkey->pk_opfamily,
5926 pk_datatype,
5927 pk_datatype,
5928 pathkey->pk_strategy);
5929 if (!OidIsValid(sortop)) /* should not happen */
5930 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
5931 pathkey->pk_strategy, pk_datatype, pk_datatype,
5932 pathkey->pk_opfamily);
5933
5934 /* Add the column to the sort arrays */
5935 sortColIdx[numsortkeys] = tle->resno;
5936 sortOperators[numsortkeys] = sortop;
5937 collations[numsortkeys] = ec->ec_collation;
5938 nullsFirst[numsortkeys] = pathkey->pk_nulls_first;
5939 numsortkeys++;
5940 }
5941
5942 /* Return results */
5943 *p_numsortkeys = numsortkeys;
5944 *p_sortColIdx = sortColIdx;
5945 *p_sortOperators = sortOperators;
5946 *p_collations = collations;
5947 *p_nullsFirst = nullsFirst;
5948
5949 return lefttree;
5950}
5951
5952/*
5953 * find_ec_member_for_tle
5954 * Locate an EquivalenceClass member matching the given TLE, if any
5955 *
5956 * Child EC members are ignored unless they belong to given 'relids'.
5957 */
5958static EquivalenceMember *
5959find_ec_member_for_tle(EquivalenceClass *ec,
5960 TargetEntry *tle,
5961 Relids relids)
5962{
5963 Expr *tlexpr;
5964 ListCell *lc;
5965
5966 /* We ignore binary-compatible relabeling on both ends */
5967 tlexpr = tle->expr;
5968 while (tlexpr && IsA(tlexpr, RelabelType))
5969 tlexpr = ((RelabelType *) tlexpr)->arg;
5970
5971 foreach(lc, ec->ec_members)
5972 {
5973 EquivalenceMember *em = (EquivalenceMember *) lfirst(lc);
5974 Expr *emexpr;
5975
5976 /*
5977 * We shouldn't be trying to sort by an equivalence class that
5978 * contains a constant, so no need to consider such cases any further.
5979 */
5980 if (em->em_is_const)
5981 continue;
5982
5983 /*
5984 * Ignore child members unless they belong to the rel being sorted.
5985 */
5986 if (em->em_is_child &&
5987 !bms_is_subset(em->em_relids, relids))
5988 continue;
5989
5990 /* Match if same expression (after stripping relabel) */
5991 emexpr = em->em_expr;
5992 while (emexpr && IsA(emexpr, RelabelType))
5993 emexpr = ((RelabelType *) emexpr)->arg;
5994
5995 if (equal(emexpr, tlexpr))
5996 return em;
5997 }
5998
5999 return NULL;
6000}
6001
6002/*
6003 * make_sort_from_pathkeys
6004 * Create sort plan to sort according to given pathkeys
6005 *
6006 * 'lefttree' is the node which yields input tuples
6007 * 'pathkeys' is the list of pathkeys by which the result is to be sorted
6008 * 'relids' is the set of relations required by prepare_sort_from_pathkeys()
6009 */
6010static Sort *
6011make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids)
6012{
6013 int numsortkeys;
6014 AttrNumber *sortColIdx;
6015 Oid *sortOperators;
6016 Oid *collations;
6017 bool *nullsFirst;
6018
6019 /* Compute sort column info, and adjust lefttree as needed */
6020 lefttree = prepare_sort_from_pathkeys(lefttree, pathkeys,
6021 relids,
6022 NULL,
6023 false,
6024 &numsortkeys,
6025 &sortColIdx,
6026 &sortOperators,
6027 &collations,
6028 &nullsFirst);
6029
6030 /* Now build the Sort node */
6031 return make_sort(lefttree, numsortkeys,
6032 sortColIdx, sortOperators,
6033 collations, nullsFirst);
6034}
6035
6036/*
6037 * make_sort_from_sortclauses
6038 * Create sort plan to sort according to given sortclauses
6039 *
6040 * 'sortcls' is a list of SortGroupClauses
6041 * 'lefttree' is the node which yields input tuples
6042 */
6043Sort *
6044make_sort_from_sortclauses(List *sortcls, Plan *lefttree)
6045{
6046 List *sub_tlist = lefttree->targetlist;
6047 ListCell *l;
6048 int numsortkeys;
6049 AttrNumber *sortColIdx;
6050 Oid *sortOperators;
6051 Oid *collations;
6052 bool *nullsFirst;
6053
6054 /* Convert list-ish representation to arrays wanted by executor */
6055 numsortkeys = list_length(sortcls);
6056 sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
6057 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
6058 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
6059 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
6060
6061 numsortkeys = 0;
6062 foreach(l, sortcls)
6063 {
6064 SortGroupClause *sortcl = (SortGroupClause *) lfirst(l);
6065 TargetEntry *tle = get_sortgroupclause_tle(sortcl, sub_tlist);
6066
6067 sortColIdx[numsortkeys] = tle->resno;
6068 sortOperators[numsortkeys] = sortcl->sortop;
6069 collations[numsortkeys] = exprCollation((Node *) tle->expr);
6070 nullsFirst[numsortkeys] = sortcl->nulls_first;
6071 numsortkeys++;
6072 }
6073
6074 return make_sort(lefttree, numsortkeys,
6075 sortColIdx, sortOperators,
6076 collations, nullsFirst);
6077}
6078
6079/*
6080 * make_sort_from_groupcols
6081 * Create sort plan to sort based on grouping columns
6082 *
6083 * 'groupcls' is the list of SortGroupClauses
6084 * 'grpColIdx' gives the column numbers to use
6085 *
6086 * This might look like it could be merged with make_sort_from_sortclauses,
6087 * but presently we *must* use the grpColIdx[] array to locate sort columns,
6088 * because the child plan's tlist is not marked with ressortgroupref info
6089 * appropriate to the grouping node. So, only the sort ordering info
6090 * is used from the SortGroupClause entries.
6091 */
6092static Sort *
6093make_sort_from_groupcols(List *groupcls,
6094 AttrNumber *grpColIdx,
6095 Plan *lefttree)
6096{
6097 List *sub_tlist = lefttree->targetlist;
6098 ListCell *l;
6099 int numsortkeys;
6100 AttrNumber *sortColIdx;
6101 Oid *sortOperators;
6102 Oid *collations;
6103 bool *nullsFirst;
6104
6105 /* Convert list-ish representation to arrays wanted by executor */
6106 numsortkeys = list_length(groupcls);
6107 sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
6108 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
6109 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
6110 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
6111
6112 numsortkeys = 0;
6113 foreach(l, groupcls)
6114 {
6115 SortGroupClause *grpcl = (SortGroupClause *) lfirst(l);
6116 TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[numsortkeys]);
6117
6118 if (!tle)
6119 elog(ERROR, "could not retrieve tle for sort-from-groupcols");
6120
6121 sortColIdx[numsortkeys] = tle->resno;
6122 sortOperators[numsortkeys] = grpcl->sortop;
6123 collations[numsortkeys] = exprCollation((Node *) tle->expr);
6124 nullsFirst[numsortkeys] = grpcl->nulls_first;
6125 numsortkeys++;
6126 }
6127
6128 return make_sort(lefttree, numsortkeys,
6129 sortColIdx, sortOperators,
6130 collations, nullsFirst);
6131}
6132
6133static Material *
6134make_material(Plan *lefttree)
6135{
6136 Material *node = makeNode(Material);
6137 Plan *plan = &node->plan;
6138
6139 plan->targetlist = lefttree->targetlist;
6140 plan->qual = NIL;
6141 plan->lefttree = lefttree;
6142 plan->righttree = NULL;
6143
6144 return node;
6145}
6146
6147/*
6148 * materialize_finished_plan: stick a Material node atop a completed plan
6149 *
6150 * There are a couple of places where we want to attach a Material node
6151 * after completion of create_plan(), without any MaterialPath path.
6152 * Those places should probably be refactored someday to do this on the
6153 * Path representation, but it's not worth the trouble yet.
6154 */
6155Plan *
6156materialize_finished_plan(Plan *subplan)
6157{
6158 Plan *matplan;
6159 Path matpath; /* dummy for result of cost_material */
6160
6161 matplan = (Plan *) make_material(subplan);
6162
6163 /*
6164 * XXX horrid kluge: if there are any initPlans attached to the subplan,
6165 * move them up to the Material node, which is now effectively the top
6166 * plan node in its query level. This prevents failure in
6167 * SS_finalize_plan(), which see for comments. We don't bother adjusting
6168 * the subplan's cost estimate for this.
6169 */
6170 matplan->initPlan = subplan->initPlan;
6171 subplan->initPlan = NIL;
6172
6173 /* Set cost data */
6174 cost_material(&matpath,
6175 subplan->startup_cost,
6176 subplan->total_cost,
6177 subplan->plan_rows,
6178 subplan->plan_width);
6179 matplan->startup_cost = matpath.startup_cost;
6180 matplan->total_cost = matpath.total_cost;
6181 matplan->plan_rows = subplan->plan_rows;
6182 matplan->plan_width = subplan->plan_width;
6183 matplan->parallel_aware = false;
6184 matplan->parallel_safe = subplan->parallel_safe;
6185
6186 return matplan;
6187}
6188
6189Agg *
6190make_agg(List *tlist, List *qual,
6191 AggStrategy aggstrategy, AggSplit aggsplit,
6192 int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,
6193 List *groupingSets, List *chain,
6194 double dNumGroups, Plan *lefttree)
6195{
6196 Agg *node = makeNode(Agg);
6197 Plan *plan = &node->plan;
6198 long numGroups;
6199
6200 /* Reduce to long, but 'ware overflow! */
6201 numGroups = (long) Min(dNumGroups, (double) LONG_MAX);
6202
6203 node->aggstrategy = aggstrategy;
6204 node->aggsplit = aggsplit;
6205 node->numCols = numGroupCols;
6206 node->grpColIdx = grpColIdx;
6207 node->grpOperators = grpOperators;
6208 node->grpCollations = grpCollations;
6209 node->numGroups = numGroups;
6210 node->aggParams = NULL; /* SS_finalize_plan() will fill this */
6211 node->groupingSets = groupingSets;
6212 node->chain = chain;
6213
6214 plan->qual = qual;
6215 plan->targetlist = tlist;
6216 plan->lefttree = lefttree;
6217 plan->righttree = NULL;
6218
6219 return node;
6220}
6221
6222static WindowAgg *
6223make_windowagg(List *tlist, Index winref,
6224 int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,
6225 int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,
6226 int frameOptions, Node *startOffset, Node *endOffset,
6227 Oid startInRangeFunc, Oid endInRangeFunc,
6228 Oid inRangeColl, bool inRangeAsc, bool inRangeNullsFirst,
6229 Plan *lefttree)
6230{
6231 WindowAgg *node = makeNode(WindowAgg);
6232 Plan *plan = &node->plan;
6233
6234 node->winref = winref;
6235 node->partNumCols = partNumCols;
6236 node->partColIdx = partColIdx;
6237 node->partOperators = partOperators;
6238 node->partCollations = partCollations;
6239 node->ordNumCols = ordNumCols;
6240 node->ordColIdx = ordColIdx;
6241 node->ordOperators = ordOperators;
6242 node->ordCollations = ordCollations;
6243 node->frameOptions = frameOptions;
6244 node->startOffset = startOffset;
6245 node->endOffset = endOffset;
6246 node->startInRangeFunc = startInRangeFunc;
6247 node->endInRangeFunc = endInRangeFunc;
6248 node->inRangeColl = inRangeColl;
6249 node->inRangeAsc = inRangeAsc;
6250 node->inRangeNullsFirst = inRangeNullsFirst;
6251
6252 plan->targetlist = tlist;
6253 plan->lefttree = lefttree;
6254 plan->righttree = NULL;
6255 /* WindowAgg nodes never have a qual clause */
6256 plan->qual = NIL;
6257
6258 return node;
6259}
6260
6261static Group *
6262make_group(List *tlist,
6263 List *qual,
6264 int numGroupCols,
6265 AttrNumber *grpColIdx,
6266 Oid *grpOperators,
6267 Oid *grpCollations,
6268 Plan *lefttree)
6269{
6270 Group *node = makeNode(Group);
6271 Plan *plan = &node->plan;
6272
6273 node->numCols = numGroupCols;
6274 node->grpColIdx = grpColIdx;
6275 node->grpOperators = grpOperators;
6276 node->grpCollations = grpCollations;
6277
6278 plan->qual = qual;
6279 plan->targetlist = tlist;
6280 plan->lefttree = lefttree;
6281 plan->righttree = NULL;
6282
6283 return node;
6284}
6285
6286/*
6287 * distinctList is a list of SortGroupClauses, identifying the targetlist items
6288 * that should be considered by the Unique filter. The input path must
6289 * already be sorted accordingly.
6290 */
6291static Unique *
6292make_unique_from_sortclauses(Plan *lefttree, List *distinctList)
6293{
6294 Unique *node = makeNode(Unique);
6295 Plan *plan = &node->plan;
6296 int numCols = list_length(distinctList);
6297 int keyno = 0;
6298 AttrNumber *uniqColIdx;
6299 Oid *uniqOperators;
6300 Oid *uniqCollations;
6301 ListCell *slitem;
6302
6303 plan->targetlist = lefttree->targetlist;
6304 plan->qual = NIL;
6305 plan->lefttree = lefttree;
6306 plan->righttree = NULL;
6307
6308 /*
6309 * convert SortGroupClause list into arrays of attr indexes and equality
6310 * operators, as wanted by executor
6311 */
6312 Assert(numCols > 0);
6313 uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
6314 uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);
6315 uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);
6316
6317 foreach(slitem, distinctList)
6318 {
6319 SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
6320 TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
6321
6322 uniqColIdx[keyno] = tle->resno;
6323 uniqOperators[keyno] = sortcl->eqop;
6324 uniqCollations[keyno] = exprCollation((Node *) tle->expr);
6325 Assert(OidIsValid(uniqOperators[keyno]));
6326 keyno++;
6327 }
6328
6329 node->numCols = numCols;
6330 node->uniqColIdx = uniqColIdx;
6331 node->uniqOperators = uniqOperators;
6332 node->uniqCollations = uniqCollations;
6333
6334 return node;
6335}
6336
6337/*
6338 * as above, but use pathkeys to identify the sort columns and semantics
6339 */
6340static Unique *
6341make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols)
6342{
6343 Unique *node = makeNode(Unique);
6344 Plan *plan = &node->plan;
6345 int keyno = 0;
6346 AttrNumber *uniqColIdx;
6347 Oid *uniqOperators;
6348 Oid *uniqCollations;
6349 ListCell *lc;
6350
6351 plan->targetlist = lefttree->targetlist;
6352 plan->qual = NIL;
6353 plan->lefttree = lefttree;
6354 plan->righttree = NULL;
6355
6356 /*
6357 * Convert pathkeys list into arrays of attr indexes and equality
6358 * operators, as wanted by executor. This has a lot in common with
6359 * prepare_sort_from_pathkeys ... maybe unify sometime?
6360 */
6361 Assert(numCols >= 0 && numCols <= list_length(pathkeys));
6362 uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
6363 uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);
6364 uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);
6365
6366 foreach(lc, pathkeys)
6367 {
6368 PathKey *pathkey = (PathKey *) lfirst(lc);
6369 EquivalenceClass *ec = pathkey->pk_eclass;
6370 EquivalenceMember *em;
6371 TargetEntry *tle = NULL;
6372 Oid pk_datatype = InvalidOid;
6373 Oid eqop;
6374 ListCell *j;
6375
6376 /* Ignore pathkeys beyond the specified number of columns */
6377 if (keyno >= numCols)
6378 break;
6379
6380 if (ec->ec_has_volatile)
6381 {
6382 /*
6383 * If the pathkey's EquivalenceClass is volatile, then it must
6384 * have come from an ORDER BY clause, and we have to match it to
6385 * that same targetlist entry.
6386 */
6387 if (ec->ec_sortref == 0) /* can't happen */
6388 elog(ERROR, "volatile EquivalenceClass has no sortref");
6389 tle = get_sortgroupref_tle(ec->ec_sortref, plan->targetlist);
6390 Assert(tle);
6391 Assert(list_length(ec->ec_members) == 1);
6392 pk_datatype = ((EquivalenceMember *) linitial(ec->ec_members))->em_datatype;
6393 }
6394 else
6395 {
6396 /*
6397 * Otherwise, we can use any non-constant expression listed in the
6398 * pathkey's EquivalenceClass. For now, we take the first tlist
6399 * item found in the EC.
6400 */
6401 foreach(j, plan->targetlist)
6402 {
6403 tle = (TargetEntry *) lfirst(j);
6404 em = find_ec_member_for_tle(ec, tle, NULL);
6405 if (em)
6406 {
6407 /* found expr already in tlist */
6408 pk_datatype = em->em_datatype;
6409 break;
6410 }
6411 tle = NULL;
6412 }
6413 }
6414
6415 if (!tle)
6416 elog(ERROR, "could not find pathkey item to sort");
6417
6418 /*
6419 * Look up the correct equality operator from the PathKey's slightly
6420 * abstracted representation.
6421 */
6422 eqop = get_opfamily_member(pathkey->pk_opfamily,
6423 pk_datatype,
6424 pk_datatype,
6425 BTEqualStrategyNumber);
6426 if (!OidIsValid(eqop)) /* should not happen */
6427 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
6428 BTEqualStrategyNumber, pk_datatype, pk_datatype,
6429 pathkey->pk_opfamily);
6430
6431 uniqColIdx[keyno] = tle->resno;
6432 uniqOperators[keyno] = eqop;
6433 uniqCollations[keyno] = ec->ec_collation;
6434
6435 keyno++;
6436 }
6437
6438 node->numCols = numCols;
6439 node->uniqColIdx = uniqColIdx;
6440 node->uniqOperators = uniqOperators;
6441 node->uniqCollations = uniqCollations;
6442
6443 return node;
6444}
6445
6446static Gather *
6447make_gather(List *qptlist,
6448 List *qpqual,
6449 int nworkers,
6450 int rescan_param,
6451 bool single_copy,
6452 Plan *subplan)
6453{
6454 Gather *node = makeNode(Gather);
6455 Plan *plan = &node->plan;
6456
6457 plan->targetlist = qptlist;
6458 plan->qual = qpqual;
6459 plan->lefttree = subplan;
6460 plan->righttree = NULL;
6461 node->num_workers = nworkers;
6462 node->rescan_param = rescan_param;
6463 node->single_copy = single_copy;
6464 node->invisible = false;
6465 node->initParam = NULL;
6466
6467 return node;
6468}
6469
6470/*
6471 * distinctList is a list of SortGroupClauses, identifying the targetlist
6472 * items that should be considered by the SetOp filter. The input path must
6473 * already be sorted accordingly.
6474 */
6475static SetOp *
6476make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree,
6477 List *distinctList, AttrNumber flagColIdx, int firstFlag,
6478 long numGroups)
6479{
6480 SetOp *node = makeNode(SetOp);
6481 Plan *plan = &node->plan;
6482 int numCols = list_length(distinctList);
6483 int keyno = 0;
6484 AttrNumber *dupColIdx;
6485 Oid *dupOperators;
6486 Oid *dupCollations;
6487 ListCell *slitem;
6488
6489 plan->targetlist = lefttree->targetlist;
6490 plan->qual = NIL;
6491 plan->lefttree = lefttree;
6492 plan->righttree = NULL;
6493
6494 /*
6495 * convert SortGroupClause list into arrays of attr indexes and equality
6496 * operators, as wanted by executor
6497 */
6498 dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
6499 dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
6500 dupCollations = (Oid *) palloc(sizeof(Oid) * numCols);
6501
6502 foreach(slitem, distinctList)
6503 {
6504 SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
6505 TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
6506
6507 dupColIdx[keyno] = tle->resno;
6508 dupOperators[keyno] = sortcl->eqop;
6509 dupCollations[keyno] = exprCollation((Node *) tle->expr);
6510 Assert(OidIsValid(dupOperators[keyno]));
6511 keyno++;
6512 }
6513
6514 node->cmd = cmd;
6515 node->strategy = strategy;
6516 node->numCols = numCols;
6517 node->dupColIdx = dupColIdx;
6518 node->dupOperators = dupOperators;
6519 node->dupCollations = dupCollations;
6520 node->flagColIdx = flagColIdx;
6521 node->firstFlag = firstFlag;
6522 node->numGroups = numGroups;
6523
6524 return node;
6525}
6526
6527/*
6528 * make_lockrows
6529 * Build a LockRows plan node
6530 */
6531static LockRows *
6532make_lockrows(Plan *lefttree, List *rowMarks, int epqParam)
6533{
6534 LockRows *node = makeNode(LockRows);
6535 Plan *plan = &node->plan;
6536
6537 plan->targetlist = lefttree->targetlist;
6538 plan->qual = NIL;
6539 plan->lefttree = lefttree;
6540 plan->righttree = NULL;
6541
6542 node->rowMarks = rowMarks;
6543 node->epqParam = epqParam;
6544
6545 return node;
6546}
6547
6548/*
6549 * make_limit
6550 * Build a Limit plan node
6551 */
6552Limit *
6553make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount)
6554{
6555 Limit *node = makeNode(Limit);
6556 Plan *plan = &node->plan;
6557
6558 plan->targetlist = lefttree->targetlist;
6559 plan->qual = NIL;
6560 plan->lefttree = lefttree;
6561 plan->righttree = NULL;
6562
6563 node->limitOffset = limitOffset;
6564 node->limitCount = limitCount;
6565
6566 return node;
6567}
6568
6569/*
6570 * make_result
6571 * Build a Result plan node
6572 */
6573static Result *
6574make_result(List *tlist,
6575 Node *resconstantqual,
6576 Plan *subplan)
6577{
6578 Result *node = makeNode(Result);
6579 Plan *plan = &node->plan;
6580
6581 plan->targetlist = tlist;
6582 plan->qual = NIL;
6583 plan->lefttree = subplan;
6584 plan->righttree = NULL;
6585 node->resconstantqual = resconstantqual;
6586
6587 return node;
6588}
6589
6590/*
6591 * make_project_set
6592 * Build a ProjectSet plan node
6593 */
6594static ProjectSet *
6595make_project_set(List *tlist,
6596 Plan *subplan)
6597{
6598 ProjectSet *node = makeNode(ProjectSet);
6599 Plan *plan = &node->plan;
6600
6601 plan->targetlist = tlist;
6602 plan->qual = NIL;
6603 plan->lefttree = subplan;
6604 plan->righttree = NULL;
6605
6606 return node;
6607}
6608
6609/*
6610 * make_modifytable
6611 * Build a ModifyTable plan node
6612 */
6613static ModifyTable *
6614make_modifytable(PlannerInfo *root,
6615 CmdType operation, bool canSetTag,
6616 Index nominalRelation, Index rootRelation,
6617 bool partColsUpdated,
6618 List *resultRelations, List *subplans, List *subroots,
6619 List *withCheckOptionLists, List *returningLists,
6620 List *rowMarks, OnConflictExpr *onconflict, int epqParam)
6621{
6622 ModifyTable *node = makeNode(ModifyTable);
6623 List *fdw_private_list;
6624 Bitmapset *direct_modify_plans;
6625 ListCell *lc;
6626 ListCell *lc2;
6627 int i;
6628
6629 Assert(list_length(resultRelations) == list_length(subplans));
6630 Assert(list_length(resultRelations) == list_length(subroots));
6631 Assert(withCheckOptionLists == NIL ||
6632 list_length(resultRelations) == list_length(withCheckOptionLists));
6633 Assert(returningLists == NIL ||
6634 list_length(resultRelations) == list_length(returningLists));
6635
6636 node->plan.lefttree = NULL;
6637 node->plan.righttree = NULL;
6638 node->plan.qual = NIL;
6639 /* setrefs.c will fill in the targetlist, if needed */
6640 node->plan.targetlist = NIL;
6641
6642 node->operation = operation;
6643 node->canSetTag = canSetTag;
6644 node->nominalRelation = nominalRelation;
6645 node->rootRelation = rootRelation;
6646 node->partColsUpdated = partColsUpdated;
6647 node->resultRelations = resultRelations;
6648 node->resultRelIndex = -1; /* will be set correctly in setrefs.c */
6649 node->rootResultRelIndex = -1; /* will be set correctly in setrefs.c */
6650 node->plans = subplans;
6651 if (!onconflict)
6652 {
6653 node->onConflictAction = ONCONFLICT_NONE;
6654 node->onConflictSet = NIL;
6655 node->onConflictWhere = NULL;
6656 node->arbiterIndexes = NIL;
6657 node->exclRelRTI = 0;
6658 node->exclRelTlist = NIL;
6659 }
6660 else
6661 {
6662 node->onConflictAction = onconflict->action;
6663 node->onConflictSet = onconflict->onConflictSet;
6664 node->onConflictWhere = onconflict->onConflictWhere;
6665
6666 /*
6667 * If a set of unique index inference elements was provided (an
6668 * INSERT...ON CONFLICT "inference specification"), then infer
6669 * appropriate unique indexes (or throw an error if none are
6670 * available).
6671 */
6672 node->arbiterIndexes = infer_arbiter_indexes(root);
6673
6674 node->exclRelRTI = onconflict->exclRelIndex;
6675 node->exclRelTlist = onconflict->exclRelTlist;
6676 }
6677 node->withCheckOptionLists = withCheckOptionLists;
6678 node->returningLists = returningLists;
6679 node->rowMarks = rowMarks;
6680 node->epqParam = epqParam;
6681
6682 /*
6683 * For each result relation that is a foreign table, allow the FDW to
6684 * construct private plan data, and accumulate it all into a list.
6685 */
6686 fdw_private_list = NIL;
6687 direct_modify_plans = NULL;
6688 i = 0;
6689 forboth(lc, resultRelations, lc2, subroots)
6690 {
6691 Index rti = lfirst_int(lc);
6692 PlannerInfo *subroot = lfirst_node(PlannerInfo, lc2);
6693 FdwRoutine *fdwroutine;
6694 List *fdw_private;
6695 bool direct_modify;
6696
6697 /*
6698 * If possible, we want to get the FdwRoutine from our RelOptInfo for
6699 * the table. But sometimes we don't have a RelOptInfo and must get
6700 * it the hard way. (In INSERT, the target relation is not scanned,
6701 * so it's not a baserel; and there are also corner cases for
6702 * updatable views where the target rel isn't a baserel.)
6703 */
6704 if (rti < subroot->simple_rel_array_size &&
6705 subroot->simple_rel_array[rti] != NULL)
6706 {
6707 RelOptInfo *resultRel = subroot->simple_rel_array[rti];
6708
6709 fdwroutine = resultRel->fdwroutine;
6710 }
6711 else
6712 {
6713 RangeTblEntry *rte = planner_rt_fetch(rti, subroot);
6714
6715 Assert(rte->rtekind == RTE_RELATION);
6716 if (rte->relkind == RELKIND_FOREIGN_TABLE)
6717 fdwroutine = GetFdwRoutineByRelId(rte->relid);
6718 else
6719 fdwroutine = NULL;
6720 }
6721
6722 /*
6723 * Try to modify the foreign table directly if (1) the FDW provides
6724 * callback functions needed for that and (2) there are no local
6725 * structures that need to be run for each modified row: row-level
6726 * triggers on the foreign table, stored generated columns, WITH CHECK
6727 * OPTIONs from parent views.
6728 */
6729 direct_modify = false;
6730 if (fdwroutine != NULL &&
6731 fdwroutine->PlanDirectModify != NULL &&
6732 fdwroutine->BeginDirectModify != NULL &&
6733 fdwroutine->IterateDirectModify != NULL &&
6734 fdwroutine->EndDirectModify != NULL &&
6735 withCheckOptionLists == NIL &&
6736 !has_row_triggers(subroot, rti, operation) &&
6737 !has_stored_generated_columns(subroot, rti))
6738 direct_modify = fdwroutine->PlanDirectModify(subroot, node, rti, i);
6739 if (direct_modify)
6740 direct_modify_plans = bms_add_member(direct_modify_plans, i);
6741
6742 if (!direct_modify &&
6743 fdwroutine != NULL &&
6744 fdwroutine->PlanForeignModify != NULL)
6745 fdw_private = fdwroutine->PlanForeignModify(subroot, node, rti, i);
6746 else
6747 fdw_private = NIL;
6748 fdw_private_list = lappend(fdw_private_list, fdw_private);
6749 i++;
6750 }
6751 node->fdwPrivLists = fdw_private_list;
6752 node->fdwDirectModifyPlans = direct_modify_plans;
6753
6754 return node;
6755}
6756
6757/*
6758 * is_projection_capable_path
6759 * Check whether a given Path node is able to do projection.
6760 */
6761bool
6762is_projection_capable_path(Path *path)
6763{
6764 /* Most plan types can project, so just list the ones that can't */
6765 switch (path->pathtype)
6766 {
6767 case T_Hash:
6768 case T_Material:
6769 case T_Sort:
6770 case T_Unique:
6771 case T_SetOp:
6772 case T_LockRows:
6773 case T_Limit:
6774 case T_ModifyTable:
6775 case T_MergeAppend:
6776 case T_RecursiveUnion:
6777 return false;
6778 case T_Append:
6779
6780 /*
6781 * Append can't project, but if an AppendPath is being used to
6782 * represent a dummy path, what will actually be generated is a
6783 * Result which can project.
6784 */
6785 return IS_DUMMY_APPEND(path);
6786 case T_ProjectSet:
6787
6788 /*
6789 * Although ProjectSet certainly projects, say "no" because we
6790 * don't want the planner to randomly replace its tlist with
6791 * something else; the SRFs have to stay at top level. This might
6792 * get relaxed later.
6793 */
6794 return false;
6795 default:
6796 break;
6797 }
6798 return true;
6799}
6800
6801/*
6802 * is_projection_capable_plan
6803 * Check whether a given Plan node is able to do projection.
6804 */
6805bool
6806is_projection_capable_plan(Plan *plan)
6807{
6808 /* Most plan types can project, so just list the ones that can't */
6809 switch (nodeTag(plan))
6810 {
6811 case T_Hash:
6812 case T_Material:
6813 case T_Sort:
6814 case T_Unique:
6815 case T_SetOp:
6816 case T_LockRows:
6817 case T_Limit:
6818 case T_ModifyTable:
6819 case T_Append:
6820 case T_MergeAppend:
6821 case T_RecursiveUnion:
6822 return false;
6823 case T_ProjectSet:
6824
6825 /*
6826 * Although ProjectSet certainly projects, say "no" because we
6827 * don't want the planner to randomly replace its tlist with
6828 * something else; the SRFs have to stay at top level. This might
6829 * get relaxed later.
6830 */
6831 return false;
6832 default:
6833 break;
6834 }
6835 return true;
6836}
6837