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