Prevent integer overflow when forming tuple width estimates.
[pgsql.git] / src / backend / optimizer / util / relnode.c
blob9dfeb4ffd4bc3696caa899bb97206da43d1effec
1 /*-------------------------------------------------------------------------
3 * relnode.c
4 * Relation-node lookup/construction routines
6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * src/backend/optimizer/util/relnode.c
13 *-------------------------------------------------------------------------
15 #include "postgres.h"
17 #include <limits.h>
19 #include "miscadmin.h"
20 #include "nodes/nodeFuncs.h"
21 #include "optimizer/appendinfo.h"
22 #include "optimizer/clauses.h"
23 #include "optimizer/cost.h"
24 #include "optimizer/inherit.h"
25 #include "optimizer/optimizer.h"
26 #include "optimizer/pathnode.h"
27 #include "optimizer/paths.h"
28 #include "optimizer/placeholder.h"
29 #include "optimizer/plancat.h"
30 #include "optimizer/restrictinfo.h"
31 #include "optimizer/tlist.h"
32 #include "rewrite/rewriteManip.h"
33 #include "parser/parse_relation.h"
34 #include "utils/hsearch.h"
35 #include "utils/lsyscache.h"
38 typedef struct JoinHashEntry
40 Relids join_relids; /* hash key --- MUST BE FIRST */
41 RelOptInfo *join_rel;
42 } JoinHashEntry;
44 static void build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel,
45 RelOptInfo *input_rel,
46 SpecialJoinInfo *sjinfo,
47 List *pushed_down_joins,
48 bool can_null);
49 static List *build_joinrel_restrictlist(PlannerInfo *root,
50 RelOptInfo *joinrel,
51 RelOptInfo *outer_rel,
52 RelOptInfo *inner_rel,
53 SpecialJoinInfo *sjinfo);
54 static void build_joinrel_joinlist(RelOptInfo *joinrel,
55 RelOptInfo *outer_rel,
56 RelOptInfo *inner_rel);
57 static List *subbuild_joinrel_restrictlist(PlannerInfo *root,
58 RelOptInfo *joinrel,
59 RelOptInfo *input_rel,
60 Relids both_input_relids,
61 List *new_restrictlist);
62 static List *subbuild_joinrel_joinlist(RelOptInfo *joinrel,
63 List *joininfo_list,
64 List *new_joininfo);
65 static void set_foreign_rel_properties(RelOptInfo *joinrel,
66 RelOptInfo *outer_rel, RelOptInfo *inner_rel);
67 static void add_join_rel(PlannerInfo *root, RelOptInfo *joinrel);
68 static void build_joinrel_partition_info(PlannerInfo *root,
69 RelOptInfo *joinrel,
70 RelOptInfo *outer_rel, RelOptInfo *inner_rel,
71 SpecialJoinInfo *sjinfo,
72 List *restrictlist);
73 static bool have_partkey_equi_join(PlannerInfo *root, RelOptInfo *joinrel,
74 RelOptInfo *rel1, RelOptInfo *rel2,
75 JoinType jointype, List *restrictlist);
76 static int match_expr_to_partition_keys(Expr *expr, RelOptInfo *rel,
77 bool strict_op);
78 static void set_joinrel_partition_key_exprs(RelOptInfo *joinrel,
79 RelOptInfo *outer_rel, RelOptInfo *inner_rel,
80 JoinType jointype);
81 static void build_child_join_reltarget(PlannerInfo *root,
82 RelOptInfo *parentrel,
83 RelOptInfo *childrel,
84 int nappinfos,
85 AppendRelInfo **appinfos);
89 * setup_simple_rel_arrays
90 * Prepare the arrays we use for quickly accessing base relations
91 * and AppendRelInfos.
93 void
94 setup_simple_rel_arrays(PlannerInfo *root)
96 int size;
97 Index rti;
98 ListCell *lc;
100 /* Arrays are accessed using RT indexes (1..N) */
101 size = list_length(root->parse->rtable) + 1;
102 root->simple_rel_array_size = size;
105 * simple_rel_array is initialized to all NULLs, since no RelOptInfos
106 * exist yet. It'll be filled by later calls to build_simple_rel().
108 root->simple_rel_array = (RelOptInfo **)
109 palloc0(size * sizeof(RelOptInfo *));
111 /* simple_rte_array is an array equivalent of the rtable list */
112 root->simple_rte_array = (RangeTblEntry **)
113 palloc0(size * sizeof(RangeTblEntry *));
114 rti = 1;
115 foreach(lc, root->parse->rtable)
117 RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
119 root->simple_rte_array[rti++] = rte;
122 /* append_rel_array is not needed if there are no AppendRelInfos */
123 if (root->append_rel_list == NIL)
125 root->append_rel_array = NULL;
126 return;
129 root->append_rel_array = (AppendRelInfo **)
130 palloc0(size * sizeof(AppendRelInfo *));
133 * append_rel_array is filled with any already-existing AppendRelInfos,
134 * which currently could only come from UNION ALL flattening. We might
135 * add more later during inheritance expansion, but it's the
136 * responsibility of the expansion code to update the array properly.
138 foreach(lc, root->append_rel_list)
140 AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc);
141 int child_relid = appinfo->child_relid;
143 /* Sanity check */
144 Assert(child_relid < size);
146 if (root->append_rel_array[child_relid])
147 elog(ERROR, "child relation already exists");
149 root->append_rel_array[child_relid] = appinfo;
154 * expand_planner_arrays
155 * Expand the PlannerInfo's per-RTE arrays by add_size members
156 * and initialize the newly added entries to NULLs
158 * Note: this causes the append_rel_array to become allocated even if
159 * it was not before. This is okay for current uses, because we only call
160 * this when adding child relations, which always have AppendRelInfos.
162 void
163 expand_planner_arrays(PlannerInfo *root, int add_size)
165 int new_size;
167 Assert(add_size > 0);
169 new_size = root->simple_rel_array_size + add_size;
171 root->simple_rel_array =
172 repalloc0_array(root->simple_rel_array, RelOptInfo *, root->simple_rel_array_size, new_size);
174 root->simple_rte_array =
175 repalloc0_array(root->simple_rte_array, RangeTblEntry *, root->simple_rel_array_size, new_size);
177 if (root->append_rel_array)
178 root->append_rel_array =
179 repalloc0_array(root->append_rel_array, AppendRelInfo *, root->simple_rel_array_size, new_size);
180 else
181 root->append_rel_array =
182 palloc0_array(AppendRelInfo *, new_size);
184 root->simple_rel_array_size = new_size;
188 * build_simple_rel
189 * Construct a new RelOptInfo for a base relation or 'other' relation.
191 RelOptInfo *
192 build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
194 RelOptInfo *rel;
195 RangeTblEntry *rte;
197 /* Rel should not exist already */
198 Assert(relid > 0 && relid < root->simple_rel_array_size);
199 if (root->simple_rel_array[relid] != NULL)
200 elog(ERROR, "rel %d already exists", relid);
202 /* Fetch RTE for relation */
203 rte = root->simple_rte_array[relid];
204 Assert(rte != NULL);
206 rel = makeNode(RelOptInfo);
207 rel->reloptkind = parent ? RELOPT_OTHER_MEMBER_REL : RELOPT_BASEREL;
208 rel->relids = bms_make_singleton(relid);
209 rel->rows = 0;
210 /* cheap startup cost is interesting iff not all tuples to be retrieved */
211 rel->consider_startup = (root->tuple_fraction > 0);
212 rel->consider_param_startup = false; /* might get changed later */
213 rel->consider_parallel = false; /* might get changed later */
214 rel->reltarget = create_empty_pathtarget();
215 rel->pathlist = NIL;
216 rel->ppilist = NIL;
217 rel->partial_pathlist = NIL;
218 rel->cheapest_startup_path = NULL;
219 rel->cheapest_total_path = NULL;
220 rel->cheapest_unique_path = NULL;
221 rel->cheapest_parameterized_paths = NIL;
222 rel->relid = relid;
223 rel->rtekind = rte->rtekind;
224 /* min_attr, max_attr, attr_needed, attr_widths are set below */
225 rel->lateral_vars = NIL;
226 rel->indexlist = NIL;
227 rel->statlist = NIL;
228 rel->pages = 0;
229 rel->tuples = 0;
230 rel->allvisfrac = 0;
231 rel->eclass_indexes = NULL;
232 rel->subroot = NULL;
233 rel->subplan_params = NIL;
234 rel->rel_parallel_workers = -1; /* set up in get_relation_info */
235 rel->amflags = 0;
236 rel->serverid = InvalidOid;
237 if (rte->rtekind == RTE_RELATION)
239 Assert(parent == NULL ||
240 parent->rtekind == RTE_RELATION ||
241 parent->rtekind == RTE_SUBQUERY);
244 * For any RELATION rte, we need a userid with which to check
245 * permission access. Baserels simply use their own
246 * RTEPermissionInfo's checkAsUser.
248 * For otherrels normally there's no RTEPermissionInfo, so we use the
249 * parent's, which normally has one. The exceptional case is that the
250 * parent is a subquery, in which case the otherrel will have its own.
252 if (rel->reloptkind == RELOPT_BASEREL ||
253 (rel->reloptkind == RELOPT_OTHER_MEMBER_REL &&
254 parent->rtekind == RTE_SUBQUERY))
256 RTEPermissionInfo *perminfo;
258 perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte);
259 rel->userid = perminfo->checkAsUser;
261 else
262 rel->userid = parent->userid;
264 else
265 rel->userid = InvalidOid;
266 rel->useridiscurrent = false;
267 rel->fdwroutine = NULL;
268 rel->fdw_private = NULL;
269 rel->unique_for_rels = NIL;
270 rel->non_unique_for_rels = NIL;
271 rel->baserestrictinfo = NIL;
272 rel->baserestrictcost.startup = 0;
273 rel->baserestrictcost.per_tuple = 0;
274 rel->baserestrict_min_security = UINT_MAX;
275 rel->joininfo = NIL;
276 rel->has_eclass_joins = false;
277 rel->consider_partitionwise_join = false; /* might get changed later */
278 rel->part_scheme = NULL;
279 rel->nparts = -1;
280 rel->boundinfo = NULL;
281 rel->partbounds_merged = false;
282 rel->partition_qual = NIL;
283 rel->part_rels = NULL;
284 rel->live_parts = NULL;
285 rel->all_partrels = NULL;
286 rel->partexprs = NULL;
287 rel->nullable_partexprs = NULL;
290 * Pass assorted information down the inheritance hierarchy.
292 if (parent)
294 /* We keep back-links to immediate parent and topmost parent. */
295 rel->parent = parent;
296 rel->top_parent = parent->top_parent ? parent->top_parent : parent;
297 rel->top_parent_relids = rel->top_parent->relids;
300 * A child rel is below the same outer joins as its parent. (We
301 * presume this info was already calculated for the parent.)
303 rel->nulling_relids = parent->nulling_relids;
306 * Also propagate lateral-reference information from appendrel parent
307 * rels to their child rels. We intentionally give each child rel the
308 * same minimum parameterization, even though it's quite possible that
309 * some don't reference all the lateral rels. This is because any
310 * append path for the parent will have to have the same
311 * parameterization for every child anyway, and there's no value in
312 * forcing extra reparameterize_path() calls. Similarly, a lateral
313 * reference to the parent prevents use of otherwise-movable join rels
314 * for each child.
316 * It's possible for child rels to have their own children, in which
317 * case the topmost parent's lateral info propagates all the way down.
319 rel->direct_lateral_relids = parent->direct_lateral_relids;
320 rel->lateral_relids = parent->lateral_relids;
321 rel->lateral_referencers = parent->lateral_referencers;
323 else
325 rel->parent = NULL;
326 rel->top_parent = NULL;
327 rel->top_parent_relids = NULL;
328 rel->nulling_relids = NULL;
329 rel->direct_lateral_relids = NULL;
330 rel->lateral_relids = NULL;
331 rel->lateral_referencers = NULL;
334 /* Check type of rtable entry */
335 switch (rte->rtekind)
337 case RTE_RELATION:
338 /* Table --- retrieve statistics from the system catalogs */
339 get_relation_info(root, rte->relid, rte->inh, rel);
340 break;
341 case RTE_SUBQUERY:
342 case RTE_FUNCTION:
343 case RTE_TABLEFUNC:
344 case RTE_VALUES:
345 case RTE_CTE:
346 case RTE_NAMEDTUPLESTORE:
349 * Subquery, function, tablefunc, values list, CTE, or ENR --- set
350 * up attr range and arrays
352 * Note: 0 is included in range to support whole-row Vars
354 rel->min_attr = 0;
355 rel->max_attr = list_length(rte->eref->colnames);
356 rel->attr_needed = (Relids *)
357 palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(Relids));
358 rel->attr_widths = (int32 *)
359 palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(int32));
360 break;
361 case RTE_RESULT:
362 /* RTE_RESULT has no columns, nor could it have whole-row Var */
363 rel->min_attr = 0;
364 rel->max_attr = -1;
365 rel->attr_needed = NULL;
366 rel->attr_widths = NULL;
367 break;
368 default:
369 elog(ERROR, "unrecognized RTE kind: %d",
370 (int) rte->rtekind);
371 break;
375 * Copy the parent's quals to the child, with appropriate substitution of
376 * variables. If any constant false or NULL clauses turn up, we can mark
377 * the child as dummy right away. (We must do this immediately so that
378 * pruning works correctly when recursing in expand_partitioned_rtentry.)
380 if (parent)
382 AppendRelInfo *appinfo = root->append_rel_array[relid];
384 Assert(appinfo != NULL);
385 if (!apply_child_basequals(root, parent, rel, rte, appinfo))
388 * Some restriction clause reduced to constant FALSE or NULL after
389 * substitution, so this child need not be scanned.
391 mark_dummy_rel(rel);
395 /* Save the finished struct in the query's simple_rel_array */
396 root->simple_rel_array[relid] = rel;
398 return rel;
402 * find_base_rel
403 * Find a base or otherrel relation entry, which must already exist.
405 RelOptInfo *
406 find_base_rel(PlannerInfo *root, int relid)
408 RelOptInfo *rel;
410 /* use an unsigned comparison to prevent negative array element access */
411 if ((uint32) relid < (uint32) root->simple_rel_array_size)
413 rel = root->simple_rel_array[relid];
414 if (rel)
415 return rel;
418 elog(ERROR, "no relation entry for relid %d", relid);
420 return NULL; /* keep compiler quiet */
424 * find_base_rel_ignore_join
425 * Find a base or otherrel relation entry, which must already exist.
427 * Unlike find_base_rel, if relid references an outer join then this
428 * will return NULL rather than raising an error. This is convenient
429 * for callers that must deal with relid sets including both base and
430 * outer joins.
432 RelOptInfo *
433 find_base_rel_ignore_join(PlannerInfo *root, int relid)
435 /* use an unsigned comparison to prevent negative array element access */
436 if ((uint32) relid < (uint32) root->simple_rel_array_size)
438 RelOptInfo *rel;
439 RangeTblEntry *rte;
441 rel = root->simple_rel_array[relid];
442 if (rel)
443 return rel;
446 * We could just return NULL here, but for debugging purposes it seems
447 * best to actually verify that the relid is an outer join and not
448 * something weird.
450 rte = root->simple_rte_array[relid];
451 if (rte && rte->rtekind == RTE_JOIN && rte->jointype != JOIN_INNER)
452 return NULL;
455 elog(ERROR, "no relation entry for relid %d", relid);
457 return NULL; /* keep compiler quiet */
461 * build_join_rel_hash
462 * Construct the auxiliary hash table for join relations.
464 static void
465 build_join_rel_hash(PlannerInfo *root)
467 HTAB *hashtab;
468 HASHCTL hash_ctl;
469 ListCell *l;
471 /* Create the hash table */
472 hash_ctl.keysize = sizeof(Relids);
473 hash_ctl.entrysize = sizeof(JoinHashEntry);
474 hash_ctl.hash = bitmap_hash;
475 hash_ctl.match = bitmap_match;
476 hash_ctl.hcxt = CurrentMemoryContext;
477 hashtab = hash_create("JoinRelHashTable",
478 256L,
479 &hash_ctl,
480 HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_CONTEXT);
482 /* Insert all the already-existing joinrels */
483 foreach(l, root->join_rel_list)
485 RelOptInfo *rel = (RelOptInfo *) lfirst(l);
486 JoinHashEntry *hentry;
487 bool found;
489 hentry = (JoinHashEntry *) hash_search(hashtab,
490 &(rel->relids),
491 HASH_ENTER,
492 &found);
493 Assert(!found);
494 hentry->join_rel = rel;
497 root->join_rel_hash = hashtab;
501 * find_join_rel
502 * Returns relation entry corresponding to 'relids' (a set of RT indexes),
503 * or NULL if none exists. This is for join relations.
505 RelOptInfo *
506 find_join_rel(PlannerInfo *root, Relids relids)
509 * Switch to using hash lookup when list grows "too long". The threshold
510 * is arbitrary and is known only here.
512 if (!root->join_rel_hash && list_length(root->join_rel_list) > 32)
513 build_join_rel_hash(root);
516 * Use either hashtable lookup or linear search, as appropriate.
518 * Note: the seemingly redundant hashkey variable is used to avoid taking
519 * the address of relids; unless the compiler is exceedingly smart, doing
520 * so would force relids out of a register and thus probably slow down the
521 * list-search case.
523 if (root->join_rel_hash)
525 Relids hashkey = relids;
526 JoinHashEntry *hentry;
528 hentry = (JoinHashEntry *) hash_search(root->join_rel_hash,
529 &hashkey,
530 HASH_FIND,
531 NULL);
532 if (hentry)
533 return hentry->join_rel;
535 else
537 ListCell *l;
539 foreach(l, root->join_rel_list)
541 RelOptInfo *rel = (RelOptInfo *) lfirst(l);
543 if (bms_equal(rel->relids, relids))
544 return rel;
548 return NULL;
552 * set_foreign_rel_properties
553 * Set up foreign-join fields if outer and inner relation are foreign
554 * tables (or joins) belonging to the same server and assigned to the same
555 * user to check access permissions as.
557 * In addition to an exact match of userid, we allow the case where one side
558 * has zero userid (implying current user) and the other side has explicit
559 * userid that happens to equal the current user; but in that case, pushdown of
560 * the join is only valid for the current user. The useridiscurrent field
561 * records whether we had to make such an assumption for this join or any
562 * sub-join.
564 * Otherwise these fields are left invalid, so GetForeignJoinPaths will not be
565 * called for the join relation.
567 static void
568 set_foreign_rel_properties(RelOptInfo *joinrel, RelOptInfo *outer_rel,
569 RelOptInfo *inner_rel)
571 if (OidIsValid(outer_rel->serverid) &&
572 inner_rel->serverid == outer_rel->serverid)
574 if (inner_rel->userid == outer_rel->userid)
576 joinrel->serverid = outer_rel->serverid;
577 joinrel->userid = outer_rel->userid;
578 joinrel->useridiscurrent = outer_rel->useridiscurrent || inner_rel->useridiscurrent;
579 joinrel->fdwroutine = outer_rel->fdwroutine;
581 else if (!OidIsValid(inner_rel->userid) &&
582 outer_rel->userid == GetUserId())
584 joinrel->serverid = outer_rel->serverid;
585 joinrel->userid = outer_rel->userid;
586 joinrel->useridiscurrent = true;
587 joinrel->fdwroutine = outer_rel->fdwroutine;
589 else if (!OidIsValid(outer_rel->userid) &&
590 inner_rel->userid == GetUserId())
592 joinrel->serverid = outer_rel->serverid;
593 joinrel->userid = inner_rel->userid;
594 joinrel->useridiscurrent = true;
595 joinrel->fdwroutine = outer_rel->fdwroutine;
601 * add_join_rel
602 * Add given join relation to the list of join relations in the given
603 * PlannerInfo. Also add it to the auxiliary hashtable if there is one.
605 static void
606 add_join_rel(PlannerInfo *root, RelOptInfo *joinrel)
608 /* GEQO requires us to append the new joinrel to the end of the list! */
609 root->join_rel_list = lappend(root->join_rel_list, joinrel);
611 /* store it into the auxiliary hashtable if there is one. */
612 if (root->join_rel_hash)
614 JoinHashEntry *hentry;
615 bool found;
617 hentry = (JoinHashEntry *) hash_search(root->join_rel_hash,
618 &(joinrel->relids),
619 HASH_ENTER,
620 &found);
621 Assert(!found);
622 hentry->join_rel = joinrel;
627 * build_join_rel
628 * Returns relation entry corresponding to the union of two given rels,
629 * creating a new relation entry if none already exists.
631 * 'joinrelids' is the Relids set that uniquely identifies the join
632 * 'outer_rel' and 'inner_rel' are relation nodes for the relations to be
633 * joined
634 * 'sjinfo': join context info
635 * 'pushed_down_joins': any pushed-down outer joins that are now completed
636 * 'restrictlist_ptr': result variable. If not NULL, *restrictlist_ptr
637 * receives the list of RestrictInfo nodes that apply to this
638 * particular pair of joinable relations.
640 * restrictlist_ptr makes the routine's API a little grotty, but it saves
641 * duplicated calculation of the restrictlist...
643 RelOptInfo *
644 build_join_rel(PlannerInfo *root,
645 Relids joinrelids,
646 RelOptInfo *outer_rel,
647 RelOptInfo *inner_rel,
648 SpecialJoinInfo *sjinfo,
649 List *pushed_down_joins,
650 List **restrictlist_ptr)
652 RelOptInfo *joinrel;
653 List *restrictlist;
655 /* This function should be used only for join between parents. */
656 Assert(!IS_OTHER_REL(outer_rel) && !IS_OTHER_REL(inner_rel));
659 * See if we already have a joinrel for this set of base rels.
661 joinrel = find_join_rel(root, joinrelids);
663 if (joinrel)
666 * Yes, so we only need to figure the restrictlist for this particular
667 * pair of component relations.
669 if (restrictlist_ptr)
670 *restrictlist_ptr = build_joinrel_restrictlist(root,
671 joinrel,
672 outer_rel,
673 inner_rel,
674 sjinfo);
675 return joinrel;
679 * Nope, so make one.
681 joinrel = makeNode(RelOptInfo);
682 joinrel->reloptkind = RELOPT_JOINREL;
683 joinrel->relids = bms_copy(joinrelids);
684 joinrel->rows = 0;
685 /* cheap startup cost is interesting iff not all tuples to be retrieved */
686 joinrel->consider_startup = (root->tuple_fraction > 0);
687 joinrel->consider_param_startup = false;
688 joinrel->consider_parallel = false;
689 joinrel->reltarget = create_empty_pathtarget();
690 joinrel->pathlist = NIL;
691 joinrel->ppilist = NIL;
692 joinrel->partial_pathlist = NIL;
693 joinrel->cheapest_startup_path = NULL;
694 joinrel->cheapest_total_path = NULL;
695 joinrel->cheapest_unique_path = NULL;
696 joinrel->cheapest_parameterized_paths = NIL;
697 /* init direct_lateral_relids from children; we'll finish it up below */
698 joinrel->direct_lateral_relids =
699 bms_union(outer_rel->direct_lateral_relids,
700 inner_rel->direct_lateral_relids);
701 joinrel->lateral_relids = min_join_parameterization(root, joinrel->relids,
702 outer_rel, inner_rel);
703 joinrel->relid = 0; /* indicates not a baserel */
704 joinrel->rtekind = RTE_JOIN;
705 joinrel->min_attr = 0;
706 joinrel->max_attr = 0;
707 joinrel->attr_needed = NULL;
708 joinrel->attr_widths = NULL;
709 joinrel->nulling_relids = NULL;
710 joinrel->lateral_vars = NIL;
711 joinrel->lateral_referencers = NULL;
712 joinrel->indexlist = NIL;
713 joinrel->statlist = NIL;
714 joinrel->pages = 0;
715 joinrel->tuples = 0;
716 joinrel->allvisfrac = 0;
717 joinrel->eclass_indexes = NULL;
718 joinrel->subroot = NULL;
719 joinrel->subplan_params = NIL;
720 joinrel->rel_parallel_workers = -1;
721 joinrel->amflags = 0;
722 joinrel->serverid = InvalidOid;
723 joinrel->userid = InvalidOid;
724 joinrel->useridiscurrent = false;
725 joinrel->fdwroutine = NULL;
726 joinrel->fdw_private = NULL;
727 joinrel->unique_for_rels = NIL;
728 joinrel->non_unique_for_rels = NIL;
729 joinrel->baserestrictinfo = NIL;
730 joinrel->baserestrictcost.startup = 0;
731 joinrel->baserestrictcost.per_tuple = 0;
732 joinrel->baserestrict_min_security = UINT_MAX;
733 joinrel->joininfo = NIL;
734 joinrel->has_eclass_joins = false;
735 joinrel->consider_partitionwise_join = false; /* might get changed later */
736 joinrel->parent = NULL;
737 joinrel->top_parent = NULL;
738 joinrel->top_parent_relids = NULL;
739 joinrel->part_scheme = NULL;
740 joinrel->nparts = -1;
741 joinrel->boundinfo = NULL;
742 joinrel->partbounds_merged = false;
743 joinrel->partition_qual = NIL;
744 joinrel->part_rels = NULL;
745 joinrel->live_parts = NULL;
746 joinrel->all_partrels = NULL;
747 joinrel->partexprs = NULL;
748 joinrel->nullable_partexprs = NULL;
750 /* Compute information relevant to the foreign relations. */
751 set_foreign_rel_properties(joinrel, outer_rel, inner_rel);
754 * Fill the joinrel's tlist with just the Vars and PHVs that need to be
755 * output from this join (ie, are needed for higher joinclauses or final
756 * output).
758 * NOTE: the tlist order for a join rel will depend on which pair of outer
759 * and inner rels we first try to build it from. But the contents should
760 * be the same regardless.
762 build_joinrel_tlist(root, joinrel, outer_rel, sjinfo, pushed_down_joins,
763 (sjinfo->jointype == JOIN_FULL));
764 build_joinrel_tlist(root, joinrel, inner_rel, sjinfo, pushed_down_joins,
765 (sjinfo->jointype != JOIN_INNER));
766 add_placeholders_to_joinrel(root, joinrel, outer_rel, inner_rel, sjinfo);
769 * add_placeholders_to_joinrel also took care of adding the ph_lateral
770 * sets of any PlaceHolderVars computed here to direct_lateral_relids, so
771 * now we can finish computing that. This is much like the computation of
772 * the transitively-closed lateral_relids in min_join_parameterization,
773 * except that here we *do* have to consider the added PHVs.
775 joinrel->direct_lateral_relids =
776 bms_del_members(joinrel->direct_lateral_relids, joinrel->relids);
779 * Construct restrict and join clause lists for the new joinrel. (The
780 * caller might or might not need the restrictlist, but I need it anyway
781 * for set_joinrel_size_estimates().)
783 restrictlist = build_joinrel_restrictlist(root, joinrel,
784 outer_rel, inner_rel,
785 sjinfo);
786 if (restrictlist_ptr)
787 *restrictlist_ptr = restrictlist;
788 build_joinrel_joinlist(joinrel, outer_rel, inner_rel);
791 * This is also the right place to check whether the joinrel has any
792 * pending EquivalenceClass joins.
794 joinrel->has_eclass_joins = has_relevant_eclass_joinclause(root, joinrel);
796 /* Store the partition information. */
797 build_joinrel_partition_info(root, joinrel, outer_rel, inner_rel, sjinfo,
798 restrictlist);
801 * Set estimates of the joinrel's size.
803 set_joinrel_size_estimates(root, joinrel, outer_rel, inner_rel,
804 sjinfo, restrictlist);
807 * Set the consider_parallel flag if this joinrel could potentially be
808 * scanned within a parallel worker. If this flag is false for either
809 * inner_rel or outer_rel, then it must be false for the joinrel also.
810 * Even if both are true, there might be parallel-restricted expressions
811 * in the targetlist or quals.
813 * Note that if there are more than two rels in this relation, they could
814 * be divided between inner_rel and outer_rel in any arbitrary way. We
815 * assume this doesn't matter, because we should hit all the same baserels
816 * and joinclauses while building up to this joinrel no matter which we
817 * take; therefore, we should make the same decision here however we get
818 * here.
820 if (inner_rel->consider_parallel && outer_rel->consider_parallel &&
821 is_parallel_safe(root, (Node *) restrictlist) &&
822 is_parallel_safe(root, (Node *) joinrel->reltarget->exprs))
823 joinrel->consider_parallel = true;
825 /* Add the joinrel to the PlannerInfo. */
826 add_join_rel(root, joinrel);
829 * Also, if dynamic-programming join search is active, add the new joinrel
830 * to the appropriate sublist. Note: you might think the Assert on number
831 * of members should be for equality, but some of the level 1 rels might
832 * have been joinrels already, so we can only assert <=.
834 if (root->join_rel_level)
836 Assert(root->join_cur_level > 0);
837 Assert(root->join_cur_level <= bms_num_members(joinrel->relids));
838 root->join_rel_level[root->join_cur_level] =
839 lappend(root->join_rel_level[root->join_cur_level], joinrel);
842 return joinrel;
846 * build_child_join_rel
847 * Builds RelOptInfo representing join between given two child relations.
849 * 'outer_rel' and 'inner_rel' are the RelOptInfos of child relations being
850 * joined
851 * 'parent_joinrel' is the RelOptInfo representing the join between parent
852 * relations. Some of the members of new RelOptInfo are produced by
853 * translating corresponding members of this RelOptInfo
854 * 'restrictlist': list of RestrictInfo nodes that apply to this particular
855 * pair of joinable relations
856 * 'sjinfo': child join's join-type details
858 RelOptInfo *
859 build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
860 RelOptInfo *inner_rel, RelOptInfo *parent_joinrel,
861 List *restrictlist, SpecialJoinInfo *sjinfo)
863 RelOptInfo *joinrel = makeNode(RelOptInfo);
864 AppendRelInfo **appinfos;
865 int nappinfos;
867 /* Only joins between "other" relations land here. */
868 Assert(IS_OTHER_REL(outer_rel) && IS_OTHER_REL(inner_rel));
870 /* The parent joinrel should have consider_partitionwise_join set. */
871 Assert(parent_joinrel->consider_partitionwise_join);
874 * Find the AppendRelInfo structures for the child baserels. We'll need
875 * these for computing the child join's relid set, and later for mapping
876 * Vars to the child rel.
878 appinfos = find_appinfos_by_relids(root,
879 bms_union(outer_rel->relids,
880 inner_rel->relids),
881 &nappinfos);
883 joinrel->reloptkind = RELOPT_OTHER_JOINREL;
884 joinrel->relids = adjust_child_relids(parent_joinrel->relids,
885 nappinfos, appinfos);
886 joinrel->rows = 0;
887 /* cheap startup cost is interesting iff not all tuples to be retrieved */
888 joinrel->consider_startup = (root->tuple_fraction > 0);
889 joinrel->consider_param_startup = false;
890 joinrel->consider_parallel = false;
891 joinrel->reltarget = create_empty_pathtarget();
892 joinrel->pathlist = NIL;
893 joinrel->ppilist = NIL;
894 joinrel->partial_pathlist = NIL;
895 joinrel->cheapest_startup_path = NULL;
896 joinrel->cheapest_total_path = NULL;
897 joinrel->cheapest_unique_path = NULL;
898 joinrel->cheapest_parameterized_paths = NIL;
899 joinrel->direct_lateral_relids = NULL;
900 joinrel->lateral_relids = NULL;
901 joinrel->relid = 0; /* indicates not a baserel */
902 joinrel->rtekind = RTE_JOIN;
903 joinrel->min_attr = 0;
904 joinrel->max_attr = 0;
905 joinrel->attr_needed = NULL;
906 joinrel->attr_widths = NULL;
907 joinrel->nulling_relids = NULL;
908 joinrel->lateral_vars = NIL;
909 joinrel->lateral_referencers = NULL;
910 joinrel->indexlist = NIL;
911 joinrel->pages = 0;
912 joinrel->tuples = 0;
913 joinrel->allvisfrac = 0;
914 joinrel->eclass_indexes = NULL;
915 joinrel->subroot = NULL;
916 joinrel->subplan_params = NIL;
917 joinrel->amflags = 0;
918 joinrel->serverid = InvalidOid;
919 joinrel->userid = InvalidOid;
920 joinrel->useridiscurrent = false;
921 joinrel->fdwroutine = NULL;
922 joinrel->fdw_private = NULL;
923 joinrel->baserestrictinfo = NIL;
924 joinrel->baserestrictcost.startup = 0;
925 joinrel->baserestrictcost.per_tuple = 0;
926 joinrel->joininfo = NIL;
927 joinrel->has_eclass_joins = false;
928 joinrel->consider_partitionwise_join = false; /* might get changed later */
929 joinrel->parent = parent_joinrel;
930 joinrel->top_parent = parent_joinrel->top_parent ? parent_joinrel->top_parent : parent_joinrel;
931 joinrel->top_parent_relids = joinrel->top_parent->relids;
932 joinrel->part_scheme = NULL;
933 joinrel->nparts = -1;
934 joinrel->boundinfo = NULL;
935 joinrel->partbounds_merged = false;
936 joinrel->partition_qual = NIL;
937 joinrel->part_rels = NULL;
938 joinrel->live_parts = NULL;
939 joinrel->all_partrels = NULL;
940 joinrel->partexprs = NULL;
941 joinrel->nullable_partexprs = NULL;
943 /* Compute information relevant to foreign relations. */
944 set_foreign_rel_properties(joinrel, outer_rel, inner_rel);
946 /* Set up reltarget struct */
947 build_child_join_reltarget(root, parent_joinrel, joinrel,
948 nappinfos, appinfos);
950 /* Construct joininfo list. */
951 joinrel->joininfo = (List *) adjust_appendrel_attrs(root,
952 (Node *) parent_joinrel->joininfo,
953 nappinfos,
954 appinfos);
957 * Lateral relids referred in child join will be same as that referred in
958 * the parent relation.
960 joinrel->direct_lateral_relids = (Relids) bms_copy(parent_joinrel->direct_lateral_relids);
961 joinrel->lateral_relids = (Relids) bms_copy(parent_joinrel->lateral_relids);
964 * If the parent joinrel has pending equivalence classes, so does the
965 * child.
967 joinrel->has_eclass_joins = parent_joinrel->has_eclass_joins;
969 /* Is the join between partitions itself partitioned? */
970 build_joinrel_partition_info(root, joinrel, outer_rel, inner_rel, sjinfo,
971 restrictlist);
973 /* Child joinrel is parallel safe if parent is parallel safe. */
974 joinrel->consider_parallel = parent_joinrel->consider_parallel;
976 /* Set estimates of the child-joinrel's size. */
977 set_joinrel_size_estimates(root, joinrel, outer_rel, inner_rel,
978 sjinfo, restrictlist);
980 /* We build the join only once. */
981 Assert(!find_join_rel(root, joinrel->relids));
983 /* Add the relation to the PlannerInfo. */
984 add_join_rel(root, joinrel);
987 * We might need EquivalenceClass members corresponding to the child join,
988 * so that we can represent sort pathkeys for it. As with children of
989 * baserels, we shouldn't need this unless there are relevant eclass joins
990 * (implying that a merge join might be possible) or pathkeys to sort by.
992 if (joinrel->has_eclass_joins || has_useful_pathkeys(root, parent_joinrel))
993 add_child_join_rel_equivalences(root,
994 nappinfos, appinfos,
995 parent_joinrel, joinrel);
997 pfree(appinfos);
999 return joinrel;
1003 * min_join_parameterization
1005 * Determine the minimum possible parameterization of a joinrel, that is, the
1006 * set of other rels it contains LATERAL references to. We save this value in
1007 * the join's RelOptInfo. This function is split out of build_join_rel()
1008 * because join_is_legal() needs the value to check a prospective join.
1010 Relids
1011 min_join_parameterization(PlannerInfo *root,
1012 Relids joinrelids,
1013 RelOptInfo *outer_rel,
1014 RelOptInfo *inner_rel)
1016 Relids result;
1019 * Basically we just need the union of the inputs' lateral_relids, less
1020 * whatever is already in the join.
1022 * It's not immediately obvious that this is a valid way to compute the
1023 * result, because it might seem that we're ignoring possible lateral refs
1024 * of PlaceHolderVars that are due to be computed at the join but not in
1025 * either input. However, because create_lateral_join_info() already
1026 * charged all such PHV refs to each member baserel of the join, they'll
1027 * be accounted for already in the inputs' lateral_relids. Likewise, we
1028 * do not need to worry about doing transitive closure here, because that
1029 * was already accounted for in the original baserel lateral_relids.
1031 result = bms_union(outer_rel->lateral_relids, inner_rel->lateral_relids);
1032 result = bms_del_members(result, joinrelids);
1033 return result;
1037 * build_joinrel_tlist
1038 * Builds a join relation's target list from an input relation.
1039 * (This is invoked twice to handle the two input relations.)
1041 * The join's targetlist includes all Vars of its member relations that
1042 * will still be needed above the join. This subroutine adds all such
1043 * Vars from the specified input rel's tlist to the join rel's tlist.
1044 * Likewise for any PlaceHolderVars emitted by the input rel.
1046 * We also compute the expected width of the join's output, making use
1047 * of data that was cached at the baserel level by set_rel_width().
1049 * Pass can_null as true if the join is an outer join that can null Vars
1050 * from this input relation. If so, we will (normally) add the join's relid
1051 * to the nulling bitmaps of Vars and PHVs bubbled up from the input.
1053 * When forming an outer join's target list, special handling is needed in
1054 * case the outer join was commuted with another one per outer join identity 3
1055 * (see optimizer/README). We must take steps to ensure that the output Vars
1056 * have the same nulling bitmaps that they would if the two joins had been
1057 * done in syntactic order; else they won't match Vars appearing higher in
1058 * the query tree. An exception to the match-the-syntactic-order rule is
1059 * that when an outer join is pushed down into another one's RHS per identity
1060 * 3, we can't mark its Vars as nulled until the now-upper outer join is also
1061 * completed. So we need to do three things:
1063 * First, we add the outer join's relid to the nulling bitmap only if the
1064 * outer join has been completely performed and the Var or PHV actually
1065 * comes from within the syntactically nullable side(s) of the outer join.
1066 * This takes care of the possibility that we have transformed
1067 * (A leftjoin B on (Pab)) leftjoin C on (Pbc)
1068 * to
1069 * A leftjoin (B leftjoin C on (Pbc)) on (Pab)
1070 * Here the pushed-down B/C join cannot mark C columns as nulled yet,
1071 * while the now-upper A/B join must not mark C columns as nulled by itself.
1073 * Second, perform the same operation for each SpecialJoinInfo listed in
1074 * pushed_down_joins (which, in this example, would be the B/C join when
1075 * we are at the now-upper A/B join). This allows the now-upper join to
1076 * complete the marking of "C" Vars that now have fully valid values.
1078 * Third, any relid in sjinfo->commute_above_r that is already part of
1079 * the joinrel is added to the nulling bitmaps of nullable Vars and PHVs.
1080 * This takes care of the reverse case where we implement
1081 * A leftjoin (B leftjoin C on (Pbc)) on (Pab)
1082 * as
1083 * (A leftjoin B on (Pab)) leftjoin C on (Pbc)
1084 * The C columns emitted by the B/C join need to be shown as nulled by both
1085 * the B/C and A/B joins, even though they've not physically traversed the
1086 * A/B join.
1088 static void
1089 build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel,
1090 RelOptInfo *input_rel,
1091 SpecialJoinInfo *sjinfo,
1092 List *pushed_down_joins,
1093 bool can_null)
1095 Relids relids = joinrel->relids;
1096 int64 tuple_width = joinrel->reltarget->width;
1097 ListCell *vars;
1098 ListCell *lc;
1100 foreach(vars, input_rel->reltarget->exprs)
1102 Var *var = (Var *) lfirst(vars);
1105 * For a PlaceHolderVar, we have to look up the PlaceHolderInfo.
1107 if (IsA(var, PlaceHolderVar))
1109 PlaceHolderVar *phv = (PlaceHolderVar *) var;
1110 PlaceHolderInfo *phinfo = find_placeholder_info(root, phv);
1112 /* Is it still needed above this joinrel? */
1113 if (bms_nonempty_difference(phinfo->ph_needed, relids))
1116 * Yup, add it to the output. If this join potentially nulls
1117 * this input, we have to update the PHV's phnullingrels,
1118 * which means making a copy.
1120 if (can_null)
1122 phv = copyObject(phv);
1123 /* See comments above to understand this logic */
1124 if (sjinfo->ojrelid != 0 &&
1125 bms_is_member(sjinfo->ojrelid, relids) &&
1126 (bms_is_subset(phv->phrels, sjinfo->syn_righthand) ||
1127 (sjinfo->jointype == JOIN_FULL &&
1128 bms_is_subset(phv->phrels, sjinfo->syn_lefthand))))
1129 phv->phnullingrels = bms_add_member(phv->phnullingrels,
1130 sjinfo->ojrelid);
1131 foreach(lc, pushed_down_joins)
1133 SpecialJoinInfo *othersj = (SpecialJoinInfo *) lfirst(lc);
1135 Assert(bms_is_member(othersj->ojrelid, relids));
1136 if (bms_is_subset(phv->phrels, othersj->syn_righthand))
1137 phv->phnullingrels = bms_add_member(phv->phnullingrels,
1138 othersj->ojrelid);
1140 phv->phnullingrels =
1141 bms_join(phv->phnullingrels,
1142 bms_intersect(sjinfo->commute_above_r,
1143 relids));
1146 joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs,
1147 phv);
1148 /* Bubbling up the precomputed result has cost zero */
1149 tuple_width += phinfo->ph_width;
1151 continue;
1155 * Otherwise, anything in a baserel or joinrel targetlist ought to be
1156 * a Var. (More general cases can only appear in appendrel child
1157 * rels, which will never be seen here.)
1159 if (!IsA(var, Var))
1160 elog(ERROR, "unexpected node type in rel targetlist: %d",
1161 (int) nodeTag(var));
1163 if (var->varno == ROWID_VAR)
1165 /* UPDATE/DELETE/MERGE row identity vars are always needed */
1166 RowIdentityVarInfo *ridinfo = (RowIdentityVarInfo *)
1167 list_nth(root->row_identity_vars, var->varattno - 1);
1169 /* Update reltarget width estimate from RowIdentityVarInfo */
1170 tuple_width += ridinfo->rowidwidth;
1172 else
1174 RelOptInfo *baserel;
1175 int ndx;
1177 /* Get the Var's original base rel */
1178 baserel = find_base_rel(root, var->varno);
1180 /* Is it still needed above this joinrel? */
1181 ndx = var->varattno - baserel->min_attr;
1182 if (!bms_nonempty_difference(baserel->attr_needed[ndx], relids))
1183 continue; /* nope, skip it */
1185 /* Update reltarget width estimate from baserel's attr_widths */
1186 tuple_width += baserel->attr_widths[ndx];
1190 * Add the Var to the output. If this join potentially nulls this
1191 * input, we have to update the Var's varnullingrels, which means
1192 * making a copy. But note that we don't ever add nullingrel bits to
1193 * row identity Vars (cf. comments in setrefs.c).
1195 if (can_null && var->varno != ROWID_VAR)
1197 var = copyObject(var);
1198 /* See comments above to understand this logic */
1199 if (sjinfo->ojrelid != 0 &&
1200 bms_is_member(sjinfo->ojrelid, relids) &&
1201 (bms_is_member(var->varno, sjinfo->syn_righthand) ||
1202 (sjinfo->jointype == JOIN_FULL &&
1203 bms_is_member(var->varno, sjinfo->syn_lefthand))))
1204 var->varnullingrels = bms_add_member(var->varnullingrels,
1205 sjinfo->ojrelid);
1206 foreach(lc, pushed_down_joins)
1208 SpecialJoinInfo *othersj = (SpecialJoinInfo *) lfirst(lc);
1210 Assert(bms_is_member(othersj->ojrelid, relids));
1211 if (bms_is_member(var->varno, othersj->syn_righthand))
1212 var->varnullingrels = bms_add_member(var->varnullingrels,
1213 othersj->ojrelid);
1215 var->varnullingrels =
1216 bms_join(var->varnullingrels,
1217 bms_intersect(sjinfo->commute_above_r,
1218 relids));
1221 joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs,
1222 var);
1224 /* Vars have cost zero, so no need to adjust reltarget->cost */
1227 joinrel->reltarget->width = clamp_width_est(tuple_width);
1231 * build_joinrel_restrictlist
1232 * build_joinrel_joinlist
1233 * These routines build lists of restriction and join clauses for a
1234 * join relation from the joininfo lists of the relations it joins.
1236 * These routines are separate because the restriction list must be
1237 * built afresh for each pair of input sub-relations we consider, whereas
1238 * the join list need only be computed once for any join RelOptInfo.
1239 * The join list is fully determined by the set of rels making up the
1240 * joinrel, so we should get the same results (up to ordering) from any
1241 * candidate pair of sub-relations. But the restriction list is whatever
1242 * is not handled in the sub-relations, so it depends on which
1243 * sub-relations are considered.
1245 * If a join clause from an input relation refers to base+OJ rels still not
1246 * present in the joinrel, then it is still a join clause for the joinrel;
1247 * we put it into the joininfo list for the joinrel. Otherwise,
1248 * the clause is now a restrict clause for the joined relation, and we
1249 * return it to the caller of build_joinrel_restrictlist() to be stored in
1250 * join paths made from this pair of sub-relations. (It will not need to
1251 * be considered further up the join tree.)
1253 * In many cases we will find the same RestrictInfos in both input
1254 * relations' joinlists, so be careful to eliminate duplicates.
1255 * Pointer equality should be a sufficient test for dups, since all
1256 * the various joinlist entries ultimately refer to RestrictInfos
1257 * pushed into them by distribute_restrictinfo_to_rels().
1259 * 'joinrel' is a join relation node
1260 * 'outer_rel' and 'inner_rel' are a pair of relations that can be joined
1261 * to form joinrel.
1262 * 'sjinfo': join context info
1264 * build_joinrel_restrictlist() returns a list of relevant restrictinfos,
1265 * whereas build_joinrel_joinlist() stores its results in the joinrel's
1266 * joininfo list. One or the other must accept each given clause!
1268 * NB: Formerly, we made deep(!) copies of each input RestrictInfo to pass
1269 * up to the join relation. I believe this is no longer necessary, because
1270 * RestrictInfo nodes are no longer context-dependent. Instead, just include
1271 * the original nodes in the lists made for the join relation.
1273 static List *
1274 build_joinrel_restrictlist(PlannerInfo *root,
1275 RelOptInfo *joinrel,
1276 RelOptInfo *outer_rel,
1277 RelOptInfo *inner_rel,
1278 SpecialJoinInfo *sjinfo)
1280 List *result;
1281 Relids both_input_relids;
1283 both_input_relids = bms_union(outer_rel->relids, inner_rel->relids);
1286 * Collect all the clauses that syntactically belong at this level,
1287 * eliminating any duplicates (important since we will see many of the
1288 * same clauses arriving from both input relations).
1290 result = subbuild_joinrel_restrictlist(root, joinrel, outer_rel,
1291 both_input_relids, NIL);
1292 result = subbuild_joinrel_restrictlist(root, joinrel, inner_rel,
1293 both_input_relids, result);
1296 * Add on any clauses derived from EquivalenceClasses. These cannot be
1297 * redundant with the clauses in the joininfo lists, so don't bother
1298 * checking.
1300 result = list_concat(result,
1301 generate_join_implied_equalities(root,
1302 joinrel->relids,
1303 outer_rel->relids,
1304 inner_rel,
1305 sjinfo));
1307 return result;
1310 static void
1311 build_joinrel_joinlist(RelOptInfo *joinrel,
1312 RelOptInfo *outer_rel,
1313 RelOptInfo *inner_rel)
1315 List *result;
1318 * Collect all the clauses that syntactically belong above this level,
1319 * eliminating any duplicates (important since we will see many of the
1320 * same clauses arriving from both input relations).
1322 result = subbuild_joinrel_joinlist(joinrel, outer_rel->joininfo, NIL);
1323 result = subbuild_joinrel_joinlist(joinrel, inner_rel->joininfo, result);
1325 joinrel->joininfo = result;
1328 static List *
1329 subbuild_joinrel_restrictlist(PlannerInfo *root,
1330 RelOptInfo *joinrel,
1331 RelOptInfo *input_rel,
1332 Relids both_input_relids,
1333 List *new_restrictlist)
1335 ListCell *l;
1337 foreach(l, input_rel->joininfo)
1339 RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
1341 if (bms_is_subset(rinfo->required_relids, joinrel->relids))
1344 * This clause should become a restriction clause for the joinrel,
1345 * since it refers to no outside rels. However, if it's a clone
1346 * clause then it might be too late to evaluate it, so we have to
1347 * check. (If it is too late, just ignore the clause, taking it
1348 * on faith that another clone was or will be selected.) Clone
1349 * clauses should always be outer-join clauses, so we compare
1350 * against both_input_relids.
1352 if (rinfo->has_clone || rinfo->is_clone)
1354 Assert(!RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids));
1355 if (!bms_is_subset(rinfo->required_relids, both_input_relids))
1356 continue;
1357 if (bms_overlap(rinfo->incompatible_relids, both_input_relids))
1358 continue;
1360 else
1363 * For non-clone clauses, we just Assert it's OK. These might
1364 * be either join or filter clauses; if it's a join clause
1365 * then it should not refer to the current join's output.
1366 * (There is little point in checking incompatible_relids,
1367 * because it'll be NULL.)
1369 Assert(RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids) ||
1370 bms_is_subset(rinfo->required_relids,
1371 both_input_relids));
1375 * OK, so add it to the list, being careful to eliminate
1376 * duplicates. (Since RestrictInfo nodes in different joinlists
1377 * will have been multiply-linked rather than copied, pointer
1378 * equality should be a sufficient test.)
1380 new_restrictlist = list_append_unique_ptr(new_restrictlist, rinfo);
1382 else
1385 * This clause is still a join clause at this level, so we ignore
1386 * it in this routine.
1391 return new_restrictlist;
1394 static List *
1395 subbuild_joinrel_joinlist(RelOptInfo *joinrel,
1396 List *joininfo_list,
1397 List *new_joininfo)
1399 ListCell *l;
1401 /* Expected to be called only for join between parent relations. */
1402 Assert(joinrel->reloptkind == RELOPT_JOINREL);
1404 foreach(l, joininfo_list)
1406 RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
1408 if (bms_is_subset(rinfo->required_relids, joinrel->relids))
1411 * This clause becomes a restriction clause for the joinrel, since
1412 * it refers to no outside rels. So we can ignore it in this
1413 * routine.
1416 else
1419 * This clause is still a join clause at this level, so add it to
1420 * the new joininfo list, being careful to eliminate duplicates.
1421 * (Since RestrictInfo nodes in different joinlists will have been
1422 * multiply-linked rather than copied, pointer equality should be
1423 * a sufficient test.)
1425 new_joininfo = list_append_unique_ptr(new_joininfo, rinfo);
1429 return new_joininfo;
1434 * fetch_upper_rel
1435 * Build a RelOptInfo describing some post-scan/join query processing,
1436 * or return a pre-existing one if somebody already built it.
1438 * An "upper" relation is identified by an UpperRelationKind and a Relids set.
1439 * The meaning of the Relids set is not specified here, and very likely will
1440 * vary for different relation kinds.
1442 * Most of the fields in an upper-level RelOptInfo are not used and are not
1443 * set here (though makeNode should ensure they're zeroes). We basically only
1444 * care about fields that are of interest to add_path() and set_cheapest().
1446 RelOptInfo *
1447 fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)
1449 RelOptInfo *upperrel;
1450 ListCell *lc;
1453 * For the moment, our indexing data structure is just a List for each
1454 * relation kind. If we ever get so many of one kind that this stops
1455 * working well, we can improve it. No code outside this function should
1456 * assume anything about how to find a particular upperrel.
1459 /* If we already made this upperrel for the query, return it */
1460 foreach(lc, root->upper_rels[kind])
1462 upperrel = (RelOptInfo *) lfirst(lc);
1464 if (bms_equal(upperrel->relids, relids))
1465 return upperrel;
1468 upperrel = makeNode(RelOptInfo);
1469 upperrel->reloptkind = RELOPT_UPPER_REL;
1470 upperrel->relids = bms_copy(relids);
1472 /* cheap startup cost is interesting iff not all tuples to be retrieved */
1473 upperrel->consider_startup = (root->tuple_fraction > 0);
1474 upperrel->consider_param_startup = false;
1475 upperrel->consider_parallel = false; /* might get changed later */
1476 upperrel->reltarget = create_empty_pathtarget();
1477 upperrel->pathlist = NIL;
1478 upperrel->cheapest_startup_path = NULL;
1479 upperrel->cheapest_total_path = NULL;
1480 upperrel->cheapest_unique_path = NULL;
1481 upperrel->cheapest_parameterized_paths = NIL;
1483 root->upper_rels[kind] = lappend(root->upper_rels[kind], upperrel);
1485 return upperrel;
1490 * find_childrel_parents
1491 * Compute the set of parent relids of an appendrel child rel.
1493 * Since appendrels can be nested, a child could have multiple levels of
1494 * appendrel ancestors. This function computes a Relids set of all the
1495 * parent relation IDs.
1497 Relids
1498 find_childrel_parents(PlannerInfo *root, RelOptInfo *rel)
1500 Relids result = NULL;
1502 Assert(rel->reloptkind == RELOPT_OTHER_MEMBER_REL);
1503 Assert(rel->relid > 0 && rel->relid < root->simple_rel_array_size);
1507 AppendRelInfo *appinfo = root->append_rel_array[rel->relid];
1508 Index prelid = appinfo->parent_relid;
1510 result = bms_add_member(result, prelid);
1512 /* traverse up to the parent rel, loop if it's also a child rel */
1513 rel = find_base_rel(root, prelid);
1514 } while (rel->reloptkind == RELOPT_OTHER_MEMBER_REL);
1516 Assert(rel->reloptkind == RELOPT_BASEREL);
1518 return result;
1523 * get_baserel_parampathinfo
1524 * Get the ParamPathInfo for a parameterized path for a base relation,
1525 * constructing one if we don't have one already.
1527 * This centralizes estimating the rowcounts for parameterized paths.
1528 * We need to cache those to be sure we use the same rowcount for all paths
1529 * of the same parameterization for a given rel. This is also a convenient
1530 * place to determine which movable join clauses the parameterized path will
1531 * be responsible for evaluating.
1533 ParamPathInfo *
1534 get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel,
1535 Relids required_outer)
1537 ParamPathInfo *ppi;
1538 Relids joinrelids;
1539 List *pclauses;
1540 Bitmapset *pserials;
1541 double rows;
1542 ListCell *lc;
1544 /* If rel has LATERAL refs, every path for it should account for them */
1545 Assert(bms_is_subset(baserel->lateral_relids, required_outer));
1547 /* Unparameterized paths have no ParamPathInfo */
1548 if (bms_is_empty(required_outer))
1549 return NULL;
1551 Assert(!bms_overlap(baserel->relids, required_outer));
1553 /* If we already have a PPI for this parameterization, just return it */
1554 if ((ppi = find_param_path_info(baserel, required_outer)))
1555 return ppi;
1558 * Identify all joinclauses that are movable to this base rel given this
1559 * parameterization.
1561 joinrelids = bms_union(baserel->relids, required_outer);
1562 pclauses = NIL;
1563 foreach(lc, baserel->joininfo)
1565 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1567 if (join_clause_is_movable_into(rinfo,
1568 baserel->relids,
1569 joinrelids))
1570 pclauses = lappend(pclauses, rinfo);
1574 * Add in joinclauses generated by EquivalenceClasses, too. (These
1575 * necessarily satisfy join_clause_is_movable_into.)
1577 pclauses = list_concat(pclauses,
1578 generate_join_implied_equalities(root,
1579 joinrelids,
1580 required_outer,
1581 baserel,
1582 NULL));
1584 /* Compute set of serial numbers of the enforced clauses */
1585 pserials = NULL;
1586 foreach(lc, pclauses)
1588 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1590 pserials = bms_add_member(pserials, rinfo->rinfo_serial);
1593 /* Estimate the number of rows returned by the parameterized scan */
1594 rows = get_parameterized_baserel_size(root, baserel, pclauses);
1596 /* And now we can build the ParamPathInfo */
1597 ppi = makeNode(ParamPathInfo);
1598 ppi->ppi_req_outer = required_outer;
1599 ppi->ppi_rows = rows;
1600 ppi->ppi_clauses = pclauses;
1601 ppi->ppi_serials = pserials;
1602 baserel->ppilist = lappend(baserel->ppilist, ppi);
1604 return ppi;
1608 * get_joinrel_parampathinfo
1609 * Get the ParamPathInfo for a parameterized path for a join relation,
1610 * constructing one if we don't have one already.
1612 * This centralizes estimating the rowcounts for parameterized paths.
1613 * We need to cache those to be sure we use the same rowcount for all paths
1614 * of the same parameterization for a given rel. This is also a convenient
1615 * place to determine which movable join clauses the parameterized path will
1616 * be responsible for evaluating.
1618 * outer_path and inner_path are a pair of input paths that can be used to
1619 * construct the join, and restrict_clauses is the list of regular join
1620 * clauses (including clauses derived from EquivalenceClasses) that must be
1621 * applied at the join node when using these inputs.
1623 * Unlike the situation for base rels, the set of movable join clauses to be
1624 * enforced at a join varies with the selected pair of input paths, so we
1625 * must calculate that and pass it back, even if we already have a matching
1626 * ParamPathInfo. We handle this by adding any clauses moved down to this
1627 * join to *restrict_clauses, which is an in/out parameter. (The addition
1628 * is done in such a way as to not modify the passed-in List structure.)
1630 * Note: when considering a nestloop join, the caller must have removed from
1631 * restrict_clauses any movable clauses that are themselves scheduled to be
1632 * pushed into the right-hand path. We do not do that here since it's
1633 * unnecessary for other join types.
1635 ParamPathInfo *
1636 get_joinrel_parampathinfo(PlannerInfo *root, RelOptInfo *joinrel,
1637 Path *outer_path,
1638 Path *inner_path,
1639 SpecialJoinInfo *sjinfo,
1640 Relids required_outer,
1641 List **restrict_clauses)
1643 ParamPathInfo *ppi;
1644 Relids join_and_req;
1645 Relids outer_and_req;
1646 Relids inner_and_req;
1647 List *pclauses;
1648 List *eclauses;
1649 List *dropped_ecs;
1650 double rows;
1651 ListCell *lc;
1653 /* If rel has LATERAL refs, every path for it should account for them */
1654 Assert(bms_is_subset(joinrel->lateral_relids, required_outer));
1656 /* Unparameterized paths have no ParamPathInfo or extra join clauses */
1657 if (bms_is_empty(required_outer))
1658 return NULL;
1660 Assert(!bms_overlap(joinrel->relids, required_outer));
1663 * Identify all joinclauses that are movable to this join rel given this
1664 * parameterization. These are the clauses that are movable into this
1665 * join, but not movable into either input path. Treat an unparameterized
1666 * input path as not accepting parameterized clauses (because it won't,
1667 * per the shortcut exit above), even though the joinclause movement rules
1668 * might allow the same clauses to be moved into a parameterized path for
1669 * that rel.
1671 join_and_req = bms_union(joinrel->relids, required_outer);
1672 if (outer_path->param_info)
1673 outer_and_req = bms_union(outer_path->parent->relids,
1674 PATH_REQ_OUTER(outer_path));
1675 else
1676 outer_and_req = NULL; /* outer path does not accept parameters */
1677 if (inner_path->param_info)
1678 inner_and_req = bms_union(inner_path->parent->relids,
1679 PATH_REQ_OUTER(inner_path));
1680 else
1681 inner_and_req = NULL; /* inner path does not accept parameters */
1683 pclauses = NIL;
1684 foreach(lc, joinrel->joininfo)
1686 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1688 if (join_clause_is_movable_into(rinfo,
1689 joinrel->relids,
1690 join_and_req) &&
1691 !join_clause_is_movable_into(rinfo,
1692 outer_path->parent->relids,
1693 outer_and_req) &&
1694 !join_clause_is_movable_into(rinfo,
1695 inner_path->parent->relids,
1696 inner_and_req))
1697 pclauses = lappend(pclauses, rinfo);
1700 /* Consider joinclauses generated by EquivalenceClasses, too */
1701 eclauses = generate_join_implied_equalities(root,
1702 join_and_req,
1703 required_outer,
1704 joinrel,
1705 NULL);
1706 /* We only want ones that aren't movable to lower levels */
1707 dropped_ecs = NIL;
1708 foreach(lc, eclauses)
1710 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1712 Assert(join_clause_is_movable_into(rinfo,
1713 joinrel->relids,
1714 join_and_req));
1715 if (join_clause_is_movable_into(rinfo,
1716 outer_path->parent->relids,
1717 outer_and_req))
1718 continue; /* drop if movable into LHS */
1719 if (join_clause_is_movable_into(rinfo,
1720 inner_path->parent->relids,
1721 inner_and_req))
1723 /* drop if movable into RHS, but remember EC for use below */
1724 Assert(rinfo->left_ec == rinfo->right_ec);
1725 dropped_ecs = lappend(dropped_ecs, rinfo->left_ec);
1726 continue;
1728 pclauses = lappend(pclauses, rinfo);
1732 * EquivalenceClasses are harder to deal with than we could wish, because
1733 * of the fact that a given EC can generate different clauses depending on
1734 * context. Suppose we have an EC {X.X, Y.Y, Z.Z} where X and Y are the
1735 * LHS and RHS of the current join and Z is in required_outer, and further
1736 * suppose that the inner_path is parameterized by both X and Z. The code
1737 * above will have produced either Z.Z = X.X or Z.Z = Y.Y from that EC,
1738 * and in the latter case will have discarded it as being movable into the
1739 * RHS. However, the EC machinery might have produced either Y.Y = X.X or
1740 * Y.Y = Z.Z as the EC enforcement clause within the inner_path; it will
1741 * not have produced both, and we can't readily tell from here which one
1742 * it did pick. If we add no clause to this join, we'll end up with
1743 * insufficient enforcement of the EC; either Z.Z or X.X will fail to be
1744 * constrained to be equal to the other members of the EC. (When we come
1745 * to join Z to this X/Y path, we will certainly drop whichever EC clause
1746 * is generated at that join, so this omission won't get fixed later.)
1748 * To handle this, for each EC we discarded such a clause from, try to
1749 * generate a clause connecting the required_outer rels to the join's LHS
1750 * ("Z.Z = X.X" in the terms of the above example). If successful, and if
1751 * the clause can't be moved to the LHS, add it to the current join's
1752 * restriction clauses. (If an EC cannot generate such a clause then it
1753 * has nothing that needs to be enforced here, while if the clause can be
1754 * moved into the LHS then it should have been enforced within that path.)
1756 * Note that we don't need similar processing for ECs whose clause was
1757 * considered to be movable into the LHS, because the LHS can't refer to
1758 * the RHS so there is no comparable ambiguity about what it might
1759 * actually be enforcing internally.
1761 if (dropped_ecs)
1763 Relids real_outer_and_req;
1765 real_outer_and_req = bms_union(outer_path->parent->relids,
1766 required_outer);
1767 eclauses =
1768 generate_join_implied_equalities_for_ecs(root,
1769 dropped_ecs,
1770 real_outer_and_req,
1771 required_outer,
1772 outer_path->parent);
1773 foreach(lc, eclauses)
1775 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1777 Assert(join_clause_is_movable_into(rinfo,
1778 outer_path->parent->relids,
1779 real_outer_and_req));
1780 if (!join_clause_is_movable_into(rinfo,
1781 outer_path->parent->relids,
1782 outer_and_req))
1783 pclauses = lappend(pclauses, rinfo);
1788 * Now, attach the identified moved-down clauses to the caller's
1789 * restrict_clauses list. By using list_concat in this order, we leave
1790 * the original list structure of restrict_clauses undamaged.
1792 *restrict_clauses = list_concat(pclauses, *restrict_clauses);
1794 /* If we already have a PPI for this parameterization, just return it */
1795 if ((ppi = find_param_path_info(joinrel, required_outer)))
1796 return ppi;
1798 /* Estimate the number of rows returned by the parameterized join */
1799 rows = get_parameterized_joinrel_size(root, joinrel,
1800 outer_path,
1801 inner_path,
1802 sjinfo,
1803 *restrict_clauses);
1806 * And now we can build the ParamPathInfo. No point in saving the
1807 * input-pair-dependent clause list, though.
1809 * Note: in GEQO mode, we'll be called in a temporary memory context, but
1810 * the joinrel structure is there too, so no problem.
1812 ppi = makeNode(ParamPathInfo);
1813 ppi->ppi_req_outer = required_outer;
1814 ppi->ppi_rows = rows;
1815 ppi->ppi_clauses = NIL;
1816 ppi->ppi_serials = NULL;
1817 joinrel->ppilist = lappend(joinrel->ppilist, ppi);
1819 return ppi;
1823 * get_appendrel_parampathinfo
1824 * Get the ParamPathInfo for a parameterized path for an append relation.
1826 * For an append relation, the rowcount estimate will just be the sum of
1827 * the estimates for its children. However, we still need a ParamPathInfo
1828 * to flag the fact that the path requires parameters. So this just creates
1829 * a suitable struct with zero ppi_rows (and no ppi_clauses either, since
1830 * the Append node isn't responsible for checking quals).
1832 ParamPathInfo *
1833 get_appendrel_parampathinfo(RelOptInfo *appendrel, Relids required_outer)
1835 ParamPathInfo *ppi;
1837 /* If rel has LATERAL refs, every path for it should account for them */
1838 Assert(bms_is_subset(appendrel->lateral_relids, required_outer));
1840 /* Unparameterized paths have no ParamPathInfo */
1841 if (bms_is_empty(required_outer))
1842 return NULL;
1844 Assert(!bms_overlap(appendrel->relids, required_outer));
1846 /* If we already have a PPI for this parameterization, just return it */
1847 if ((ppi = find_param_path_info(appendrel, required_outer)))
1848 return ppi;
1850 /* Else build the ParamPathInfo */
1851 ppi = makeNode(ParamPathInfo);
1852 ppi->ppi_req_outer = required_outer;
1853 ppi->ppi_rows = 0;
1854 ppi->ppi_clauses = NIL;
1855 ppi->ppi_serials = NULL;
1856 appendrel->ppilist = lappend(appendrel->ppilist, ppi);
1858 return ppi;
1862 * Returns a ParamPathInfo for the parameterization given by required_outer, if
1863 * already available in the given rel. Returns NULL otherwise.
1865 ParamPathInfo *
1866 find_param_path_info(RelOptInfo *rel, Relids required_outer)
1868 ListCell *lc;
1870 foreach(lc, rel->ppilist)
1872 ParamPathInfo *ppi = (ParamPathInfo *) lfirst(lc);
1874 if (bms_equal(ppi->ppi_req_outer, required_outer))
1875 return ppi;
1878 return NULL;
1882 * get_param_path_clause_serials
1883 * Given a parameterized Path, return the set of pushed-down clauses
1884 * (identified by rinfo_serial numbers) enforced within the Path.
1886 Bitmapset *
1887 get_param_path_clause_serials(Path *path)
1889 if (path->param_info == NULL)
1890 return NULL; /* not parameterized */
1891 if (IsA(path, NestPath) ||
1892 IsA(path, MergePath) ||
1893 IsA(path, HashPath))
1896 * For a join path, combine clauses enforced within either input path
1897 * with those enforced as joinrestrictinfo in this path. Note that
1898 * joinrestrictinfo may include some non-pushed-down clauses, but for
1899 * current purposes it's okay if we include those in the result. (To
1900 * be more careful, we could check for clause_relids overlapping the
1901 * path parameterization, but it's not worth the cycles for now.)
1903 JoinPath *jpath = (JoinPath *) path;
1904 Bitmapset *pserials;
1905 ListCell *lc;
1907 pserials = NULL;
1908 pserials = bms_add_members(pserials,
1909 get_param_path_clause_serials(jpath->outerjoinpath));
1910 pserials = bms_add_members(pserials,
1911 get_param_path_clause_serials(jpath->innerjoinpath));
1912 foreach(lc, jpath->joinrestrictinfo)
1914 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
1916 pserials = bms_add_member(pserials, rinfo->rinfo_serial);
1918 return pserials;
1920 else if (IsA(path, AppendPath))
1923 * For an appendrel, take the intersection of the sets of clauses
1924 * enforced in each input path.
1926 AppendPath *apath = (AppendPath *) path;
1927 Bitmapset *pserials;
1928 ListCell *lc;
1930 pserials = NULL;
1931 foreach(lc, apath->subpaths)
1933 Path *subpath = (Path *) lfirst(lc);
1934 Bitmapset *subserials;
1936 subserials = get_param_path_clause_serials(subpath);
1937 if (lc == list_head(apath->subpaths))
1938 pserials = bms_copy(subserials);
1939 else
1940 pserials = bms_int_members(pserials, subserials);
1942 return pserials;
1944 else if (IsA(path, MergeAppendPath))
1946 /* Same as AppendPath case */
1947 MergeAppendPath *apath = (MergeAppendPath *) path;
1948 Bitmapset *pserials;
1949 ListCell *lc;
1951 pserials = NULL;
1952 foreach(lc, apath->subpaths)
1954 Path *subpath = (Path *) lfirst(lc);
1955 Bitmapset *subserials;
1957 subserials = get_param_path_clause_serials(subpath);
1958 if (lc == list_head(apath->subpaths))
1959 pserials = bms_copy(subserials);
1960 else
1961 pserials = bms_int_members(pserials, subserials);
1963 return pserials;
1965 else
1968 * Otherwise, it's a baserel path and we can use the
1969 * previously-computed set of serial numbers.
1971 return path->param_info->ppi_serials;
1976 * build_joinrel_partition_info
1977 * Checks if the two relations being joined can use partitionwise join
1978 * and if yes, initialize partitioning information of the resulting
1979 * partitioned join relation.
1981 static void
1982 build_joinrel_partition_info(PlannerInfo *root,
1983 RelOptInfo *joinrel, RelOptInfo *outer_rel,
1984 RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo,
1985 List *restrictlist)
1987 PartitionScheme part_scheme;
1989 /* Nothing to do if partitionwise join technique is disabled. */
1990 if (!enable_partitionwise_join)
1992 Assert(!IS_PARTITIONED_REL(joinrel));
1993 return;
1997 * We can only consider this join as an input to further partitionwise
1998 * joins if (a) the input relations are partitioned and have
1999 * consider_partitionwise_join=true, (b) the partition schemes match, and
2000 * (c) we can identify an equi-join between the partition keys. Note that
2001 * if it were possible for have_partkey_equi_join to return different
2002 * answers for the same joinrel depending on which join ordering we try
2003 * first, this logic would break. That shouldn't happen, though, because
2004 * of the way the query planner deduces implied equalities and reorders
2005 * the joins. Please see optimizer/README for details.
2007 if (outer_rel->part_scheme == NULL || inner_rel->part_scheme == NULL ||
2008 !outer_rel->consider_partitionwise_join ||
2009 !inner_rel->consider_partitionwise_join ||
2010 outer_rel->part_scheme != inner_rel->part_scheme ||
2011 !have_partkey_equi_join(root, joinrel, outer_rel, inner_rel,
2012 sjinfo->jointype, restrictlist))
2014 Assert(!IS_PARTITIONED_REL(joinrel));
2015 return;
2018 part_scheme = outer_rel->part_scheme;
2021 * This function will be called only once for each joinrel, hence it
2022 * should not have partitioning fields filled yet.
2024 Assert(!joinrel->part_scheme && !joinrel->partexprs &&
2025 !joinrel->nullable_partexprs && !joinrel->part_rels &&
2026 !joinrel->boundinfo);
2029 * If the join relation is partitioned, it uses the same partitioning
2030 * scheme as the joining relations.
2032 * Note: we calculate the partition bounds, number of partitions, and
2033 * child-join relations of the join relation in try_partitionwise_join().
2035 joinrel->part_scheme = part_scheme;
2036 set_joinrel_partition_key_exprs(joinrel, outer_rel, inner_rel,
2037 sjinfo->jointype);
2040 * Set the consider_partitionwise_join flag.
2042 Assert(outer_rel->consider_partitionwise_join);
2043 Assert(inner_rel->consider_partitionwise_join);
2044 joinrel->consider_partitionwise_join = true;
2048 * have_partkey_equi_join
2050 * Returns true if there exist equi-join conditions involving pairs
2051 * of matching partition keys of the relations being joined for all
2052 * partition keys.
2054 static bool
2055 have_partkey_equi_join(PlannerInfo *root, RelOptInfo *joinrel,
2056 RelOptInfo *rel1, RelOptInfo *rel2,
2057 JoinType jointype, List *restrictlist)
2059 PartitionScheme part_scheme = rel1->part_scheme;
2060 ListCell *lc;
2061 int cnt_pks;
2062 bool pk_has_clause[PARTITION_MAX_KEYS];
2063 bool strict_op;
2066 * This function must only be called when the joined relations have same
2067 * partitioning scheme.
2069 Assert(rel1->part_scheme == rel2->part_scheme);
2070 Assert(part_scheme);
2072 memset(pk_has_clause, 0, sizeof(pk_has_clause));
2073 foreach(lc, restrictlist)
2075 RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
2076 OpExpr *opexpr;
2077 Expr *expr1;
2078 Expr *expr2;
2079 int ipk1;
2080 int ipk2;
2082 /* If processing an outer join, only use its own join clauses. */
2083 if (IS_OUTER_JOIN(jointype) &&
2084 RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids))
2085 continue;
2087 /* Skip clauses which can not be used for a join. */
2088 if (!rinfo->can_join)
2089 continue;
2091 /* Skip clauses which are not equality conditions. */
2092 if (!rinfo->mergeopfamilies && !OidIsValid(rinfo->hashjoinoperator))
2093 continue;
2095 /* Should be OK to assume it's an OpExpr. */
2096 opexpr = castNode(OpExpr, rinfo->clause);
2098 /* Match the operands to the relation. */
2099 if (bms_is_subset(rinfo->left_relids, rel1->relids) &&
2100 bms_is_subset(rinfo->right_relids, rel2->relids))
2102 expr1 = linitial(opexpr->args);
2103 expr2 = lsecond(opexpr->args);
2105 else if (bms_is_subset(rinfo->left_relids, rel2->relids) &&
2106 bms_is_subset(rinfo->right_relids, rel1->relids))
2108 expr1 = lsecond(opexpr->args);
2109 expr2 = linitial(opexpr->args);
2111 else
2112 continue;
2115 * Now we need to know whether the join operator is strict; see
2116 * comments in pathnodes.h.
2118 strict_op = op_strict(opexpr->opno);
2121 * Vars appearing in the relation's partition keys will not have any
2122 * varnullingrels, but those in expr1 and expr2 will if we're above
2123 * outer joins that could null the respective rels. It's okay to
2124 * match anyway, if the join operator is strict.
2126 if (strict_op)
2128 if (bms_overlap(rel1->relids, root->outer_join_rels))
2129 expr1 = (Expr *) remove_nulling_relids((Node *) expr1,
2130 root->outer_join_rels,
2131 NULL);
2132 if (bms_overlap(rel2->relids, root->outer_join_rels))
2133 expr2 = (Expr *) remove_nulling_relids((Node *) expr2,
2134 root->outer_join_rels,
2135 NULL);
2139 * Only clauses referencing the partition keys are useful for
2140 * partitionwise join.
2142 ipk1 = match_expr_to_partition_keys(expr1, rel1, strict_op);
2143 if (ipk1 < 0)
2144 continue;
2145 ipk2 = match_expr_to_partition_keys(expr2, rel2, strict_op);
2146 if (ipk2 < 0)
2147 continue;
2150 * If the clause refers to keys at different ordinal positions, it can
2151 * not be used for partitionwise join.
2153 if (ipk1 != ipk2)
2154 continue;
2157 * The clause allows partitionwise join only if it uses the same
2158 * operator family as that specified by the partition key.
2160 if (rel1->part_scheme->strategy == PARTITION_STRATEGY_HASH)
2162 if (!OidIsValid(rinfo->hashjoinoperator) ||
2163 !op_in_opfamily(rinfo->hashjoinoperator,
2164 part_scheme->partopfamily[ipk1]))
2165 continue;
2167 else if (!list_member_oid(rinfo->mergeopfamilies,
2168 part_scheme->partopfamily[ipk1]))
2169 continue;
2171 /* Mark the partition key as having an equi-join clause. */
2172 pk_has_clause[ipk1] = true;
2175 /* Check whether every partition key has an equi-join condition. */
2176 for (cnt_pks = 0; cnt_pks < part_scheme->partnatts; cnt_pks++)
2178 if (!pk_has_clause[cnt_pks])
2179 return false;
2182 return true;
2186 * match_expr_to_partition_keys
2188 * Tries to match an expression to one of the nullable or non-nullable
2189 * partition keys of "rel". Returns the matched key's ordinal position,
2190 * or -1 if the expression could not be matched to any of the keys.
2192 * strict_op must be true if the expression will be compared with the
2193 * partition key using a strict operator. This allows us to consider
2194 * nullable as well as nonnullable partition keys.
2196 static int
2197 match_expr_to_partition_keys(Expr *expr, RelOptInfo *rel, bool strict_op)
2199 int cnt;
2201 /* This function should be called only for partitioned relations. */
2202 Assert(rel->part_scheme);
2203 Assert(rel->partexprs);
2204 Assert(rel->nullable_partexprs);
2206 /* Remove any relabel decorations. */
2207 while (IsA(expr, RelabelType))
2208 expr = (Expr *) (castNode(RelabelType, expr))->arg;
2210 for (cnt = 0; cnt < rel->part_scheme->partnatts; cnt++)
2212 ListCell *lc;
2214 /* We can always match to the non-nullable partition keys. */
2215 foreach(lc, rel->partexprs[cnt])
2217 if (equal(lfirst(lc), expr))
2218 return cnt;
2221 if (!strict_op)
2222 continue;
2225 * If it's a strict join operator then a NULL partition key on one
2226 * side will not join to any partition key on the other side, and in
2227 * particular such a row can't join to a row from a different
2228 * partition on the other side. So, it's okay to search the nullable
2229 * partition keys as well.
2231 foreach(lc, rel->nullable_partexprs[cnt])
2233 if (equal(lfirst(lc), expr))
2234 return cnt;
2238 return -1;
2242 * set_joinrel_partition_key_exprs
2243 * Initialize partition key expressions for a partitioned joinrel.
2245 static void
2246 set_joinrel_partition_key_exprs(RelOptInfo *joinrel,
2247 RelOptInfo *outer_rel, RelOptInfo *inner_rel,
2248 JoinType jointype)
2250 PartitionScheme part_scheme = joinrel->part_scheme;
2251 int partnatts = part_scheme->partnatts;
2253 joinrel->partexprs = (List **) palloc0(sizeof(List *) * partnatts);
2254 joinrel->nullable_partexprs =
2255 (List **) palloc0(sizeof(List *) * partnatts);
2258 * The joinrel's partition expressions are the same as those of the input
2259 * rels, but we must properly classify them as nullable or not in the
2260 * joinrel's output. (Also, we add some more partition expressions if
2261 * it's a FULL JOIN.)
2263 for (int cnt = 0; cnt < partnatts; cnt++)
2265 /* mark these const to enforce that we copy them properly */
2266 const List *outer_expr = outer_rel->partexprs[cnt];
2267 const List *outer_null_expr = outer_rel->nullable_partexprs[cnt];
2268 const List *inner_expr = inner_rel->partexprs[cnt];
2269 const List *inner_null_expr = inner_rel->nullable_partexprs[cnt];
2270 List *partexpr = NIL;
2271 List *nullable_partexpr = NIL;
2272 ListCell *lc;
2274 switch (jointype)
2277 * A join relation resulting from an INNER join may be
2278 * regarded as partitioned by either of the inner and outer
2279 * relation keys. For example, A INNER JOIN B ON A.a = B.b
2280 * can be regarded as partitioned on either A.a or B.b. So we
2281 * add both keys to the joinrel's partexpr lists. However,
2282 * anything that was already nullable still has to be treated
2283 * as nullable.
2285 case JOIN_INNER:
2286 partexpr = list_concat_copy(outer_expr, inner_expr);
2287 nullable_partexpr = list_concat_copy(outer_null_expr,
2288 inner_null_expr);
2289 break;
2292 * A join relation resulting from a SEMI or ANTI join may be
2293 * regarded as partitioned by the outer relation keys. The
2294 * inner relation's keys are no longer interesting; since they
2295 * aren't visible in the join output, nothing could join to
2296 * them.
2298 case JOIN_SEMI:
2299 case JOIN_ANTI:
2300 partexpr = list_copy(outer_expr);
2301 nullable_partexpr = list_copy(outer_null_expr);
2302 break;
2305 * A join relation resulting from a LEFT OUTER JOIN likewise
2306 * may be regarded as partitioned on the (non-nullable) outer
2307 * relation keys. The inner (nullable) relation keys are okay
2308 * as partition keys for further joins as long as they involve
2309 * strict join operators.
2311 case JOIN_LEFT:
2312 partexpr = list_copy(outer_expr);
2313 nullable_partexpr = list_concat_copy(inner_expr,
2314 outer_null_expr);
2315 nullable_partexpr = list_concat(nullable_partexpr,
2316 inner_null_expr);
2317 break;
2320 * For FULL OUTER JOINs, both relations are nullable, so the
2321 * resulting join relation may be regarded as partitioned on
2322 * either of inner and outer relation keys, but only for joins
2323 * that involve strict join operators.
2325 case JOIN_FULL:
2326 nullable_partexpr = list_concat_copy(outer_expr,
2327 inner_expr);
2328 nullable_partexpr = list_concat(nullable_partexpr,
2329 outer_null_expr);
2330 nullable_partexpr = list_concat(nullable_partexpr,
2331 inner_null_expr);
2334 * Also add CoalesceExprs corresponding to each possible
2335 * full-join output variable (that is, left side coalesced to
2336 * right side), so that we can match equijoin expressions
2337 * using those variables. We really only need these for
2338 * columns merged by JOIN USING, and only with the pairs of
2339 * input items that correspond to the data structures that
2340 * parse analysis would build for such variables. But it's
2341 * hard to tell which those are, so just make all the pairs.
2342 * Extra items in the nullable_partexprs list won't cause big
2343 * problems. (It's possible that such items will get matched
2344 * to user-written COALESCEs, but it should still be valid to
2345 * partition on those, since they're going to be either the
2346 * partition column or NULL; it's the same argument as for
2347 * partitionwise nesting of any outer join.) We assume no
2348 * type coercions are needed to make the coalesce expressions,
2349 * since columns of different types won't have gotten
2350 * classified as the same PartitionScheme. Note that we
2351 * intentionally leave out the varnullingrels decoration that
2352 * would ordinarily appear on the Vars inside these
2353 * CoalesceExprs, because have_partkey_equi_join will strip
2354 * varnullingrels from the expressions it will compare to the
2355 * partexprs.
2357 foreach(lc, list_concat_copy(outer_expr, outer_null_expr))
2359 Node *larg = (Node *) lfirst(lc);
2360 ListCell *lc2;
2362 foreach(lc2, list_concat_copy(inner_expr, inner_null_expr))
2364 Node *rarg = (Node *) lfirst(lc2);
2365 CoalesceExpr *c = makeNode(CoalesceExpr);
2367 c->coalescetype = exprType(larg);
2368 c->coalescecollid = exprCollation(larg);
2369 c->args = list_make2(larg, rarg);
2370 c->location = -1;
2371 nullable_partexpr = lappend(nullable_partexpr, c);
2374 break;
2376 default:
2377 elog(ERROR, "unrecognized join type: %d", (int) jointype);
2380 joinrel->partexprs[cnt] = partexpr;
2381 joinrel->nullable_partexprs[cnt] = nullable_partexpr;
2386 * build_child_join_reltarget
2387 * Set up a child-join relation's reltarget from a parent-join relation.
2389 static void
2390 build_child_join_reltarget(PlannerInfo *root,
2391 RelOptInfo *parentrel,
2392 RelOptInfo *childrel,
2393 int nappinfos,
2394 AppendRelInfo **appinfos)
2396 /* Build the targetlist */
2397 childrel->reltarget->exprs = (List *)
2398 adjust_appendrel_attrs(root,
2399 (Node *) parentrel->reltarget->exprs,
2400 nappinfos, appinfos);
2402 /* Set the cost and width fields */
2403 childrel->reltarget->cost.startup = parentrel->reltarget->cost.startup;
2404 childrel->reltarget->cost.per_tuple = parentrel->reltarget->cost.per_tuple;
2405 childrel->reltarget->width = parentrel->reltarget->width;