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 354 of file restrictinfo.c.

References castNode, RestrictInfo::clause, lappend(), lfirst, 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_nestloop_plan(), create_samplescan_plan(), create_seqscan_plan(), create_subqueryscan_plan(), create_tablefuncscan_plan(), create_tidscan_plan(), create_valuesscan_plan(), create_worktablescan_plan(), fileGetForeignPlan(), foreign_join_ok(), and get_gating_quals().

356 {
357  List *result = NIL;
358  ListCell *l;
359 
360  foreach(l, restrictinfo_list)
361  {
363 
364  if (rinfo->pseudoconstant == pseudoconstant)
365  result = lappend(result, rinfo->clause);
366  }
367  return result;
368 }
#define NIL
Definition: pg_list.h:69
#define castNode(_type_, nodeptr)
Definition: nodes.h:587
bool pseudoconstant
Definition: relation.h:1668
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1660
#define lfirst(lc)
Definition: pg_list.h:106
Definition: pg_list.h:45
void extract_actual_join_clauses ( List restrictinfo_list,
List **  joinquals,
List **  otherquals 
)

Definition at line 381 of file restrictinfo.c.

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

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

384 {
385  ListCell *l;
386 
387  *joinquals = NIL;
388  *otherquals = NIL;
389 
390  foreach(l, restrictinfo_list)
391  {
393 
394  if (rinfo->is_pushed_down)
395  {
396  if (!rinfo->pseudoconstant)
397  *otherquals = lappend(*otherquals, rinfo->clause);
398  }
399  else
400  {
401  /* joinquals shouldn't have been marked pseudoconstant */
402  Assert(!rinfo->pseudoconstant);
403  *joinquals = lappend(*joinquals, rinfo->clause);
404  }
405  }
406 }
#define NIL
Definition: pg_list.h:69
#define castNode(_type_, nodeptr)
Definition: nodes.h:587
bool pseudoconstant
Definition: relation.h:1668
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1660
bool is_pushed_down
Definition: relation.h:1662
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
List* get_actual_clauses ( List restrictinfo_list)

Definition at line 331 of file restrictinfo.c.

References Assert, castNode, RestrictInfo::clause, lappend(), lfirst, 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().

332 {
333  List *result = NIL;
334  ListCell *l;
335 
336  foreach(l, restrictinfo_list)
337  {
339 
340  Assert(!rinfo->pseudoconstant);
341 
342  result = lappend(result, rinfo->clause);
343  }
344  return result;
345 }
#define NIL
Definition: pg_list.h:69
#define castNode(_type_, nodeptr)
Definition: nodes.h:587
bool pseudoconstant
Definition: relation.h:1668
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1660
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
Definition: pg_list.h:45
bool join_clause_is_movable_into ( RestrictInfo rinfo,
Relids  currentrelids,
Relids  current_and_outer 
)

Definition at line 508 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().

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

Definition at line 435 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().

436 {
437  /* Clause must physically reference target rel */
438  if (!bms_is_member(baserel->relid, rinfo->clause_relids))
439  return false;
440 
441  /* Cannot move an outer-join clause into the join's outer side */
442  if (bms_is_member(baserel->relid, rinfo->outer_relids))
443  return false;
444 
445  /* Target rel must not be nullable below the clause */
446  if (bms_is_member(baserel->relid, rinfo->nullable_relids))
447  return false;
448 
449  /* Clause must not use any rels with LATERAL references to this rel */
450  if (bms_overlap(baserel->lateral_referencers, rinfo->clause_relids))
451  return false;
452 
453  return true;
454 }
Relids clause_relids
Definition: relation.h:1675
Relids outer_relids
Definition: relation.h:1681
Index relid
Definition: relation.h:522
Relids lateral_referencers
Definition: relation.h:530
Relids nullable_relids
Definition: relation.h:1684
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:442
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:419
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(), NULL, and or_clause().

