1 /*-------------------------------------------------------------------------
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
11 * src/backend/optimizer/util/relnode.c
13 *-------------------------------------------------------------------------
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 */
44 static void build_joinrel_tlist(PlannerInfo
*root
, RelOptInfo
*joinrel
,
45 RelOptInfo
*input_rel
,
46 SpecialJoinInfo
*sjinfo
,
47 List
*pushed_down_joins
,
49 static List
*build_joinrel_restrictlist(PlannerInfo
*root
,
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
,
59 RelOptInfo
*input_rel
,
60 Relids both_input_relids
,
61 List
*new_restrictlist
);
62 static List
*subbuild_joinrel_joinlist(RelOptInfo
*joinrel
,
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
,
70 RelOptInfo
*outer_rel
, RelOptInfo
*inner_rel
,
71 SpecialJoinInfo
*sjinfo
,
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
,
78 static void set_joinrel_partition_key_exprs(RelOptInfo
*joinrel
,
79 RelOptInfo
*outer_rel
, RelOptInfo
*inner_rel
,
81 static void build_child_join_reltarget(PlannerInfo
*root
,
82 RelOptInfo
*parentrel
,
85 AppendRelInfo
**appinfos
);
89 * setup_simple_rel_arrays
90 * Prepare the arrays we use for quickly accessing base relations
94 setup_simple_rel_arrays(PlannerInfo
*root
)
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
*));
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
;
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
;
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.
163 expand_planner_arrays(PlannerInfo
*root
, int add_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
);
181 root
->append_rel_array
=
182 palloc0_array(AppendRelInfo
*, new_size
);
184 root
->simple_rel_array_size
= new_size
;
189 * Construct a new RelOptInfo for a base relation or 'other' relation.
192 build_simple_rel(PlannerInfo
*root
, int relid
, RelOptInfo
*parent
)
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
];
206 rel
= makeNode(RelOptInfo
);
207 rel
->reloptkind
= parent
? RELOPT_OTHER_MEMBER_REL
: RELOPT_BASEREL
;
208 rel
->relids
= bms_make_singleton(relid
);
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();
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
;
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
;
231 rel
->eclass_indexes
= NULL
;
233 rel
->subplan_params
= NIL
;
234 rel
->rel_parallel_workers
= -1; /* set up in get_relation_info */
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
;
262 rel
->userid
= parent
->userid
;
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
;
276 rel
->has_eclass_joins
= false;
277 rel
->consider_partitionwise_join
= false; /* might get changed later */
278 rel
->part_scheme
= NULL
;
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.
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
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
;
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
)
338 /* Table --- retrieve statistics from the system catalogs */
339 get_relation_info(root
, rte
->relid
, rte
->inh
, rel
);
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
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
));
362 /* RTE_RESULT has no columns, nor could it have whole-row Var */
365 rel
->attr_needed
= NULL
;
366 rel
->attr_widths
= NULL
;
369 elog(ERROR
, "unrecognized RTE kind: %d",
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.)
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.
395 /* Save the finished struct in the query's simple_rel_array */
396 root
->simple_rel_array
[relid
] = rel
;
403 * Find a base or otherrel relation entry, which must already exist.
406 find_base_rel(PlannerInfo
*root
, int relid
)
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
];
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
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
)
441 rel
= root
->simple_rel_array
[relid
];
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
450 rte
= root
->simple_rte_array
[relid
];
451 if (rte
&& rte
->rtekind
== RTE_JOIN
&& rte
->jointype
!= JOIN_INNER
)
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.
465 build_join_rel_hash(PlannerInfo
*root
)
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",
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
;
489 hentry
= (JoinHashEntry
*) hash_search(hashtab
,
494 hentry
->join_rel
= rel
;
497 root
->join_rel_hash
= hashtab
;
502 * Returns relation entry corresponding to 'relids' (a set of RT indexes),
503 * or NULL if none exists. This is for join relations.
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
523 if (root
->join_rel_hash
)
525 Relids hashkey
= relids
;
526 JoinHashEntry
*hentry
;
528 hentry
= (JoinHashEntry
*) hash_search(root
->join_rel_hash
,
533 return hentry
->join_rel
;
539 foreach(l
, root
->join_rel_list
)
541 RelOptInfo
*rel
= (RelOptInfo
*) lfirst(l
);
543 if (bms_equal(rel
->relids
, relids
))
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
564 * Otherwise these fields are left invalid, so GetForeignJoinPaths will not be
565 * called for the join relation.
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
;
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.
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
;
617 hentry
= (JoinHashEntry
*) hash_search(root
->join_rel_hash
,
622 hentry
->join_rel
= joinrel
;
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
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...
644 build_join_rel(PlannerInfo
*root
,
646 RelOptInfo
*outer_rel
,
647 RelOptInfo
*inner_rel
,
648 SpecialJoinInfo
*sjinfo
,
649 List
*pushed_down_joins
,
650 List
**restrictlist_ptr
)
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
);
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
,
681 joinrel
= makeNode(RelOptInfo
);
682 joinrel
->reloptkind
= RELOPT_JOINREL
;
683 joinrel
->relids
= bms_copy(joinrelids
);
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
;
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
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
,
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
,
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
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
);
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
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
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
;
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
,
883 joinrel
->reloptkind
= RELOPT_OTHER_JOINREL
;
884 joinrel
->relids
= adjust_child_relids(parent_joinrel
->relids
,
885 nappinfos
, appinfos
);
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
;
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
,
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
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
,
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
,
995 parent_joinrel
, 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.
1011 min_join_parameterization(PlannerInfo
*root
,
1013 RelOptInfo
*outer_rel
,
1014 RelOptInfo
*inner_rel
)
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
);
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)
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)
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
1089 build_joinrel_tlist(PlannerInfo
*root
, RelOptInfo
*joinrel
,
1090 RelOptInfo
*input_rel
,
1091 SpecialJoinInfo
*sjinfo
,
1092 List
*pushed_down_joins
,
1095 Relids relids
= joinrel
->relids
;
1096 int64 tuple_width
= joinrel
->reltarget
->width
;
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.
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
,
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
,
1140 phv
->phnullingrels
=
1141 bms_join(phv
->phnullingrels
,
1142 bms_intersect(sjinfo
->commute_above_r
,
1146 joinrel
->reltarget
->exprs
= lappend(joinrel
->reltarget
->exprs
,
1148 /* Bubbling up the precomputed result has cost zero */
1149 tuple_width
+= phinfo
->ph_width
;
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.)
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
;
1174 RelOptInfo
*baserel
;
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
,
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
,
1215 var
->varnullingrels
=
1216 bms_join(var
->varnullingrels
,
1217 bms_intersect(sjinfo
->commute_above_r
,
1221 joinrel
->reltarget
->exprs
= lappend(joinrel
->reltarget
->exprs
,
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
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.
1274 build_joinrel_restrictlist(PlannerInfo
*root
,
1275 RelOptInfo
*joinrel
,
1276 RelOptInfo
*outer_rel
,
1277 RelOptInfo
*inner_rel
,
1278 SpecialJoinInfo
*sjinfo
)
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
1300 result
= list_concat(result
,
1301 generate_join_implied_equalities(root
,
1311 build_joinrel_joinlist(RelOptInfo
*joinrel
,
1312 RelOptInfo
*outer_rel
,
1313 RelOptInfo
*inner_rel
)
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
;
1329 subbuild_joinrel_restrictlist(PlannerInfo
*root
,
1330 RelOptInfo
*joinrel
,
1331 RelOptInfo
*input_rel
,
1332 Relids both_input_relids
,
1333 List
*new_restrictlist
)
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
))
1357 if (bms_overlap(rinfo
->incompatible_relids
, both_input_relids
))
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
);
1385 * This clause is still a join clause at this level, so we ignore
1386 * it in this routine.
1391 return new_restrictlist
;
1395 subbuild_joinrel_joinlist(RelOptInfo
*joinrel
,
1396 List
*joininfo_list
,
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
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
;
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().
1447 fetch_upper_rel(PlannerInfo
*root
, UpperRelationKind kind
, Relids relids
)
1449 RelOptInfo
*upperrel
;
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
))
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
);
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.
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
);
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.
1534 get_baserel_parampathinfo(PlannerInfo
*root
, RelOptInfo
*baserel
,
1535 Relids required_outer
)
1540 Bitmapset
*pserials
;
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
))
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
)))
1558 * Identify all joinclauses that are movable to this base rel given this
1561 joinrelids
= bms_union(baserel
->relids
, required_outer
);
1563 foreach(lc
, baserel
->joininfo
)
1565 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(lc
);
1567 if (join_clause_is_movable_into(rinfo
,
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
,
1584 /* Compute set of serial numbers of the enforced clauses */
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
);
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.
1636 get_joinrel_parampathinfo(PlannerInfo
*root
, RelOptInfo
*joinrel
,
1639 SpecialJoinInfo
*sjinfo
,
1640 Relids required_outer
,
1641 List
**restrict_clauses
)
1644 Relids join_and_req
;
1645 Relids outer_and_req
;
1646 Relids inner_and_req
;
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
))
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
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
));
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
));
1681 inner_and_req
= NULL
; /* inner path does not accept parameters */
1684 foreach(lc
, joinrel
->joininfo
)
1686 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(lc
);
1688 if (join_clause_is_movable_into(rinfo
,
1691 !join_clause_is_movable_into(rinfo
,
1692 outer_path
->parent
->relids
,
1694 !join_clause_is_movable_into(rinfo
,
1695 inner_path
->parent
->relids
,
1697 pclauses
= lappend(pclauses
, rinfo
);
1700 /* Consider joinclauses generated by EquivalenceClasses, too */
1701 eclauses
= generate_join_implied_equalities(root
,
1706 /* We only want ones that aren't movable to lower levels */
1708 foreach(lc
, eclauses
)
1710 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(lc
);
1712 Assert(join_clause_is_movable_into(rinfo
,
1715 if (join_clause_is_movable_into(rinfo
,
1716 outer_path
->parent
->relids
,
1718 continue; /* drop if movable into LHS */
1719 if (join_clause_is_movable_into(rinfo
,
1720 inner_path
->parent
->relids
,
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
);
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.
1763 Relids real_outer_and_req
;
1765 real_outer_and_req
= bms_union(outer_path
->parent
->relids
,
1768 generate_join_implied_equalities_for_ecs(root
,
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
,
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
)))
1798 /* Estimate the number of rows returned by the parameterized join */
1799 rows
= get_parameterized_joinrel_size(root
, joinrel
,
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
);
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).
1833 get_appendrel_parampathinfo(RelOptInfo
*appendrel
, Relids required_outer
)
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
))
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
)))
1850 /* Else build the ParamPathInfo */
1851 ppi
= makeNode(ParamPathInfo
);
1852 ppi
->ppi_req_outer
= required_outer
;
1854 ppi
->ppi_clauses
= NIL
;
1855 ppi
->ppi_serials
= NULL
;
1856 appendrel
->ppilist
= lappend(appendrel
->ppilist
, ppi
);
1862 * Returns a ParamPathInfo for the parameterization given by required_outer, if
1863 * already available in the given rel. Returns NULL otherwise.
1866 find_param_path_info(RelOptInfo
*rel
, Relids required_outer
)
1870 foreach(lc
, rel
->ppilist
)
1872 ParamPathInfo
*ppi
= (ParamPathInfo
*) lfirst(lc
);
1874 if (bms_equal(ppi
->ppi_req_outer
, required_outer
))
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.
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
;
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
);
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
;
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
);
1940 pserials
= bms_int_members(pserials
, subserials
);
1944 else if (IsA(path
, MergeAppendPath
))
1946 /* Same as AppendPath case */
1947 MergeAppendPath
*apath
= (MergeAppendPath
*) path
;
1948 Bitmapset
*pserials
;
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
);
1961 pserials
= bms_int_members(pserials
, subserials
);
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.
1982 build_joinrel_partition_info(PlannerInfo
*root
,
1983 RelOptInfo
*joinrel
, RelOptInfo
*outer_rel
,
1984 RelOptInfo
*inner_rel
, SpecialJoinInfo
*sjinfo
,
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
));
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
));
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
,
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
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
;
2062 bool pk_has_clause
[PARTITION_MAX_KEYS
];
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
);
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
))
2087 /* Skip clauses which can not be used for a join. */
2088 if (!rinfo
->can_join
)
2091 /* Skip clauses which are not equality conditions. */
2092 if (!rinfo
->mergeopfamilies
&& !OidIsValid(rinfo
->hashjoinoperator
))
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
);
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.
2128 if (bms_overlap(rel1
->relids
, root
->outer_join_rels
))
2129 expr1
= (Expr
*) remove_nulling_relids((Node
*) expr1
,
2130 root
->outer_join_rels
,
2132 if (bms_overlap(rel2
->relids
, root
->outer_join_rels
))
2133 expr2
= (Expr
*) remove_nulling_relids((Node
*) expr2
,
2134 root
->outer_join_rels
,
2139 * Only clauses referencing the partition keys are useful for
2140 * partitionwise join.
2142 ipk1
= match_expr_to_partition_keys(expr1
, rel1
, strict_op
);
2145 ipk2
= match_expr_to_partition_keys(expr2
, rel2
, strict_op
);
2150 * If the clause refers to keys at different ordinal positions, it can
2151 * not be used for partitionwise join.
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
]))
2167 else if (!list_member_oid(rinfo
->mergeopfamilies
,
2168 part_scheme
->partopfamily
[ipk1
]))
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
])
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.
2197 match_expr_to_partition_keys(Expr
*expr
, RelOptInfo
*rel
, bool strict_op
)
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
++)
2214 /* We can always match to the non-nullable partition keys. */
2215 foreach(lc
, rel
->partexprs
[cnt
])
2217 if (equal(lfirst(lc
), expr
))
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
))
2242 * set_joinrel_partition_key_exprs
2243 * Initialize partition key expressions for a partitioned joinrel.
2246 set_joinrel_partition_key_exprs(RelOptInfo
*joinrel
,
2247 RelOptInfo
*outer_rel
, RelOptInfo
*inner_rel
,
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
;
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
2286 partexpr
= list_concat_copy(outer_expr
, inner_expr
);
2287 nullable_partexpr
= list_concat_copy(outer_null_expr
,
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
2300 partexpr
= list_copy(outer_expr
);
2301 nullable_partexpr
= list_copy(outer_null_expr
);
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.
2312 partexpr
= list_copy(outer_expr
);
2313 nullable_partexpr
= list_concat_copy(inner_expr
,
2315 nullable_partexpr
= list_concat(nullable_partexpr
,
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.
2326 nullable_partexpr
= list_concat_copy(outer_expr
,
2328 nullable_partexpr
= list_concat(nullable_partexpr
,
2330 nullable_partexpr
= list_concat(nullable_partexpr
,
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
2357 foreach(lc
, list_concat_copy(outer_expr
, outer_null_expr
))
2359 Node
*larg
= (Node
*) lfirst(lc
);
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
);
2371 nullable_partexpr
= lappend(nullable_partexpr
, c
);
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.
2390 build_child_join_reltarget(PlannerInfo
*root
,
2391 RelOptInfo
*parentrel
,
2392 RelOptInfo
*childrel
,
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
;