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