PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
restrictinfo.h File Reference
#include "nodes/pathnodes.h"
Include dependency graph for restrictinfo.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define make_simple_restrictinfo(root, clause)
 

Functions

RestrictInfomake_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)
 
RestrictInfomake_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)
 
RestrictInfocommute_restrictinfo (RestrictInfo *rinfo, Oid comm_op)
 
bool restriction_is_or_clause (RestrictInfo *restrictinfo)
 
bool restriction_is_securely_promotable (RestrictInfo *restrictinfo, RelOptInfo *rel)
 
Listget_actual_clauses (List *restrictinfo_list)
 
Listextract_actual_clauses (List *restrictinfo_list, bool pseudoconstant)
 
void extract_actual_join_clauses (List *restrictinfo_list, Relids joinrelids, List **joinquals, List **otherquals)
 
bool join_clause_is_movable_to (RestrictInfo *rinfo, RelOptInfo *baserel)
 
bool join_clause_is_movable_into (RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer)
 
static bool clause_sides_match_join (RestrictInfo *rinfo, Relids outerrelids, Relids innerrelids)
 

Macro Definition Documentation

◆ make_simple_restrictinfo

#define make_simple_restrictinfo (   root,
  clause 
)
Value:
make_restrictinfo(root, clause, true, false, false, false, 0, \
NULL, NULL, NULL)
tree ctl root
Definition: radixtree.h:1857
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

Definition at line 21 of file restrictinfo.h.

Function Documentation

◆ clause_sides_match_join()

static bool clause_sides_match_join ( RestrictInfo rinfo,
Relids  outerrelids,
Relids  innerrelids 
)
inlinestatic

Definition at line 73 of file restrictinfo.h.

75{
76 if (bms_is_subset(rinfo->left_relids, outerrelids) &&
77 bms_is_subset(rinfo->right_relids, innerrelids))
78 {
79 /* lefthand side is outer */
80 rinfo->outer_is_left = true;
81 return true;
82 }
83 else if (bms_is_subset(rinfo->left_relids, innerrelids) &&
84 bms_is_subset(rinfo->right_relids, outerrelids))
85 {
86 /* righthand side is outer */
87 rinfo->outer_is_left = false;
88 return true;
89 }
90 return false; /* no good for these input relations */
91}
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:412

References bms_is_subset().

Referenced by hash_inner_and_outer(), is_innerrel_unique_for(), join_is_removable(), paraminfo_get_equal_hashops(), and select_mergejoin_clauses().

◆ commute_restrictinfo()

RestrictInfo * commute_restrictinfo ( RestrictInfo rinfo,
Oid  comm_op 
)

Definition at line 350 of file restrictinfo.c.

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}
#define Assert(condition)
Definition: c.h:815
#define makeNode(_type_)
Definition: nodes.h:155
#define castNode(_type_, nodeptr)
Definition: nodes.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
#define InvalidOid
Definition: postgres_ext.h:37
Oid opno
Definition: primnodes.h:834
List * args
Definition: primnodes.h:852
Expr * clause
Definition: pathnodes.h:2575

References OpExpr::args, Assert, castNode, RestrictInfo::clause, InvalidOid, linitial, list_length(), list_make2, lsecond, makeNode, NIL, and OpExpr::opno.

Referenced by match_opclause_to_indexcol().

◆ extract_actual_clauses()

List * extract_actual_clauses ( List restrictinfo_list,
bool  pseudoconstant 
)

◆ extract_actual_join_clauses()

void extract_actual_join_clauses ( List restrictinfo_list,
Relids  joinrelids,
List **  joinquals,
List **  otherquals 
)

Definition at line 513 of file restrictinfo.c.

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}
#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)
Definition: pathnodes.h:2732

References Assert, RestrictInfo::clause, lappend(), lfirst_node, NIL, rinfo_is_constant_true(), and RINFO_IS_PUSHED_DOWN.

Referenced by create_hashjoin_plan(), create_mergejoin_plan(), and create_nestloop_plan().

◆ get_actual_clauses()

List * get_actual_clauses ( List restrictinfo_list)

Definition at line 460 of file restrictinfo.c.

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}

References Assert, RestrictInfo::clause, lappend(), lfirst_node, NIL, and rinfo_is_constant_true().

