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