PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
joininfo.c File Reference
Include dependency graph for joininfo.c:

Go to the source code of this file.

Functions

bool have_relevant_joinclause (PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
 
void add_join_clause_to_rels (PlannerInfo *root, RestrictInfo *restrictinfo, Relids join_relids)
 
void remove_join_clause_from_rels (PlannerInfo *root, RestrictInfo *restrictinfo, Relids join_relids)
 

Function Documentation

◆ add_join_clause_to_rels()

void add_join_clause_to_rels ( PlannerInfo root,
RestrictInfo restrictinfo,
Relids  join_relids 
)

Definition at line 98 of file joininfo.c.

101 {
102  int cur_relid;
103 
104  /* Don't add the clause if it is always true */
105  if (restriction_is_always_true(root, restrictinfo))
106  return;
107 
108  /*
109  * Substitute the origin qual with constant-FALSE if it is provably always
110  * false.
111  *
112  * Note that we need to keep the same rinfo_serial, since it is in
113  * practice the same condition. We also need to reset the
114  * last_rinfo_serial counter, which is essential to ensure that the
115  * RestrictInfos for the "same" qual condition get identical serial
116  * numbers (see deconstruct_distribute_oj_quals).
117  */
118  if (restriction_is_always_false(root, restrictinfo))
119  {
120  int save_rinfo_serial = restrictinfo->rinfo_serial;
121  int save_last_rinfo_serial = root->last_rinfo_serial;
122 
123  restrictinfo = make_restrictinfo(root,
124  (Expr *) makeBoolConst(false, false),
125  restrictinfo->is_pushed_down,
126  restrictinfo->has_clone,
127  restrictinfo->is_clone,
128  restrictinfo->pseudoconstant,
129  0, /* security_level */
130  restrictinfo->required_relids,
131  restrictinfo->incompatible_relids,
132  restrictinfo->outer_relids);
133  restrictinfo->rinfo_serial = save_rinfo_serial;
134  root->last_rinfo_serial = save_last_rinfo_serial;
135  }
136 
137  cur_relid = -1;
138  while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
139  {
140  RelOptInfo *rel = find_base_rel_ignore_join(root, cur_relid);
141 
142  /* We only need to add the clause to baserels */
143  if (rel == NULL)
144  continue;
145  rel->joininfo = lappend(rel->joininfo, restrictinfo);
146  }
147 }
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1306
bool restriction_is_always_true(PlannerInfo *root, RestrictInfo *restrictinfo)
Definition: initsplan.c:2850
bool restriction_is_always_false(PlannerInfo *root, RestrictInfo *restrictinfo)
Definition: initsplan.c:2899
List * lappend(List *list, void *datum)
Definition: list.c:339
Node * makeBoolConst(bool value, bool isnull)
Definition: makefuncs.c:359
tree ctl root
Definition: radixtree.h:1886
RelOptInfo * find_base_rel_ignore_join(PlannerInfo *root, int relid)
Definition: relnode.c:454
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
List * joininfo
Definition: pathnodes.h:991
bool is_pushed_down
Definition: pathnodes.h:2577
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
bool has_clone
Definition: pathnodes.h:2586

References bms_next_member(), find_base_rel_ignore_join(), RestrictInfo::has_clone, RestrictInfo::incompatible_relids, RestrictInfo::is_clone, RestrictInfo::is_pushed_down, RelOptInfo::joininfo, lappend(), make_restrictinfo(), makeBoolConst(), RestrictInfo::outer_relids, RestrictInfo::required_relids, restriction_is_always_false(), restriction_is_always_true(), RestrictInfo::rinfo_serial, and root.

Referenced by distribute_restrictinfo_to_rels().

◆ have_relevant_joinclause()

bool have_relevant_joinclause ( PlannerInfo root,
RelOptInfo rel1,
RelOptInfo rel2 
)

Definition at line 39 of file joininfo.c.

41 {
42  bool result = false;
43  List *joininfo;
44  Relids other_relids;
45  ListCell *l;
46 
47  /*
48  * We could scan either relation's joininfo list; may as well use the
49  * shorter one.
50  */
51  if (list_length(rel1->joininfo) <= list_length(rel2->joininfo))
52  {
53  joininfo = rel1->joininfo;
54  other_relids = rel2->relids;
55  }
56  else
57  {
58  joininfo = rel2->joininfo;
59  other_relids = rel1->relids;
60  }
61 
62  foreach(l, joininfo)
63  {
64  RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
65 
66  if (bms_overlap(other_relids, rinfo->required_relids))
67  {
68  result = true;
69  break;
70  }
71  }
72 
73  /*
74  * We also need to check the EquivalenceClass data structure, which might
75  * contain relationships not emitted into the joininfo lists.
76  */
77  if (!result && rel1->has_eclass_joins && rel2->has_eclass_joins)
78  result = have_relevant_eclass_joinclause(root, rel1, rel2);
79 
80  return result;
81 }
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:582
bool have_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
Definition: equivclass.c:3146
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
Definition: pg_list.h:54
Relids relids
Definition: pathnodes.h:871
bool has_eclass_joins
Definition: pathnodes.h:993

References bms_overlap(), RelOptInfo::has_eclass_joins, have_relevant_eclass_joinclause(), RelOptInfo::joininfo, lfirst, list_length(), RelOptInfo::relids, RestrictInfo::required_relids, and root.

Referenced by desirable_join(), has_legal_joinclause(), join_search_one_level(), and make_rels_by_clause_joins().

◆ remove_join_clause_from_rels()

void remove_join_clause_from_rels ( PlannerInfo root,
RestrictInfo restrictinfo,
Relids  join_relids 
)

Definition at line 161 of file joininfo.c.

164 {
165  int cur_relid;
166 
167  cur_relid = -1;
168  while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
169  {
170  RelOptInfo *rel = find_base_rel_ignore_join(root, cur_relid);
171 
172  /* We would only have added the clause to baserels */
173  if (rel == NULL)
174  continue;
175 
176  /*
177  * Remove the restrictinfo from the list. Pointer comparison is
178  * sufficient.
179  */
180  Assert(list_member_ptr(rel->joininfo, restrictinfo));
181  rel->joininfo = list_delete_ptr(rel->joininfo, restrictinfo);
182  }
183 }
#define Assert(condition)
Definition: c.h:837
List * list_delete_ptr(List *list, void *datum)
Definition: list.c:872
bool list_member_ptr(const List *list, const void *datum)
Definition: list.c:682

References Assert, bms_next_member(), find_base_rel_ignore_join(), RelOptInfo::joininfo, list_delete_ptr(), list_member_ptr(), and root.

Referenced by remove_rel_from_query().