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  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 contrucitng RestrictInfos above OR clause, which already has
100  * RestrictInfos above its subclauses.
101  */
102 RestrictInfo *
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  */
261 static 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));
290  return (Expr *) make_plain_restrictinfo(root,
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
322  return (Expr *) make_plain_restrictinfo(root,
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  */
349 RestrictInfo *
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  */
406 bool
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  */
421 bool
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  */
443 static 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  */
459 List *
460 get_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  */
484 List *
485 extract_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 &&
496  !rinfo_is_constant_true(rinfo))
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  */
512 void
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 &&
530  !rinfo_is_constant_true(rinfo))
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  */
574 bool
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  */
660 bool
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 }
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:837
unsigned int Index
Definition: c.h:593
bool contain_leaked_vars(Node *clause)
Definition: clauses.c:1262
List * lappend(List *list, void *datum)
Definition: list.c:339
Expr * make_andclause(List *andclauses)
Definition: makefuncs.c:677
Expr * make_orclause(List *orclauses)
Definition: makefuncs.c:693
static bool is_andclause(const void *clause)
Definition: nodeFuncs.h:107
static bool is_orclause(const void *clause)
Definition: nodeFuncs.h:116
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:76
static Node * get_rightop(const void *clause)
Definition: nodeFuncs.h:95
static Node * get_leftop(const void *clause)
Definition: nodeFuncs.h:83
#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:2731
@ VOLATILITY_UNKNOWN
Definition: pathnodes.h:1507
#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:1886
List * get_actual_clauses(List *restrictinfo_list)
Definition: restrictinfo.c:460
bool restriction_is_or_clause(RestrictInfo *restrictinfo)
Definition: restrictinfo.c:407
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
void extract_actual_join_clauses(List *restrictinfo_list, Relids joinrelids, List **joinquals, List **otherquals)
Definition: restrictinfo.c:513
RestrictInfo * commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op)
Definition: restrictinfo.c:350
bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, RelOptInfo *rel)
Definition: restrictinfo.c:422
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
List * extract_actual_clauses(List *restrictinfo_list, bool pseudoconstant)
Definition: restrictinfo.c:485
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
bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel)
Definition: restrictinfo.c:575
static bool rinfo_is_constant_true(RestrictInfo *rinfo)
Definition: restrictinfo.c:444
Definition: pg_list.h:54
Definition: nodes.h:129
Oid opno
Definition: primnodes.h:818
List * args
Definition: primnodes.h:836
Index relid
Definition: pathnodes.h:918
Relids lateral_referencers
Definition: pathnodes.h:942
Relids nulling_relids
Definition: pathnodes.h:938
Index baserestrict_min_security
Definition: pathnodes.h:989
bool is_pushed_down
Definition: pathnodes.h:2577
Index security_level
Definition: pathnodes.h:2596
Relids required_relids
Definition: pathnodes.h:2605
int rinfo_serial
Definition: pathnodes.h:2646
Relids outer_relids
Definition: pathnodes.h:2611
Relids incompatible_relids
Definition: pathnodes.h:2608
Expr * clause
Definition: pathnodes.h:2574
bool has_clone
Definition: pathnodes.h:2586
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition: var.c:113