/src/postgres/src/backend/optimizer/path/joinrels.c
Line | Count | Source |
1 | | /*------------------------------------------------------------------------- |
2 | | * |
3 | | * joinrels.c |
4 | | * Routines to determine which relations should be joined |
5 | | * |
6 | | * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group |
7 | | * Portions Copyright (c) 1994, Regents of the University of California |
8 | | * |
9 | | * |
10 | | * IDENTIFICATION |
11 | | * src/backend/optimizer/path/joinrels.c |
12 | | * |
13 | | *------------------------------------------------------------------------- |
14 | | */ |
15 | | #include "postgres.h" |
16 | | |
17 | | #include "miscadmin.h" |
18 | | #include "optimizer/appendinfo.h" |
19 | | #include "optimizer/cost.h" |
20 | | #include "optimizer/joininfo.h" |
21 | | #include "optimizer/pathnode.h" |
22 | | #include "optimizer/paths.h" |
23 | | #include "optimizer/planner.h" |
24 | | #include "partitioning/partbounds.h" |
25 | | #include "utils/memutils.h" |
26 | | |
27 | | |
28 | | static void make_rels_by_clause_joins(PlannerInfo *root, |
29 | | RelOptInfo *old_rel, |
30 | | List *other_rels, |
31 | | int first_rel_idx); |
32 | | static void make_rels_by_clauseless_joins(PlannerInfo *root, |
33 | | RelOptInfo *old_rel, |
34 | | List *other_rels); |
35 | | static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel); |
36 | | static bool has_legal_joinclause(PlannerInfo *root, RelOptInfo *rel); |
37 | | static bool restriction_is_constant_false(List *restrictlist, |
38 | | RelOptInfo *joinrel, |
39 | | bool only_pushed_down); |
40 | | static void make_grouped_join_rel(PlannerInfo *root, RelOptInfo *rel1, |
41 | | RelOptInfo *rel2, RelOptInfo *joinrel, |
42 | | SpecialJoinInfo *sjinfo, List *restrictlist); |
43 | | static void populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, |
44 | | RelOptInfo *rel2, RelOptInfo *joinrel, |
45 | | SpecialJoinInfo *sjinfo, List *restrictlist); |
46 | | static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, |
47 | | RelOptInfo *rel2, RelOptInfo *joinrel, |
48 | | SpecialJoinInfo *parent_sjinfo, |
49 | | List *parent_restrictlist); |
50 | | static SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root, |
51 | | SpecialJoinInfo *parent_sjinfo, |
52 | | Relids left_relids, Relids right_relids); |
53 | | static void free_child_join_sjinfo(SpecialJoinInfo *child_sjinfo, |
54 | | SpecialJoinInfo *parent_sjinfo); |
55 | | static void compute_partition_bounds(PlannerInfo *root, RelOptInfo *rel1, |
56 | | RelOptInfo *rel2, RelOptInfo *joinrel, |
57 | | SpecialJoinInfo *parent_sjinfo, |
58 | | List **parts1, List **parts2); |
59 | | static void get_matching_part_pairs(PlannerInfo *root, RelOptInfo *joinrel, |
60 | | RelOptInfo *rel1, RelOptInfo *rel2, |
61 | | List **parts1, List **parts2); |
62 | | |
63 | | |
64 | | /* |
65 | | * join_search_one_level |
66 | | * Consider ways to produce join relations containing exactly 'level' |
67 | | * jointree items. (This is one step of the dynamic-programming method |
68 | | * embodied in standard_join_search.) Join rel nodes for each feasible |
69 | | * combination of lower-level rels are created and returned in a list. |
70 | | * Implementation paths are created for each such joinrel, too. |
71 | | * |
72 | | * level: level of rels we want to make this time |
73 | | * root->join_rel_level[j], 1 <= j < level, is a list of rels containing j items |
74 | | * |
75 | | * The result is returned in root->join_rel_level[level]. |
76 | | */ |
77 | | void |
78 | | join_search_one_level(PlannerInfo *root, int level) |
79 | 0 | { |
80 | 0 | List **joinrels = root->join_rel_level; |
81 | 0 | ListCell *r; |
82 | 0 | int k; |
83 | |
|
84 | 0 | Assert(joinrels[level] == NIL); |
85 | | |
86 | | /* Set join_cur_level so that new joinrels are added to proper list */ |
87 | 0 | root->join_cur_level = level; |
88 | | |
89 | | /* |
90 | | * First, consider left-sided and right-sided plans, in which rels of |
91 | | * exactly level-1 member relations are joined against initial relations. |
92 | | * We prefer to join using join clauses, but if we find a rel of level-1 |
93 | | * members that has no join clauses, we will generate Cartesian-product |
94 | | * joins against all initial rels not already contained in it. |
95 | | */ |
96 | 0 | foreach(r, joinrels[level - 1]) |
97 | 0 | { |
98 | 0 | RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); |
99 | |
|
100 | 0 | if (old_rel->joininfo != NIL || old_rel->has_eclass_joins || |
101 | 0 | has_join_restriction(root, old_rel)) |
102 | 0 | { |
103 | 0 | int first_rel; |
104 | | |
105 | | /* |
106 | | * There are join clauses or join order restrictions relevant to |
107 | | * this rel, so consider joins between this rel and (only) those |
108 | | * initial rels it is linked to by a clause or restriction. |
109 | | * |
110 | | * At level 2 this condition is symmetric, so there is no need to |
111 | | * look at initial rels before this one in the list; we already |
112 | | * considered such joins when we were at the earlier rel. (The |
113 | | * mirror-image joins are handled automatically by make_join_rel.) |
114 | | * In later passes (level > 2), we join rels of the previous level |
115 | | * to each initial rel they don't already include but have a join |
116 | | * clause or restriction with. |
117 | | */ |
118 | 0 | if (level == 2) /* consider remaining initial rels */ |
119 | 0 | first_rel = foreach_current_index(r) + 1; |
120 | 0 | else |
121 | 0 | first_rel = 0; |
122 | |
|
123 | 0 | make_rels_by_clause_joins(root, old_rel, joinrels[1], first_rel); |
124 | 0 | } |
125 | 0 | else |
126 | 0 | { |
127 | | /* |
128 | | * Oops, we have a relation that is not joined to any other |
129 | | * relation, either directly or by join-order restrictions. |
130 | | * Cartesian product time. |
131 | | * |
132 | | * We consider a cartesian product with each not-already-included |
133 | | * initial rel, whether it has other join clauses or not. At |
134 | | * level 2, if there are two or more clauseless initial rels, we |
135 | | * will redundantly consider joining them in both directions; but |
136 | | * such cases aren't common enough to justify adding complexity to |
137 | | * avoid the duplicated effort. |
138 | | */ |
139 | 0 | make_rels_by_clauseless_joins(root, |
140 | 0 | old_rel, |
141 | 0 | joinrels[1]); |
142 | 0 | } |
143 | 0 | } |
144 | | |
145 | | /* |
146 | | * Now, consider "bushy plans" in which relations of k initial rels are |
147 | | * joined to relations of level-k initial rels, for 2 <= k <= level-2. |
148 | | * |
149 | | * We only consider bushy-plan joins for pairs of rels where there is a |
150 | | * suitable join clause (or join order restriction), in order to avoid |
151 | | * unreasonable growth of planning time. |
152 | | */ |
153 | 0 | for (k = 2;; k++) |
154 | 0 | { |
155 | 0 | int other_level = level - k; |
156 | | |
157 | | /* |
158 | | * Since make_join_rel(x, y) handles both x,y and y,x cases, we only |
159 | | * need to go as far as the halfway point. |
160 | | */ |
161 | 0 | if (k > other_level) |
162 | 0 | break; |
163 | | |
164 | 0 | foreach(r, joinrels[k]) |
165 | 0 | { |
166 | 0 | RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); |
167 | 0 | int first_rel; |
168 | 0 | ListCell *r2; |
169 | | |
170 | | /* |
171 | | * We can ignore relations without join clauses here, unless they |
172 | | * participate in join-order restrictions --- then we might have |
173 | | * to force a bushy join plan. |
174 | | */ |
175 | 0 | if (old_rel->joininfo == NIL && !old_rel->has_eclass_joins && |
176 | 0 | !has_join_restriction(root, old_rel)) |
177 | 0 | continue; |
178 | | |
179 | 0 | if (k == other_level) /* only consider remaining rels */ |
180 | 0 | first_rel = foreach_current_index(r) + 1; |
181 | 0 | else |
182 | 0 | first_rel = 0; |
183 | |
|
184 | 0 | for_each_from(r2, joinrels[other_level], first_rel) |
185 | 0 | { |
186 | 0 | RelOptInfo *new_rel = (RelOptInfo *) lfirst(r2); |
187 | |
|
188 | 0 | if (!bms_overlap(old_rel->relids, new_rel->relids)) |
189 | 0 | { |
190 | | /* |
191 | | * OK, we can build a rel of the right level from this |
192 | | * pair of rels. Do so if there is at least one relevant |
193 | | * join clause or join order restriction. |
194 | | */ |
195 | 0 | if (have_relevant_joinclause(root, old_rel, new_rel) || |
196 | 0 | have_join_order_restriction(root, old_rel, new_rel)) |
197 | 0 | { |
198 | 0 | (void) make_join_rel(root, old_rel, new_rel); |
199 | 0 | } |
200 | 0 | } |
201 | 0 | } |
202 | 0 | } |
203 | 0 | } |
204 | | |
205 | | /*---------- |
206 | | * Last-ditch effort: if we failed to find any usable joins so far, force |
207 | | * a set of cartesian-product joins to be generated. This handles the |
208 | | * special case where all the available rels have join clauses but we |
209 | | * cannot use any of those clauses yet. This can only happen when we are |
210 | | * considering a join sub-problem (a sub-joinlist) and all the rels in the |
211 | | * sub-problem have only join clauses with rels outside the sub-problem. |
212 | | * An example is |
213 | | * |
214 | | * SELECT ... FROM a INNER JOIN b ON TRUE, c, d, ... |
215 | | * WHERE a.w = c.x and b.y = d.z; |
216 | | * |
217 | | * If the "a INNER JOIN b" sub-problem does not get flattened into the |
218 | | * upper level, we must be willing to make a cartesian join of a and b; |
219 | | * but the code above will not have done so, because it thought that both |
220 | | * a and b have joinclauses. We consider only left-sided and right-sided |
221 | | * cartesian joins in this case (no bushy). |
222 | | *---------- |
223 | | */ |
224 | 0 | if (joinrels[level] == NIL) |
225 | 0 | { |
226 | | /* |
227 | | * This loop is just like the first one, except we always call |
228 | | * make_rels_by_clauseless_joins(). |
229 | | */ |
230 | 0 | foreach(r, joinrels[level - 1]) |
231 | 0 | { |
232 | 0 | RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); |
233 | |
|
234 | 0 | make_rels_by_clauseless_joins(root, |
235 | 0 | old_rel, |
236 | 0 | joinrels[1]); |
237 | 0 | } |
238 | | |
239 | | /*---------- |
240 | | * When special joins are involved, there may be no legal way |
241 | | * to make an N-way join for some values of N. For example consider |
242 | | * |
243 | | * SELECT ... FROM t1 WHERE |
244 | | * x IN (SELECT ... FROM t2,t3 WHERE ...) AND |
245 | | * y IN (SELECT ... FROM t4,t5 WHERE ...) |
246 | | * |
247 | | * We will flatten this query to a 5-way join problem, but there are |
248 | | * no 4-way joins that join_is_legal() will consider legal. We have |
249 | | * to accept failure at level 4 and go on to discover a workable |
250 | | * bushy plan at level 5. |
251 | | * |
252 | | * However, if there are no special joins and no lateral references |
253 | | * then join_is_legal() should never fail, and so the following sanity |
254 | | * check is useful. |
255 | | *---------- |
256 | | */ |
257 | 0 | if (joinrels[level] == NIL && |
258 | 0 | root->join_info_list == NIL && |
259 | 0 | !root->hasLateralRTEs) |
260 | 0 | elog(ERROR, "failed to build any %d-way joins", level); |
261 | 0 | } |
262 | 0 | } |
263 | | |
264 | | /* |
265 | | * make_rels_by_clause_joins |
266 | | * Build joins between the given relation 'old_rel' and other relations |
267 | | * that participate in join clauses that 'old_rel' also participates in |
268 | | * (or participate in join-order restrictions with it). |
269 | | * The join rels are returned in root->join_rel_level[join_cur_level]. |
270 | | * |
271 | | * Note: at levels above 2 we will generate the same joined relation in |
272 | | * multiple ways --- for example (a join b) join c is the same RelOptInfo as |
273 | | * (b join c) join a, though the second case will add a different set of Paths |
274 | | * to it. This is the reason for using the join_rel_level mechanism, which |
275 | | * automatically ensures that each new joinrel is only added to the list once. |
276 | | * |
277 | | * 'old_rel' is the relation entry for the relation to be joined |
278 | | * 'other_rels': a list containing the other rels to be considered for joining |
279 | | * 'first_rel_idx': the first rel to be considered in 'other_rels' |
280 | | * |
281 | | * Currently, this is only used with initial rels in other_rels, but it |
282 | | * will work for joining to joinrels too. |
283 | | */ |
284 | | static void |
285 | | make_rels_by_clause_joins(PlannerInfo *root, |
286 | | RelOptInfo *old_rel, |
287 | | List *other_rels, |
288 | | int first_rel_idx) |
289 | 0 | { |
290 | 0 | ListCell *l; |
291 | |
|
292 | 0 | for_each_from(l, other_rels, first_rel_idx) |
293 | 0 | { |
294 | 0 | RelOptInfo *other_rel = (RelOptInfo *) lfirst(l); |
295 | |
|
296 | 0 | if (!bms_overlap(old_rel->relids, other_rel->relids) && |
297 | 0 | (have_relevant_joinclause(root, old_rel, other_rel) || |
298 | 0 | have_join_order_restriction(root, old_rel, other_rel))) |
299 | 0 | { |
300 | 0 | (void) make_join_rel(root, old_rel, other_rel); |
301 | 0 | } |
302 | 0 | } |
303 | 0 | } |
304 | | |
305 | | /* |
306 | | * make_rels_by_clauseless_joins |
307 | | * Given a relation 'old_rel' and a list of other relations |
308 | | * 'other_rels', create a join relation between 'old_rel' and each |
309 | | * member of 'other_rels' that isn't already included in 'old_rel'. |
310 | | * The join rels are returned in root->join_rel_level[join_cur_level]. |
311 | | * |
312 | | * 'old_rel' is the relation entry for the relation to be joined |
313 | | * 'other_rels': a list containing the other rels to be considered for joining |
314 | | * |
315 | | * Currently, this is only used with initial rels in other_rels, but it would |
316 | | * work for joining to joinrels too. |
317 | | */ |
318 | | static void |
319 | | make_rels_by_clauseless_joins(PlannerInfo *root, |
320 | | RelOptInfo *old_rel, |
321 | | List *other_rels) |
322 | 0 | { |
323 | 0 | ListCell *l; |
324 | |
|
325 | 0 | foreach(l, other_rels) |
326 | 0 | { |
327 | 0 | RelOptInfo *other_rel = (RelOptInfo *) lfirst(l); |
328 | |
|
329 | 0 | if (!bms_overlap(other_rel->relids, old_rel->relids)) |
330 | 0 | { |
331 | 0 | (void) make_join_rel(root, old_rel, other_rel); |
332 | 0 | } |
333 | 0 | } |
334 | 0 | } |
335 | | |
336 | | |
337 | | /* |
338 | | * join_is_legal |
339 | | * Determine whether a proposed join is legal given the query's |
340 | | * join order constraints; and if it is, determine the join type. |
341 | | * |
342 | | * Caller must supply not only the two rels, but the union of their relids. |
343 | | * (We could simplify the API by computing joinrelids locally, but this |
344 | | * would be redundant work in the normal path through make_join_rel. |
345 | | * Note that this value does NOT include the RT index of any outer join that |
346 | | * might need to be performed here, so it's not the canonical identifier |
347 | | * of the join relation.) |
348 | | * |
349 | | * On success, *sjinfo_p is set to NULL if this is to be a plain inner join, |
350 | | * else it's set to point to the associated SpecialJoinInfo node. Also, |
351 | | * *reversed_p is set true if the given relations need to be swapped to |
352 | | * match the SpecialJoinInfo node. |
353 | | */ |
354 | | static bool |
355 | | join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, |
356 | | Relids joinrelids, |
357 | | SpecialJoinInfo **sjinfo_p, bool *reversed_p) |
358 | 0 | { |
359 | 0 | SpecialJoinInfo *match_sjinfo; |
360 | 0 | bool reversed; |
361 | 0 | bool unique_ified; |
362 | 0 | bool must_be_leftjoin; |
363 | 0 | ListCell *l; |
364 | | |
365 | | /* |
366 | | * Ensure output params are set on failure return. This is just to |
367 | | * suppress uninitialized-variable warnings from overly anal compilers. |
368 | | */ |
369 | 0 | *sjinfo_p = NULL; |
370 | 0 | *reversed_p = false; |
371 | | |
372 | | /* |
373 | | * If we have any special joins, the proposed join might be illegal; and |
374 | | * in any case we have to determine its join type. Scan the join info |
375 | | * list for matches and conflicts. |
376 | | */ |
377 | 0 | match_sjinfo = NULL; |
378 | 0 | reversed = false; |
379 | 0 | unique_ified = false; |
380 | 0 | must_be_leftjoin = false; |
381 | |
|
382 | 0 | foreach(l, root->join_info_list) |
383 | 0 | { |
384 | 0 | SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); |
385 | | |
386 | | /* |
387 | | * This special join is not relevant unless its RHS overlaps the |
388 | | * proposed join. (Check this first as a fast path for dismissing |
389 | | * most irrelevant SJs quickly.) |
390 | | */ |
391 | 0 | if (!bms_overlap(sjinfo->min_righthand, joinrelids)) |
392 | 0 | continue; |
393 | | |
394 | | /* |
395 | | * Also, not relevant if proposed join is fully contained within RHS |
396 | | * (ie, we're still building up the RHS). |
397 | | */ |
398 | 0 | if (bms_is_subset(joinrelids, sjinfo->min_righthand)) |
399 | 0 | continue; |
400 | | |
401 | | /* |
402 | | * Also, not relevant if SJ is already done within either input. |
403 | | */ |
404 | 0 | if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && |
405 | 0 | bms_is_subset(sjinfo->min_righthand, rel1->relids)) |
406 | 0 | continue; |
407 | 0 | if (bms_is_subset(sjinfo->min_lefthand, rel2->relids) && |
408 | 0 | bms_is_subset(sjinfo->min_righthand, rel2->relids)) |
409 | 0 | continue; |
410 | | |
411 | | /* |
412 | | * If it's a semijoin and we already joined the RHS to any other rels |
413 | | * within either input, then we must have unique-ified the RHS at that |
414 | | * point (see below). Therefore the semijoin is no longer relevant in |
415 | | * this join path. |
416 | | */ |
417 | 0 | if (sjinfo->jointype == JOIN_SEMI) |
418 | 0 | { |
419 | 0 | if (bms_is_subset(sjinfo->syn_righthand, rel1->relids) && |
420 | 0 | !bms_equal(sjinfo->syn_righthand, rel1->relids)) |
421 | 0 | continue; |
422 | 0 | if (bms_is_subset(sjinfo->syn_righthand, rel2->relids) && |
423 | 0 | !bms_equal(sjinfo->syn_righthand, rel2->relids)) |
424 | 0 | continue; |
425 | 0 | } |
426 | | |
427 | | /* |
428 | | * If one input contains min_lefthand and the other contains |
429 | | * min_righthand, then we can perform the SJ at this join. |
430 | | * |
431 | | * Reject if we get matches to more than one SJ; that implies we're |
432 | | * considering something that's not really valid. |
433 | | */ |
434 | 0 | if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && |
435 | 0 | bms_is_subset(sjinfo->min_righthand, rel2->relids)) |
436 | 0 | { |
437 | 0 | if (match_sjinfo) |
438 | 0 | return false; /* invalid join path */ |
439 | 0 | match_sjinfo = sjinfo; |
440 | 0 | reversed = false; |
441 | 0 | } |
442 | 0 | else if (bms_is_subset(sjinfo->min_lefthand, rel2->relids) && |
443 | 0 | bms_is_subset(sjinfo->min_righthand, rel1->relids)) |
444 | 0 | { |
445 | 0 | if (match_sjinfo) |
446 | 0 | return false; /* invalid join path */ |
447 | 0 | match_sjinfo = sjinfo; |
448 | 0 | reversed = true; |
449 | 0 | } |
450 | 0 | else if (sjinfo->jointype == JOIN_SEMI && |
451 | 0 | bms_equal(sjinfo->syn_righthand, rel2->relids) && |
452 | 0 | create_unique_paths(root, rel2, sjinfo) != NULL) |
453 | 0 | { |
454 | | /*---------- |
455 | | * For a semijoin, we can join the RHS to anything else by |
456 | | * unique-ifying the RHS (if the RHS can be unique-ified). |
457 | | * We will only get here if we have the full RHS but less |
458 | | * than min_lefthand on the LHS. |
459 | | * |
460 | | * The reason to consider such a join path is exemplified by |
461 | | * SELECT ... FROM a,b WHERE (a.x,b.y) IN (SELECT c1,c2 FROM c) |
462 | | * If we insist on doing this as a semijoin we will first have |
463 | | * to form the cartesian product of A*B. But if we unique-ify |
464 | | * C then the semijoin becomes a plain innerjoin and we can join |
465 | | * in any order, eg C to A and then to B. When C is much smaller |
466 | | * than A and B this can be a huge win. So we allow C to be |
467 | | * joined to just A or just B here, and then make_join_rel has |
468 | | * to handle the case properly. |
469 | | * |
470 | | * Note that actually we'll allow unique-ified C to be joined to |
471 | | * some other relation D here, too. That is legal, if usually not |
472 | | * very sane, and this routine is only concerned with legality not |
473 | | * with whether the join is good strategy. |
474 | | *---------- |
475 | | */ |
476 | 0 | if (match_sjinfo) |
477 | 0 | return false; /* invalid join path */ |
478 | 0 | match_sjinfo = sjinfo; |
479 | 0 | reversed = false; |
480 | 0 | unique_ified = true; |
481 | 0 | } |
482 | 0 | else if (sjinfo->jointype == JOIN_SEMI && |
483 | 0 | bms_equal(sjinfo->syn_righthand, rel1->relids) && |
484 | 0 | create_unique_paths(root, rel1, sjinfo) != NULL) |
485 | 0 | { |
486 | | /* Reversed semijoin case */ |
487 | 0 | if (match_sjinfo) |
488 | 0 | return false; /* invalid join path */ |
489 | 0 | match_sjinfo = sjinfo; |
490 | 0 | reversed = true; |
491 | 0 | unique_ified = true; |
492 | 0 | } |
493 | 0 | else |
494 | 0 | { |
495 | | /* |
496 | | * Otherwise, the proposed join overlaps the RHS but isn't a valid |
497 | | * implementation of this SJ. But don't panic quite yet: the RHS |
498 | | * violation might have occurred previously, in one or both input |
499 | | * relations, in which case we must have previously decided that |
500 | | * it was OK to commute some other SJ with this one. If we need |
501 | | * to perform this join to finish building up the RHS, rejecting |
502 | | * it could lead to not finding any plan at all. (This can occur |
503 | | * because of the heuristics elsewhere in this file that postpone |
504 | | * clauseless joins: we might not consider doing a clauseless join |
505 | | * within the RHS until after we've performed other, validly |
506 | | * commutable SJs with one or both sides of the clauseless join.) |
507 | | * This consideration boils down to the rule that if both inputs |
508 | | * overlap the RHS, we can allow the join --- they are either |
509 | | * fully within the RHS, or represent previously-allowed joins to |
510 | | * rels outside it. |
511 | | */ |
512 | 0 | if (bms_overlap(rel1->relids, sjinfo->min_righthand) && |
513 | 0 | bms_overlap(rel2->relids, sjinfo->min_righthand)) |
514 | 0 | continue; /* assume valid previous violation of RHS */ |
515 | | |
516 | | /* |
517 | | * The proposed join could still be legal, but only if we're |
518 | | * allowed to associate it into the RHS of this SJ. That means |
519 | | * this SJ must be a LEFT join (not SEMI or ANTI, and certainly |
520 | | * not FULL) and the proposed join must not overlap the LHS. |
521 | | */ |
522 | 0 | if (sjinfo->jointype != JOIN_LEFT || |
523 | 0 | bms_overlap(joinrelids, sjinfo->min_lefthand)) |
524 | 0 | return false; /* invalid join path */ |
525 | | |
526 | | /* |
527 | | * To be valid, the proposed join must be a LEFT join; otherwise |
528 | | * it can't associate into this SJ's RHS. But we may not yet have |
529 | | * found the SpecialJoinInfo matching the proposed join, so we |
530 | | * can't test that yet. Remember the requirement for later. |
531 | | */ |
532 | 0 | must_be_leftjoin = true; |
533 | 0 | } |
534 | 0 | } |
535 | | |
536 | | /* |
537 | | * Fail if violated any SJ's RHS and didn't match to a LEFT SJ: the |
538 | | * proposed join can't associate into an SJ's RHS. |
539 | | * |
540 | | * Also, fail if the proposed join's predicate isn't strict; we're |
541 | | * essentially checking to see if we can apply outer-join identity 3, and |
542 | | * that's a requirement. (This check may be redundant with checks in |
543 | | * make_outerjoininfo, but I'm not quite sure, and it's cheap to test.) |
544 | | */ |
545 | 0 | if (must_be_leftjoin && |
546 | 0 | (match_sjinfo == NULL || |
547 | 0 | match_sjinfo->jointype != JOIN_LEFT || |
548 | 0 | !match_sjinfo->lhs_strict)) |
549 | 0 | return false; /* invalid join path */ |
550 | | |
551 | | /* |
552 | | * We also have to check for constraints imposed by LATERAL references. |
553 | | */ |
554 | 0 | if (root->hasLateralRTEs) |
555 | 0 | { |
556 | 0 | bool lateral_fwd; |
557 | 0 | bool lateral_rev; |
558 | 0 | Relids join_lateral_rels; |
559 | | |
560 | | /* |
561 | | * The proposed rels could each contain lateral references to the |
562 | | * other, in which case the join is impossible. If there are lateral |
563 | | * references in just one direction, then the join has to be done with |
564 | | * a nestloop with the lateral referencer on the inside. If the join |
565 | | * matches an SJ that cannot be implemented by such a nestloop, the |
566 | | * join is impossible. |
567 | | * |
568 | | * Also, if the lateral reference is only indirect, we should reject |
569 | | * the join; whatever rel(s) the reference chain goes through must be |
570 | | * joined to first. |
571 | | */ |
572 | 0 | lateral_fwd = bms_overlap(rel1->relids, rel2->lateral_relids); |
573 | 0 | lateral_rev = bms_overlap(rel2->relids, rel1->lateral_relids); |
574 | 0 | if (lateral_fwd && lateral_rev) |
575 | 0 | return false; /* have lateral refs in both directions */ |
576 | 0 | if (lateral_fwd) |
577 | 0 | { |
578 | | /* has to be implemented as nestloop with rel1 on left */ |
579 | 0 | if (match_sjinfo && |
580 | 0 | (reversed || |
581 | 0 | unique_ified || |
582 | 0 | match_sjinfo->jointype == JOIN_FULL)) |
583 | 0 | return false; /* not implementable as nestloop */ |
584 | | /* check there is a direct reference from rel2 to rel1 */ |
585 | 0 | if (!bms_overlap(rel1->relids, rel2->direct_lateral_relids)) |
586 | 0 | return false; /* only indirect refs, so reject */ |
587 | 0 | } |
588 | 0 | else if (lateral_rev) |
589 | 0 | { |
590 | | /* has to be implemented as nestloop with rel2 on left */ |
591 | 0 | if (match_sjinfo && |
592 | 0 | (!reversed || |
593 | 0 | unique_ified || |
594 | 0 | match_sjinfo->jointype == JOIN_FULL)) |
595 | 0 | return false; /* not implementable as nestloop */ |
596 | | /* check there is a direct reference from rel1 to rel2 */ |
597 | 0 | if (!bms_overlap(rel2->relids, rel1->direct_lateral_relids)) |
598 | 0 | return false; /* only indirect refs, so reject */ |
599 | 0 | } |
600 | | |
601 | | /* |
602 | | * LATERAL references could also cause problems later on if we accept |
603 | | * this join: if the join's minimum parameterization includes any rels |
604 | | * that would have to be on the inside of an outer join with this join |
605 | | * rel, then it's never going to be possible to build the complete |
606 | | * query using this join. We should reject this join not only because |
607 | | * it'll save work, but because if we don't, the clauseless-join |
608 | | * heuristics might think that legality of this join means that some |
609 | | * other join rel need not be formed, and that could lead to failure |
610 | | * to find any plan at all. We have to consider not only rels that |
611 | | * are directly on the inner side of an OJ with the joinrel, but also |
612 | | * ones that are indirectly so, so search to find all such rels. |
613 | | * Likewise, input rels of the current join search that laterally |
614 | | * reference the joinrel or any rel found so far cannot supply a |
615 | | * parameter to the joinrel, so include those too. |
616 | | */ |
617 | 0 | join_lateral_rels = min_join_parameterization(root, joinrelids, |
618 | 0 | rel1, rel2); |
619 | 0 | if (join_lateral_rels) |
620 | 0 | { |
621 | 0 | Relids join_plus_rhs = bms_copy(joinrelids); |
622 | 0 | bool more; |
623 | |
|
624 | 0 | do |
625 | 0 | { |
626 | 0 | more = false; |
627 | 0 | foreach(l, root->join_info_list) |
628 | 0 | { |
629 | 0 | SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); |
630 | | |
631 | | /* ignore full joins --- their ordering is predetermined */ |
632 | 0 | if (sjinfo->jointype == JOIN_FULL) |
633 | 0 | continue; |
634 | | |
635 | 0 | if (bms_overlap(sjinfo->min_lefthand, join_plus_rhs) && |
636 | 0 | !bms_is_subset(sjinfo->min_righthand, join_plus_rhs)) |
637 | 0 | { |
638 | 0 | join_plus_rhs = bms_add_members(join_plus_rhs, |
639 | 0 | sjinfo->min_righthand); |
640 | 0 | more = true; |
641 | 0 | } |
642 | 0 | } |
643 | | |
644 | | /* |
645 | | * Add input rels that laterally reference any rel found so |
646 | | * far. An input rel can be a sub-joinlist's joinrel, which |
647 | | * must be taken as a whole. |
648 | | */ |
649 | 0 | foreach(l, root->initial_rels) |
650 | 0 | { |
651 | 0 | RelOptInfo *irel = (RelOptInfo *) lfirst(l); |
652 | |
|
653 | 0 | if (bms_overlap(irel->lateral_relids, join_plus_rhs) && |
654 | 0 | !bms_is_subset(irel->relids, join_plus_rhs)) |
655 | 0 | { |
656 | 0 | join_plus_rhs = bms_add_members(join_plus_rhs, |
657 | 0 | irel->relids); |
658 | 0 | more = true; |
659 | 0 | } |
660 | 0 | } |
661 | 0 | } while (more); |
662 | 0 | if (bms_overlap(join_plus_rhs, join_lateral_rels)) |
663 | 0 | return false; /* will not be able to join to some RHS rel */ |
664 | | |
665 | | /* |
666 | | * Furthermore, the minimum parameterization can include |
667 | | * outer-join relids as well as baserel relids. In such a case |
668 | | * the value laterally needed is an output of that outer join, so |
669 | | * the outer join must be formed strictly outside this join for |
670 | | * the value to be supplied to it. That's not possible if any rel |
671 | | * needed to form the outer join is within join_plus_rhs, since |
672 | | * all such rels must join into this join's own join tree. If we |
673 | | * accepted this join anyway, every path for it would require a |
674 | | * parameter that can never be supplied, so it could never appear |
675 | | * in a complete plan. |
676 | | */ |
677 | 0 | if (bms_overlap(join_lateral_rels, root->outer_join_rels)) |
678 | 0 | { |
679 | 0 | foreach(l, root->join_info_list) |
680 | 0 | { |
681 | 0 | SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); |
682 | |
|
683 | 0 | if (!bms_is_member(sjinfo->ojrelid, join_lateral_rels)) |
684 | 0 | continue; |
685 | 0 | if (bms_overlap(join_plus_rhs, sjinfo->min_lefthand) || |
686 | 0 | bms_overlap(join_plus_rhs, sjinfo->min_righthand)) |
687 | 0 | return false; /* OJ can't be formed outside join */ |
688 | 0 | } |
689 | 0 | } |
690 | 0 | } |
691 | 0 | } |
692 | | |
693 | | /* Otherwise, it's a valid join */ |
694 | 0 | *sjinfo_p = match_sjinfo; |
695 | 0 | *reversed_p = reversed; |
696 | 0 | return true; |
697 | 0 | } |
698 | | |
699 | | /* |
700 | | * init_dummy_sjinfo |
701 | | * Populate the given SpecialJoinInfo for a plain inner join between the |
702 | | * left and right relations specified by left_relids and right_relids |
703 | | * respectively. |
704 | | * |
705 | | * Normally, an inner join does not have a SpecialJoinInfo node associated with |
706 | | * it. But some functions involved in join planning require one containing at |
707 | | * least the information of which relations are being joined. So we initialize |
708 | | * that information here. |
709 | | */ |
710 | | void |
711 | | init_dummy_sjinfo(SpecialJoinInfo *sjinfo, Relids left_relids, |
712 | | Relids right_relids) |
713 | 0 | { |
714 | 0 | sjinfo->type = T_SpecialJoinInfo; |
715 | 0 | sjinfo->min_lefthand = left_relids; |
716 | 0 | sjinfo->min_righthand = right_relids; |
717 | 0 | sjinfo->syn_lefthand = left_relids; |
718 | 0 | sjinfo->syn_righthand = right_relids; |
719 | 0 | sjinfo->jointype = JOIN_INNER; |
720 | 0 | sjinfo->ojrelid = 0; |
721 | 0 | sjinfo->commute_above_l = NULL; |
722 | 0 | sjinfo->commute_above_r = NULL; |
723 | 0 | sjinfo->commute_below_l = NULL; |
724 | 0 | sjinfo->commute_below_r = NULL; |
725 | | /* we don't bother trying to make the remaining fields valid */ |
726 | 0 | sjinfo->lhs_strict = false; |
727 | 0 | sjinfo->semi_can_btree = false; |
728 | 0 | sjinfo->semi_can_hash = false; |
729 | 0 | sjinfo->semi_operators = NIL; |
730 | 0 | sjinfo->semi_rhs_exprs = NIL; |
731 | 0 | } |
732 | | |
733 | | /* |
734 | | * make_join_rel |
735 | | * Find or create a join RelOptInfo that represents the join of |
736 | | * the two given rels, and add to it path information for paths |
737 | | * created with the two rels as outer and inner rel. |
738 | | * (The join rel may already contain paths generated from other |
739 | | * pairs of rels that add up to the same set of base rels.) |
740 | | * |
741 | | * NB: will return NULL if attempted join is not valid. This can happen |
742 | | * when working with outer joins, or with IN or EXISTS clauses that have been |
743 | | * turned into joins. |
744 | | */ |
745 | | RelOptInfo * |
746 | | make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2) |
747 | 0 | { |
748 | 0 | Relids joinrelids; |
749 | 0 | SpecialJoinInfo *sjinfo; |
750 | 0 | bool reversed; |
751 | 0 | List *pushed_down_joins = NIL; |
752 | 0 | SpecialJoinInfo sjinfo_data; |
753 | 0 | RelOptInfo *joinrel; |
754 | 0 | List *restrictlist; |
755 | | |
756 | | /* We should never try to join two overlapping sets of rels. */ |
757 | 0 | Assert(!bms_overlap(rel1->relids, rel2->relids)); |
758 | | |
759 | | /* Construct Relids set that identifies the joinrel (without OJ as yet). */ |
760 | 0 | joinrelids = bms_union(rel1->relids, rel2->relids); |
761 | | |
762 | | /* Check validity and determine join type. */ |
763 | 0 | if (!join_is_legal(root, rel1, rel2, joinrelids, |
764 | 0 | &sjinfo, &reversed)) |
765 | 0 | { |
766 | | /* invalid join path */ |
767 | 0 | bms_free(joinrelids); |
768 | 0 | return NULL; |
769 | 0 | } |
770 | | |
771 | | /* |
772 | | * Add outer join relid(s) to form the canonical relids. Any added outer |
773 | | * joins besides sjinfo itself are appended to pushed_down_joins. |
774 | | */ |
775 | 0 | joinrelids = add_outer_joins_to_relids(root, joinrelids, sjinfo, |
776 | 0 | &pushed_down_joins); |
777 | | |
778 | | /* Swap rels if needed to match the join info. */ |
779 | 0 | if (reversed) |
780 | 0 | { |
781 | 0 | RelOptInfo *trel = rel1; |
782 | |
|
783 | 0 | rel1 = rel2; |
784 | 0 | rel2 = trel; |
785 | 0 | } |
786 | | |
787 | | /* |
788 | | * If it's a plain inner join, then we won't have found anything in |
789 | | * join_info_list. Make up a SpecialJoinInfo so that selectivity |
790 | | * estimation functions will know what's being joined. |
791 | | */ |
792 | 0 | if (sjinfo == NULL) |
793 | 0 | { |
794 | 0 | sjinfo = &sjinfo_data; |
795 | 0 | init_dummy_sjinfo(sjinfo, rel1->relids, rel2->relids); |
796 | 0 | } |
797 | | |
798 | | /* |
799 | | * Find or build the join RelOptInfo, and compute the restrictlist that |
800 | | * goes with this particular joining. |
801 | | */ |
802 | 0 | joinrel = build_join_rel(root, joinrelids, rel1, rel2, |
803 | 0 | sjinfo, pushed_down_joins, |
804 | 0 | &restrictlist); |
805 | | |
806 | | /* |
807 | | * If we've already proven this join is empty, we needn't consider any |
808 | | * more paths for it. |
809 | | */ |
810 | 0 | if (is_dummy_rel(joinrel)) |
811 | 0 | { |
812 | 0 | bms_free(joinrelids); |
813 | 0 | return joinrel; |
814 | 0 | } |
815 | | |
816 | | /* Build a grouped join relation for 'joinrel' if possible. */ |
817 | 0 | make_grouped_join_rel(root, rel1, rel2, joinrel, sjinfo, |
818 | 0 | restrictlist); |
819 | | |
820 | | /* Add paths to the join relation. */ |
821 | 0 | populate_joinrel_with_paths(root, rel1, rel2, joinrel, sjinfo, |
822 | 0 | restrictlist); |
823 | |
|
824 | 0 | bms_free(joinrelids); |
825 | |
|
826 | 0 | return joinrel; |
827 | 0 | } |
828 | | |
829 | | /* |
830 | | * add_outer_joins_to_relids |
831 | | * Add relids to input_relids to represent any outer joins that will be |
832 | | * calculated at this join. |
833 | | * |
834 | | * input_relids is the union of the relid sets of the two input relations. |
835 | | * Note that we modify this in-place and return it; caller must bms_copy() |
836 | | * it first, if a separate value is desired. |
837 | | * |
838 | | * sjinfo represents the join being performed. |
839 | | * |
840 | | * If the current join completes the calculation of any outer joins that |
841 | | * have been pushed down per outer-join identity 3, those relids will be |
842 | | * added to the result along with sjinfo's own relid. If pushed_down_joins |
843 | | * is not NULL, then also the SpecialJoinInfos for such added outer joins will |
844 | | * be appended to *pushed_down_joins (so caller must initialize it to NIL). |
845 | | */ |
846 | | Relids |
847 | | add_outer_joins_to_relids(PlannerInfo *root, Relids input_relids, |
848 | | SpecialJoinInfo *sjinfo, |
849 | | List **pushed_down_joins) |
850 | 0 | { |
851 | | /* Nothing to do if this isn't an outer join with an assigned relid. */ |
852 | 0 | if (sjinfo == NULL || sjinfo->ojrelid == 0) |
853 | 0 | return input_relids; |
854 | | |
855 | | /* |
856 | | * If it's not a left join, we have no rules that would permit executing |
857 | | * it in non-syntactic order, so just form the syntactic relid set. (This |
858 | | * is just a quick-exit test; we'd come to the same conclusion anyway, |
859 | | * since its commute_below_l and commute_above_l sets must be empty.) |
860 | | */ |
861 | 0 | if (sjinfo->jointype != JOIN_LEFT) |
862 | 0 | return bms_add_member(input_relids, sjinfo->ojrelid); |
863 | | |
864 | | /* |
865 | | * We cannot add the OJ relid if this join has been pushed into the RHS of |
866 | | * a syntactically-lower left join per OJ identity 3. (If it has, then we |
867 | | * cannot claim that its outputs represent the final state of its RHS.) |
868 | | * There will not be any other OJs that can be added either, so we're |
869 | | * done. |
870 | | */ |
871 | 0 | if (!bms_is_subset(sjinfo->commute_below_l, input_relids)) |
872 | 0 | return input_relids; |
873 | | |
874 | | /* OK to add OJ's own relid */ |
875 | 0 | input_relids = bms_add_member(input_relids, sjinfo->ojrelid); |
876 | | |
877 | | /* |
878 | | * Contrariwise, if we are now forming the final result of such a commuted |
879 | | * pair of OJs, it's time to add the relid(s) of the pushed-down join(s). |
880 | | * We can skip this if this join was never a candidate to be pushed up. |
881 | | */ |
882 | 0 | if (sjinfo->commute_above_l) |
883 | 0 | { |
884 | 0 | Relids commute_above_rels = bms_copy(sjinfo->commute_above_l); |
885 | 0 | ListCell *lc; |
886 | | |
887 | | /* |
888 | | * The current join could complete the nulling of more than one |
889 | | * pushed-down join, so we have to examine all the SpecialJoinInfos. |
890 | | * Because join_info_list was built in bottom-up order, it's |
891 | | * sufficient to traverse it once: an ojrelid we add in one loop |
892 | | * iteration would not have affected decisions of earlier iterations. |
893 | | */ |
894 | 0 | foreach(lc, root->join_info_list) |
895 | 0 | { |
896 | 0 | SpecialJoinInfo *othersj = (SpecialJoinInfo *) lfirst(lc); |
897 | |
|
898 | 0 | if (othersj == sjinfo || |
899 | 0 | othersj->ojrelid == 0 || othersj->jointype != JOIN_LEFT) |
900 | 0 | continue; /* definitely not interesting */ |
901 | | |
902 | 0 | if (!bms_is_member(othersj->ojrelid, commute_above_rels)) |
903 | 0 | continue; |
904 | | |
905 | | /* Add it if not already present but conditions now satisfied */ |
906 | 0 | if (!bms_is_member(othersj->ojrelid, input_relids) && |
907 | 0 | bms_is_subset(othersj->min_lefthand, input_relids) && |
908 | 0 | bms_is_subset(othersj->min_righthand, input_relids) && |
909 | 0 | bms_is_subset(othersj->commute_below_l, input_relids)) |
910 | 0 | { |
911 | 0 | input_relids = bms_add_member(input_relids, othersj->ojrelid); |
912 | | /* report such pushed down outer joins, if asked */ |
913 | 0 | if (pushed_down_joins != NULL) |
914 | 0 | *pushed_down_joins = lappend(*pushed_down_joins, othersj); |
915 | | |
916 | | /* |
917 | | * We must also check any joins that othersj potentially |
918 | | * commutes with. They likewise must appear later in |
919 | | * join_info_list than othersj itself, so we can visit them |
920 | | * later in this loop. |
921 | | */ |
922 | 0 | commute_above_rels = bms_add_members(commute_above_rels, |
923 | 0 | othersj->commute_above_l); |
924 | 0 | } |
925 | 0 | } |
926 | 0 | } |
927 | |
|
928 | 0 | return input_relids; |
929 | 0 | } |
930 | | |
931 | | /* |
932 | | * make_grouped_join_rel |
933 | | * Build a grouped join relation for the given "joinrel" if eager |
934 | | * aggregation is applicable and the resulting grouped paths are considered |
935 | | * useful. |
936 | | * |
937 | | * There are two strategies for generating grouped paths for a join relation: |
938 | | * |
939 | | * 1. Join a grouped (partially aggregated) input relation with a non-grouped |
940 | | * input (e.g., AGG(B) JOIN A). |
941 | | * |
942 | | * 2. Apply partial aggregation (sorted or hashed) on top of existing |
943 | | * non-grouped join paths (e.g., AGG(A JOIN B)). |
944 | | * |
945 | | * To limit planning effort and avoid an explosion of alternatives, we adopt a |
946 | | * strategy where partial aggregation is only pushed to the lowest possible |
947 | | * level in the join tree that is deemed useful. That is, if grouped paths can |
948 | | * be built using the first strategy, we skip consideration of the second |
949 | | * strategy for the same join level. |
950 | | * |
951 | | * Additionally, if there are multiple lowest useful levels where partial |
952 | | * aggregation could be applied, such as in a join tree with relations A, B, |
953 | | * and C where both "AGG(A JOIN B) JOIN C" and "A JOIN AGG(B JOIN C)" are valid |
954 | | * placements, we choose only the first one encountered during join search. |
955 | | * This avoids generating multiple versions of the same grouped relation based |
956 | | * on different aggregation placements. |
957 | | * |
958 | | * These heuristics also ensure that all grouped paths for the same grouped |
959 | | * relation produce the same set of rows, which is a basic assumption in the |
960 | | * planner. |
961 | | */ |
962 | | static void |
963 | | make_grouped_join_rel(PlannerInfo *root, RelOptInfo *rel1, |
964 | | RelOptInfo *rel2, RelOptInfo *joinrel, |
965 | | SpecialJoinInfo *sjinfo, List *restrictlist) |
966 | 0 | { |
967 | 0 | RelOptInfo *grouped_rel; |
968 | 0 | RelOptInfo *grouped_rel1; |
969 | 0 | RelOptInfo *grouped_rel2; |
970 | 0 | bool rel1_empty; |
971 | 0 | bool rel2_empty; |
972 | 0 | Relids apply_agg_at; |
973 | | |
974 | | /* |
975 | | * If there are no aggregate expressions or grouping expressions, eager |
976 | | * aggregation is not possible. |
977 | | */ |
978 | 0 | if (root->agg_clause_list == NIL || |
979 | 0 | root->group_expr_list == NIL) |
980 | 0 | return; |
981 | | |
982 | | /* Retrieve the grouped relations for the two input rels */ |
983 | 0 | grouped_rel1 = rel1->grouped_rel; |
984 | 0 | grouped_rel2 = rel2->grouped_rel; |
985 | |
|
986 | 0 | rel1_empty = (grouped_rel1 == NULL || IS_DUMMY_REL(grouped_rel1)); |
987 | 0 | rel2_empty = (grouped_rel2 == NULL || IS_DUMMY_REL(grouped_rel2)); |
988 | | |
989 | | /* Find or construct a grouped joinrel for this joinrel */ |
990 | 0 | grouped_rel = joinrel->grouped_rel; |
991 | 0 | if (grouped_rel == NULL) |
992 | 0 | { |
993 | 0 | RelAggInfo *agg_info = NULL; |
994 | | |
995 | | /* |
996 | | * Prepare the information needed to create grouped paths for this |
997 | | * join relation. |
998 | | */ |
999 | 0 | agg_info = create_rel_agg_info(root, joinrel, rel1_empty == rel2_empty); |
1000 | 0 | if (agg_info == NULL) |
1001 | 0 | return; |
1002 | | |
1003 | | /* |
1004 | | * If grouped paths for the given join relation are not considered |
1005 | | * useful, and no grouped paths can be built by joining grouped input |
1006 | | * relations, skip building the grouped join relation. |
1007 | | */ |
1008 | 0 | if (!agg_info->agg_useful && |
1009 | 0 | (rel1_empty == rel2_empty)) |
1010 | 0 | return; |
1011 | | |
1012 | | /* build the grouped relation */ |
1013 | 0 | grouped_rel = build_grouped_rel(root, joinrel); |
1014 | 0 | grouped_rel->reltarget = agg_info->target; |
1015 | |
|
1016 | 0 | if (rel1_empty != rel2_empty) |
1017 | 0 | { |
1018 | | /* |
1019 | | * If there is exactly one grouped input relation, then we can |
1020 | | * build grouped paths by joining the input relations. Set size |
1021 | | * estimates for the grouped join relation based on the input |
1022 | | * relations, and update the set of relids where partial |
1023 | | * aggregation is applied to that of the grouped input relation. |
1024 | | */ |
1025 | 0 | set_joinrel_size_estimates(root, grouped_rel, |
1026 | 0 | rel1_empty ? rel1 : grouped_rel1, |
1027 | 0 | rel2_empty ? rel2 : grouped_rel2, |
1028 | 0 | sjinfo, restrictlist); |
1029 | 0 | agg_info->apply_agg_at = rel1_empty ? |
1030 | 0 | grouped_rel2->agg_info->apply_agg_at : |
1031 | 0 | grouped_rel1->agg_info->apply_agg_at; |
1032 | 0 | } |
1033 | 0 | else |
1034 | 0 | { |
1035 | | /* |
1036 | | * Otherwise, grouped paths can be built by applying partial |
1037 | | * aggregation on top of existing non-grouped join paths. Set |
1038 | | * size estimates for the grouped join relation based on the |
1039 | | * estimated number of groups, and track the set of relids where |
1040 | | * partial aggregation is applied. Note that these values may be |
1041 | | * updated later if it is determined that grouped paths can be |
1042 | | * constructed by joining other input relations. |
1043 | | */ |
1044 | 0 | grouped_rel->rows = agg_info->grouped_rows; |
1045 | 0 | agg_info->apply_agg_at = bms_copy(joinrel->relids); |
1046 | 0 | } |
1047 | |
|
1048 | 0 | grouped_rel->agg_info = agg_info; |
1049 | 0 | joinrel->grouped_rel = grouped_rel; |
1050 | 0 | } |
1051 | | |
1052 | 0 | Assert(IS_GROUPED_REL(grouped_rel)); |
1053 | | |
1054 | | /* We may have already proven this grouped join relation to be dummy. */ |
1055 | 0 | if (IS_DUMMY_REL(grouped_rel)) |
1056 | 0 | return; |
1057 | | |
1058 | | /* |
1059 | | * Nothing to do if there's no grouped input relation. Also, joining two |
1060 | | * grouped relations is not currently supported. |
1061 | | */ |
1062 | 0 | if (rel1_empty == rel2_empty) |
1063 | 0 | return; |
1064 | | |
1065 | | /* |
1066 | | * Get the set of relids where partial aggregation is applied among the |
1067 | | * given input relations. |
1068 | | */ |
1069 | 0 | apply_agg_at = rel1_empty ? |
1070 | 0 | grouped_rel2->agg_info->apply_agg_at : |
1071 | 0 | grouped_rel1->agg_info->apply_agg_at; |
1072 | | |
1073 | | /* |
1074 | | * If it's not the designated level, skip building grouped paths. |
1075 | | * |
1076 | | * One exception is when it is a subset of the previously recorded level. |
1077 | | * In that case, we need to update the designated level to this one, and |
1078 | | * adjust the size estimates for the grouped join relation accordingly. |
1079 | | * For example, suppose partial aggregation can be applied on top of (B |
1080 | | * JOIN C). If we first construct the join as ((A JOIN B) JOIN C), we'd |
1081 | | * record the designated level as including all three relations (A B C). |
1082 | | * Later, when we consider (A JOIN (B JOIN C)), we encounter the smaller |
1083 | | * (B C) join level directly. Since this is a subset of the previous |
1084 | | * level and still valid for partial aggregation, we update the designated |
1085 | | * level to (B C), and adjust the size estimates accordingly. |
1086 | | */ |
1087 | 0 | if (!bms_equal(apply_agg_at, grouped_rel->agg_info->apply_agg_at)) |
1088 | 0 | { |
1089 | 0 | if (bms_is_subset(apply_agg_at, grouped_rel->agg_info->apply_agg_at)) |
1090 | 0 | { |
1091 | | /* Adjust the size estimates for the grouped join relation. */ |
1092 | 0 | set_joinrel_size_estimates(root, grouped_rel, |
1093 | 0 | rel1_empty ? rel1 : grouped_rel1, |
1094 | 0 | rel2_empty ? rel2 : grouped_rel2, |
1095 | 0 | sjinfo, restrictlist); |
1096 | 0 | grouped_rel->agg_info->apply_agg_at = apply_agg_at; |
1097 | 0 | } |
1098 | 0 | else |
1099 | 0 | return; |
1100 | 0 | } |
1101 | | |
1102 | | /* Make paths for the grouped join relation. */ |
1103 | 0 | populate_joinrel_with_paths(root, |
1104 | 0 | rel1_empty ? rel1 : grouped_rel1, |
1105 | 0 | rel2_empty ? rel2 : grouped_rel2, |
1106 | 0 | grouped_rel, |
1107 | 0 | sjinfo, |
1108 | 0 | restrictlist); |
1109 | 0 | } |
1110 | | |
1111 | | /* |
1112 | | * populate_joinrel_with_paths |
1113 | | * Add paths to the given joinrel for given pair of joining relations. The |
1114 | | * SpecialJoinInfo provides details about the join and the restrictlist |
1115 | | * contains the join clauses and the other clauses applicable for given pair |
1116 | | * of the joining relations. |
1117 | | */ |
1118 | | static void |
1119 | | populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, |
1120 | | RelOptInfo *rel2, RelOptInfo *joinrel, |
1121 | | SpecialJoinInfo *sjinfo, List *restrictlist) |
1122 | 0 | { |
1123 | 0 | RelOptInfo *unique_rel2; |
1124 | | |
1125 | | /* |
1126 | | * Consider paths using each rel as both outer and inner. Depending on |
1127 | | * the join type, a provably empty outer or inner rel might mean the join |
1128 | | * is provably empty too; in which case throw away any previously computed |
1129 | | * paths and mark the join as dummy. (We do it this way since it's |
1130 | | * conceivable that dummy-ness of a multi-element join might only be |
1131 | | * noticeable for certain construction paths.) |
1132 | | * |
1133 | | * Also, a provably constant-false join restriction typically means that |
1134 | | * we can skip evaluating one or both sides of the join. We do this by |
1135 | | * marking the appropriate rel as dummy. For outer joins, a |
1136 | | * constant-false restriction that is pushed down still means the whole |
1137 | | * join is dummy, while a non-pushed-down one means that no inner rows |
1138 | | * will join so we can treat the inner rel as dummy. |
1139 | | * |
1140 | | * We need only consider the jointypes that appear in join_info_list, plus |
1141 | | * JOIN_INNER. |
1142 | | */ |
1143 | 0 | switch (sjinfo->jointype) |
1144 | 0 | { |
1145 | 0 | case JOIN_INNER: |
1146 | 0 | if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || |
1147 | 0 | restriction_is_constant_false(restrictlist, joinrel, false)) |
1148 | 0 | { |
1149 | 0 | mark_dummy_rel(joinrel); |
1150 | 0 | break; |
1151 | 0 | } |
1152 | 0 | add_paths_to_joinrel(root, joinrel, rel1, rel2, |
1153 | 0 | JOIN_INNER, sjinfo, |
1154 | 0 | restrictlist); |
1155 | 0 | add_paths_to_joinrel(root, joinrel, rel2, rel1, |
1156 | 0 | JOIN_INNER, sjinfo, |
1157 | 0 | restrictlist); |
1158 | 0 | break; |
1159 | 0 | case JOIN_LEFT: |
1160 | 0 | if (is_dummy_rel(rel1) || |
1161 | 0 | restriction_is_constant_false(restrictlist, joinrel, true)) |
1162 | 0 | { |
1163 | 0 | mark_dummy_rel(joinrel); |
1164 | 0 | break; |
1165 | 0 | } |
1166 | 0 | if (restriction_is_constant_false(restrictlist, joinrel, false) && |
1167 | 0 | bms_is_subset(rel2->relids, sjinfo->syn_righthand)) |
1168 | 0 | mark_dummy_rel(rel2); |
1169 | 0 | add_paths_to_joinrel(root, joinrel, rel1, rel2, |
1170 | 0 | JOIN_LEFT, sjinfo, |
1171 | 0 | restrictlist); |
1172 | 0 | add_paths_to_joinrel(root, joinrel, rel2, rel1, |
1173 | 0 | JOIN_RIGHT, sjinfo, |
1174 | 0 | restrictlist); |
1175 | 0 | break; |
1176 | 0 | case JOIN_FULL: |
1177 | 0 | if ((is_dummy_rel(rel1) && is_dummy_rel(rel2)) || |
1178 | 0 | restriction_is_constant_false(restrictlist, joinrel, true)) |
1179 | 0 | { |
1180 | 0 | mark_dummy_rel(joinrel); |
1181 | 0 | break; |
1182 | 0 | } |
1183 | 0 | add_paths_to_joinrel(root, joinrel, rel1, rel2, |
1184 | 0 | JOIN_FULL, sjinfo, |
1185 | 0 | restrictlist); |
1186 | 0 | add_paths_to_joinrel(root, joinrel, rel2, rel1, |
1187 | 0 | JOIN_FULL, sjinfo, |
1188 | 0 | restrictlist); |
1189 | | |
1190 | | /* |
1191 | | * If there are join quals that aren't mergeable or hashable, we |
1192 | | * may not be able to build any valid plan. Complain here so that |
1193 | | * we can give a somewhat-useful error message. (Since we have no |
1194 | | * flexibility of planning for a full join, there's no chance of |
1195 | | * succeeding later with another pair of input rels.) |
1196 | | */ |
1197 | 0 | if (joinrel->pathlist == NIL) |
1198 | 0 | ereport(ERROR, |
1199 | 0 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
1200 | 0 | errmsg("FULL JOIN is only supported with merge-joinable or hash-joinable join conditions"))); |
1201 | 0 | break; |
1202 | 0 | case JOIN_SEMI: |
1203 | | |
1204 | | /* |
1205 | | * We might have a normal semijoin, or a case where we don't have |
1206 | | * enough rels to do the semijoin but can unique-ify the RHS and |
1207 | | * then do an innerjoin (see comments in join_is_legal). In the |
1208 | | * latter case we can't apply JOIN_SEMI joining. |
1209 | | */ |
1210 | 0 | if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && |
1211 | 0 | bms_is_subset(sjinfo->min_righthand, rel2->relids)) |
1212 | 0 | { |
1213 | 0 | if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || |
1214 | 0 | restriction_is_constant_false(restrictlist, joinrel, false)) |
1215 | 0 | { |
1216 | 0 | mark_dummy_rel(joinrel); |
1217 | 0 | break; |
1218 | 0 | } |
1219 | 0 | add_paths_to_joinrel(root, joinrel, rel1, rel2, |
1220 | 0 | JOIN_SEMI, sjinfo, |
1221 | 0 | restrictlist); |
1222 | 0 | add_paths_to_joinrel(root, joinrel, rel2, rel1, |
1223 | 0 | JOIN_RIGHT_SEMI, sjinfo, |
1224 | 0 | restrictlist); |
1225 | 0 | } |
1226 | | |
1227 | | /* |
1228 | | * If we know how to unique-ify the RHS and one input rel is |
1229 | | * exactly the RHS (not a superset) we can consider unique-ifying |
1230 | | * it and then doing a regular join. (The create_unique_paths |
1231 | | * check here is probably redundant with what join_is_legal did, |
1232 | | * but if so the check is cheap because it's cached. So test |
1233 | | * anyway to be sure.) |
1234 | | */ |
1235 | 0 | if (bms_equal(sjinfo->syn_righthand, rel2->relids) && |
1236 | 0 | (unique_rel2 = create_unique_paths(root, rel2, sjinfo)) != NULL) |
1237 | 0 | { |
1238 | 0 | if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || |
1239 | 0 | restriction_is_constant_false(restrictlist, joinrel, false)) |
1240 | 0 | { |
1241 | 0 | mark_dummy_rel(joinrel); |
1242 | 0 | break; |
1243 | 0 | } |
1244 | 0 | add_paths_to_joinrel(root, joinrel, rel1, unique_rel2, |
1245 | 0 | JOIN_UNIQUE_INNER, sjinfo, |
1246 | 0 | restrictlist); |
1247 | 0 | add_paths_to_joinrel(root, joinrel, unique_rel2, rel1, |
1248 | 0 | JOIN_UNIQUE_OUTER, sjinfo, |
1249 | 0 | restrictlist); |
1250 | 0 | } |
1251 | 0 | break; |
1252 | 0 | case JOIN_ANTI: |
1253 | 0 | if (is_dummy_rel(rel1) || |
1254 | 0 | restriction_is_constant_false(restrictlist, joinrel, true)) |
1255 | 0 | { |
1256 | 0 | mark_dummy_rel(joinrel); |
1257 | 0 | break; |
1258 | 0 | } |
1259 | 0 | if (restriction_is_constant_false(restrictlist, joinrel, false) && |
1260 | 0 | bms_is_subset(rel2->relids, sjinfo->syn_righthand)) |
1261 | 0 | mark_dummy_rel(rel2); |
1262 | 0 | add_paths_to_joinrel(root, joinrel, rel1, rel2, |
1263 | 0 | JOIN_ANTI, sjinfo, |
1264 | 0 | restrictlist); |
1265 | 0 | add_paths_to_joinrel(root, joinrel, rel2, rel1, |
1266 | 0 | JOIN_RIGHT_ANTI, sjinfo, |
1267 | 0 | restrictlist); |
1268 | 0 | break; |
1269 | 0 | default: |
1270 | | /* other values not expected here */ |
1271 | 0 | elog(ERROR, "unrecognized join type: %d", (int) sjinfo->jointype); |
1272 | 0 | break; |
1273 | 0 | } |
1274 | | |
1275 | | /* Apply partitionwise join technique, if possible. */ |
1276 | 0 | try_partitionwise_join(root, rel1, rel2, joinrel, sjinfo, restrictlist); |
1277 | 0 | } |
1278 | | |
1279 | | |
1280 | | /* |
1281 | | * have_join_order_restriction |
1282 | | * Detect whether the two relations should be joined to satisfy |
1283 | | * a join-order restriction arising from special or lateral joins. |
1284 | | * |
1285 | | * In practice this is always used with have_relevant_joinclause(), and so |
1286 | | * could be merged with that function, but it seems clearer to separate the |
1287 | | * two concerns. We need this test because there are degenerate cases where |
1288 | | * a clauseless join must be performed to satisfy join-order restrictions. |
1289 | | * Also, if one rel has a lateral reference to the other, or both are needed |
1290 | | * to compute some PHV, we should consider joining them even if the join would |
1291 | | * be clauseless. |
1292 | | * |
1293 | | * Note: this is only a problem if one side of a degenerate outer join |
1294 | | * contains multiple rels, or a clauseless join is required within an |
1295 | | * IN/EXISTS RHS; else we will find a join path via the "last ditch" case in |
1296 | | * join_search_one_level(). We could dispense with this test if we were |
1297 | | * willing to try bushy plans in the "last ditch" case, but that seems much |
1298 | | * less efficient. |
1299 | | */ |
1300 | | bool |
1301 | | have_join_order_restriction(PlannerInfo *root, |
1302 | | RelOptInfo *rel1, RelOptInfo *rel2) |
1303 | 0 | { |
1304 | 0 | bool result = false; |
1305 | 0 | ListCell *l; |
1306 | | |
1307 | | /* |
1308 | | * If either side has a direct lateral reference to the other, attempt the |
1309 | | * join regardless of outer-join considerations. |
1310 | | */ |
1311 | 0 | if (bms_overlap(rel1->relids, rel2->direct_lateral_relids) || |
1312 | 0 | bms_overlap(rel2->relids, rel1->direct_lateral_relids)) |
1313 | 0 | return true; |
1314 | | |
1315 | | /* |
1316 | | * Likewise, if both rels are needed to compute some PlaceHolderVar, |
1317 | | * attempt the join regardless of outer-join considerations. (This is not |
1318 | | * very desirable, because a PHV with a large eval_at set will cause a lot |
1319 | | * of probably-useless joins to be considered, but failing to do this can |
1320 | | * cause us to fail to construct a plan at all.) |
1321 | | */ |
1322 | 0 | foreach(l, root->placeholder_list) |
1323 | 0 | { |
1324 | 0 | PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l); |
1325 | |
|
1326 | 0 | if (bms_is_subset(rel1->relids, phinfo->ph_eval_at) && |
1327 | 0 | bms_is_subset(rel2->relids, phinfo->ph_eval_at)) |
1328 | 0 | return true; |
1329 | 0 | } |
1330 | | |
1331 | | /* |
1332 | | * It's possible that the rels correspond to the left and right sides of a |
1333 | | * degenerate outer join, that is, one with no joinclause mentioning the |
1334 | | * non-nullable side; in which case we should force the join to occur. |
1335 | | * |
1336 | | * Also, the two rels could represent a clauseless join that has to be |
1337 | | * completed to build up the LHS or RHS of an outer join. |
1338 | | */ |
1339 | 0 | foreach(l, root->join_info_list) |
1340 | 0 | { |
1341 | 0 | SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); |
1342 | | |
1343 | | /* ignore full joins --- other mechanisms handle them */ |
1344 | 0 | if (sjinfo->jointype == JOIN_FULL) |
1345 | 0 | continue; |
1346 | | |
1347 | | /* Can we perform the SJ with these rels? */ |
1348 | 0 | if (bms_is_subset(sjinfo->min_lefthand, rel1->relids) && |
1349 | 0 | bms_is_subset(sjinfo->min_righthand, rel2->relids)) |
1350 | 0 | { |
1351 | 0 | result = true; |
1352 | 0 | break; |
1353 | 0 | } |
1354 | 0 | if (bms_is_subset(sjinfo->min_lefthand, rel2->relids) && |
1355 | 0 | bms_is_subset(sjinfo->min_righthand, rel1->relids)) |
1356 | 0 | { |
1357 | 0 | result = true; |
1358 | 0 | break; |
1359 | 0 | } |
1360 | | |
1361 | | /* |
1362 | | * Might we need to join these rels to complete the RHS? We have to |
1363 | | * use "overlap" tests since either rel might include a lower SJ that |
1364 | | * has been proven to commute with this one. |
1365 | | */ |
1366 | 0 | if (bms_overlap(sjinfo->min_righthand, rel1->relids) && |
1367 | 0 | bms_overlap(sjinfo->min_righthand, rel2->relids)) |
1368 | 0 | { |
1369 | 0 | result = true; |
1370 | 0 | break; |
1371 | 0 | } |
1372 | | |
1373 | | /* Likewise for the LHS. */ |
1374 | 0 | if (bms_overlap(sjinfo->min_lefthand, rel1->relids) && |
1375 | 0 | bms_overlap(sjinfo->min_lefthand, rel2->relids)) |
1376 | 0 | { |
1377 | 0 | result = true; |
1378 | 0 | break; |
1379 | 0 | } |
1380 | 0 | } |
1381 | | |
1382 | | /* |
1383 | | * We do not force the join to occur if either input rel can legally be |
1384 | | * joined to anything else using joinclauses. This essentially means that |
1385 | | * clauseless bushy joins are put off as long as possible. The reason is |
1386 | | * that when there is a join order restriction high up in the join tree |
1387 | | * (that is, with many rels inside the LHS or RHS), we would otherwise |
1388 | | * expend lots of effort considering very stupid join combinations within |
1389 | | * its LHS or RHS. |
1390 | | */ |
1391 | 0 | if (result) |
1392 | 0 | { |
1393 | 0 | if (has_legal_joinclause(root, rel1) || |
1394 | 0 | has_legal_joinclause(root, rel2)) |
1395 | 0 | result = false; |
1396 | 0 | } |
1397 | |
|
1398 | 0 | return result; |
1399 | 0 | } |
1400 | | |
1401 | | |
1402 | | /* |
1403 | | * has_join_restriction |
1404 | | * Detect whether the specified relation has join-order restrictions, |
1405 | | * due to being inside an outer join or an IN (sub-SELECT), |
1406 | | * or participating in any LATERAL references or multi-rel PHVs. |
1407 | | * |
1408 | | * Essentially, this tests whether have_join_order_restriction() could |
1409 | | * succeed with this rel and some other one. It's OK if we sometimes |
1410 | | * say "true" incorrectly. (Therefore, we don't bother with the relatively |
1411 | | * expensive has_legal_joinclause test.) |
1412 | | */ |
1413 | | static bool |
1414 | | has_join_restriction(PlannerInfo *root, RelOptInfo *rel) |
1415 | 0 | { |
1416 | 0 | ListCell *l; |
1417 | |
|
1418 | 0 | if (rel->lateral_relids != NULL || rel->lateral_referencers != NULL) |
1419 | 0 | return true; |
1420 | | |
1421 | 0 | foreach(l, root->placeholder_list) |
1422 | 0 | { |
1423 | 0 | PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l); |
1424 | |
|
1425 | 0 | if (bms_is_subset(rel->relids, phinfo->ph_eval_at) && |
1426 | 0 | !bms_equal(rel->relids, phinfo->ph_eval_at)) |
1427 | 0 | return true; |
1428 | 0 | } |
1429 | | |
1430 | 0 | foreach(l, root->join_info_list) |
1431 | 0 | { |
1432 | 0 | SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); |
1433 | | |
1434 | | /* ignore full joins --- other mechanisms preserve their ordering */ |
1435 | 0 | if (sjinfo->jointype == JOIN_FULL) |
1436 | 0 | continue; |
1437 | | |
1438 | | /* ignore if SJ is already contained in rel */ |
1439 | 0 | if (bms_is_subset(sjinfo->min_lefthand, rel->relids) && |
1440 | 0 | bms_is_subset(sjinfo->min_righthand, rel->relids)) |
1441 | 0 | continue; |
1442 | | |
1443 | | /* restricted if it overlaps LHS or RHS, but doesn't contain SJ */ |
1444 | 0 | if (bms_overlap(sjinfo->min_lefthand, rel->relids) || |
1445 | 0 | bms_overlap(sjinfo->min_righthand, rel->relids)) |
1446 | 0 | return true; |
1447 | 0 | } |
1448 | | |
1449 | 0 | return false; |
1450 | 0 | } |
1451 | | |
1452 | | |
1453 | | /* |
1454 | | * has_legal_joinclause |
1455 | | * Detect whether the specified relation can legally be joined |
1456 | | * to any other rels using join clauses. |
1457 | | * |
1458 | | * We consider only joins to single other relations in the current |
1459 | | * initial_rels list. This is sufficient to get a "true" result in most real |
1460 | | * queries, and an occasional erroneous "false" will only cost a bit more |
1461 | | * planning time. The reason for this limitation is that considering joins to |
1462 | | * other joins would require proving that the other join rel can legally be |
1463 | | * formed, which seems like too much trouble for something that's only a |
1464 | | * heuristic to save planning time. (Note: we must look at initial_rels |
1465 | | * and not all of the query, since when we are planning a sub-joinlist we |
1466 | | * may be forced to make clauseless joins within initial_rels even though |
1467 | | * there are join clauses linking to other parts of the query.) |
1468 | | */ |
1469 | | static bool |
1470 | | has_legal_joinclause(PlannerInfo *root, RelOptInfo *rel) |
1471 | 0 | { |
1472 | 0 | ListCell *lc; |
1473 | |
|
1474 | 0 | foreach(lc, root->initial_rels) |
1475 | 0 | { |
1476 | 0 | RelOptInfo *rel2 = (RelOptInfo *) lfirst(lc); |
1477 | | |
1478 | | /* ignore rels that are already in "rel" */ |
1479 | 0 | if (bms_overlap(rel->relids, rel2->relids)) |
1480 | 0 | continue; |
1481 | | |
1482 | 0 | if (have_relevant_joinclause(root, rel, rel2)) |
1483 | 0 | { |
1484 | 0 | Relids joinrelids; |
1485 | 0 | SpecialJoinInfo *sjinfo; |
1486 | 0 | bool reversed; |
1487 | | |
1488 | | /* join_is_legal needs relids of the union */ |
1489 | 0 | joinrelids = bms_union(rel->relids, rel2->relids); |
1490 | |
|
1491 | 0 | if (join_is_legal(root, rel, rel2, joinrelids, |
1492 | 0 | &sjinfo, &reversed)) |
1493 | 0 | { |
1494 | | /* Yes, this will work */ |
1495 | 0 | bms_free(joinrelids); |
1496 | 0 | return true; |
1497 | 0 | } |
1498 | | |
1499 | 0 | bms_free(joinrelids); |
1500 | 0 | } |
1501 | 0 | } |
1502 | | |
1503 | 0 | return false; |
1504 | 0 | } |
1505 | | |
1506 | | |
1507 | | /* |
1508 | | * is_dummy_rel --- has relation been proven empty? |
1509 | | */ |
1510 | | bool |
1511 | | is_dummy_rel(RelOptInfo *rel) |
1512 | 0 | { |
1513 | 0 | Path *path; |
1514 | | |
1515 | | /* |
1516 | | * A rel that is known dummy will have just one path that is a childless |
1517 | | * Append. (Even if somehow it has more paths, a childless Append will |
1518 | | * have cost zero and hence should be at the front of the pathlist.) |
1519 | | */ |
1520 | 0 | if (rel->pathlist == NIL) |
1521 | 0 | return false; |
1522 | 0 | path = (Path *) linitial(rel->pathlist); |
1523 | | |
1524 | | /* |
1525 | | * Initially, a dummy path will just be a childless Append. But in later |
1526 | | * planning stages we might stick a ProjectSetPath and/or ProjectionPath |
1527 | | * on top, since Append can't project. Rather than make assumptions about |
1528 | | * which combinations can occur, just descend through whatever we find. |
1529 | | */ |
1530 | 0 | for (;;) |
1531 | 0 | { |
1532 | 0 | if (IsA(path, ProjectionPath)) |
1533 | 0 | path = ((ProjectionPath *) path)->subpath; |
1534 | 0 | else if (IsA(path, ProjectSetPath)) |
1535 | 0 | path = ((ProjectSetPath *) path)->subpath; |
1536 | 0 | else |
1537 | 0 | break; |
1538 | 0 | } |
1539 | 0 | if (IS_DUMMY_APPEND(path)) |
1540 | 0 | return true; |
1541 | 0 | return false; |
1542 | 0 | } |
1543 | | |
1544 | | /* |
1545 | | * Mark a relation as proven empty. |
1546 | | * |
1547 | | * During GEQO planning, this can get invoked more than once on the same |
1548 | | * baserel struct, so it's worth checking to see if the rel is already marked |
1549 | | * dummy. |
1550 | | * |
1551 | | * Also, when called during GEQO join planning, we are in a short-lived |
1552 | | * memory context. We must make sure that the dummy path attached to a |
1553 | | * baserel survives the GEQO cycle, else the baserel is trashed for future |
1554 | | * GEQO cycles. On the other hand, when we are marking a joinrel during GEQO, |
1555 | | * we don't want the dummy path to clutter the main planning context. Upshot |
1556 | | * is that the best solution is to explicitly make the dummy path in the same |
1557 | | * context the given RelOptInfo is in. |
1558 | | */ |
1559 | | void |
1560 | | mark_dummy_rel(RelOptInfo *rel) |
1561 | 0 | { |
1562 | 0 | MemoryContext oldcontext; |
1563 | 0 | AppendPathInput in = {0}; |
1564 | | |
1565 | | /* Already marked? */ |
1566 | 0 | if (is_dummy_rel(rel)) |
1567 | 0 | return; |
1568 | | |
1569 | | /* No, so choose correct context to make the dummy path in */ |
1570 | 0 | oldcontext = MemoryContextSwitchTo(GetMemoryChunkContext(rel)); |
1571 | | |
1572 | | /* Set dummy size estimate */ |
1573 | 0 | rel->rows = 0; |
1574 | | |
1575 | | /* Evict any previously chosen paths */ |
1576 | 0 | rel->pathlist = NIL; |
1577 | 0 | rel->partial_pathlist = NIL; |
1578 | | |
1579 | | /* Set up the dummy path */ |
1580 | 0 | add_path(rel, (Path *) create_append_path(NULL, rel, in, |
1581 | 0 | NIL, rel->lateral_relids, |
1582 | 0 | 0, false, -1)); |
1583 | | |
1584 | | /* Set or update cheapest_total_path and related fields */ |
1585 | 0 | set_cheapest(rel); |
1586 | |
|
1587 | 0 | MemoryContextSwitchTo(oldcontext); |
1588 | 0 | } |
1589 | | |
1590 | | |
1591 | | /* |
1592 | | * restriction_is_constant_false --- is a restrictlist just FALSE? |
1593 | | * |
1594 | | * In cases where a qual is provably constant FALSE, eval_const_expressions |
1595 | | * will generally have thrown away anything that's ANDed with it. In outer |
1596 | | * join situations this will leave us computing cartesian products only to |
1597 | | * decide there's no match for an outer row, which is pretty stupid. So, |
1598 | | * we need to detect the case. |
1599 | | * |
1600 | | * If only_pushed_down is true, then consider only quals that are pushed-down |
1601 | | * from the point of view of the joinrel. |
1602 | | */ |
1603 | | static bool |
1604 | | restriction_is_constant_false(List *restrictlist, |
1605 | | RelOptInfo *joinrel, |
1606 | | bool only_pushed_down) |
1607 | 0 | { |
1608 | 0 | ListCell *lc; |
1609 | | |
1610 | | /* |
1611 | | * Despite the above comment, the restriction list we see here might |
1612 | | * possibly have other members besides the FALSE constant, since other |
1613 | | * quals could get "pushed down" to the outer join level. So we check |
1614 | | * each member of the list. |
1615 | | */ |
1616 | 0 | foreach(lc, restrictlist) |
1617 | 0 | { |
1618 | 0 | RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc); |
1619 | |
|
1620 | 0 | if (only_pushed_down && !RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids)) |
1621 | 0 | continue; |
1622 | | |
1623 | 0 | if (rinfo->clause && IsA(rinfo->clause, Const)) |
1624 | 0 | { |
1625 | 0 | Const *con = (Const *) rinfo->clause; |
1626 | | |
1627 | | /* constant NULL is as good as constant FALSE for our purposes */ |
1628 | 0 | if (con->constisnull) |
1629 | 0 | return true; |
1630 | 0 | if (!DatumGetBool(con->constvalue)) |
1631 | 0 | return true; |
1632 | 0 | } |
1633 | 0 | } |
1634 | 0 | return false; |
1635 | 0 | } |
1636 | | |
1637 | | /* |
1638 | | * Assess whether join between given two partitioned relations can be broken |
1639 | | * down into joins between matching partitions; a technique called |
1640 | | * "partitionwise join" |
1641 | | * |
1642 | | * Partitionwise join is possible when a. Joining relations have same |
1643 | | * partitioning scheme b. There exists an equi-join between the partition keys |
1644 | | * of the two relations. |
1645 | | * |
1646 | | * Partitionwise join is planned as follows (details: optimizer/README.) |
1647 | | * |
1648 | | * 1. Create the RelOptInfos for joins between matching partitions i.e |
1649 | | * child-joins and add paths to them. |
1650 | | * |
1651 | | * 2. Construct Append or MergeAppend paths across the set of child joins. |
1652 | | * This second phase is implemented by generate_partitionwise_join_paths(). |
1653 | | * |
1654 | | * The RelOptInfo, SpecialJoinInfo and restrictlist for each child join are |
1655 | | * obtained by translating the respective parent join structures. |
1656 | | */ |
1657 | | static void |
1658 | | try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, |
1659 | | RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo, |
1660 | | List *parent_restrictlist) |
1661 | 0 | { |
1662 | 0 | bool rel1_is_simple = IS_SIMPLE_REL(rel1); |
1663 | 0 | bool rel2_is_simple = IS_SIMPLE_REL(rel2); |
1664 | 0 | List *parts1 = NIL; |
1665 | 0 | List *parts2 = NIL; |
1666 | 0 | ListCell *lcr1 = NULL; |
1667 | 0 | ListCell *lcr2 = NULL; |
1668 | 0 | int cnt_parts; |
1669 | | |
1670 | | /* Guard against stack overflow due to overly deep partition hierarchy. */ |
1671 | 0 | check_stack_depth(); |
1672 | | |
1673 | | /* Nothing to do, if the join relation is not partitioned. */ |
1674 | 0 | if (joinrel->part_scheme == NULL || joinrel->nparts == 0) |
1675 | 0 | return; |
1676 | | |
1677 | | /* The join relation should have consider_partitionwise_join set. */ |
1678 | 0 | Assert(joinrel->consider_partitionwise_join); |
1679 | | |
1680 | | /* |
1681 | | * We can not perform partitionwise join if either of the joining |
1682 | | * relations is not partitioned. |
1683 | | */ |
1684 | 0 | if (!IS_PARTITIONED_REL(rel1) || !IS_PARTITIONED_REL(rel2)) |
1685 | 0 | return; |
1686 | | |
1687 | 0 | Assert(REL_HAS_ALL_PART_PROPS(rel1) && REL_HAS_ALL_PART_PROPS(rel2)); |
1688 | | |
1689 | | /* The joining relations should have consider_partitionwise_join set. */ |
1690 | 0 | Assert(rel1->consider_partitionwise_join && |
1691 | 0 | rel2->consider_partitionwise_join); |
1692 | | |
1693 | | /* |
1694 | | * The partition scheme of the join relation should match that of the |
1695 | | * joining relations. |
1696 | | */ |
1697 | 0 | Assert(joinrel->part_scheme == rel1->part_scheme && |
1698 | 0 | joinrel->part_scheme == rel2->part_scheme); |
1699 | |
|
1700 | 0 | Assert(!(joinrel->partbounds_merged && (joinrel->nparts <= 0))); |
1701 | |
|
1702 | 0 | compute_partition_bounds(root, rel1, rel2, joinrel, parent_sjinfo, |
1703 | 0 | &parts1, &parts2); |
1704 | |
|
1705 | 0 | if (joinrel->partbounds_merged) |
1706 | 0 | { |
1707 | 0 | lcr1 = list_head(parts1); |
1708 | 0 | lcr2 = list_head(parts2); |
1709 | 0 | } |
1710 | | |
1711 | | /* |
1712 | | * Create child-join relations for this partitioned join, if those don't |
1713 | | * exist. Add paths to child-joins for a pair of child relations |
1714 | | * corresponding to the given pair of parent relations. |
1715 | | */ |
1716 | 0 | for (cnt_parts = 0; cnt_parts < joinrel->nparts; cnt_parts++) |
1717 | 0 | { |
1718 | 0 | RelOptInfo *child_rel1; |
1719 | 0 | RelOptInfo *child_rel2; |
1720 | 0 | bool rel1_empty; |
1721 | 0 | bool rel2_empty; |
1722 | 0 | SpecialJoinInfo *child_sjinfo; |
1723 | 0 | List *child_restrictlist; |
1724 | 0 | RelOptInfo *child_joinrel; |
1725 | 0 | AppendRelInfo **appinfos; |
1726 | 0 | int nappinfos; |
1727 | 0 | Relids child_relids; |
1728 | |
|
1729 | 0 | if (joinrel->partbounds_merged) |
1730 | 0 | { |
1731 | 0 | child_rel1 = lfirst_node(RelOptInfo, lcr1); |
1732 | 0 | child_rel2 = lfirst_node(RelOptInfo, lcr2); |
1733 | 0 | lcr1 = lnext(parts1, lcr1); |
1734 | 0 | lcr2 = lnext(parts2, lcr2); |
1735 | 0 | } |
1736 | 0 | else |
1737 | 0 | { |
1738 | 0 | child_rel1 = rel1->part_rels[cnt_parts]; |
1739 | 0 | child_rel2 = rel2->part_rels[cnt_parts]; |
1740 | 0 | } |
1741 | |
|
1742 | 0 | rel1_empty = (child_rel1 == NULL || IS_DUMMY_REL(child_rel1)); |
1743 | 0 | rel2_empty = (child_rel2 == NULL || IS_DUMMY_REL(child_rel2)); |
1744 | | |
1745 | | /* |
1746 | | * Check for cases where we can prove that this segment of the join |
1747 | | * returns no rows, due to one or both inputs being empty (including |
1748 | | * inputs that have been pruned away entirely). If so just ignore it. |
1749 | | * These rules are equivalent to populate_joinrel_with_paths's rules |
1750 | | * for dummy input relations. |
1751 | | */ |
1752 | 0 | switch (parent_sjinfo->jointype) |
1753 | 0 | { |
1754 | 0 | case JOIN_INNER: |
1755 | 0 | case JOIN_SEMI: |
1756 | 0 | if (rel1_empty || rel2_empty) |
1757 | 0 | continue; /* ignore this join segment */ |
1758 | 0 | break; |
1759 | 0 | case JOIN_LEFT: |
1760 | 0 | case JOIN_ANTI: |
1761 | 0 | if (rel1_empty) |
1762 | 0 | continue; /* ignore this join segment */ |
1763 | 0 | break; |
1764 | 0 | case JOIN_FULL: |
1765 | 0 | if (rel1_empty && rel2_empty) |
1766 | 0 | continue; /* ignore this join segment */ |
1767 | 0 | break; |
1768 | 0 | default: |
1769 | | /* other values not expected here */ |
1770 | 0 | elog(ERROR, "unrecognized join type: %d", |
1771 | 0 | (int) parent_sjinfo->jointype); |
1772 | 0 | break; |
1773 | 0 | } |
1774 | | |
1775 | | /* |
1776 | | * If a child has been pruned entirely then we can't generate paths |
1777 | | * for it, so we have to reject partitionwise joining unless we were |
1778 | | * able to eliminate this partition above. |
1779 | | */ |
1780 | 0 | if (child_rel1 == NULL || child_rel2 == NULL) |
1781 | 0 | { |
1782 | | /* |
1783 | | * Mark the joinrel as unpartitioned so that later functions treat |
1784 | | * it correctly. |
1785 | | */ |
1786 | 0 | joinrel->nparts = 0; |
1787 | 0 | return; |
1788 | 0 | } |
1789 | | |
1790 | | /* |
1791 | | * If a leaf relation has consider_partitionwise_join=false, it means |
1792 | | * that it's a dummy relation for which we skipped setting up tlist |
1793 | | * expressions and adding EC members in set_append_rel_size(), so |
1794 | | * again we have to fail here. |
1795 | | */ |
1796 | 0 | if (rel1_is_simple && !child_rel1->consider_partitionwise_join) |
1797 | 0 | { |
1798 | 0 | Assert(child_rel1->reloptkind == RELOPT_OTHER_MEMBER_REL); |
1799 | 0 | Assert(IS_DUMMY_REL(child_rel1)); |
1800 | 0 | joinrel->nparts = 0; |
1801 | 0 | return; |
1802 | 0 | } |
1803 | 0 | if (rel2_is_simple && !child_rel2->consider_partitionwise_join) |
1804 | 0 | { |
1805 | 0 | Assert(child_rel2->reloptkind == RELOPT_OTHER_MEMBER_REL); |
1806 | 0 | Assert(IS_DUMMY_REL(child_rel2)); |
1807 | 0 | joinrel->nparts = 0; |
1808 | 0 | return; |
1809 | 0 | } |
1810 | | |
1811 | | /* We should never try to join two overlapping sets of rels. */ |
1812 | 0 | Assert(!bms_overlap(child_rel1->relids, child_rel2->relids)); |
1813 | | |
1814 | | /* |
1815 | | * Construct SpecialJoinInfo from parent join relations's |
1816 | | * SpecialJoinInfo. |
1817 | | */ |
1818 | 0 | child_sjinfo = build_child_join_sjinfo(root, parent_sjinfo, |
1819 | 0 | child_rel1->relids, |
1820 | 0 | child_rel2->relids); |
1821 | | |
1822 | | /* Find the AppendRelInfo structures */ |
1823 | 0 | child_relids = bms_union(child_rel1->relids, child_rel2->relids); |
1824 | 0 | appinfos = find_appinfos_by_relids(root, child_relids, |
1825 | 0 | &nappinfos); |
1826 | | |
1827 | | /* |
1828 | | * Construct restrictions applicable to the child join from those |
1829 | | * applicable to the parent join. |
1830 | | */ |
1831 | 0 | child_restrictlist = |
1832 | 0 | (List *) adjust_appendrel_attrs(root, |
1833 | 0 | (Node *) parent_restrictlist, |
1834 | 0 | nappinfos, appinfos); |
1835 | | |
1836 | | /* Find or construct the child join's RelOptInfo */ |
1837 | 0 | child_joinrel = joinrel->part_rels[cnt_parts]; |
1838 | 0 | if (!child_joinrel) |
1839 | 0 | { |
1840 | 0 | child_joinrel = build_child_join_rel(root, child_rel1, child_rel2, |
1841 | 0 | joinrel, child_restrictlist, |
1842 | 0 | child_sjinfo, nappinfos, appinfos); |
1843 | 0 | joinrel->part_rels[cnt_parts] = child_joinrel; |
1844 | 0 | joinrel->live_parts = bms_add_member(joinrel->live_parts, cnt_parts); |
1845 | 0 | joinrel->all_partrels = bms_add_members(joinrel->all_partrels, |
1846 | 0 | child_joinrel->relids); |
1847 | 0 | } |
1848 | | |
1849 | | /* Assert we got the right one */ |
1850 | 0 | Assert(bms_equal(child_joinrel->relids, |
1851 | 0 | adjust_child_relids(joinrel->relids, |
1852 | 0 | nappinfos, appinfos))); |
1853 | | |
1854 | | /* Build a grouped join relation for 'child_joinrel' if possible */ |
1855 | 0 | make_grouped_join_rel(root, child_rel1, child_rel2, |
1856 | 0 | child_joinrel, child_sjinfo, |
1857 | 0 | child_restrictlist); |
1858 | | |
1859 | | /* And make paths for the child join */ |
1860 | 0 | populate_joinrel_with_paths(root, child_rel1, child_rel2, |
1861 | 0 | child_joinrel, child_sjinfo, |
1862 | 0 | child_restrictlist); |
1863 | | |
1864 | | /* |
1865 | | * When there are thousands of partitions involved, this loop will |
1866 | | * accumulate a significant amount of memory usage from objects that |
1867 | | * are only needed within the loop. Free these local objects eagerly |
1868 | | * at the end of each iteration. |
1869 | | */ |
1870 | 0 | pfree(appinfos); |
1871 | 0 | bms_free(child_relids); |
1872 | 0 | free_child_join_sjinfo(child_sjinfo, parent_sjinfo); |
1873 | 0 | } |
1874 | 0 | } |
1875 | | |
1876 | | /* |
1877 | | * Construct the SpecialJoinInfo for a child-join by translating |
1878 | | * SpecialJoinInfo for the join between parents. left_relids and right_relids |
1879 | | * are the relids of left and right side of the join respectively. |
1880 | | * |
1881 | | * If translations are added to or removed from this function, consider |
1882 | | * updating free_child_join_sjinfo() accordingly. |
1883 | | */ |
1884 | | static SpecialJoinInfo * |
1885 | | build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo, |
1886 | | Relids left_relids, Relids right_relids) |
1887 | 0 | { |
1888 | 0 | SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo); |
1889 | 0 | AppendRelInfo **left_appinfos; |
1890 | 0 | int left_nappinfos; |
1891 | 0 | AppendRelInfo **right_appinfos; |
1892 | 0 | int right_nappinfos; |
1893 | | |
1894 | | /* Dummy SpecialJoinInfos can be created without any translation. */ |
1895 | 0 | if (parent_sjinfo->jointype == JOIN_INNER) |
1896 | 0 | { |
1897 | 0 | Assert(parent_sjinfo->ojrelid == 0); |
1898 | 0 | init_dummy_sjinfo(sjinfo, left_relids, right_relids); |
1899 | 0 | return sjinfo; |
1900 | 0 | } |
1901 | | |
1902 | 0 | memcpy(sjinfo, parent_sjinfo, sizeof(SpecialJoinInfo)); |
1903 | 0 | left_appinfos = find_appinfos_by_relids(root, left_relids, |
1904 | 0 | &left_nappinfos); |
1905 | 0 | right_appinfos = find_appinfos_by_relids(root, right_relids, |
1906 | 0 | &right_nappinfos); |
1907 | |
|
1908 | 0 | sjinfo->min_lefthand = adjust_child_relids(sjinfo->min_lefthand, |
1909 | 0 | left_nappinfos, left_appinfos); |
1910 | 0 | sjinfo->min_righthand = adjust_child_relids(sjinfo->min_righthand, |
1911 | 0 | right_nappinfos, |
1912 | 0 | right_appinfos); |
1913 | 0 | sjinfo->syn_lefthand = adjust_child_relids(sjinfo->syn_lefthand, |
1914 | 0 | left_nappinfos, left_appinfos); |
1915 | 0 | sjinfo->syn_righthand = adjust_child_relids(sjinfo->syn_righthand, |
1916 | 0 | right_nappinfos, |
1917 | 0 | right_appinfos); |
1918 | | /* outer-join relids need no adjustment */ |
1919 | 0 | sjinfo->semi_rhs_exprs = (List *) adjust_appendrel_attrs(root, |
1920 | 0 | (Node *) sjinfo->semi_rhs_exprs, |
1921 | 0 | right_nappinfos, |
1922 | 0 | right_appinfos); |
1923 | |
|
1924 | 0 | pfree(left_appinfos); |
1925 | 0 | pfree(right_appinfos); |
1926 | |
|
1927 | 0 | return sjinfo; |
1928 | 0 | } |
1929 | | |
1930 | | /* |
1931 | | * free_child_join_sjinfo |
1932 | | * Free memory consumed by a SpecialJoinInfo created by |
1933 | | * build_child_join_sjinfo() |
1934 | | * |
1935 | | * Only members that are translated copies of their counterpart in the parent |
1936 | | * SpecialJoinInfo are freed here. |
1937 | | */ |
1938 | | static void |
1939 | | free_child_join_sjinfo(SpecialJoinInfo *child_sjinfo, |
1940 | | SpecialJoinInfo *parent_sjinfo) |
1941 | 0 | { |
1942 | | /* |
1943 | | * Dummy SpecialJoinInfos of inner joins do not have any translated fields |
1944 | | * and hence no fields that to be freed. |
1945 | | */ |
1946 | 0 | if (child_sjinfo->jointype != JOIN_INNER) |
1947 | 0 | { |
1948 | 0 | if (child_sjinfo->min_lefthand != parent_sjinfo->min_lefthand) |
1949 | 0 | bms_free(child_sjinfo->min_lefthand); |
1950 | |
|
1951 | 0 | if (child_sjinfo->min_righthand != parent_sjinfo->min_righthand) |
1952 | 0 | bms_free(child_sjinfo->min_righthand); |
1953 | |
|
1954 | 0 | if (child_sjinfo->syn_lefthand != parent_sjinfo->syn_lefthand) |
1955 | 0 | bms_free(child_sjinfo->syn_lefthand); |
1956 | |
|
1957 | 0 | if (child_sjinfo->syn_righthand != parent_sjinfo->syn_righthand) |
1958 | 0 | bms_free(child_sjinfo->syn_righthand); |
1959 | |
|
1960 | 0 | Assert(child_sjinfo->commute_above_l == parent_sjinfo->commute_above_l); |
1961 | 0 | Assert(child_sjinfo->commute_above_r == parent_sjinfo->commute_above_r); |
1962 | 0 | Assert(child_sjinfo->commute_below_l == parent_sjinfo->commute_below_l); |
1963 | 0 | Assert(child_sjinfo->commute_below_r == parent_sjinfo->commute_below_r); |
1964 | |
|
1965 | 0 | Assert(child_sjinfo->semi_operators == parent_sjinfo->semi_operators); |
1966 | | |
1967 | | /* |
1968 | | * semi_rhs_exprs may in principle be freed, but a simple pfree() does |
1969 | | * not suffice, so we leave it alone. |
1970 | | */ |
1971 | 0 | } |
1972 | |
|
1973 | 0 | pfree(child_sjinfo); |
1974 | 0 | } |
1975 | | |
1976 | | /* |
1977 | | * compute_partition_bounds |
1978 | | * Compute the partition bounds for a join rel from those for inputs |
1979 | | */ |
1980 | | static void |
1981 | | compute_partition_bounds(PlannerInfo *root, RelOptInfo *rel1, |
1982 | | RelOptInfo *rel2, RelOptInfo *joinrel, |
1983 | | SpecialJoinInfo *parent_sjinfo, |
1984 | | List **parts1, List **parts2) |
1985 | 0 | { |
1986 | | /* |
1987 | | * If we don't have the partition bounds for the join rel yet, try to |
1988 | | * compute those along with pairs of partitions to be joined. |
1989 | | */ |
1990 | 0 | if (joinrel->nparts == -1) |
1991 | 0 | { |
1992 | 0 | PartitionScheme part_scheme = joinrel->part_scheme; |
1993 | 0 | PartitionBoundInfo boundinfo = NULL; |
1994 | 0 | int nparts = 0; |
1995 | |
|
1996 | 0 | Assert(joinrel->boundinfo == NULL); |
1997 | 0 | Assert(joinrel->part_rels == NULL); |
1998 | | |
1999 | | /* |
2000 | | * See if the partition bounds for inputs are exactly the same, in |
2001 | | * which case we don't need to work hard: the join rel will have the |
2002 | | * same partition bounds as inputs, and the partitions with the same |
2003 | | * cardinal positions will form the pairs. |
2004 | | * |
2005 | | * Note: even in cases where one or both inputs have merged bounds, it |
2006 | | * would be possible for both the bounds to be exactly the same, but |
2007 | | * it seems unlikely to be worth the cycles to check. |
2008 | | */ |
2009 | 0 | if (!rel1->partbounds_merged && |
2010 | 0 | !rel2->partbounds_merged && |
2011 | 0 | rel1->nparts == rel2->nparts && |
2012 | 0 | partition_bounds_equal(part_scheme->partnatts, |
2013 | 0 | part_scheme->parttyplen, |
2014 | 0 | part_scheme->parttypbyval, |
2015 | 0 | rel1->boundinfo, rel2->boundinfo)) |
2016 | 0 | { |
2017 | 0 | boundinfo = rel1->boundinfo; |
2018 | 0 | nparts = rel1->nparts; |
2019 | 0 | } |
2020 | 0 | else |
2021 | 0 | { |
2022 | | /* Try merging the partition bounds for inputs. */ |
2023 | 0 | boundinfo = partition_bounds_merge(part_scheme->partnatts, |
2024 | 0 | part_scheme->partsupfunc, |
2025 | 0 | part_scheme->partcollation, |
2026 | 0 | rel1, rel2, |
2027 | 0 | parent_sjinfo->jointype, |
2028 | 0 | parts1, parts2); |
2029 | 0 | if (boundinfo == NULL) |
2030 | 0 | { |
2031 | 0 | joinrel->nparts = 0; |
2032 | 0 | return; |
2033 | 0 | } |
2034 | 0 | nparts = list_length(*parts1); |
2035 | 0 | joinrel->partbounds_merged = true; |
2036 | 0 | } |
2037 | | |
2038 | 0 | Assert(nparts > 0); |
2039 | 0 | joinrel->boundinfo = boundinfo; |
2040 | 0 | joinrel->nparts = nparts; |
2041 | 0 | joinrel->part_rels = palloc0_array(RelOptInfo *, nparts); |
2042 | 0 | } |
2043 | 0 | else |
2044 | 0 | { |
2045 | 0 | Assert(joinrel->nparts > 0); |
2046 | 0 | Assert(joinrel->boundinfo); |
2047 | 0 | Assert(joinrel->part_rels); |
2048 | | |
2049 | | /* |
2050 | | * If the join rel's partbounds_merged flag is true, it means inputs |
2051 | | * are not guaranteed to have the same partition bounds, therefore we |
2052 | | * can't assume that the partitions at the same cardinal positions |
2053 | | * form the pairs; let get_matching_part_pairs() generate the pairs. |
2054 | | * Otherwise, nothing to do since we can assume that. |
2055 | | */ |
2056 | 0 | if (joinrel->partbounds_merged) |
2057 | 0 | { |
2058 | 0 | get_matching_part_pairs(root, joinrel, rel1, rel2, |
2059 | 0 | parts1, parts2); |
2060 | 0 | Assert(list_length(*parts1) == joinrel->nparts); |
2061 | 0 | Assert(list_length(*parts2) == joinrel->nparts); |
2062 | 0 | } |
2063 | 0 | } |
2064 | 0 | } |
2065 | | |
2066 | | /* |
2067 | | * get_matching_part_pairs |
2068 | | * Generate pairs of partitions to be joined from inputs |
2069 | | */ |
2070 | | static void |
2071 | | get_matching_part_pairs(PlannerInfo *root, RelOptInfo *joinrel, |
2072 | | RelOptInfo *rel1, RelOptInfo *rel2, |
2073 | | List **parts1, List **parts2) |
2074 | 0 | { |
2075 | 0 | bool rel1_is_simple = IS_SIMPLE_REL(rel1); |
2076 | 0 | bool rel2_is_simple = IS_SIMPLE_REL(rel2); |
2077 | 0 | int cnt_parts; |
2078 | |
|
2079 | 0 | *parts1 = NIL; |
2080 | 0 | *parts2 = NIL; |
2081 | |
|
2082 | 0 | for (cnt_parts = 0; cnt_parts < joinrel->nparts; cnt_parts++) |
2083 | 0 | { |
2084 | 0 | RelOptInfo *child_joinrel = joinrel->part_rels[cnt_parts]; |
2085 | 0 | RelOptInfo *child_rel1; |
2086 | 0 | RelOptInfo *child_rel2; |
2087 | 0 | Relids child_relids1; |
2088 | 0 | Relids child_relids2; |
2089 | | |
2090 | | /* |
2091 | | * If this segment of the join is empty, it means that this segment |
2092 | | * was ignored when previously creating child-join paths for it in |
2093 | | * try_partitionwise_join() as it would not contribute to the join |
2094 | | * result, due to one or both inputs being empty; add NULL to each of |
2095 | | * the given lists so that this segment will be ignored again in that |
2096 | | * function. |
2097 | | */ |
2098 | 0 | if (!child_joinrel) |
2099 | 0 | { |
2100 | 0 | *parts1 = lappend(*parts1, NULL); |
2101 | 0 | *parts2 = lappend(*parts2, NULL); |
2102 | 0 | continue; |
2103 | 0 | } |
2104 | | |
2105 | | /* |
2106 | | * Get a relids set of partition(s) involved in this join segment that |
2107 | | * are from the rel1 side. |
2108 | | */ |
2109 | 0 | child_relids1 = bms_intersect(child_joinrel->relids, |
2110 | 0 | rel1->all_partrels); |
2111 | 0 | Assert(bms_num_members(child_relids1) == bms_num_members(rel1->relids)); |
2112 | | |
2113 | | /* |
2114 | | * Get a child rel for rel1 with the relids. Note that we should have |
2115 | | * the child rel even if rel1 is a join rel, because in that case the |
2116 | | * partitions specified in the relids would have matching/overlapping |
2117 | | * boundaries, so the specified partitions should be considered as |
2118 | | * ones to be joined when planning partitionwise joins of rel1, |
2119 | | * meaning that the child rel would have been built by the time we get |
2120 | | * here. |
2121 | | */ |
2122 | 0 | if (rel1_is_simple) |
2123 | 0 | { |
2124 | 0 | int varno = bms_singleton_member(child_relids1); |
2125 | |
|
2126 | 0 | child_rel1 = find_base_rel(root, varno); |
2127 | 0 | } |
2128 | 0 | else |
2129 | 0 | child_rel1 = find_join_rel(root, child_relids1); |
2130 | 0 | Assert(child_rel1); |
2131 | | |
2132 | | /* |
2133 | | * Get a relids set of partition(s) involved in this join segment that |
2134 | | * are from the rel2 side. |
2135 | | */ |
2136 | 0 | child_relids2 = bms_intersect(child_joinrel->relids, |
2137 | 0 | rel2->all_partrels); |
2138 | 0 | Assert(bms_num_members(child_relids2) == bms_num_members(rel2->relids)); |
2139 | | |
2140 | | /* |
2141 | | * Get a child rel for rel2 with the relids. See above comments. |
2142 | | */ |
2143 | 0 | if (rel2_is_simple) |
2144 | 0 | { |
2145 | 0 | int varno = bms_singleton_member(child_relids2); |
2146 | |
|
2147 | 0 | child_rel2 = find_base_rel(root, varno); |
2148 | 0 | } |
2149 | 0 | else |
2150 | 0 | child_rel2 = find_join_rel(root, child_relids2); |
2151 | 0 | Assert(child_rel2); |
2152 | | |
2153 | | /* |
2154 | | * The join of rel1 and rel2 is legal, so is the join of the child |
2155 | | * rels obtained above; add them to the given lists as a join pair |
2156 | | * producing this join segment. |
2157 | | */ |
2158 | 0 | *parts1 = lappend(*parts1, child_rel1); |
2159 | 0 | *parts2 = lappend(*parts2, child_rel2); |
2160 | 0 | } |
2161 | 0 | } |