Referenced by build_implied_join_equality(), consider_new_or_clause(), distribute_qual_to_rels(), 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:518
bool and_clause(Node *clause)
Definition: clauses.c:313
bool or_clause(Node *clause)
Definition: clauses.c:279
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:224
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
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_relids, list_length(), makeNode, RestrictInfo::mergeopfamilies, NIL, RestrictInfo::norm_selec, NULL, 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_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 
203  return restrictinfo;
204 }
QualCost eval_cost
Definition: relation.h:1697
#define NIL
Definition: pg_list.h:69
bool contain_leaked_vars(Node *clause)
Definition: clauses.c:1427
Index security_level
Definition: relation.h:1672
Relids required_relids
Definition: relation.h:1678
bool leakproof
Definition: relation.h:1670
Expr * orclause
Definition: relation.h:1691
Relids clause_relids
Definition: relation.h:1675
bool pseudoconstant
Definition: relation.h:1668
Definition: nodes.h:518
Relids left_relids
Definition: relation.h:1687
EquivalenceClass * right_ec
Definition: relation.h:1709
List * mergeopfamilies
Definition: relation.h:1705
Cost startup
Definition: relation.h:45
Relids outer_relids
Definition: relation.h:1681
Selectivity norm_selec
Definition: relation.h:1698
#define is_opclause(clause)
Definition: clauses.h:20
EquivalenceMember * left_em
Definition: relation.h:1710
Node * get_leftop(const Expr *clause)
Definition: clauses.c:198
EquivalenceClass * parent_ec
Definition: relation.h:1694
bool can_join
Definition: relation.h:1666
bool outerjoin_delayed
Definition: relation.h:1664
bool outer_is_left
Definition: relation.h:1715
Selectivity outer_selec
Definition: relation.h:1701
Relids pull_varnos(Node *node)
Definition: var.c:95
EquivalenceMember * right_em
Definition: relation.h:1711
Expr * clause
Definition: relation.h:1660
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:633
Relids nullable_relids
Definition: relation.h:1684
#define InvalidOid
Definition: postgres_ext.h:36
bool is_pushed_down
Definition: relation.h:1662
Selectivity left_bucketsize
Definition: relation.h:1721
#define makeNode(_type_)
Definition: nodes.h:566
Relids right_relids
Definition: relation.h:1688
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:217
Oid hashjoinoperator
Definition: relation.h:1718
static int list_length(const List *l)
Definition: pg_list.h:89
Node * get_rightop(const Expr *clause)
Definition: clauses.c:215
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:442
Selectivity right_bucketsize
Definition: relation.h:1722
EquivalenceClass * left_ec
Definition: relation.h:1708
List * scansel_cache
Definition: relation.h:1712
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 224 of file restrictinfo.c.

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

Referenced by make_restrictinfo().

232 {
233  if (or_clause((Node *) clause))
234  {
235  List *orlist = NIL;
236  ListCell *temp;
237 
238  foreach(temp, ((BoolExpr *) clause)->args)
239  orlist = lappend(orlist,
241  is_pushed_down,
242  outerjoin_delayed,
243  pseudoconstant,
244  security_level,
245  NULL,
246  outer_relids,
247  nullable_relids));
248  return (Expr *) make_restrictinfo_internal(clause,
249  make_orclause(orlist),
250  is_pushed_down,
251  outerjoin_delayed,
252  pseudoconstant,
253  security_level,
254  required_relids,
255  outer_relids,
256  nullable_relids);
257  }
258  else if (and_clause((Node *) clause))
259  {
260  List *andlist = NIL;
261  ListCell *temp;
262 
263  foreach(temp, ((BoolExpr *) clause)->args)
264  andlist = lappend(andlist,
266  is_pushed_down,
267  outerjoin_delayed,
268  pseudoconstant,
269  security_level,
270  required_relids,
271  outer_relids,
272  nullable_relids));
273  return make_andclause(andlist);
274  }
275  else
276  return (Expr *) make_restrictinfo_internal(clause,
277  NULL,
278  is_pushed_down,
279  outerjoin_delayed,
280  pseudoconstant,
281  security_level,
282  required_relids,
283  outer_relids,
284  nullable_relids);
285 }
#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:518
bool and_clause(Node *clause)
Definition: clauses.c:313
List * lappend(List *list, void *datum)
Definition: list.c:128
bool or_clause(Node *clause)
Definition: clauses.c:279
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:224
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
Expr * make_andclause(List *andclauses)
Definition: clauses.c:326
Definition: pg_list.h:45
Expr * make_orclause(List *orclauses)
Definition: clauses.c:292
bool restriction_is_or_clause ( RestrictInfo restrictinfo)

Definition at line 293 of file restrictinfo.c.

References NULL, and RestrictInfo::orclause.

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

294 {
295  if (restrictinfo->orclause != NULL)
296  return true;
297  else
298  return false;
299 }
Expr * orclause
Definition: relation.h:1691
#define NULL
Definition: c.h:229
bool restriction_is_securely_promotable ( RestrictInfo restrictinfo,
RelOptInfo rel 
)

Definition at line 308 of file restrictinfo.c.

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

Referenced by match_clause_to_index(), and TidQualFromBaseRestrictinfo().

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