PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
restrictinfo.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * restrictinfo.c
4 * RestrictInfo node manipulation routines.
5 *
6 * Portions Copyright (c) 1996-2025, 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 "nodes/makefuncs.h"
18#include "nodes/nodeFuncs.h"
19#include "optimizer/clauses.h"
20#include "optimizer/optimizer.h"
22
23
25 Expr *clause,
26 bool is_pushed_down,
27 bool has_clone,
28 bool is_clone,
29 bool pseudoconstant,
30 Index security_level,
31 Relids required_relids,
32 Relids incompatible_relids,
33 Relids outer_relids);
34
35
36/*
37 * make_restrictinfo
38 *
39 * Build a RestrictInfo node containing the given subexpression.
40 *
41 * The is_pushed_down, has_clone, is_clone, and pseudoconstant flags for the
42 * RestrictInfo must be supplied by the caller, as well as the correct values
43 * for security_level, incompatible_relids, and outer_relids.
44 * required_relids can be NULL, in which case it defaults to the actual clause
45 * contents (i.e., clause_relids).
46 *
47 * We initialize fields that depend only on the given subexpression, leaving
48 * others that depend on context (or may never be needed at all) to be filled
49 * later.
50 */
53 Expr *clause,
54 bool is_pushed_down,
55 bool has_clone,
56 bool is_clone,
57 bool pseudoconstant,
58 Index security_level,
59 Relids required_relids,
60 Relids incompatible_relids,
61 Relids outer_relids)
62{
63 /*
64 * If it's an OR clause, build a modified copy with RestrictInfos inserted
65 * above each subclause of the top-level AND/OR structure.
66 */
67 if (is_orclause(clause))
69 clause,
70 is_pushed_down,
71 has_clone,
72 is_clone,
73 pseudoconstant,
74 security_level,
75 required_relids,
76 incompatible_relids,
77 outer_relids);
78
79 /* Shouldn't be an AND clause, else AND/OR flattening messed up */
80 Assert(!is_andclause(clause));
81
83 clause,
84 NULL,
85 is_pushed_down,
86 has_clone,
87 is_clone,
88 pseudoconstant,
89 security_level,
90 required_relids,
91 incompatible_relids,
92 outer_relids);
93}
94
95/*
96 * make_plain_restrictinfo
97 *
98 * Common code for the main entry points and the recursive cases. Also,
99 * useful while constructing RestrictInfos above OR clause, which already has
100 * RestrictInfos above its subclauses.
101 */
104 Expr *clause,
105 Expr *orclause,
106 bool is_pushed_down,
107 bool has_clone,
108 bool is_clone,
109 bool pseudoconstant,
110 Index security_level,
111 Relids required_relids,
112 Relids incompatible_relids,
113 Relids outer_relids)
114{
115 RestrictInfo *restrictinfo = makeNode(RestrictInfo);
116 Relids baserels;
117
118 restrictinfo->clause = clause;
119 restrictinfo->orclause = orclause;
120 restrictinfo->is_pushed_down = is_pushed_down;
121 restrictinfo->pseudoconstant = pseudoconstant;
122 restrictinfo->has_clone = has_clone;
123 restrictinfo->is_clone = is_clone;
124 restrictinfo->can_join = false; /* may get set below */
125 restrictinfo->security_level = security_level;
126 restrictinfo->incompatible_relids = incompatible_relids;
127 restrictinfo->outer_relids = outer_relids;
128
129 /*
130 * If it's potentially delayable by lower-level security quals, figure out
131 * whether it's leakproof. We can skip testing this for level-zero quals,
132 * since they would never get delayed on security grounds anyway.
133 */
134 if (security_level > 0)
135 restrictinfo->leakproof = !contain_leaked_vars((Node *) clause);
136 else
137 restrictinfo->leakproof = false; /* really, "don't know" */
138
139 /*
140 * Mark volatility as unknown. The contain_volatile_functions function
141 * will determine if there are any volatile functions when called for the
142 * first time with this RestrictInfo.
143 */
144 restrictinfo->has_volatile = VOLATILITY_UNKNOWN;
145
146 /*
147 * If it's a binary opclause, set up left/right relids info. In any case
148 * set up the total clause relids info.
149 */
150 if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
151 {
152 restrictinfo->left_relids = pull_varnos(root, get_leftop(clause));
153 restrictinfo->right_relids = pull_varnos(root, get_rightop(clause));
154
155 restrictinfo->clause_relids = bms_union(restrictinfo->left_relids,
156 restrictinfo->right_relids);
157
158 /*
159 * Does it look like a normal join clause, i.e., a binary operator
160 * relating expressions that come from distinct relations? If so we
161 * might be able to use it in a join algorithm. Note that this is a
162 * purely syntactic test that is made regardless of context.
163 */
164 if (!bms_is_empty(restrictinfo->left_relids) &&
165 !bms_is_empty(restrictinfo->right_relids) &&
166 !bms_overlap(restrictinfo->left_relids,
167 restrictinfo->right_relids))
168 {
169 restrictinfo->can_join = true;
170 /* pseudoconstant should certainly not be true */
171 Assert(!restrictinfo->pseudoconstant);
172 }
173 }
174 else
175 {
176 /* Not a binary opclause, so mark left/right relid sets as empty */
177 restrictinfo->left_relids = NULL;
178 restrictinfo->right_relids = NULL;
179 /* and get the total relid set the hard way */
180 restrictinfo->clause_relids = pull_varnos(root, (Node *) clause);
181 }
182
183 /* required_relids defaults to clause_relids */
184 if (required_relids != NULL)
185 restrictinfo->required_relids = required_relids;
186 else
187 restrictinfo->required_relids = restrictinfo->clause_relids;
188
189 /*
190 * Count the number of base rels appearing in clause_relids. To do this,
191 * we just delete rels mentioned in root->outer_join_rels and count the
192 * survivors. Because we are called during deconstruct_jointree which is
193 * the same tree walk that populates outer_join_rels, this is a little bit
194 * unsafe-looking; but it should be fine because the recursion in
195 * deconstruct_jointree should already have visited any outer join that
196 * could be mentioned in this clause.
197 */
198 baserels = bms_difference(restrictinfo->clause_relids,
199 root->outer_join_rels);
200 restrictinfo->num_base_rels = bms_num_members(baserels);
201 bms_free(baserels);
202
203 /*
204 * Label this RestrictInfo with a fresh serial number.
205 */
206 restrictinfo->rinfo_serial = ++(root->last_rinfo_serial);
207
208 /*
209 * Fill in all the cacheable fields with "not yet set" markers. None of
210 * these will be computed until/unless needed. Note in particular that we
211 * don't mark a binary opclause as mergejoinable or hashjoinable here;
212 * that happens only if it appears in the right context (top level of a
213 * joinclause list).
214 */
215 restrictinfo->parent_ec = NULL;
216
217 restrictinfo->eval_cost.startup = -1;
218 restrictinfo->norm_selec = -1;
219 restrictinfo->outer_selec = -1;
220
221 restrictinfo->mergeopfamilies = NIL;
222
223 restrictinfo->left_ec = NULL;
224 restrictinfo->right_ec = NULL;
225 restrictinfo->left_em = NULL;
226 restrictinfo->right_em = NULL;
227 restrictinfo->scansel_cache = NIL;
228
229 restrictinfo->outer_is_left = false;
230
231 restrictinfo->hashjoinoperator = InvalidOid;
232
233 restrictinfo->left_bucketsize = -1;
234 restrictinfo->right_bucketsize = -1;
235 restrictinfo->left_mcvfreq = -1;
236 restrictinfo->right_mcvfreq = -1;
237
238 restrictinfo->left_hasheqoperator = InvalidOid;
239 restrictinfo->right_hasheqoperator = InvalidOid;
240
241 return restrictinfo;
242}
243
244/*
245 * Recursively insert sub-RestrictInfo nodes into a boolean expression.
246 *
247 * We put RestrictInfos above simple (non-AND/OR) clauses and above
248 * sub-OR clauses, but not above sub-AND clauses, because there's no need.
249 * This may seem odd but it is closely related to the fact that we use
250 * implicit-AND lists at top level of RestrictInfo lists. Only ORs and
251 * simple clauses are valid RestrictInfos.
252 *
253 * The same is_pushed_down, has_clone, is_clone, and pseudoconstant flag
254 * values can be applied to all RestrictInfo nodes in the result. Likewise
255 * for security_level, incompatible_relids, and outer_relids.
256 *
257 * The given required_relids are attached to our top-level output,
258 * but any OR-clause constituents are allowed to default to just the
259 * contained rels.
260 */
261static Expr *
263 Expr *clause,
264 bool is_pushed_down,
265 bool has_clone,
266 bool is_clone,
267 bool pseudoconstant,
268 Index security_level,
269 Relids required_relids,
270 Relids incompatible_relids,
271 Relids outer_relids)
272{
273 if (is_orclause(clause))
274 {
275 List *orlist = NIL;
276 ListCell *temp;
277
278 foreach(temp, ((BoolExpr *) clause)->args)
279 orlist = lappend(orlist,
281 lfirst(temp),
282 is_pushed_down,
283 has_clone,
284 is_clone,
285 pseudoconstant,
286 security_level,
287 NULL,
288 incompatible_relids,
289 outer_relids));
291 clause,
292 make_orclause(orlist),
293 is_pushed_down,
294 has_clone,
295 is_clone,
296 pseudoconstant,
297 security_level,
298 required_relids,
299 incompatible_relids,
300 outer_relids);
301 }
302 else if (is_andclause(clause))
303 {
304 List *andlist = NIL;
305 ListCell *temp;
306
307 foreach(temp, ((BoolExpr *) clause)->args)
308 andlist = lappend(andlist,
310 lfirst(temp),
311 is_pushed_down,
312 has_clone,
313 is_clone,
314 pseudoconstant,
315 security_level,
316 required_relids,
317 incompatible_relids,
318 outer_relids));
319 return make_andclause(andlist);
320 }
321 else
323 clause,
324 NULL,
325 is_pushed_down,
326 has_clone,
327 is_clone,
328 pseudoconstant,
329 security_level,
330 required_relids,
331 incompatible_relids,
332 outer_relids);
333}
334
335/*
336 * commute_restrictinfo
337 *
338 * Given a RestrictInfo containing a binary opclause, produce a RestrictInfo
339 * representing the commutation of that clause. The caller must pass the
340 * OID of the commutator operator (which it's presumably looked up, else
341 * it would not know this is valid).
342 *
343 * Beware that the result shares sub-structure with the given RestrictInfo.
344 * That's okay for the intended usage with derived index quals, but might
345 * be hazardous if the source is subject to change. Also notice that we
346 * assume without checking that the commutator op is a member of the same
347 * btree and hash opclasses as the original op.
348 */
351{
352 RestrictInfo *result;
353 OpExpr *newclause;
354 OpExpr *clause = castNode(OpExpr, rinfo->clause);
355
356 Assert(list_length(clause->args) == 2);
357
358 /* flat-copy all the fields of clause ... */
359 newclause = makeNode(OpExpr);
360 memcpy(newclause, clause, sizeof(OpExpr));
361
362 /* ... and adjust those we need to change to commute it */
363 newclause->opno = comm_op;
364 newclause->opfuncid = InvalidOid;
365 newclause->args = list_make2(lsecond(clause->args),
366 linitial(clause->args));
367
368 /* likewise, flat-copy all the fields of rinfo ... */
369 result = makeNode(RestrictInfo);
370 memcpy(result, rinfo, sizeof(RestrictInfo));
371
372 /*
373 * ... and adjust those we need to change. Note in particular that we can
374 * preserve any cached selectivity or cost estimates, since those ought to
375 * be the same for the new clause. Likewise we can keep the source's
376 * parent_ec. It's also important that we keep the same rinfo_serial.
377 */
378 result->clause = (Expr *) newclause;
379 result->left_relids = rinfo->right_relids;
380 result->right_relids = rinfo->left_relids;
381 Assert(result->orclause == NULL);
382 result->left_ec = rinfo->right_ec;
383 result->right_ec = rinfo->left_ec;
384 result->left_em = rinfo->right_em;
385 result->right_em = rinfo->left_em;
386 result->scansel_cache = NIL; /* not worth updating this */
387 if (rinfo->hashjoinoperator == clause->opno)
388 result->hashjoinoperator = comm_op;
389 else
390 result->hashjoinoperator = InvalidOid;
391 result->left_bucketsize = rinfo->right_bucketsize;
392 result->right_bucketsize = rinfo->left_bucketsize;
393 result->left_mcvfreq = rinfo->right_mcvfreq;
394 result->right_mcvfreq = rinfo->left_mcvfreq;
395 result->left_hasheqoperator = InvalidOid;
396 result->right_hasheqoperator = InvalidOid;
397
398 return result;
399}
400
401/*
402 * restriction_is_or_clause
403 *
404 * Returns t iff the restrictinfo node contains an 'or' clause.
405 */
406bool
408{
409 if (restrictinfo->orclause != NULL)
410 return true;
411 else
412 return false;
413}
414
415/*
416 * restriction_is_securely_promotable
417 *
418 * Returns true if it's okay to evaluate this clause "early", that is before
419 * other restriction clauses attached to the specified relation.
420 */
421bool
423 RelOptInfo *rel)
424{
425 /*
426 * It's okay if there are no baserestrictinfo clauses for the rel that
427 * would need to go before this one, *or* if this one is leakproof.
428 */
429 if (restrictinfo->security_level <= rel->baserestrict_min_security ||
430 restrictinfo->leakproof)
431 return true;
432 else
433 return false;
434}
435
436/*
437 * Detect whether a RestrictInfo's clause is constant TRUE (note that it's
438 * surely of type boolean). No such WHERE clause could survive qual
439 * canonicalization, but equivclass.c may generate such RestrictInfos for
440 * reasons discussed therein. We should drop them again when creating
441 * the finished plan, which is handled by the next few functions.
442 */
443static inline bool
445{
446 return IsA(rinfo->clause, Const) &&
447 !((Const *) rinfo->clause)->constisnull &&
448 DatumGetBool(((Const *) rinfo->clause)->constvalue);
449}
450
451/*
452 * get_actual_clauses
453 *
454 * Returns a list containing the bare clauses from 'restrictinfo_list'.
455 *
456 * This is only to be used in cases where none of the RestrictInfos can
457 * be pseudoconstant clauses (for instance, it's OK on indexqual lists).
458 */
459List *
460get_actual_clauses(List *restrictinfo_list)
461{
462 List *result = NIL;
463 ListCell *l;
464
465 foreach(l, restrictinfo_list)
466 {
468
469 Assert(!rinfo->pseudoconstant);
471
472 result = lappend(result, rinfo->clause);
473 }
474 return result;
475}
476
477/*
478 * extract_actual_clauses
479 *
480 * Extract bare clauses from 'restrictinfo_list', returning either the
481 * regular ones or the pseudoconstant ones per 'pseudoconstant'.
482 * Constant-TRUE clauses are dropped in any case.
483 */
484List *
485extract_actual_clauses(List *restrictinfo_list,
486 bool pseudoconstant)
487{
488 List *result = NIL;
489 ListCell *l;
490
491 foreach(l, restrictinfo_list)
492 {
494
495 if (rinfo->pseudoconstant == pseudoconstant &&
497 result = lappend(result, rinfo->clause);
498 }
499 return result;
500}
501
502/*
503 * extract_actual_join_clauses
504 *
505 * Extract bare clauses from 'restrictinfo_list', separating those that
506 * semantically match the join level from those that were pushed down.
507 * Pseudoconstant and constant-TRUE clauses are excluded from the results.
508 *
509 * This is only used at outer joins, since for plain joins we don't care
510 * about pushed-down-ness.
511 */
512void
514 Relids joinrelids,
515 List **joinquals,
516 List **otherquals)
517{
518 ListCell *l;
519
520 *joinquals = NIL;
521 *otherquals = NIL;
522
523 foreach(l, restrictinfo_list)
524 {
526
527 if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids))
528 {
529 if (!rinfo->pseudoconstant &&
531 *otherquals = lappend(*otherquals, rinfo->clause);
532 }
533 else
534 {
535 /* joinquals shouldn't have been marked pseudoconstant */
536 Assert(!rinfo->pseudoconstant);
537 if (!rinfo_is_constant_true(rinfo))
538 *joinquals = lappend(*joinquals, rinfo->clause);
539 }
540 }
541}
542
543/*
544 * join_clause_is_movable_to
545 * Test whether a join clause is a safe candidate for parameterization
546 * of a scan on the specified base relation.
547 *
548 * A movable join clause is one that can safely be evaluated at a rel below
549 * its normal semantic level (ie, its required_relids), if the values of
550 * variables that it would need from other rels are provided.
551 *
552 * We insist that the clause actually reference the target relation; this
553 * prevents undesirable movement of degenerate join clauses, and ensures
554 * that there is a unique place that a clause can be moved down to.
555 *
556 * We cannot move an outer-join clause into the non-nullable side of its
557 * outer join, as that would change the results (rows would be suppressed
558 * rather than being null-extended).
559 *
560 * Also there must not be an outer join below the clause that would null the
561 * Vars coming from the target relation. Otherwise the clause might give
562 * results different from what it would give at its normal semantic level.
563 *
564 * Also, the join clause must not use any relations that have LATERAL
565 * references to the target relation, since we could not put such rels on
566 * the outer side of a nestloop with the target relation.
567 *
568 * Also, we reject is_clone versions of outer-join clauses. This has the
569 * effect of preventing us from generating variant parameterized paths
570 * that differ only in which outer joins null the parameterization rel(s).
571 * Generating one path from the minimally-parameterized has_clone version
572 * is sufficient.
573 */
574bool
576{
577 /* Clause must physically reference target rel */
578 if (!bms_is_member(baserel->relid, rinfo->clause_relids))
579 return false;
580
581 /* Cannot move an outer-join clause into the join's outer side */
582 if (bms_is_member(baserel->relid, rinfo->outer_relids))
583 return false;
584
585 /*
586 * Target rel's Vars must not be nulled by any outer join. We can check
587 * this without groveling through the individual Vars by seeing whether
588 * clause_relids (which includes all such Vars' varnullingrels) includes
589 * any outer join that can null the target rel. You might object that
590 * this could reject the clause on the basis of an OJ relid that came from
591 * some other rel's Var. However, that would still mean that the clause
592 * came from above that outer join and shouldn't be pushed down; so there
593 * should be no false positives.
594 */
595 if (bms_overlap(rinfo->clause_relids, baserel->nulling_relids))
596 return false;
597
598 /* Clause must not use any rels with LATERAL references to this rel */
599 if (bms_overlap(baserel->lateral_referencers, rinfo->clause_relids))
600 return false;
601
602 /* Ignore clones, too */
603 if (rinfo->is_clone)
604 return false;
605
606 return true;
607}
608
609/*
610 * join_clause_is_movable_into
611 * Test whether a join clause is movable and can be evaluated within
612 * the current join context.
613 *
614 * currentrelids: the relids of the proposed evaluation location
615 * current_and_outer: the union of currentrelids and the required_outer
616 * relids (parameterization's outer relations)
617 *
618 * The API would be a bit clearer if we passed the current relids and the
619 * outer relids separately and did bms_union internally; but since most
620 * callers need to apply this function to multiple clauses, we make the
621 * caller perform the union.
622 *
623 * Obviously, the clause must only refer to Vars available from the current
624 * relation plus the outer rels. We also check that it does reference at
625 * least one current Var, ensuring that the clause will be pushed down to
626 * a unique place in a parameterized join tree. And we check that we're
627 * not pushing the clause into its outer-join outer side.
628 *
629 * We used to need to check that we're not pushing the clause into a lower
630 * outer join's inner side. However, now that clause_relids includes
631 * references to potentially-nulling outer joins, the other tests handle that
632 * concern. If the clause references any Var coming from the inside of a
633 * lower outer join, its clause_relids will mention that outer join, causing
634 * the evaluability check to fail; while if it references no such Vars, the
635 * references-a-target-rel check will fail.
636 *
637 * There's no check here equivalent to join_clause_is_movable_to's test on
638 * lateral_referencers. We assume the caller wouldn't be inquiring unless
639 * it'd verified that the proposed outer rels don't have lateral references
640 * to the current rel(s). (If we are considering join paths with the outer
641 * rels on the outside and the current rels on the inside, then this should
642 * have been checked at the outset of such consideration; see join_is_legal
643 * and the path parameterization checks in joinpath.c.) On the other hand,
644 * in join_clause_is_movable_to we are asking whether the clause could be
645 * moved for some valid set of outer rels, so we don't have the benefit of
646 * relying on prior checks for lateral-reference validity.
647 *
648 * Likewise, we don't check is_clone here: rejecting the inappropriate
649 * variants of a cloned clause must be handled upstream.
650 *
651 * Note: if this returns true, it means that the clause could be moved to
652 * this join relation, but that doesn't mean that this is the lowest join
653 * it could be moved to. Caller may need to make additional calls to verify
654 * that this doesn't succeed on either of the inputs of a proposed join.
655 *
656 * Note: get_joinrel_parampathinfo depends on the fact that if
657 * current_and_outer is NULL, this function will always return false
658 * (since one or the other of the first two tests must fail).
659 */
660bool
662 Relids currentrelids,
663 Relids current_and_outer)
664{
665 /* Clause must be evaluable given available context */
666 if (!bms_is_subset(rinfo->clause_relids, current_and_outer))
667 return false;
668
669 /* Clause must physically reference at least one target rel */
670 if (!bms_overlap(currentrelids, rinfo->clause_relids))
671 return false;
672
673 /* Cannot move an outer-join clause into the join's outer side */
674 if (bms_overlap(currentrelids, rinfo->outer_relids))
675 return false;
676
677 return true;
678}
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:346
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:412
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:751
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:251
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:582
#define bms_is_empty(a)
Definition: bitmapset.h:118
unsigned int Index
Definition: c.h:585
bool contain_leaked_vars(Node *clause)
Definition: clauses.c:1264
Assert(PointerIsAligned(start, uint64))
List * lappend(List *list, void *datum)
Definition: list.c:339
Expr * make_orclause(List *orclauses)
Definition: makefuncs.c:743
Expr * make_andclause(List *andclauses)
Definition: makefuncs.c:727
static bool is_andclause(const void *clause)
Definition: nodeFuncs.h:107
static bool is_orclause(const void *clause)
Definition: nodeFuncs.h:116
static Node * get_rightop(const void *clause)
Definition: nodeFuncs.h:95
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:76
static Node * get_leftop(const void *clause)
Definition: nodeFuncs.h:83
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define makeNode(_type_)
Definition: nodes.h:161
#define castNode(_type_, nodeptr)
Definition: nodes.h:182
#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)
Definition: pathnodes.h:2857
@ VOLATILITY_UNKNOWN
Definition: pathnodes.h:1634
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
#define list_make2(x1, x2)
Definition: pg_list.h:214
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
tree ctl root
Definition: radixtree.h:1857
bool restriction_is_or_clause(RestrictInfo *restrictinfo)
Definition: restrictinfo.c:407
List * extract_actual_clauses(List *restrictinfo_list, bool pseudoconstant)
Definition: restrictinfo.c:485
void extract_actual_join_clauses(List *restrictinfo_list, Relids joinrelids, List **joinquals, List **otherquals)
Definition: restrictinfo.c:513
bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, RelOptInfo *rel)
Definition: restrictinfo.c:422
RestrictInfo * make_plain_restrictinfo(PlannerInfo *root, Expr *clause, Expr *orclause, bool is_pushed_down, bool has_clone, bool is_clone, bool pseudoconstant, Index security_level, Relids required_relids, Relids incompatible_relids, Relids outer_relids)
Definition: restrictinfo.c:103
List * get_actual_clauses(List *restrictinfo_list)
Definition: restrictinfo.c:460
static Expr * make_sub_restrictinfos(PlannerInfo *root, Expr *clause, bool is_pushed_down, bool has_clone, bool is_clone, bool pseudoconstant, Index security_level, Relids required_relids, Relids incompatible_relids, Relids outer_relids)
Definition: restrictinfo.c:262
bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer)
Definition: restrictinfo.c:661
bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel)
Definition: restrictinfo.c:575
RestrictInfo * make_restrictinfo(PlannerInfo *root, Expr *clause, bool is_pushed_down, bool has_clone, bool is_clone, bool pseudoconstant, Index security_level, Relids required_relids, Relids incompatible_relids, Relids outer_relids)
Definition: restrictinfo.c:52
RestrictInfo * commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op)
Definition: restrictinfo.c:350
static bool rinfo_is_constant_true(RestrictInfo *rinfo)
Definition: restrictinfo.c:444
Definition: pg_list.h:54
Definition: nodes.h:135
Oid opno
Definition: primnodes.h:835
List * args
Definition: primnodes.h:853
Index relid
Definition: pathnodes.h:945
Relids lateral_referencers
Definition: pathnodes.h:969
Relids nulling_relids
Definition: pathnodes.h:965
Index baserestrict_min_security
Definition: pathnodes.h:1016
bool is_pushed_down
Definition: pathnodes.h:2703
Index security_level
Definition: pathnodes.h:2722
Relids required_relids
Definition: pathnodes.h:2731
int rinfo_serial
Definition: pathnodes.h:2772
Relids outer_relids
Definition: pathnodes.h:2737
Relids incompatible_relids
Definition: pathnodes.h:2734
Expr * clause
Definition: pathnodes.h:2700
bool has_clone
Definition: pathnodes.h:2712
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition: var.c:114