1 /*-------------------------------------------------------------------------
2  *
3  * relnode.c
4  *	  Relation-node lookup/construction routines
5  *
6  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/backend/optimizer/util/relnode.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "miscadmin.h"
18 #include "optimizer/clauses.h"
19 #include "optimizer/cost.h"
20 #include "optimizer/pathnode.h"
21 #include "optimizer/paths.h"
22 #include "optimizer/placeholder.h"
23 #include "optimizer/plancat.h"
24 #include "optimizer/restrictinfo.h"
25 #include "optimizer/tlist.h"
26 #include "utils/hsearch.h"
27 
28 
29 typedef struct JoinHashEntry
30 {
31 	Relids		join_relids;	/* hash key --- MUST BE FIRST */
32 	RelOptInfo *join_rel;
33 } JoinHashEntry;
34 
35 static void build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel,
36 					RelOptInfo *input_rel);
37 static List *build_joinrel_restrictlist(PlannerInfo *root,
38 						   RelOptInfo *joinrel,
39 						   RelOptInfo *outer_rel,
40 						   RelOptInfo *inner_rel);
41 static void build_joinrel_joinlist(RelOptInfo *joinrel,
42 					   RelOptInfo *outer_rel,
43 					   RelOptInfo *inner_rel);
44 static List *subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
45 							  List *joininfo_list,
46 							  List *new_restrictlist);
47 static List *subbuild_joinrel_joinlist(RelOptInfo *joinrel,
48 						  List *joininfo_list,
49 						  List *new_joininfo);
50 
51 
52 /*
53  * setup_simple_rel_arrays
54  *	  Prepare the arrays we use for quickly accessing base relations.
55  */
56 void
setup_simple_rel_arrays(PlannerInfo * root)57 setup_simple_rel_arrays(PlannerInfo *root)
58 {
59 	Index		rti;
60 	ListCell   *lc;
61 
62 	/* Arrays are accessed using RT indexes (1..N) */
63 	root->simple_rel_array_size = list_length(root->parse->rtable) + 1;
64 
65 	/* simple_rel_array is initialized to all NULLs */
66 	root->simple_rel_array = (RelOptInfo **)
67 		palloc0(root->simple_rel_array_size * sizeof(RelOptInfo *));
68 
69 	/* simple_rte_array is an array equivalent of the rtable list */
70 	root->simple_rte_array = (RangeTblEntry **)
71 		palloc0(root->simple_rel_array_size * sizeof(RangeTblEntry *));
72 	rti = 1;
73 	foreach(lc, root->parse->rtable)
74 	{
75 		RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
76 
77 		root->simple_rte_array[rti++] = rte;
78 	}
79 }
80 
81 /*
82  * build_simple_rel
83  *	  Construct a new RelOptInfo for a base relation or 'other' relation.
84  */
85 RelOptInfo *
build_simple_rel(PlannerInfo * root,int relid,RelOptKind reloptkind)86 build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind)
87 {
88 	RelOptInfo *rel;
89 	RangeTblEntry *rte;
90 
91 	/* Rel should not exist already */
92 	Assert(relid > 0 && relid < root->simple_rel_array_size);
93 	if (root->simple_rel_array[relid] != NULL)
94 		elog(ERROR, "rel %d already exists", relid);
95 
96 	/* Fetch RTE for relation */
97 	rte = root->simple_rte_array[relid];
98 	Assert(rte != NULL);
99 
100 	rel = makeNode(RelOptInfo);
101 	rel->reloptkind = reloptkind;
102 	rel->relids = bms_make_singleton(relid);
103 	rel->rows = 0;
104 	/* cheap startup cost is interesting iff not all tuples to be retrieved */
105 	rel->consider_startup = (root->tuple_fraction > 0);
106 	rel->consider_param_startup = false;		/* might get changed later */
107 	rel->consider_parallel = false;		/* might get changed later */
108 	rel->reltarget = create_empty_pathtarget();
109 	rel->pathlist = NIL;
110 	rel->ppilist = NIL;
111 	rel->partial_pathlist = NIL;
112 	rel->cheapest_startup_path = NULL;
113 	rel->cheapest_total_path = NULL;
114 	rel->cheapest_unique_path = NULL;
115 	rel->cheapest_parameterized_paths = NIL;
116 	rel->direct_lateral_relids = NULL;
117 	rel->lateral_relids = NULL;
118 	rel->relid = relid;
119 	rel->rtekind = rte->rtekind;
120 	/* min_attr, max_attr, attr_needed, attr_widths are set below */
121 	rel->lateral_vars = NIL;
122 	rel->lateral_referencers = NULL;
123 	rel->indexlist = NIL;
124 	rel->pages = 0;
125 	rel->tuples = 0;
126 	rel->allvisfrac = 0;
127 	rel->subroot = NULL;
128 	rel->subplan_params = NIL;
129 	rel->rel_parallel_workers = -1;		/* set up in get_relation_info */
130 	rel->serverid = InvalidOid;
131 	rel->userid = rte->checkAsUser;
132 	rel->useridiscurrent = false;
133 	rel->fdwroutine = NULL;
134 	rel->fdw_private = NULL;
135 	rel->baserestrictinfo = NIL;
136 	rel->baserestrictcost.startup = 0;
137 	rel->baserestrictcost.per_tuple = 0;
138 	rel->joininfo = NIL;
139 	rel->has_eclass_joins = false;
140 
141 	/* Check type of rtable entry */
142 	switch (rte->rtekind)
143 	{
144 		case RTE_RELATION:
145 			/* Table --- retrieve statistics from the system catalogs */
146 			get_relation_info(root, rte->relid, rte->inh, rel);
147 			break;
148 		case RTE_SUBQUERY:
149 		case RTE_FUNCTION:
150 		case RTE_VALUES:
151 		case RTE_CTE:
152 
153 			/*
154 			 * Subquery, function, or values list --- set up attr range and
155 			 * arrays
156 			 *
157 			 * Note: 0 is included in range to support whole-row Vars
158 			 */
159 			rel->min_attr = 0;
160 			rel->max_attr = list_length(rte->eref->colnames);
161 			rel->attr_needed = (Relids *)
162 				palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(Relids));
163 			rel->attr_widths = (int32 *)
164 				palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(int32));
165 			break;
166 		default:
167 			elog(ERROR, "unrecognized RTE kind: %d",
168 				 (int) rte->rtekind);
169 			break;
170 	}
171 
172 	/* Save the finished struct in the query's simple_rel_array */
173 	root->simple_rel_array[relid] = rel;
174 
175 	/*
176 	 * If this rel is an appendrel parent, recurse to build "other rel"
177 	 * RelOptInfos for its children.  They are "other rels" because they are
178 	 * not in the main join tree, but we will need RelOptInfos to plan access
179 	 * to them.
180 	 */
181 	if (rte->inh)
182 	{
183 		ListCell   *l;
184 
185 		foreach(l, root->append_rel_list)
186 		{
187 			AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
188 
189 			/* append_rel_list contains all append rels; ignore others */
190 			if (appinfo->parent_relid != relid)
191 				continue;
192 
193 			(void) build_simple_rel(root, appinfo->child_relid,
194 									RELOPT_OTHER_MEMBER_REL);
195 		}
196 	}
197 
198 	return rel;
199 }
200 
201 /*
202  * find_base_rel
203  *	  Find a base or other relation entry, which must already exist.
204  */
205 RelOptInfo *
find_base_rel(PlannerInfo * root,int relid)206 find_base_rel(PlannerInfo *root, int relid)
207 {
208 	RelOptInfo *rel;
209 
210 	Assert(relid > 0);
211 
212 	if (relid < root->simple_rel_array_size)
213 	{
214 		rel = root->simple_rel_array[relid];
215 		if (rel)
216 			return rel;
217 	}
218 
219 	elog(ERROR, "no relation entry for relid %d", relid);
220 
221 	return NULL;				/* keep compiler quiet */
222 }
223 
224 /*
225  * build_join_rel_hash
226  *	  Construct the auxiliary hash table for join relations.
227  */
228 static void
build_join_rel_hash(PlannerInfo * root)229 build_join_rel_hash(PlannerInfo *root)
230 {
231 	HTAB	   *hashtab;
232 	HASHCTL		hash_ctl;
233 	ListCell   *l;
234 
235 	/* Create the hash table */
236 	MemSet(&hash_ctl, 0, sizeof(hash_ctl));
237 	hash_ctl.keysize = sizeof(Relids);
238 	hash_ctl.entrysize = sizeof(JoinHashEntry);
239 	hash_ctl.hash = bitmap_hash;
240 	hash_ctl.match = bitmap_match;
241 	hash_ctl.hcxt = CurrentMemoryContext;
242 	hashtab = hash_create("JoinRelHashTable",
243 						  256L,
244 						  &hash_ctl,
245 					HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_CONTEXT);
246 
247 	/* Insert all the already-existing joinrels */
248 	foreach(l, root->join_rel_list)
249 	{
250 		RelOptInfo *rel = (RelOptInfo *) lfirst(l);
251 		JoinHashEntry *hentry;
252 		bool		found;
253 
254 		hentry = (JoinHashEntry *) hash_search(hashtab,
255 											   &(rel->relids),
256 											   HASH_ENTER,
257 											   &found);
258 		Assert(!found);
259 		hentry->join_rel = rel;
260 	}
261 
262 	root->join_rel_hash = hashtab;
263 }
264 
265 /*
266  * find_join_rel
267  *	  Returns relation entry corresponding to 'relids' (a set of RT indexes),
268  *	  or NULL if none exists.  This is for join relations.
269  */
270 RelOptInfo *
find_join_rel(PlannerInfo * root,Relids relids)271 find_join_rel(PlannerInfo *root, Relids relids)
272 {
273 	/*
274 	 * Switch to using hash lookup when list grows "too long".  The threshold
275 	 * is arbitrary and is known only here.
276 	 */
277 	if (!root->join_rel_hash && list_length(root->join_rel_list) > 32)
278 		build_join_rel_hash(root);
279 
280 	/*
281 	 * Use either hashtable lookup or linear search, as appropriate.
282 	 *
283 	 * Note: the seemingly redundant hashkey variable is used to avoid taking
284 	 * the address of relids; unless the compiler is exceedingly smart, doing
285 	 * so would force relids out of a register and thus probably slow down the
286 	 * list-search case.
287 	 */
288 	if (root->join_rel_hash)
289 	{
290 		Relids		hashkey = relids;
291 		JoinHashEntry *hentry;
292 
293 		hentry = (JoinHashEntry *) hash_search(root->join_rel_hash,
294 											   &hashkey,
295 											   HASH_FIND,
296 											   NULL);
297 		if (hentry)
298 			return hentry->join_rel;
299 	}
300 	else
301 	{
302 		ListCell   *l;
303 
304 		foreach(l, root->join_rel_list)
305 		{
306 			RelOptInfo *rel = (RelOptInfo *) lfirst(l);
307 
308 			if (bms_equal(rel->relids, relids))
309 				return rel;
310 		}
311 	}
312 
313 	return NULL;
314 }
315 
316 /*
317  * build_join_rel
318  *	  Returns relation entry corresponding to the union of two given rels,
319  *	  creating a new relation entry if none already exists.
320  *
321  * 'joinrelids' is the Relids set that uniquely identifies the join
322  * 'outer_rel' and 'inner_rel' are relation nodes for the relations to be
323  *		joined
324  * 'sjinfo': join context info
325  * 'restrictlist_ptr': result variable.  If not NULL, *restrictlist_ptr
326  *		receives the list of RestrictInfo nodes that apply to this
327  *		particular pair of joinable relations.
328  *
329  * restrictlist_ptr makes the routine's API a little grotty, but it saves
330  * duplicated calculation of the restrictlist...
331  */
332 RelOptInfo *
build_join_rel(PlannerInfo * root,Relids joinrelids,RelOptInfo * outer_rel,RelOptInfo * inner_rel,SpecialJoinInfo * sjinfo,List ** restrictlist_ptr)333 build_join_rel(PlannerInfo *root,
334 			   Relids joinrelids,
335 			   RelOptInfo *outer_rel,
336 			   RelOptInfo *inner_rel,
337 			   SpecialJoinInfo *sjinfo,
338 			   List **restrictlist_ptr)
339 {
340 	RelOptInfo *joinrel;
341 	List	   *restrictlist;
342 
343 	/*
344 	 * See if we already have a joinrel for this set of base rels.
345 	 */
346 	joinrel = find_join_rel(root, joinrelids);
347 
348 	if (joinrel)
349 	{
350 		/*
351 		 * Yes, so we only need to figure the restrictlist for this particular
352 		 * pair of component relations.
353 		 */
354 		if (restrictlist_ptr)
355 			*restrictlist_ptr = build_joinrel_restrictlist(root,
356 														   joinrel,
357 														   outer_rel,
358 														   inner_rel);
359 		return joinrel;
360 	}
361 
362 	/*
363 	 * Nope, so make one.
364 	 */
365 	joinrel = makeNode(RelOptInfo);
366 	joinrel->reloptkind = RELOPT_JOINREL;
367 	joinrel->relids = bms_copy(joinrelids);
368 	joinrel->rows = 0;
369 	/* cheap startup cost is interesting iff not all tuples to be retrieved */
370 	joinrel->consider_startup = (root->tuple_fraction > 0);
371 	joinrel->consider_param_startup = false;
372 	joinrel->consider_parallel = false;
373 	joinrel->reltarget = create_empty_pathtarget();
374 	joinrel->pathlist = NIL;
375 	joinrel->ppilist = NIL;
376 	joinrel->partial_pathlist = NIL;
377 	joinrel->cheapest_startup_path = NULL;
378 	joinrel->cheapest_total_path = NULL;
379 	joinrel->cheapest_unique_path = NULL;
380 	joinrel->cheapest_parameterized_paths = NIL;
381 	/* init direct_lateral_relids from children; we'll finish it up below */
382 	joinrel->direct_lateral_relids =
383 		bms_union(outer_rel->direct_lateral_relids,
384 				  inner_rel->direct_lateral_relids);
385 	joinrel->lateral_relids = min_join_parameterization(root, joinrel->relids,
386 														outer_rel, inner_rel);
387 	joinrel->relid = 0;			/* indicates not a baserel */
388 	joinrel->rtekind = RTE_JOIN;
389 	joinrel->min_attr = 0;
390 	joinrel->max_attr = 0;
391 	joinrel->attr_needed = NULL;
392 	joinrel->attr_widths = NULL;
393 	joinrel->lateral_vars = NIL;
394 	joinrel->lateral_referencers = NULL;
395 	joinrel->indexlist = NIL;
396 	joinrel->pages = 0;
397 	joinrel->tuples = 0;
398 	joinrel->allvisfrac = 0;
399 	joinrel->subroot = NULL;
400 	joinrel->subplan_params = NIL;
401 	joinrel->rel_parallel_workers = -1;
402 	joinrel->serverid = InvalidOid;
403 	joinrel->userid = InvalidOid;
404 	joinrel->useridiscurrent = false;
405 	joinrel->fdwroutine = NULL;
406 	joinrel->fdw_private = NULL;
407 	joinrel->baserestrictinfo = NIL;
408 	joinrel->baserestrictcost.startup = 0;
409 	joinrel->baserestrictcost.per_tuple = 0;
410 	joinrel->joininfo = NIL;
411 	joinrel->has_eclass_joins = false;
412 
413 	/*
414 	 * Set up foreign-join fields if outer and inner relation are foreign
415 	 * tables (or joins) belonging to the same server and assigned to the same
416 	 * user to check access permissions as.  In addition to an exact match of
417 	 * userid, we allow the case where one side has zero userid (implying
418 	 * current user) and the other side has explicit userid that happens to
419 	 * equal the current user; but in that case, pushdown of the join is only
420 	 * valid for the current user.  The useridiscurrent field records whether
421 	 * we had to make such an assumption for this join or any sub-join.
422 	 *
423 	 * Otherwise these fields are left invalid, so GetForeignJoinPaths will
424 	 * not be called for the join relation.
425 	 */
426 	if (OidIsValid(outer_rel->serverid) &&
427 		inner_rel->serverid == outer_rel->serverid)
428 	{
429 		if (inner_rel->userid == outer_rel->userid)
430 		{
431 			joinrel->serverid = outer_rel->serverid;
432 			joinrel->userid = outer_rel->userid;
433 			joinrel->useridiscurrent = outer_rel->useridiscurrent || inner_rel->useridiscurrent;
434 			joinrel->fdwroutine = outer_rel->fdwroutine;
435 		}
436 		else if (!OidIsValid(inner_rel->userid) &&
437 				 outer_rel->userid == GetUserId())
438 		{
439 			joinrel->serverid = outer_rel->serverid;
440 			joinrel->userid = outer_rel->userid;
441 			joinrel->useridiscurrent = true;
442 			joinrel->fdwroutine = outer_rel->fdwroutine;
443 		}
444 		else if (!OidIsValid(outer_rel->userid) &&
445 				 inner_rel->userid == GetUserId())
446 		{
447 			joinrel->serverid = outer_rel->serverid;
448 			joinrel->userid = inner_rel->userid;
449 			joinrel->useridiscurrent = true;
450 			joinrel->fdwroutine = outer_rel->fdwroutine;
451 		}
452 	}
453 
454 	/*
455 	 * Create a new tlist containing just the vars that need to be output from
456 	 * this join (ie, are needed for higher joinclauses or final output).
457 	 *
458 	 * NOTE: the tlist order for a join rel will depend on which pair of outer
459 	 * and inner rels we first try to build it from.  But the contents should
460 	 * be the same regardless.
461 	 */
462 	build_joinrel_tlist(root, joinrel, outer_rel);
463 	build_joinrel_tlist(root, joinrel, inner_rel);
464 	add_placeholders_to_joinrel(root, joinrel, outer_rel, inner_rel);
465 
466 	/*
467 	 * add_placeholders_to_joinrel also took care of adding the ph_lateral
468 	 * sets of any PlaceHolderVars computed here to direct_lateral_relids, so
469 	 * now we can finish computing that.  This is much like the computation of
470 	 * the transitively-closed lateral_relids in min_join_parameterization,
471 	 * except that here we *do* have to consider the added PHVs.
472 	 */
473 	joinrel->direct_lateral_relids =
474 		bms_del_members(joinrel->direct_lateral_relids, joinrel->relids);
475 	if (bms_is_empty(joinrel->direct_lateral_relids))
476 		joinrel->direct_lateral_relids = NULL;
477 
478 	/*
479 	 * Construct restrict and join clause lists for the new joinrel. (The
480 	 * caller might or might not need the restrictlist, but I need it anyway
481 	 * for set_joinrel_size_estimates().)
482 	 */
483 	restrictlist = build_joinrel_restrictlist(root, joinrel,
484 											  outer_rel, inner_rel);
485 	if (restrictlist_ptr)
486 		*restrictlist_ptr = restrictlist;
487 	build_joinrel_joinlist(joinrel, outer_rel, inner_rel);
488 
489 	/*
490 	 * This is also the right place to check whether the joinrel has any
491 	 * pending EquivalenceClass joins.
492 	 */
493 	joinrel->has_eclass_joins = has_relevant_eclass_joinclause(root, joinrel);
494 
495 	/*
496 	 * Set estimates of the joinrel's size.
497 	 */
498 	set_joinrel_size_estimates(root, joinrel, outer_rel, inner_rel,
499 							   sjinfo, restrictlist);
500 
501 	/*
502 	 * Set the consider_parallel flag if this joinrel could potentially be
503 	 * scanned within a parallel worker.  If this flag is false for either
504 	 * inner_rel or outer_rel, then it must be false for the joinrel also.
505 	 * Even if both are true, there might be parallel-restricted expressions
506 	 * in the targetlist or quals.
507 	 *
508 	 * Note that if there are more than two rels in this relation, they could
509 	 * be divided between inner_rel and outer_rel in any arbitrary way.  We
510 	 * assume this doesn't matter, because we should hit all the same baserels
511 	 * and joinclauses while building up to this joinrel no matter which we
512 	 * take; therefore, we should make the same decision here however we get
513 	 * here.
514 	 */
515 	if (inner_rel->consider_parallel && outer_rel->consider_parallel &&
516 		!has_parallel_hazard((Node *) restrictlist, false) &&
517 		!has_parallel_hazard((Node *) joinrel->reltarget->exprs, false))
518 		joinrel->consider_parallel = true;
519 
520 	/*
521 	 * Add the joinrel to the query's joinrel list, and store it into the
522 	 * auxiliary hashtable if there is one.  NB: GEQO requires us to append
523 	 * the new joinrel to the end of the list!
524 	 */
525 	root->join_rel_list = lappend(root->join_rel_list, joinrel);
526 
527 	if (root->join_rel_hash)
528 	{
529 		JoinHashEntry *hentry;
530 		bool		found;
531 
532 		hentry = (JoinHashEntry *) hash_search(root->join_rel_hash,
533 											   &(joinrel->relids),
534 											   HASH_ENTER,
535 											   &found);
536 		Assert(!found);
537 		hentry->join_rel = joinrel;
538 	}
539 
540 	/*
541 	 * Also, if dynamic-programming join search is active, add the new joinrel
542 	 * to the appropriate sublist.  Note: you might think the Assert on number
543 	 * of members should be for equality, but some of the level 1 rels might
544 	 * have been joinrels already, so we can only assert <=.
545 	 */
546 	if (root->join_rel_level)
547 	{
548 		Assert(root->join_cur_level > 0);
549 		Assert(root->join_cur_level <= bms_num_members(joinrel->relids));
550 		root->join_rel_level[root->join_cur_level] =
551 			lappend(root->join_rel_level[root->join_cur_level], joinrel);
552 	}
553 
554 	return joinrel;
555 }
556 
557 /*
558  * min_join_parameterization
559  *
560  * Determine the minimum possible parameterization of a joinrel, that is, the
561  * set of other rels it contains LATERAL references to.  We save this value in
562  * the join's RelOptInfo.  This function is split out of build_join_rel()
563  * because join_is_legal() needs the value to check a prospective join.
564  */
565 Relids
min_join_parameterization(PlannerInfo * root,Relids joinrelids,RelOptInfo * outer_rel,RelOptInfo * inner_rel)566 min_join_parameterization(PlannerInfo *root,
567 						  Relids joinrelids,
568 						  RelOptInfo *outer_rel,
569 						  RelOptInfo *inner_rel)
570 {
571 	Relids		result;
572 
573 	/*
574 	 * Basically we just need the union of the inputs' lateral_relids, less
575 	 * whatever is already in the join.
576 	 *
577 	 * It's not immediately obvious that this is a valid way to compute the
578 	 * result, because it might seem that we're ignoring possible lateral refs
579 	 * of PlaceHolderVars that are due to be computed at the join but not in
580 	 * either input.  However, because create_lateral_join_info() already
581 	 * charged all such PHV refs to each member baserel of the join, they'll
582 	 * be accounted for already in the inputs' lateral_relids.  Likewise, we
583 	 * do not need to worry about doing transitive closure here, because that
584 	 * was already accounted for in the original baserel lateral_relids.
585 	 */
586 	result = bms_union(outer_rel->lateral_relids, inner_rel->lateral_relids);
587 	result = bms_del_members(result, joinrelids);
588 
589 	/* Maintain invariant that result is exactly NULL if empty */
590 	if (bms_is_empty(result))
591 		result = NULL;
592 
593 	return result;
594 }
595 
596 /*
597  * build_joinrel_tlist
598  *	  Builds a join relation's target list from an input relation.
599  *	  (This is invoked twice to handle the two input relations.)
600  *
601  * The join's targetlist includes all Vars of its member relations that
602  * will still be needed above the join.  This subroutine adds all such
603  * Vars from the specified input rel's tlist to the join rel's tlist.
604  *
605  * We also compute the expected width of the join's output, making use
606  * of data that was cached at the baserel level by set_rel_width().
607  */
608 static void
build_joinrel_tlist(PlannerInfo * root,RelOptInfo * joinrel,RelOptInfo * input_rel)609 build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel,
610 					RelOptInfo *input_rel)
611 {
612 	Relids		relids = joinrel->relids;
613 	ListCell   *vars;
614 
615 	foreach(vars, input_rel->reltarget->exprs)
616 	{
617 		Var		   *var = (Var *) lfirst(vars);
618 		RelOptInfo *baserel;
619 		int			ndx;
620 
621 		/*
622 		 * Ignore PlaceHolderVars in the input tlists; we'll make our own
623 		 * decisions about whether to copy them.
624 		 */
625 		if (IsA(var, PlaceHolderVar))
626 			continue;
627 
628 		/*
629 		 * Otherwise, anything in a baserel or joinrel targetlist ought to be
630 		 * a Var.  (More general cases can only appear in appendrel child
631 		 * rels, which will never be seen here.)
632 		 */
633 		if (!IsA(var, Var))
634 			elog(ERROR, "unexpected node type in rel targetlist: %d",
635 				 (int) nodeTag(var));
636 
637 		/* Get the Var's original base rel */
638 		baserel = find_base_rel(root, var->varno);
639 
640 		/* Is it still needed above this joinrel? */
641 		ndx = var->varattno - baserel->min_attr;
642 		if (bms_nonempty_difference(baserel->attr_needed[ndx], relids))
643 		{
644 			/* Yup, add it to the output */
645 			joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, var);
646 			/* Vars have cost zero, so no need to adjust reltarget->cost */
647 			joinrel->reltarget->width += baserel->attr_widths[ndx];
648 		}
649 	}
650 }
651 
652 /*
653  * build_joinrel_restrictlist
654  * build_joinrel_joinlist
655  *	  These routines build lists of restriction and join clauses for a
656  *	  join relation from the joininfo lists of the relations it joins.
657  *
658  *	  These routines are separate because the restriction list must be
659  *	  built afresh for each pair of input sub-relations we consider, whereas
660  *	  the join list need only be computed once for any join RelOptInfo.
661  *	  The join list is fully determined by the set of rels making up the
662  *	  joinrel, so we should get the same results (up to ordering) from any
663  *	  candidate pair of sub-relations.  But the restriction list is whatever
664  *	  is not handled in the sub-relations, so it depends on which
665  *	  sub-relations are considered.
666  *
667  *	  If a join clause from an input relation refers to base rels still not
668  *	  present in the joinrel, then it is still a join clause for the joinrel;
669  *	  we put it into the joininfo list for the joinrel.  Otherwise,
670  *	  the clause is now a restrict clause for the joined relation, and we
671  *	  return it to the caller of build_joinrel_restrictlist() to be stored in
672  *	  join paths made from this pair of sub-relations.  (It will not need to
673  *	  be considered further up the join tree.)
674  *
675  *	  In many cases we will find the same RestrictInfos in both input
676  *	  relations' joinlists, so be careful to eliminate duplicates.
677  *	  Pointer equality should be a sufficient test for dups, since all
678  *	  the various joinlist entries ultimately refer to RestrictInfos
679  *	  pushed into them by distribute_restrictinfo_to_rels().
680  *
681  * 'joinrel' is a join relation node
682  * 'outer_rel' and 'inner_rel' are a pair of relations that can be joined
683  *		to form joinrel.
684  *
685  * build_joinrel_restrictlist() returns a list of relevant restrictinfos,
686  * whereas build_joinrel_joinlist() stores its results in the joinrel's
687  * joininfo list.  One or the other must accept each given clause!
688  *
689  * NB: Formerly, we made deep(!) copies of each input RestrictInfo to pass
690  * up to the join relation.  I believe this is no longer necessary, because
691  * RestrictInfo nodes are no longer context-dependent.  Instead, just include
692  * the original nodes in the lists made for the join relation.
693  */
694 static List *
build_joinrel_restrictlist(PlannerInfo * root,RelOptInfo * joinrel,RelOptInfo * outer_rel,RelOptInfo * inner_rel)695 build_joinrel_restrictlist(PlannerInfo *root,
696 						   RelOptInfo *joinrel,
697 						   RelOptInfo *outer_rel,
698 						   RelOptInfo *inner_rel)
699 {
700 	List	   *result;
701 
702 	/*
703 	 * Collect all the clauses that syntactically belong at this level,
704 	 * eliminating any duplicates (important since we will see many of the
705 	 * same clauses arriving from both input relations).
706 	 */
707 	result = subbuild_joinrel_restrictlist(joinrel, outer_rel->joininfo, NIL);
708 	result = subbuild_joinrel_restrictlist(joinrel, inner_rel->joininfo, result);
709 
710 	/*
711 	 * Add on any clauses derived from EquivalenceClasses.  These cannot be
712 	 * redundant with the clauses in the joininfo lists, so don't bother
713 	 * checking.
714 	 */
715 	result = list_concat(result,
716 						 generate_join_implied_equalities(root,
717 														  joinrel->relids,
718 														  outer_rel->relids,
719 														  inner_rel));
720 
721 	return result;
722 }
723 
724 static void
build_joinrel_joinlist(RelOptInfo * joinrel,RelOptInfo * outer_rel,RelOptInfo * inner_rel)725 build_joinrel_joinlist(RelOptInfo *joinrel,
726 					   RelOptInfo *outer_rel,
727 					   RelOptInfo *inner_rel)
728 {
729 	List	   *result;
730 
731 	/*
732 	 * Collect all the clauses that syntactically belong above this level,
733 	 * eliminating any duplicates (important since we will see many of the
734 	 * same clauses arriving from both input relations).
735 	 */
736 	result = subbuild_joinrel_joinlist(joinrel, outer_rel->joininfo, NIL);
737 	result = subbuild_joinrel_joinlist(joinrel, inner_rel->joininfo, result);
738 
739 	joinrel->joininfo = result;
740 }
741 
742 static List *
subbuild_joinrel_restrictlist(RelOptInfo * joinrel,List * joininfo_list,List * new_restrictlist)743 subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
744 							  List *joininfo_list,
745 							  List *new_restrictlist)
746 {
747 	ListCell   *l;
748 
749 	foreach(l, joininfo_list)
750 	{
751 		RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
752 
753 		if (bms_is_subset(rinfo->required_relids, joinrel->relids))
754 		{
755 			/*
756 			 * This clause becomes a restriction clause for the joinrel, since
757 			 * it refers to no outside rels.  Add it to the list, being
758 			 * careful to eliminate duplicates. (Since RestrictInfo nodes in
759 			 * different joinlists will have been multiply-linked rather than
760 			 * copied, pointer equality should be a sufficient test.)
761 			 */
762 			new_restrictlist = list_append_unique_ptr(new_restrictlist, rinfo);
763 		}
764 		else
765 		{
766 			/*
767 			 * This clause is still a join clause at this level, so we ignore
768 			 * it in this routine.
769 			 */
770 		}
771 	}
772 
773 	return new_restrictlist;
774 }
775 
776 static List *
subbuild_joinrel_joinlist(RelOptInfo * joinrel,List * joininfo_list,List * new_joininfo)777 subbuild_joinrel_joinlist(RelOptInfo *joinrel,
778 						  List *joininfo_list,
779 						  List *new_joininfo)
780 {
781 	ListCell   *l;
782 
783 	foreach(l, joininfo_list)
784 	{
785 		RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
786 
787 		if (bms_is_subset(rinfo->required_relids, joinrel->relids))
788 		{
789 			/*
790 			 * This clause becomes a restriction clause for the joinrel, since
791 			 * it refers to no outside rels.  So we can ignore it in this
792 			 * routine.
793 			 */
794 		}
795 		else
796 		{
797 			/*
798 			 * This clause is still a join clause at this level, so add it to
799 			 * the new joininfo list, being careful to eliminate duplicates.
800 			 * (Since RestrictInfo nodes in different joinlists will have been
801 			 * multiply-linked rather than copied, pointer equality should be
802 			 * a sufficient test.)
803 			 */
804 			new_joininfo = list_append_unique_ptr(new_joininfo, rinfo);
805 		}
806 	}
807 
808 	return new_joininfo;
809 }
810 
811 
812 /*
813  * build_empty_join_rel
814  *		Build a dummy join relation describing an empty set of base rels.
815  *
816  * This is used for queries with empty FROM clauses, such as "SELECT 2+2" or
817  * "INSERT INTO foo VALUES(...)".  We don't try very hard to make the empty
818  * joinrel completely valid, since no real planning will be done with it ---
819  * we just need it to carry a simple Result path out of query_planner().
820  */
821 RelOptInfo *
build_empty_join_rel(PlannerInfo * root)822 build_empty_join_rel(PlannerInfo *root)
823 {
824 	RelOptInfo *joinrel;
825 
826 	/* The dummy join relation should be the only one ... */
827 	Assert(root->join_rel_list == NIL);
828 
829 	joinrel = makeNode(RelOptInfo);
830 	joinrel->reloptkind = RELOPT_JOINREL;
831 	joinrel->relids = NULL;		/* empty set */
832 	joinrel->rows = 1;			/* we produce one row for such cases */
833 	joinrel->rtekind = RTE_JOIN;
834 	joinrel->reltarget = create_empty_pathtarget();
835 
836 	root->join_rel_list = lappend(root->join_rel_list, joinrel);
837 
838 	return joinrel;
839 }
840 
841 
842 /*
843  * fetch_upper_rel
844  *		Build a RelOptInfo describing some post-scan/join query processing,
845  *		or return a pre-existing one if somebody already built it.
846  *
847  * An "upper" relation is identified by an UpperRelationKind and a Relids set.
848  * The meaning of the Relids set is not specified here, and very likely will
849  * vary for different relation kinds.
850  *
851  * Most of the fields in an upper-level RelOptInfo are not used and are not
852  * set here (though makeNode should ensure they're zeroes).  We basically only
853  * care about fields that are of interest to add_path() and set_cheapest().
854  */
855 RelOptInfo *
fetch_upper_rel(PlannerInfo * root,UpperRelationKind kind,Relids relids)856 fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)
857 {
858 	RelOptInfo *upperrel;
859 	ListCell   *lc;
860 
861 	/*
862 	 * For the moment, our indexing data structure is just a List for each
863 	 * relation kind.  If we ever get so many of one kind that this stops
864 	 * working well, we can improve it.  No code outside this function should
865 	 * assume anything about how to find a particular upperrel.
866 	 */
867 
868 	/* If we already made this upperrel for the query, return it */
869 	foreach(lc, root->upper_rels[kind])
870 	{
871 		upperrel = (RelOptInfo *) lfirst(lc);
872 
873 		if (bms_equal(upperrel->relids, relids))
874 			return upperrel;
875 	}
876 
877 	upperrel = makeNode(RelOptInfo);
878 	upperrel->reloptkind = RELOPT_UPPER_REL;
879 	upperrel->relids = bms_copy(relids);
880 
881 	/* cheap startup cost is interesting iff not all tuples to be retrieved */
882 	upperrel->consider_startup = (root->tuple_fraction > 0);
883 	upperrel->consider_param_startup = false;
884 	upperrel->consider_parallel = false;		/* might get changed later */
885 	upperrel->reltarget = create_empty_pathtarget();
886 	upperrel->pathlist = NIL;
887 	upperrel->cheapest_startup_path = NULL;
888 	upperrel->cheapest_total_path = NULL;
889 	upperrel->cheapest_unique_path = NULL;
890 	upperrel->cheapest_parameterized_paths = NIL;
891 
892 	root->upper_rels[kind] = lappend(root->upper_rels[kind], upperrel);
893 
894 	return upperrel;
895 }
896 
897 
898 /*
899  * find_childrel_appendrelinfo
900  *		Get the AppendRelInfo associated with an appendrel child rel.
901  *
902  * This search could be eliminated by storing a link in child RelOptInfos,
903  * but for now it doesn't seem performance-critical.  (Also, it might be
904  * difficult to maintain such a link during mutation of the append_rel_list.)
905  */
906 AppendRelInfo *
find_childrel_appendrelinfo(PlannerInfo * root,RelOptInfo * rel)907 find_childrel_appendrelinfo(PlannerInfo *root, RelOptInfo *rel)
908 {
909 	Index		relid = rel->relid;
910 	ListCell   *lc;
911 
912 	/* Should only be called on child rels */
913 	Assert(rel->reloptkind == RELOPT_OTHER_MEMBER_REL);
914 
915 	foreach(lc, root->append_rel_list)
916 	{
917 		AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc);
918 
919 		if (appinfo->child_relid == relid)
920 			return appinfo;
921 	}
922 	/* should have found the entry ... */
923 	elog(ERROR, "child rel %d not found in append_rel_list", relid);
924 	return NULL;				/* not reached */
925 }
926 
927 
928 /*
929  * find_childrel_top_parent
930  *		Fetch the topmost appendrel parent rel of an appendrel child rel.
931  *
932  * Since appendrels can be nested, a child could have multiple levels of
933  * appendrel ancestors.  This function locates the topmost ancestor,
934  * which will be a regular baserel not an otherrel.
935  */
936 RelOptInfo *
find_childrel_top_parent(PlannerInfo * root,RelOptInfo * rel)937 find_childrel_top_parent(PlannerInfo *root, RelOptInfo *rel)
938 {
939 	do
940 	{
941 		AppendRelInfo *appinfo = find_childrel_appendrelinfo(root, rel);
942 		Index		prelid = appinfo->parent_relid;
943 
944 		/* traverse up to the parent rel, loop if it's also a child rel */
945 		rel = find_base_rel(root, prelid);
946 	} while (rel->reloptkind == RELOPT_OTHER_MEMBER_REL);
947 
948 	Assert(rel->reloptkind == RELOPT_BASEREL);
949 
950 	return rel;
951 }
952 
953 
954 /*
955  * find_childrel_parents
956  *		Compute the set of parent relids of an appendrel child rel.
957  *
958  * Since appendrels can be nested, a child could have multiple levels of
959  * appendrel ancestors.  This function computes a Relids set of all the
960  * parent relation IDs.
961  */
962 Relids
find_childrel_parents(PlannerInfo * root,RelOptInfo * rel)963 find_childrel_parents(PlannerInfo *root, RelOptInfo *rel)
964 {
965 	Relids		result = NULL;
966 
967 	do
968 	{
969 		AppendRelInfo *appinfo = find_childrel_appendrelinfo(root, rel);
970 		Index		prelid = appinfo->parent_relid;
971 
972 		result = bms_add_member(result, prelid);
973 
974 		/* traverse up to the parent rel, loop if it's also a child rel */
975 		rel = find_base_rel(root, prelid);
976 	} while (rel->reloptkind == RELOPT_OTHER_MEMBER_REL);
977 
978 	Assert(rel->reloptkind == RELOPT_BASEREL);
979 
980 	return result;
981 }
982 
983 
984 /*
985  * get_baserel_parampathinfo
986  *		Get the ParamPathInfo for a parameterized path for a base relation,
987  *		constructing one if we don't have one already.
988  *
989  * This centralizes estimating the rowcounts for parameterized paths.
990  * We need to cache those to be sure we use the same rowcount for all paths
991  * of the same parameterization for a given rel.  This is also a convenient
992  * place to determine which movable join clauses the parameterized path will
993  * be responsible for evaluating.
994  */
995 ParamPathInfo *
get_baserel_parampathinfo(PlannerInfo * root,RelOptInfo * baserel,Relids required_outer)996 get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel,
997 						  Relids required_outer)
998 {
999 	ParamPathInfo *ppi;
1000 	Relids		joinrelids;
1001 	List	   *pclauses;
1002 	double		rows;
1003 	ListCell   *lc;
1004 
1005 	/* If rel has LATERAL refs, every path for it should account for them */
1006 	Assert(bms_is_subset(baserel->lateral_relids, required_outer));
1007 
1008 	/* Unparameterized paths have no ParamPathInfo */
1009 	if (bms_is_empty(required_outer))
1010 		return NULL;
1011 
1012 	Assert(!bms_overlap(baserel->relids, required_outer));
1013 
1014 	/* If we already have a PPI for this parameterization, just return it */
1015 	foreach(lc, baserel->ppilist)
1016 	{
1017 		ppi = (ParamPathInfo *) lfirst(lc);
1018 		if (bms_equal(ppi->ppi_req_outer, required_outer))
1019 			return ppi;
1020 	}
1021 
1022 	/*
1023 	 * Identify all joinclauses that are movable to this base rel given this
1024 	 * parameterization.
1025 	 */
1026 	joinrelids = bms_union(baserel->relids, required_outer);
1027 	pclauses = NIL;
1028 	foreach(lc, baserel->joininfo)
1029 	{
1030 		RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1031 
1032 		if (join_clause_is_movable_into(rinfo,
1033 										baserel->relids,
1034 										joinrelids))
1035 			pclauses = lappend(pclauses, rinfo);
1036 	}
1037 
1038 	/*
1039 	 * Add in joinclauses generated by EquivalenceClasses, too.  (These
1040 	 * necessarily satisfy join_clause_is_movable_into.)
1041 	 */
1042 	pclauses = list_concat(pclauses,
1043 						   generate_join_implied_equalities(root,
1044 															joinrelids,
1045 															required_outer,
1046 															baserel));
1047 
1048 	/* Estimate the number of rows returned by the parameterized scan */
1049 	rows = get_parameterized_baserel_size(root, baserel, pclauses);
1050 
1051 	/* And now we can build the ParamPathInfo */
1052 	ppi = makeNode(ParamPathInfo);
1053 	ppi->ppi_req_outer = required_outer;
1054 	ppi->ppi_rows = rows;
1055 	ppi->ppi_clauses = pclauses;
1056 	baserel->ppilist = lappend(baserel->ppilist, ppi);
1057 
1058 	return ppi;
1059 }
1060 
1061 /*
1062  * get_joinrel_parampathinfo
1063  *		Get the ParamPathInfo for a parameterized path for a join relation,
1064  *		constructing one if we don't have one already.
1065  *
1066  * This centralizes estimating the rowcounts for parameterized paths.
1067  * We need to cache those to be sure we use the same rowcount for all paths
1068  * of the same parameterization for a given rel.  This is also a convenient
1069  * place to determine which movable join clauses the parameterized path will
1070  * be responsible for evaluating.
1071  *
1072  * outer_path and inner_path are a pair of input paths that can be used to
1073  * construct the join, and restrict_clauses is the list of regular join
1074  * clauses (including clauses derived from EquivalenceClasses) that must be
1075  * applied at the join node when using these inputs.
1076  *
1077  * Unlike the situation for base rels, the set of movable join clauses to be
1078  * enforced at a join varies with the selected pair of input paths, so we
1079  * must calculate that and pass it back, even if we already have a matching
1080  * ParamPathInfo.  We handle this by adding any clauses moved down to this
1081  * join to *restrict_clauses, which is an in/out parameter.  (The addition
1082  * is done in such a way as to not modify the passed-in List structure.)
1083  *
1084  * Note: when considering a nestloop join, the caller must have removed from
1085  * restrict_clauses any movable clauses that are themselves scheduled to be
1086  * pushed into the right-hand path.  We do not do that here since it's
1087  * unnecessary for other join types.
1088  */
1089 ParamPathInfo *
get_joinrel_parampathinfo(PlannerInfo * root,RelOptInfo * joinrel,Path * outer_path,Path * inner_path,SpecialJoinInfo * sjinfo,Relids required_outer,List ** restrict_clauses)1090 get_joinrel_parampathinfo(PlannerInfo *root, RelOptInfo *joinrel,
1091 						  Path *outer_path,
1092 						  Path *inner_path,
1093 						  SpecialJoinInfo *sjinfo,
1094 						  Relids required_outer,
1095 						  List **restrict_clauses)
1096 {
1097 	ParamPathInfo *ppi;
1098 	Relids		join_and_req;
1099 	Relids		outer_and_req;
1100 	Relids		inner_and_req;
1101 	List	   *pclauses;
1102 	List	   *eclauses;
1103 	List	   *dropped_ecs;
1104 	double		rows;
1105 	ListCell   *lc;
1106 
1107 	/* If rel has LATERAL refs, every path for it should account for them */
1108 	Assert(bms_is_subset(joinrel->lateral_relids, required_outer));
1109 
1110 	/* Unparameterized paths have no ParamPathInfo or extra join clauses */
1111 	if (bms_is_empty(required_outer))
1112 		return NULL;
1113 
1114 	Assert(!bms_overlap(joinrel->relids, required_outer));
1115 
1116 	/*
1117 	 * Identify all joinclauses that are movable to this join rel given this
1118 	 * parameterization.  These are the clauses that are movable into this
1119 	 * join, but not movable into either input path.  Treat an unparameterized
1120 	 * input path as not accepting parameterized clauses (because it won't,
1121 	 * per the shortcut exit above), even though the joinclause movement rules
1122 	 * might allow the same clauses to be moved into a parameterized path for
1123 	 * that rel.
1124 	 */
1125 	join_and_req = bms_union(joinrel->relids, required_outer);
1126 	if (outer_path->param_info)
1127 		outer_and_req = bms_union(outer_path->parent->relids,
1128 								  PATH_REQ_OUTER(outer_path));
1129 	else
1130 		outer_and_req = NULL;	/* outer path does not accept parameters */
1131 	if (inner_path->param_info)
1132 		inner_and_req = bms_union(inner_path->parent->relids,
1133 								  PATH_REQ_OUTER(inner_path));
1134 	else
1135 		inner_and_req = NULL;	/* inner path does not accept parameters */
1136 
1137 	pclauses = NIL;
1138 	foreach(lc, joinrel->joininfo)
1139 	{
1140 		RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1141 
1142 		if (join_clause_is_movable_into(rinfo,
1143 										joinrel->relids,
1144 										join_and_req) &&
1145 			!join_clause_is_movable_into(rinfo,
1146 										 outer_path->parent->relids,
1147 										 outer_and_req) &&
1148 			!join_clause_is_movable_into(rinfo,
1149 										 inner_path->parent->relids,
1150 										 inner_and_req))
1151 			pclauses = lappend(pclauses, rinfo);
1152 	}
1153 
1154 	/* Consider joinclauses generated by EquivalenceClasses, too */
1155 	eclauses = generate_join_implied_equalities(root,
1156 												join_and_req,
1157 												required_outer,
1158 												joinrel);
1159 	/* We only want ones that aren't movable to lower levels */
1160 	dropped_ecs = NIL;
1161 	foreach(lc, eclauses)
1162 	{
1163 		RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1164 
1165 		/*
1166 		 * In principle, join_clause_is_movable_into() should accept anything
1167 		 * returned by generate_join_implied_equalities(); but because its
1168 		 * analysis is only approximate, sometimes it doesn't.  So we
1169 		 * currently cannot use this Assert; instead just assume it's okay to
1170 		 * apply the joinclause at this level.
1171 		 */
1172 #ifdef NOT_USED
1173 		Assert(join_clause_is_movable_into(rinfo,
1174 										   joinrel->relids,
1175 										   join_and_req));
1176 #endif
1177 		if (join_clause_is_movable_into(rinfo,
1178 										outer_path->parent->relids,
1179 										outer_and_req))
1180 			continue;			/* drop if movable into LHS */
1181 		if (join_clause_is_movable_into(rinfo,
1182 										inner_path->parent->relids,
1183 										inner_and_req))
1184 		{
1185 			/* drop if movable into RHS, but remember EC for use below */
1186 			Assert(rinfo->left_ec == rinfo->right_ec);
1187 			dropped_ecs = lappend(dropped_ecs, rinfo->left_ec);
1188 			continue;
1189 		}
1190 		pclauses = lappend(pclauses, rinfo);
1191 	}
1192 
1193 	/*
1194 	 * EquivalenceClasses are harder to deal with than we could wish, because
1195 	 * of the fact that a given EC can generate different clauses depending on
1196 	 * context.  Suppose we have an EC {X.X, Y.Y, Z.Z} where X and Y are the
1197 	 * LHS and RHS of the current join and Z is in required_outer, and further
1198 	 * suppose that the inner_path is parameterized by both X and Z.  The code
1199 	 * above will have produced either Z.Z = X.X or Z.Z = Y.Y from that EC,
1200 	 * and in the latter case will have discarded it as being movable into the
1201 	 * RHS.  However, the EC machinery might have produced either Y.Y = X.X or
1202 	 * Y.Y = Z.Z as the EC enforcement clause within the inner_path; it will
1203 	 * not have produced both, and we can't readily tell from here which one
1204 	 * it did pick.  If we add no clause to this join, we'll end up with
1205 	 * insufficient enforcement of the EC; either Z.Z or X.X will fail to be
1206 	 * constrained to be equal to the other members of the EC.  (When we come
1207 	 * to join Z to this X/Y path, we will certainly drop whichever EC clause
1208 	 * is generated at that join, so this omission won't get fixed later.)
1209 	 *
1210 	 * To handle this, for each EC we discarded such a clause from, try to
1211 	 * generate a clause connecting the required_outer rels to the join's LHS
1212 	 * ("Z.Z = X.X" in the terms of the above example).  If successful, and if
1213 	 * the clause can't be moved to the LHS, add it to the current join's
1214 	 * restriction clauses.  (If an EC cannot generate such a clause then it
1215 	 * has nothing that needs to be enforced here, while if the clause can be
1216 	 * moved into the LHS then it should have been enforced within that path.)
1217 	 *
1218 	 * Note that we don't need similar processing for ECs whose clause was
1219 	 * considered to be movable into the LHS, because the LHS can't refer to
1220 	 * the RHS so there is no comparable ambiguity about what it might
1221 	 * actually be enforcing internally.
1222 	 */
1223 	if (dropped_ecs)
1224 	{
1225 		Relids		real_outer_and_req;
1226 
1227 		real_outer_and_req = bms_union(outer_path->parent->relids,
1228 									   required_outer);
1229 		eclauses =
1230 			generate_join_implied_equalities_for_ecs(root,
1231 													 dropped_ecs,
1232 													 real_outer_and_req,
1233 													 required_outer,
1234 													 outer_path->parent);
1235 		foreach(lc, eclauses)
1236 		{
1237 			RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1238 
1239 			/* As above, can't quite assert this here */
1240 #ifdef NOT_USED
1241 			Assert(join_clause_is_movable_into(rinfo,
1242 											   outer_path->parent->relids,
1243 											   real_outer_and_req));
1244 #endif
1245 			if (!join_clause_is_movable_into(rinfo,
1246 											 outer_path->parent->relids,
1247 											 outer_and_req))
1248 				pclauses = lappend(pclauses, rinfo);
1249 		}
1250 	}
1251 
1252 	/*
1253 	 * Now, attach the identified moved-down clauses to the caller's
1254 	 * restrict_clauses list.  By using list_concat in this order, we leave
1255 	 * the original list structure of restrict_clauses undamaged.
1256 	 */
1257 	*restrict_clauses = list_concat(pclauses, *restrict_clauses);
1258 
1259 	/* If we already have a PPI for this parameterization, just return it */
1260 	foreach(lc, joinrel->ppilist)
1261 	{
1262 		ppi = (ParamPathInfo *) lfirst(lc);
1263 		if (bms_equal(ppi->ppi_req_outer, required_outer))
1264 			return ppi;
1265 	}
1266 
1267 	/* Estimate the number of rows returned by the parameterized join */
1268 	rows = get_parameterized_joinrel_size(root, joinrel,
1269 										  outer_path,
1270 										  inner_path,
1271 										  sjinfo,
1272 										  *restrict_clauses);
1273 
1274 	/*
1275 	 * And now we can build the ParamPathInfo.  No point in saving the
1276 	 * input-pair-dependent clause list, though.
1277 	 *
1278 	 * Note: in GEQO mode, we'll be called in a temporary memory context, but
1279 	 * the joinrel structure is there too, so no problem.
1280 	 */
1281 	ppi = makeNode(ParamPathInfo);
1282 	ppi->ppi_req_outer = required_outer;
1283 	ppi->ppi_rows = rows;
1284 	ppi->ppi_clauses = NIL;
1285 	joinrel->ppilist = lappend(joinrel->ppilist, ppi);
1286 
1287 	return ppi;
1288 }
1289 
1290 /*
1291  * get_appendrel_parampathinfo
1292  *		Get the ParamPathInfo for a parameterized path for an append relation.
1293  *
1294  * For an append relation, the rowcount estimate will just be the sum of
1295  * the estimates for its children.  However, we still need a ParamPathInfo
1296  * to flag the fact that the path requires parameters.  So this just creates
1297  * a suitable struct with zero ppi_rows (and no ppi_clauses either, since
1298  * the Append node isn't responsible for checking quals).
1299  */
1300 ParamPathInfo *
get_appendrel_parampathinfo(RelOptInfo * appendrel,Relids required_outer)1301 get_appendrel_parampathinfo(RelOptInfo *appendrel, Relids required_outer)
1302 {
1303 	ParamPathInfo *ppi;
1304 	ListCell   *lc;
1305 
1306 	/* If rel has LATERAL refs, every path for it should account for them */
1307 	Assert(bms_is_subset(appendrel->lateral_relids, required_outer));
1308 
1309 	/* Unparameterized paths have no ParamPathInfo */
1310 	if (bms_is_empty(required_outer))
1311 		return NULL;
1312 
1313 	Assert(!bms_overlap(appendrel->relids, required_outer));
1314 
1315 	/* If we already have a PPI for this parameterization, just return it */
1316 	foreach(lc, appendrel->ppilist)
1317 	{
1318 		ppi = (ParamPathInfo *) lfirst(lc);
1319 		if (bms_equal(ppi->ppi_req_outer, required_outer))
1320 			return ppi;
1321 	}
1322 
1323 	/* Else build the ParamPathInfo */
1324 	ppi = makeNode(ParamPathInfo);
1325 	ppi->ppi_req_outer = required_outer;
1326 	ppi->ppi_rows = 0;
1327 	ppi->ppi_clauses = NIL;
1328 	appendrel->ppilist = lappend(appendrel->ppilist, ppi);
1329 
1330 	return ppi;
1331 }
1332