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