1 /*-------------------------------------------------------------------------
2 *
3 * restrictinfo.c
4 * RestrictInfo node manipulation routines.
5 *
6 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/optimizer/util/restrictinfo.c
12 *
13 *-------------------------------------------------------------------------
14 */
15 #include "postgres.h"
16
17 #include "optimizer/clauses.h"
18 #include "optimizer/restrictinfo.h"
19 #include "optimizer/var.h"
20
21
22 static RestrictInfo *make_restrictinfo_internal(Expr *clause,
23 Expr *orclause,
24 bool is_pushed_down,
25 bool outerjoin_delayed,
26 bool pseudoconstant,
27 Index security_level,
28 Relids required_relids,
29 Relids outer_relids,
30 Relids nullable_relids);
31 static Expr *make_sub_restrictinfos(Expr *clause,
32 bool is_pushed_down,
33 bool outerjoin_delayed,
34 bool pseudoconstant,
35 Index security_level,
36 Relids required_relids,
37 Relids outer_relids,
38 Relids nullable_relids);
39
40
41 /*
42 * make_restrictinfo
43 *
44 * Build a RestrictInfo node containing the given subexpression.
45 *
46 * The is_pushed_down, outerjoin_delayed, and pseudoconstant flags for the
47 * RestrictInfo must be supplied by the caller, as well as the correct values
48 * for security_level, outer_relids, and nullable_relids.
49 * required_relids can be NULL, in which case it defaults to the actual clause
50 * contents (i.e., clause_relids).
51 *
52 * We initialize fields that depend only on the given subexpression, leaving
53 * others that depend on context (or may never be needed at all) to be filled
54 * later.
55 */
56 RestrictInfo *
make_restrictinfo(Expr * clause,bool is_pushed_down,bool outerjoin_delayed,bool pseudoconstant,Index security_level,Relids required_relids,Relids outer_relids,Relids nullable_relids)57 make_restrictinfo(Expr *clause,
58 bool is_pushed_down,
59 bool outerjoin_delayed,
60 bool pseudoconstant,
61 Index security_level,
62 Relids required_relids,
63 Relids outer_relids,
64 Relids nullable_relids)
65 {
66 /*
67 * If it's an OR clause, build a modified copy with RestrictInfos inserted
68 * above each subclause of the top-level AND/OR structure.
69 */
70 if (or_clause((Node *) clause))
71 return (RestrictInfo *) make_sub_restrictinfos(clause,
72 is_pushed_down,
73 outerjoin_delayed,
74 pseudoconstant,
75 security_level,
76 required_relids,
77 outer_relids,
78 nullable_relids);
79
80 /* Shouldn't be an AND clause, else AND/OR flattening messed up */
81 Assert(!and_clause((Node *) clause));
82
83 return make_restrictinfo_internal(clause,
84 NULL,
85 is_pushed_down,
86 outerjoin_delayed,
87 pseudoconstant,
88 security_level,
89 required_relids,
90 outer_relids,
91 nullable_relids);
92 }
93
94 /*
95 * make_restrictinfo_internal
96 *
97 * Common code for the main entry points and the recursive cases.
98 */
99 static RestrictInfo *
make_restrictinfo_internal(Expr * clause,Expr * orclause,bool is_pushed_down,bool outerjoin_delayed,bool pseudoconstant,Index security_level,Relids required_relids,Relids outer_relids,Relids nullable_relids)100 make_restrictinfo_internal(Expr *clause,
101 Expr *orclause,
102 bool is_pushed_down,
103 bool outerjoin_delayed,
104 bool pseudoconstant,
105 Index security_level,
106 Relids required_relids,
107 Relids outer_relids,
108 Relids nullable_relids)
109 {
110 RestrictInfo *restrictinfo = makeNode(RestrictInfo);
111
112 restrictinfo->clause = clause;
113 restrictinfo->orclause = orclause;
114 restrictinfo->is_pushed_down = is_pushed_down;
115 restrictinfo->outerjoin_delayed = outerjoin_delayed;
116 restrictinfo->pseudoconstant = pseudoconstant;
117 restrictinfo->can_join = false; /* may get set below */
118 restrictinfo->security_level = security_level;
119 restrictinfo->outer_relids = outer_relids;
120 restrictinfo->nullable_relids = nullable_relids;
121
122 /*
123 * If it's potentially delayable by lower-level security quals, figure out
124 * whether it's leakproof. We can skip testing this for level-zero quals,
125 * since they would never get delayed on security grounds anyway.
126 */
127 if (security_level > 0)
128 restrictinfo->leakproof = !contain_leaked_vars((Node *) clause);
129 else
130 restrictinfo->leakproof = false; /* really, "don't know" */
131
132 /*
133 * If it's a binary opclause, set up left/right relids info. In any case
134 * set up the total clause relids info.
135 */
136 if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
137 {
138 restrictinfo->left_relids = pull_varnos(get_leftop(clause));
139 restrictinfo->right_relids = pull_varnos(get_rightop(clause));
140
141 restrictinfo->clause_relids = bms_union(restrictinfo->left_relids,
142 restrictinfo->right_relids);
143
144 /*
145 * Does it look like a normal join clause, i.e., a binary operator
146 * relating expressions that come from distinct relations? If so we
147 * might be able to use it in a join algorithm. Note that this is a
148 * purely syntactic test that is made regardless of context.
149 */
150 if (!bms_is_empty(restrictinfo->left_relids) &&
151 !bms_is_empty(restrictinfo->right_relids) &&
152 !bms_overlap(restrictinfo->left_relids,
153 restrictinfo->right_relids))
154 {
155 restrictinfo->can_join = true;
156 /* pseudoconstant should certainly not be true */
157 Assert(!restrictinfo->pseudoconstant);
158 }
159 }
160 else
161 {
162 /* Not a binary opclause, so mark left/right relid sets as empty */
163 restrictinfo->left_relids = NULL;
164 restrictinfo->right_relids = NULL;
165 /* and get the total relid set the hard way */
166 restrictinfo->clause_relids = pull_varnos((Node *) clause);
167 }
168
169 /* required_relids defaults to clause_relids */
170 if (required_relids != NULL)
171 restrictinfo->required_relids = required_relids;
172 else
173 restrictinfo->required_relids = restrictinfo->clause_relids;
174
175 /*
176 * Fill in all the cacheable fields with "not yet set" markers. None of
177 * these will be computed until/unless needed. Note in particular that we
178 * don't mark a binary opclause as mergejoinable or hashjoinable here;
179 * that happens only if it appears in the right context (top level of a
180 * joinclause list).
181 */
182 restrictinfo->parent_ec = NULL;
183
184 restrictinfo->eval_cost.startup = -1;
185 restrictinfo->norm_selec = -1;
186 restrictinfo->outer_selec = -1;
187
188 restrictinfo->mergeopfamilies = NIL;
189
190 restrictinfo->left_ec = NULL;
191 restrictinfo->right_ec = NULL;
192 restrictinfo->left_em = NULL;
193 restrictinfo->right_em = NULL;
194 restrictinfo->scansel_cache = NIL;
195
196 restrictinfo->outer_is_left = false;
197
198 restrictinfo->hashjoinoperator = InvalidOid;
199
200 restrictinfo->left_bucketsize = -1;
201 restrictinfo->right_bucketsize = -1;
202
203 return restrictinfo;
204 }
205
206 /*
207 * Recursively insert sub-RestrictInfo nodes into a boolean expression.
208 *
209 * We put RestrictInfos above simple (non-AND/OR) clauses and above
210 * sub-OR clauses, but not above sub-AND clauses, because there's no need.
211 * This may seem odd but it is closely related to the fact that we use
212 * implicit-AND lists at top level of RestrictInfo lists. Only ORs and
213 * simple clauses are valid RestrictInfos.
214 *
215 * The same is_pushed_down, outerjoin_delayed, and pseudoconstant flag
216 * values can be applied to all RestrictInfo nodes in the result. Likewise
217 * for security_level, outer_relids, and nullable_relids.
218 *
219 * The given required_relids are attached to our top-level output,
220 * but any OR-clause constituents are allowed to default to just the
221 * contained rels.
222 */
223 static Expr *
make_sub_restrictinfos(Expr * clause,bool is_pushed_down,bool outerjoin_delayed,bool pseudoconstant,Index security_level,Relids required_relids,Relids outer_relids,Relids nullable_relids)224 make_sub_restrictinfos(Expr *clause,
225 bool is_pushed_down,
226 bool outerjoin_delayed,
227 bool pseudoconstant,
228 Index security_level,
229 Relids required_relids,
230 Relids outer_relids,
231 Relids nullable_relids)
232 {
233 if (or_clause((Node *) clause))
234 {
235 List *orlist = NIL;
236 ListCell *temp;
237
238 foreach(temp, ((BoolExpr *) clause)->args)
239 orlist = lappend(orlist,
240 make_sub_restrictinfos(lfirst(temp),
241 is_pushed_down,
242 outerjoin_delayed,
243 pseudoconstant,
244 security_level,
245 NULL,
246 outer_relids,
247 nullable_relids));
248 return (Expr *) make_restrictinfo_internal(clause,
249 make_orclause(orlist),
250 is_pushed_down,
251 outerjoin_delayed,
252 pseudoconstant,
253 security_level,
254 required_relids,
255 outer_relids,
256 nullable_relids);
257 }
258 else if (and_clause((Node *) clause))
259 {
260 List *andlist = NIL;
261 ListCell *temp;
262
263 foreach(temp, ((BoolExpr *) clause)->args)
264 andlist = lappend(andlist,
265 make_sub_restrictinfos(lfirst(temp),
266 is_pushed_down,
267 outerjoin_delayed,
268 pseudoconstant,
269 security_level,
270 required_relids,
271 outer_relids,
272 nullable_relids));
273 return make_andclause(andlist);
274 }
275 else
276 return (Expr *) make_restrictinfo_internal(clause,
277 NULL,
278 is_pushed_down,
279 outerjoin_delayed,
280 pseudoconstant,
281 security_level,
282 required_relids,
283 outer_relids,
284 nullable_relids);
285 }
286
287 /*
288 * restriction_is_or_clause
289 *
290 * Returns t iff the restrictinfo node contains an 'or' clause.
291 */
292 bool
restriction_is_or_clause(RestrictInfo * restrictinfo)293 restriction_is_or_clause(RestrictInfo *restrictinfo)
294 {
295 if (restrictinfo->orclause != NULL)
296 return true;
297 else
298 return false;
299 }
300
301 /*
302 * restriction_is_securely_promotable
303 *
304 * Returns true if it's okay to evaluate this clause "early", that is before
305 * other restriction clauses attached to the specified relation.
306 */
307 bool
restriction_is_securely_promotable(RestrictInfo * restrictinfo,RelOptInfo * rel)308 restriction_is_securely_promotable(RestrictInfo *restrictinfo,
309 RelOptInfo *rel)
310 {
311 /*
312 * It's okay if there are no baserestrictinfo clauses for the rel that
313 * would need to go before this one, *or* if this one is leakproof.
314 */
315 if (restrictinfo->security_level <= rel->baserestrict_min_security ||
316 restrictinfo->leakproof)
317 return true;
318 else
319 return false;
320 }
321
322 /*
323 * get_actual_clauses
324 *
325 * Returns a list containing the bare clauses from 'restrictinfo_list'.
326 *
327 * This is only to be used in cases where none of the RestrictInfos can
328 * be pseudoconstant clauses (for instance, it's OK on indexqual lists).
329 */
330 List *
get_actual_clauses(List * restrictinfo_list)331 get_actual_clauses(List *restrictinfo_list)
332 {
333 List *result = NIL;
334 ListCell *l;
335
336 foreach(l, restrictinfo_list)
337 {
338 RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
339
340 Assert(!rinfo->pseudoconstant);
341
342 result = lappend(result, rinfo->clause);
343 }
344 return result;
345 }
346
347 /*
348 * extract_actual_clauses
349 *
350 * Extract bare clauses from 'restrictinfo_list', returning either the
351 * regular ones or the pseudoconstant ones per 'pseudoconstant'.
352 */
353 List *
extract_actual_clauses(List * restrictinfo_list,bool pseudoconstant)354 extract_actual_clauses(List *restrictinfo_list,
355 bool pseudoconstant)
356 {
357 List *result = NIL;
358 ListCell *l;
359
360 foreach(l, restrictinfo_list)
361 {
362 RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
363
364 if (rinfo->pseudoconstant == pseudoconstant)
365 result = lappend(result, rinfo->clause);
366 }
367 return result;
368 }
369
370 /*
371 * extract_actual_join_clauses
372 *
373 * Extract bare clauses from 'restrictinfo_list', separating those that
374 * semantically match the join level from those that were pushed down.
375 * Pseudoconstant clauses are excluded from the results.
376 *
377 * This is only used at outer joins, since for plain joins we don't care
378 * about pushed-down-ness.
379 */
380 void
extract_actual_join_clauses(List * restrictinfo_list,Relids joinrelids,List ** joinquals,List ** otherquals)381 extract_actual_join_clauses(List *restrictinfo_list,
382 Relids joinrelids,
383 List **joinquals,
384 List **otherquals)
385 {
386 ListCell *l;
387
388 *joinquals = NIL;
389 *otherquals = NIL;
390
391 foreach(l, restrictinfo_list)
392 {
393 RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
394
395 if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids))
396 {
397 if (!rinfo->pseudoconstant)
398 *otherquals = lappend(*otherquals, rinfo->clause);
399 }
400 else
401 {
402 /* joinquals shouldn't have been marked pseudoconstant */
403 Assert(!rinfo->pseudoconstant);
404 *joinquals = lappend(*joinquals, rinfo->clause);
405 }
406 }
407 }
408
409
410 /*
411 * join_clause_is_movable_to
412 * Test whether a join clause is a safe candidate for parameterization
413 * of a scan on the specified base relation.
414 *
415 * A movable join clause is one that can safely be evaluated at a rel below
416 * its normal semantic level (ie, its required_relids), if the values of
417 * variables that it would need from other rels are provided.
418 *
419 * We insist that the clause actually reference the target relation; this
420 * prevents undesirable movement of degenerate join clauses, and ensures
421 * that there is a unique place that a clause can be moved down to.
422 *
423 * We cannot move an outer-join clause into the non-nullable side of its
424 * outer join, as that would change the results (rows would be suppressed
425 * rather than being null-extended).
426 *
427 * Also there must not be an outer join below the clause that would null the
428 * Vars coming from the target relation. Otherwise the clause might give
429 * results different from what it would give at its normal semantic level.
430 *
431 * Also, the join clause must not use any relations that have LATERAL
432 * references to the target relation, since we could not put such rels on
433 * the outer side of a nestloop with the target relation.
434 */
435 bool
join_clause_is_movable_to(RestrictInfo * rinfo,RelOptInfo * baserel)436 join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel)
437 {
438 /* Clause must physically reference target rel */
439 if (!bms_is_member(baserel->relid, rinfo->clause_relids))
440 return false;
441
442 /* Cannot move an outer-join clause into the join's outer side */
443 if (bms_is_member(baserel->relid, rinfo->outer_relids))
444 return false;
445
446 /* Target rel must not be nullable below the clause */
447 if (bms_is_member(baserel->relid, rinfo->nullable_relids))
448 return false;
449
450 /* Clause must not use any rels with LATERAL references to this rel */
451 if (bms_overlap(baserel->lateral_referencers, rinfo->clause_relids))
452 return false;
453
454 return true;
455 }
456
457 /*
458 * join_clause_is_movable_into
459 * Test whether a join clause is movable and can be evaluated within
460 * the current join context.
461 *
462 * currentrelids: the relids of the proposed evaluation location
463 * current_and_outer: the union of currentrelids and the required_outer
464 * relids (parameterization's outer relations)
465 *
466 * The API would be a bit clearer if we passed the current relids and the
467 * outer relids separately and did bms_union internally; but since most
468 * callers need to apply this function to multiple clauses, we make the
469 * caller perform the union.
470 *
471 * Obviously, the clause must only refer to Vars available from the current
472 * relation plus the outer rels. We also check that it does reference at
473 * least one current Var, ensuring that the clause will be pushed down to
474 * a unique place in a parameterized join tree. And we check that we're
475 * not pushing the clause into its outer-join outer side, nor down into
476 * a lower outer join's inner side.
477 *
478 * The check about pushing a clause down into a lower outer join's inner side
479 * is only approximate; it sometimes returns "false" when actually it would
480 * be safe to use the clause here because we're still above the outer join
481 * in question. This is okay as long as the answers at different join levels
482 * are consistent: it just means we might sometimes fail to push a clause as
483 * far down as it could safely be pushed. It's unclear whether it would be
484 * worthwhile to do this more precisely. (But if it's ever fixed to be
485 * exactly accurate, there's an Assert in get_joinrel_parampathinfo() that
486 * should be re-enabled.)
487 *
488 * There's no check here equivalent to join_clause_is_movable_to's test on
489 * lateral_referencers. We assume the caller wouldn't be inquiring unless
490 * it'd verified that the proposed outer rels don't have lateral references
491 * to the current rel(s). (If we are considering join paths with the outer
492 * rels on the outside and the current rels on the inside, then this should
493 * have been checked at the outset of such consideration; see join_is_legal
494 * and the path parameterization checks in joinpath.c.) On the other hand,
495 * in join_clause_is_movable_to we are asking whether the clause could be
496 * moved for some valid set of outer rels, so we don't have the benefit of
497 * relying on prior checks for lateral-reference validity.
498 *
499 * Note: if this returns true, it means that the clause could be moved to
500 * this join relation, but that doesn't mean that this is the lowest join
501 * it could be moved to. Caller may need to make additional calls to verify
502 * that this doesn't succeed on either of the inputs of a proposed join.
503 *
504 * Note: get_joinrel_parampathinfo depends on the fact that if
505 * current_and_outer is NULL, this function will always return false
506 * (since one or the other of the first two tests must fail).
507 */
508 bool
join_clause_is_movable_into(RestrictInfo * rinfo,Relids currentrelids,Relids current_and_outer)509 join_clause_is_movable_into(RestrictInfo *rinfo,
510 Relids currentrelids,
511 Relids current_and_outer)
512 {
513 /* Clause must be evaluable given available context */
514 if (!bms_is_subset(rinfo->clause_relids, current_and_outer))
515 return false;
516
517 /* Clause must physically reference at least one target rel */
518 if (!bms_overlap(currentrelids, rinfo->clause_relids))
519 return false;
520
521 /* Cannot move an outer-join clause into the join's outer side */
522 if (bms_overlap(currentrelids, rinfo->outer_relids))
523 return false;
524
525 /*
526 * Target rel(s) must not be nullable below the clause. This is
527 * approximate, in the safe direction, because the current join might be
528 * above the join where the nulling would happen, in which case the clause
529 * would work correctly here. But we don't have enough info to be sure.
530 */
531 if (bms_overlap(currentrelids, rinfo->nullable_relids))
532 return false;
533
534 return true;
535 }
536