Referenced by create_bitmap_subplan(), create_hashjoin_plan(), create_join_plan(), and create_mergejoin_plan().

◆ join_clause_is_movable_into()

bool join_clause_is_movable_into ( RestrictInfo rinfo,
Relids  currentrelids,
Relids  current_and_outer 
)

Definition at line 661 of file restrictinfo.c.

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_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:582
Relids outer_relids
Definition: pathnodes.h:2612

References bms_is_subset(), bms_overlap(), and RestrictInfo::outer_relids.

Referenced by get_baserel_parampathinfo(), get_joinrel_parampathinfo(), and has_indexed_join_quals().

◆ join_clause_is_movable_to()

bool join_clause_is_movable_to ( RestrictInfo rinfo,
RelOptInfo baserel 
)

Definition at line 575 of file restrictinfo.c.

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}
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
Index relid
Definition: pathnodes.h:918
Relids lateral_referencers
Definition: pathnodes.h:942
Relids nulling_relids
Definition: pathnodes.h:938

References bms_is_member(), bms_overlap(), RestrictInfo::is_clone, RelOptInfo::lateral_referencers, RelOptInfo::nulling_relids, RestrictInfo::outer_relids, and RelOptInfo::relid.

Referenced by BuildParameterizedTidPaths(), check_index_predicates(), extract_restriction_or_clauses(), match_join_clauses_to_index(), and postgresGetForeignPaths().

◆ make_plain_restrictinfo()

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 at line 103 of file restrictinfo.c.

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}
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:346
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:751
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:251
#define bms_is_empty(a)
Definition: bitmapset.h:118
bool contain_leaked_vars(Node *clause)
Definition: clauses.c:1262
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
@ VOLATILITY_UNKNOWN
Definition: pathnodes.h:1509
Definition: nodes.h:129
bool is_pushed_down
Definition: pathnodes.h:2578
Index security_level
Definition: pathnodes.h:2597
Relids required_relids
Definition: pathnodes.h:2606
int rinfo_serial
Definition: pathnodes.h:2647
Relids incompatible_relids
Definition: pathnodes.h:2609
bool has_clone
Definition: pathnodes.h:2587
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition: var.c:114

References generate_unaccent_rules::args, Assert, bms_difference(), bms_free(), bms_is_empty, bms_num_members(), bms_overlap(), bms_union(), RestrictInfo::clause, contain_leaked_vars(), get_leftop(), get_rightop(), RestrictInfo::has_clone, RestrictInfo::incompatible_relids, InvalidOid, RestrictInfo::is_clone, is_opclause(), RestrictInfo::is_pushed_down, list_length(), makeNode, NIL, RestrictInfo::outer_relids, pull_varnos(), RestrictInfo::required_relids, RestrictInfo::rinfo_serial, root, RestrictInfo::security_level, and VOLATILITY_UNKNOWN.

Referenced by group_similar_or_args(), make_restrictinfo(), and make_sub_restrictinfos().

◆ make_restrictinfo()

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 at line 52 of file restrictinfo.c.

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}
static bool is_andclause(const void *clause)
Definition: nodeFuncs.h:107
static bool is_orclause(const void *clause)
Definition: nodeFuncs.h:116
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
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

References Assert, is_andclause(), is_orclause(), make_plain_restrictinfo(), make_sub_restrictinfos(), and root.

Referenced by add_base_clause_to_rel(), add_join_clause_to_rels(), apply_child_basequals(), build_implied_join_equality(), consider_new_or_clause(), distribute_qual_to_rels(), foreign_grouping_ok(), process_equivalence(), process_implied_equality(), and reconsider_outer_join_clauses().

◆ restriction_is_or_clause()

bool restriction_is_or_clause ( RestrictInfo restrictinfo)

◆ restriction_is_securely_promotable()

bool restriction_is_securely_promotable ( RestrictInfo restrictinfo,
RelOptInfo rel 
)

Definition at line 422 of file restrictinfo.c.

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}
Index baserestrict_min_security
Definition: pathnodes.h:989

References RelOptInfo::baserestrict_min_security, and RestrictInfo::security_level.

Referenced by BuildParameterizedTidPaths(), match_clause_to_index(), and RestrictInfoIsTidQual().