PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
restrictinfo.c File Reference
#include "postgres.h"
#include "optimizer/clauses.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/var.h"
Include dependency graph for restrictinfo.c:

Go to the source code of this file.

Functions

static RestrictInfomake_restrictinfo_internal (Expr *clause, Expr *orclause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
 
static Exprmake_sub_restrictinfos (Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
 
RestrictInfomake_restrictinfo (Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
 
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, 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)
 

Function Documentation

List* extract_actual_clauses ( List restrictinfo_list,
bool  pseudoconstant 
)

Definition at line 356 of file restrictinfo.c.

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

Referenced by create_bitmap_scan_plan(), create_ctescan_plan(), create_functionscan_plan(), create_hashjoin_plan(), create_indexscan_plan(), create_mergejoin_plan(), create_namedtuplestorescan_plan(), create_nestloop_plan(), create_samplescan_plan(), create_seqscan_plan(), create_subqueryscan_plan(), create_tablefuncscan_plan(), create_tidscan_plan(), create_valuesscan_plan(), create_worktablescan_plan(), fileGetForeignPlan(), get_gating_quals(), and postgresGetForeignPlan().

358 {
359  List *result = NIL;
360  ListCell *l;
361 
362  foreach(l, restrictinfo_list)
363  {
365 
366  if (rinfo->pseudoconstant == pseudoconstant)
367  result = lappend(result, rinfo->clause);
368  }
369  return result;
370 }
#define NIL
Definition: pg_list.h:69
bool pseudoconstant
Definition: relation.h:1843
#define lfirst_node(type, lc)
Definition: pg_list.h:109
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1835
Definition: pg_list.h:45
void extract_actual_join_clauses ( List restrictinfo_list,
List **  joinquals,
List **  otherquals 
)

Definition at line 383 of file restrictinfo.c.

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

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

386 {
387  ListCell *l;
388 
389  *joinquals = NIL;
390  *otherquals = NIL;
391 
392  foreach(l, restrictinfo_list)
393  {
395 
396  if (rinfo->is_pushed_down)
397  {
398  if (!rinfo->pseudoconstant)
399  *otherquals = lappend(*otherquals, rinfo->clause);
400  }
401  else
402  {
403  /* joinquals shouldn't have been marked pseudoconstant */
404  Assert(!rinfo->pseudoconstant);
405  *joinquals = lappend(*joinquals, rinfo->clause);
406  }
407  }
408 }
#define NIL
Definition: pg_list.h:69
bool pseudoconstant
Definition: relation.h:1843
#define lfirst_node(type, lc)
Definition: pg_list.h:109
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1835
bool is_pushed_down
Definition: relation.h:1837
#define Assert(condition)
Definition: c.h:681
List* get_actual_clauses ( List restrictinfo_list)

Definition at line 333 of file restrictinfo.c.

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

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

334 {
335  List *result = NIL;
336  ListCell *l;
337 
338  foreach(l, restrictinfo_list)
339  {
341 
342  Assert(!rinfo->pseudoconstant);
343 
344  result = lappend(result, rinfo->clause);
345  }
346  return result;
347 }
#define NIL
Definition: pg_list.h:69
bool pseudoconstant
Definition: relation.h:1843
#define lfirst_node(type, lc)
Definition: pg_list.h:109
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1835
#define Assert(condition)
Definition: c.h:681
Definition: pg_list.h:45
bool join_clause_is_movable_into ( RestrictInfo rinfo,
Relids  currentrelids,
Relids  current_and_outer 
)

Definition at line 510 of file restrictinfo.c.

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

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

513 {
514  /* Clause must be evaluable given available context */
515  if (!bms_is_subset(rinfo->clause_relids, current_and_outer))
516  return false;
517 
518  /* Clause must physically reference at least one target rel */
519  if (!bms_overlap(currentrelids, rinfo->clause_relids))
520  return false;
521 
522  /* Cannot move an outer-join clause into the join's outer side */
523  if (bms_overlap(currentrelids, rinfo->outer_relids))
524  return false;
525 
526  /*
527  * Target rel(s) must not be nullable below the clause. This is
528  * approximate, in the safe direction, because the current join might be
529  * above the join where the nulling would happen, in which case the clause
530  * would work correctly here. But we don't have enough info to be sure.
531  */
532  if (bms_overlap(currentrelids, rinfo->nullable_relids))
533  return false;
534 
535  return true;
536 }
Relids clause_relids
Definition: relation.h:1850
Relids outer_relids
Definition: relation.h:1856
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:308
Relids nullable_relids
Definition: relation.h:1859
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:443
bool join_clause_is_movable_to ( RestrictInfo rinfo,
RelOptInfo baserel 
)

Definition at line 437 of file restrictinfo.c.

References bms_is_member(), bms_overlap(), RestrictInfo::clause_relids, RelOptInfo::lateral_referencers, RestrictInfo::nullable_relids, RestrictInfo::outer_relids, and RelOptInfo::relid.

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

438 {
439  /* Clause must physically reference target rel */
440  if (!bms_is_member(baserel->relid, rinfo->clause_relids))
441  return false;
442 
443  /* Cannot move an outer-join clause into the join's outer side */
444  if (bms_is_member(baserel->relid, rinfo->outer_relids))
445  return false;
446 
447  /* Target rel must not be nullable below the clause */
448  if (bms_is_member(baserel->relid, rinfo->nullable_relids))
449  return false;
450 
451  /* Clause must not use any rels with LATERAL references to this rel */
452  if (bms_overlap(baserel->lateral_referencers, rinfo->clause_relids))
453  return false;
454 
455  return true;
456 }
Relids clause_relids
Definition: relation.h:1850
Relids outer_relids
Definition: relation.h:1856
Index relid
Definition: relation.h:613
Relids lateral_referencers
Definition: relation.h:621
Relids nullable_relids
Definition: relation.h:1859
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:443
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:420
RestrictInfo* make_restrictinfo ( Expr clause,
bool  is_pushed_down,
bool  outerjoin_delayed,
bool  pseudoconstant,
Index  security_level,
Relids  required_relids,
Relids  outer_relids,
Relids  nullable_relids 
)

Definition at line 57 of file restrictinfo.c.

References and_clause(), Assert, make_restrictinfo_internal(), make_sub_restrictinfos(), and or_clause().

Referenced by build_implied_join_equality(), consider_new_or_clause(), distribute_qual_to_rels(), foreign_grouping_ok(), process_equivalence(), and set_append_rel_size().

65 {
66  /*
67  * If it's an OR clause, build a modified copy with RestrictInfos inserted
68  * above each subclause of the top-level AND/OR structure.
69  */
70  if (or_clause((Node *) clause))
71  return (RestrictInfo *) make_sub_restrictinfos(clause,
72  is_pushed_down,
73  outerjoin_delayed,
74  pseudoconstant,
75  security_level,
76  required_relids,
77  outer_relids,
78  nullable_relids);
79 
80  /* Shouldn't be an AND clause, else AND/OR flattening messed up */
81  Assert(!and_clause((Node *) clause));
82 
83  return make_restrictinfo_internal(clause,
84  NULL,
85  is_pushed_down,
86  outerjoin_delayed,
87  pseudoconstant,
88  security_level,
89  required_relids,
90  outer_relids,
91  nullable_relids);
92 }
static RestrictInfo * make_restrictinfo_internal(Expr *clause, Expr *orclause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
Definition: restrictinfo.c:100
Definition: nodes.h:510
bool and_clause(Node *clause)
Definition: clauses.c:314
bool or_clause(Node *clause)
Definition: clauses.c:280
static Expr * make_sub_restrictinfos(Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
Definition: restrictinfo.c:226
#define Assert(condition)
Definition: c.h:681
static RestrictInfo * make_restrictinfo_internal ( Expr clause,
Expr orclause,
bool  is_pushed_down,
bool  outerjoin_delayed,
bool  pseudoconstant,
Index  security_level,
Relids  required_relids,
Relids  outer_relids,
Relids  nullable_relids 
)
static

Definition at line 100 of file restrictinfo.c.

References generate_unaccent_rules::args, Assert, bms_is_empty(), bms_overlap(), bms_union(), RestrictInfo::can_join, RestrictInfo::clause, RestrictInfo::clause_relids, contain_leaked_vars(), RestrictInfo::eval_cost, get_leftop(), get_rightop(), RestrictInfo::hashjoinoperator, InvalidOid, is_opclause, RestrictInfo::is_pushed_down, RestrictInfo::leakproof, RestrictInfo::left_bucketsize, RestrictInfo::left_ec, RestrictInfo::left_em, RestrictInfo::left_mcvfreq, RestrictInfo::left_relids, list_length(), makeNode, RestrictInfo::mergeopfamilies, NIL, RestrictInfo::norm_selec, RestrictInfo::nullable_relids, RestrictInfo::orclause, RestrictInfo::outer_is_left, RestrictInfo::outer_relids, RestrictInfo::outer_selec, RestrictInfo::outerjoin_delayed, RestrictInfo::parent_ec, RestrictInfo::pseudoconstant, pull_varnos(), RestrictInfo::required_relids, RestrictInfo::right_bucketsize, RestrictInfo::right_ec, RestrictInfo::right_em, RestrictInfo::right_mcvfreq, RestrictInfo::right_relids, RestrictInfo::scansel_cache, RestrictInfo::security_level, and QualCost::startup.

Referenced by make_restrictinfo(), and make_sub_restrictinfos().

109 {
110  RestrictInfo *restrictinfo = makeNode(RestrictInfo);
111 
112  restrictinfo->clause = clause;
113  restrictinfo->orclause = orclause;
114  restrictinfo->is_pushed_down = is_pushed_down;
115  restrictinfo->outerjoin_delayed = outerjoin_delayed;
116  restrictinfo->pseudoconstant = pseudoconstant;
117  restrictinfo->can_join = false; /* may get set below */
118  restrictinfo->security_level = security_level;
119  restrictinfo->outer_relids = outer_relids;
120  restrictinfo->nullable_relids = nullable_relids;
121 
122  /*
123  * If it's potentially delayable by lower-level security quals, figure out
124  * whether it's leakproof. We can skip testing this for level-zero quals,
125  * since they would never get delayed on security grounds anyway.
126  */
127  if (security_level > 0)
128  restrictinfo->leakproof = !contain_leaked_vars((Node *) clause);
129  else
130  restrictinfo->leakproof = false; /* really, "don't know" */
131 
132  /*
133  * If it's a binary opclause, set up left/right relids info. In any case
134  * set up the total clause relids info.
135  */
136  if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
137  {
138  restrictinfo->left_relids = pull_varnos(get_leftop(clause));
139  restrictinfo->right_relids = pull_varnos(get_rightop(clause));
140 
141  restrictinfo->clause_relids = bms_union(restrictinfo->left_relids,
142  restrictinfo->right_relids);
143 
144  /*
145  * Does it look like a normal join clause, i.e., a binary operator
146  * relating expressions that come from distinct relations? If so we
147  * might be able to use it in a join algorithm. Note that this is a
148  * purely syntactic test that is made regardless of context.
149  */
150  if (!bms_is_empty(restrictinfo->left_relids) &&
151  !bms_is_empty(restrictinfo->right_relids) &&
152  !bms_overlap(restrictinfo->left_relids,
153  restrictinfo->right_relids))
154  {
155  restrictinfo->can_join = true;
156  /* pseudoconstant should certainly not be true */
157  Assert(!restrictinfo->pseudoconstant);
158  }
159  }
160  else
161  {
162  /* Not a binary opclause, so mark left/right relid sets as empty */
163  restrictinfo->left_relids = NULL;
164  restrictinfo->right_relids = NULL;
165  /* and get the total relid set the hard way */
166  restrictinfo->clause_relids = pull_varnos((Node *) clause);
167  }
168 
169  /* required_relids defaults to clause_relids */
170  if (required_relids != NULL)
171  restrictinfo->required_relids = required_relids;
172  else
173  restrictinfo->required_relids = restrictinfo->clause_relids;
174 
175  /*
176  * Fill in all the cacheable fields with "not yet set" markers. None of
177  * these will be computed until/unless needed. Note in particular that we
178  * don't mark a binary opclause as mergejoinable or hashjoinable here;
179  * that happens only if it appears in the right context (top level of a
180  * joinclause list).
181  */
182  restrictinfo->parent_ec = NULL;
183 
184  restrictinfo->eval_cost.startup = -1;
185  restrictinfo->norm_selec = -1;
186  restrictinfo->outer_selec = -1;
187 
188  restrictinfo->mergeopfamilies = NIL;
189 
190  restrictinfo->left_ec = NULL;
191  restrictinfo->right_ec = NULL;
192  restrictinfo->left_em = NULL;
193  restrictinfo->right_em = NULL;
194  restrictinfo->scansel_cache = NIL;
195 
196  restrictinfo->outer_is_left = false;
197 
198  restrictinfo->hashjoinoperator = InvalidOid;
199 
200  restrictinfo->left_bucketsize = -1;
201  restrictinfo->right_bucketsize = -1;
202  restrictinfo->left_mcvfreq = -1;
203  restrictinfo->right_mcvfreq = -1;
204 
205  return restrictinfo;
206 }
QualCost eval_cost
Definition: relation.h:1872
#define NIL
Definition: pg_list.h:69
bool contain_leaked_vars(Node *clause)
Definition: clauses.c:1489
Index security_level
Definition: relation.h:1847
Relids required_relids
Definition: relation.h:1853
Selectivity right_mcvfreq
Definition: relation.h:1899
bool leakproof
Definition: relation.h:1845
Expr * orclause
Definition: relation.h:1866
Relids clause_relids
Definition: relation.h:1850
bool pseudoconstant
Definition: relation.h:1843
Definition: nodes.h:510
Relids left_relids
Definition: relation.h:1862
EquivalenceClass * right_ec
Definition: relation.h:1884
List * mergeopfamilies
Definition: relation.h:1880
Cost startup
Definition: relation.h:45
Relids outer_relids
Definition: relation.h:1856
Selectivity norm_selec
Definition: relation.h:1873
#define is_opclause(clause)
Definition: clauses.h:20
EquivalenceMember * left_em
Definition: relation.h:1885
Node * get_leftop(const Expr *clause)
Definition: clauses.c:199
EquivalenceClass * parent_ec
Definition: relation.h:1869
bool can_join
Definition: relation.h:1841
bool outerjoin_delayed
Definition: relation.h:1839
bool outer_is_left
Definition: relation.h:1890
Selectivity outer_selec
Definition: relation.h:1876
Relids pull_varnos(Node *node)
Definition: var.c:95
EquivalenceMember * right_em
Definition: relation.h:1886
Expr * clause
Definition: relation.h:1835
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:663
Relids nullable_relids
Definition: relation.h:1859
#define InvalidOid
Definition: postgres_ext.h:36
bool is_pushed_down
Definition: relation.h:1837
Selectivity left_bucketsize
Definition: relation.h:1896
#define makeNode(_type_)
Definition: nodes.h:558
Relids right_relids
Definition: relation.h:1863
#define Assert(condition)
Definition: c.h:681
Selectivity left_mcvfreq
Definition: relation.h:1898
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:218
Oid hashjoinoperator
Definition: relation.h:1893
static int list_length(const List *l)
Definition: pg_list.h:89
Node * get_rightop(const Expr *clause)
Definition: clauses.c:216
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:443
Selectivity right_bucketsize
Definition: relation.h:1897
EquivalenceClass * left_ec
Definition: relation.h:1883
List * scansel_cache
Definition: relation.h:1887
static Expr * make_sub_restrictinfos ( Expr clause,
bool  is_pushed_down,
bool  outerjoin_delayed,
bool  pseudoconstant,
Index  security_level,
Relids  required_relids,
Relids  outer_relids,
Relids  nullable_relids 
)
static

Definition at line 226 of file restrictinfo.c.

References and_clause(), generate_unaccent_rules::args, lappend(), lfirst, make_andclause(), make_orclause(), make_restrictinfo_internal(), NIL, and or_clause().

Referenced by make_restrictinfo().

234 {
235  if (or_clause((Node *) clause))
236  {
237  List *orlist = NIL;
238  ListCell *temp;
239 
240  foreach(temp, ((BoolExpr *) clause)->args)
241  orlist = lappend(orlist,
243  is_pushed_down,
244  outerjoin_delayed,
245  pseudoconstant,
246  security_level,
247  NULL,
248  outer_relids,
249  nullable_relids));
250  return (Expr *) make_restrictinfo_internal(clause,
251  make_orclause(orlist),
252  is_pushed_down,
253  outerjoin_delayed,
254  pseudoconstant,
255  security_level,
256  required_relids,
257  outer_relids,
258  nullable_relids);
259  }
260  else if (and_clause((Node *) clause))
261  {
262  List *andlist = NIL;
263  ListCell *temp;
264 
265  foreach(temp, ((BoolExpr *) clause)->args)
266  andlist = lappend(andlist,
268  is_pushed_down,
269  outerjoin_delayed,
270  pseudoconstant,
271  security_level,
272  required_relids,
273  outer_relids,
274  nullable_relids));
275  return make_andclause(andlist);
276  }
277  else
278  return (Expr *) make_restrictinfo_internal(clause,
279  NULL,
280  is_pushed_down,
281  outerjoin_delayed,
282  pseudoconstant,
283  security_level,
284  required_relids,
285  outer_relids,
286  nullable_relids);
287 }
#define NIL
Definition: pg_list.h:69
static RestrictInfo * make_restrictinfo_internal(Expr *clause, Expr *orclause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
Definition: restrictinfo.c:100
Definition: nodes.h:510
bool and_clause(Node *clause)
Definition: clauses.c:314
List * lappend(List *list, void *datum)
Definition: list.c:128
bool or_clause(Node *clause)
Definition: clauses.c:280
static Expr * make_sub_restrictinfos(Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Index security_level, Relids required_relids, Relids outer_relids, Relids nullable_relids)
Definition: restrictinfo.c:226
#define lfirst(lc)
Definition: pg_list.h:106
Expr * make_andclause(List *andclauses)
Definition: clauses.c:327
Definition: pg_list.h:45
Expr * make_orclause(List *orclauses)
Definition: clauses.c:293
bool restriction_is_or_clause ( RestrictInfo restrictinfo)

Definition at line 295 of file restrictinfo.c.

References RestrictInfo::orclause.

Referenced by extract_or_clause(), extract_restriction_or_clauses(), generate_bitmap_or_paths(), and match_join_clauses_to_index().

296 {
297  if (restrictinfo->orclause != NULL)
298  return true;
299  else
300  return false;
301 }
Expr * orclause
Definition: relation.h:1866
bool restriction_is_securely_promotable ( RestrictInfo restrictinfo,
RelOptInfo rel 
)

Definition at line 310 of file restrictinfo.c.

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

Referenced by match_clause_to_index(), and TidQualFromBaseRestrictinfo().

312 {
313  /*
314  * It's okay if there are no baserestrictinfo clauses for the rel that
315  * would need to go before this one, *or* if this one is leakproof.
316  */
317  if (restrictinfo->security_level <= rel->baserestrict_min_security ||
318  restrictinfo->leakproof)
319  return true;
320  else
321  return false;
322 }
Index security_level
Definition: relation.h:1847
bool leakproof
Definition: relation.h:1845
Index baserestrict_min_security
Definition: relation.h:647