52 int relid,
int ojrelid);
54 int relid,
int ojrelid);
58 List *clause_list,
List **extra_clauses);
66 List **extra_clauses);
90 foreach(lc,
root->join_info_list)
113 elog(
ERROR,
"failed to find relation %d in joinlist", innerrelid);
152 rinfo->outer_is_left =
true;
159 rinfo->outer_is_left =
false;
202 if (innerrelid ==
root->parse->resultRelation)
236 if (!
bms_is_subset(innerrel->attr_needed[attroff], inputrelids))
249 foreach(l,
root->placeholder_list)
306 if (!restrictinfo->can_join ||
307 restrictinfo->mergeopfamilies ==
NIL)
319 clause_list =
lappend(clause_list, restrictinfo);
351 int relid = rel->
relid;
352 int ojrelid = (sjinfo != NULL) ? sjinfo->
ojrelid : -1;
360 for (rti = 1; rti <
root->simple_rel_array_size; rti++)
366 if (otherrel == NULL)
379 otherrel->attr_needed[attroff] =
381 otherrel->attr_needed[attroff] =
382 replace_relid(otherrel->attr_needed[attroff], ojrelid, subst);
405 foreach(l,
root->join_info_list)
440 foreach(l,
root->placeholder_list)
451 root->placeholder_array[phinfo->
phid] = NULL;
516 join_plus_commute =
bms_union(joinrelids,
527 foreach(l, joininfos)
548 #ifdef USE_ASSERT_CHECKING
565 foreach(l,
root->eq_classes)
584 root->simple_rel_array[relid] = NULL;
605 rinfo->clause_relids =
bms_copy(rinfo->clause_relids);
606 rinfo->clause_relids =
bms_del_member(rinfo->clause_relids, relid);
607 rinfo->clause_relids =
bms_del_member(rinfo->clause_relids, ojrelid);
619 foreach(lc, ((
BoolExpr *) rinfo->orclause)->args)
629 foreach(lc2, andargs)
715 foreach(jl, joinlist)
726 result =
lappend(result, jlnode);
737 result =
lappend(result, sublist);
741 elog(
ERROR,
"unrecognized joinlist node type: %d",
771 foreach(lc,
root->join_info_list)
860 if (
ind->unique &&
ind->immediate &&
ind->indpred ==
NIL)
900 List **extra_clauses)
923 Query *subquery =
root->simple_rte_array[relid]->subquery;
937 foreach(l, clause_list)
954 if (rinfo->outer_is_left)
971 if (!var || !
IsA(var,
Var) ||
1072 if (query->hasTargetSRFs)
1153 lg =
lnext(topop->groupClauses, lg);
1189 forboth(lc1, colnos, lc2, opids)
1233 jointype, restrictlist, force_cache, NULL);
1251 List **extra_clauses)
1257 bool self_join = (extra_clauses != NULL);
1260 if (restrictlist ==
NIL)
1310 jointype, restrictlist,
1311 self_join ? &outer_exprs : NULL))
1333 *extra_clauses = outer_exprs;
1355 if (force_cache ||
root->join_search_private)
1380 List **extra_clauses)
1392 foreach(lc, restrictlist)
1405 if (!restrictinfo->can_join ||
1406 restrictinfo->mergeopfamilies ==
NIL)
1418 clause_list =
lappend(clause_list, restrictinfo);
1454 var->varnosyn = ctx->
to;
1482 ctx->sublevels_up--;
1496 rinfo->clause_relids =
1498 rinfo->left_relids =
1500 rinfo->right_relids =
1515 if (rinfo->mergeopfamilies &&
1525 if (leftOp != NULL &&
equal(leftOp, rightOp))
1529 ntest->
arg = leftOp;
1531 ntest->argisrow =
false;
1534 rinfo->mergeopfamilies =
NIL;
1536 Assert(rinfo->orclause == NULL);
1624 bool is_redundant =
false;
1628 new_members =
lappend(new_members, em);
1638 foreach(lc1, new_members)
1647 is_redundant =
true;
1653 new_members =
lappend(new_members, em);
1666 bool is_redundant =
false;
1670 new_sources =
lappend(new_sources, rinfo);
1681 foreach(lc1, new_sources)
1685 if (!
equal(rinfo->clause_relids, other->clause_relids))
1690 is_redundant =
true;
1696 new_sources =
lappend(new_sources, rinfo);
1716 int saved_rinfo_serial =
a->rinfo_serial;
1719 a->rinfo_serial =
b->rinfo_serial;
1721 a->rinfo_serial = saved_rinfo_serial;
1766 foreach(lc, joininfos)
1774 jinfo_candidates =
lappend(jinfo_candidates, rinfo);
1776 binfo_candidates =
lappend(binfo_candidates, rinfo);
1794 jinfo_candidates =
lappend(jinfo_candidates, rinfo);
1796 binfo_candidates =
lappend(binfo_candidates, rinfo);
1809 foreach(lc, binfo_candidates)
1813 bool is_redundant =
false;
1821 if (!
bms_equal(src->clause_relids, rinfo->clause_relids))
1826 (rinfo->parent_ec != NULL
1827 && src->parent_ec == rinfo->parent_ec)
1830 is_redundant =
true;
1837 foreach(lc, jinfo_candidates)
1841 bool is_redundant =
false;
1849 if (!
bms_equal(src->clause_relids, rinfo->clause_relids))
1854 (rinfo->parent_ec != NULL
1855 && src->parent_ec == rinfo->parent_ec)
1858 is_redundant =
true;
1896 for (
i = toKeep->
min_attr; i <= toKeep->max_attr;
i++)
1900 toRemove->attr_needed[attno] =
replace_relid(toRemove->attr_needed[attno],
1902 toKeep->attr_needed[attno] =
bms_add_members(toKeep->attr_needed[attno],
1903 toRemove->attr_needed[attno]);
1960 root->simple_rel_array[toRemove->
relid] = NULL;
1977 List **otherjoinquals,
int from,
int to)
1983 foreach(lc, joinquals)
1991 if (!rinfo->mergeopfamilies ||
1996 ojoinquals =
lappend(ojoinquals, rinfo);
2004 ojoinquals =
lappend(ojoinquals, rinfo);
2024 if (
equal(leftexpr, rightexpr))
2025 sjoinquals =
lappend(sjoinquals, rinfo);
2027 ojoinquals =
lappend(ojoinquals, rinfo);
2030 *selfjoinquals = sjoinquals;
2031 *otherjoinquals = ojoinquals;
2046 foreach(lc, uclauses)
2052 bool matched =
false;
2079 if (orinfo->mergeopfamilies ==
NIL)
2090 if (
equal(iclause, oclause) &&
equal(c1, c2))
2126 if (
root->parse->resultRelation == r)
2133 Relids joinrelids = NULL;
2136 List *selfjoinquals;
2137 List *otherjoinquals;
2139 bool jinfo_check =
true;
2144 if (
root->parse->resultRelation == k)
2149 root->simple_rte_array[r]->relid);
2156 foreach(lc,
root->join_info_list)
2165 jinfo_check =
false;
2178 foreach(lc,
root->rowMarks)
2182 if (rowMark->
rti == k)
2187 else if (rowMark->
rti == r)
2226 &otherjoinquals, inner->
relid, outer->
relid);
2289 foreach(jl, joinlist)
2303 rte->relkind == RELKIND_RELATION &&
2315 elog(
ERROR,
"unrecognized joinlist node type: %d",
2336 candidates[
j].
reloid =
root->simple_rte_array[
i]->relid;
2353 for (
j = 1;
j < numRels + 1;
j++)
2355 if (
j == numRels || candidates[
j].reloid != candidates[
i].reloid)
List * remove_useless_joins(PlannerInfo *root, List *joinlist)
static int self_join_candidates_cmp(const void *a, const void *b)
static bool match_unique_clauses(PlannerInfo *root, RelOptInfo *outer, List *uclauses, Index relid)
static void split_selfjoin_quals(PlannerInfo *root, List *joinquals, List **selfjoinquals, List **otherjoinquals, int from, int to)
bool enable_self_join_removal
static bool clause_sides_match_join(RestrictInfo *rinfo, Relids outerrelids, Relids innerrelids)
static void remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel, int subst, SpecialJoinInfo *sjinfo, Relids joinrelids)
bool innerrel_is_unique(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache)
static List * remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved)
static bool replace_varno_walker(Node *node, ReplaceVarnoContext *ctx)
static void remove_leftjoinrel_from_query(PlannerInfo *root, int relid, SpecialJoinInfo *sjinfo)
static Bitmapset * replace_relid(Relids relids, int oldId, int newId)
bool query_is_distinct_for(Query *query, List *colnos, List *opids)
static Relids remove_self_joins_one_group(PlannerInfo *root, Relids relids)
static Oid distinct_col_search(int colno, List *colnos, List *opids)
static bool is_innerrel_unique_for(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, List **extra_clauses)
static bool rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, List *clause_list, List **extra_clauses)
bool innerrel_is_unique_ext(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache, List **extra_clauses)
bool query_supports_distinctness(Query *query)
List * remove_useless_self_joins(PlannerInfo *root, List *joinlist)
static void update_eclasses(EquivalenceClass *ec, int from, int to)
static bool restrict_infos_logically_equal(RestrictInfo *a, RestrictInfo *b)
static Relids remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove)
static void replace_varno(Node *node, int from, int to)
static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)
void reduce_unique_semijoins(PlannerInfo *root)
static void remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid)
static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel)
static void remove_self_join_rel(PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark, RelOptInfo *toKeep, RelOptInfo *toRemove, List *restrictlist)
static void remove_rel_from_eclass(EquivalenceClass *ec, int relid, int ojrelid)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
int bms_singleton_member(const Bitmapset *a)
void bms_free(Bitmapset *a)
int bms_num_members(const Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_del_member(Bitmapset *a, int x)
BMS_Membership bms_membership(const Bitmapset *a)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
bool bms_get_singleton_member(const Bitmapset *a, int *member)
#define Assert(condition)
#define OidIsValid(objectId)
bool equal(const void *a, const void *b)
List * generate_join_implied_equalities(PlannerInfo *root, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo)
bool relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel, List *restrictlist, List *exprlist, List *oprlist, List **extra_clauses)
void distribute_restrictinfo_to_rels(PlannerInfo *root, RestrictInfo *restrictinfo)
if(TABLE==NULL||TABLE_index==NULL)
void remove_join_clause_from_rels(PlannerInfo *root, RestrictInfo *restrictinfo, Relids join_relids)
List * list_delete_ptr(List *list, void *datum)
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
List * lappend_oid(List *list, Oid datum)
List * list_copy(const List *oldlist)
List * list_delete_cell(List *list, ListCell *cell)
void list_free(List *list)
List * list_concat(List *list1, const List *list2)
bool list_member(const List *list, const void *datum)
bool equality_ops_are_compatible(Oid opno1, Oid opno2)
void pfree(void *pointer)
static bool is_andclause(const void *clause)
static bool is_orclause(const void *clause)
#define query_tree_walker(q, w, c, f)
#define query_or_expression_tree_walker(n, w, c, f)
static bool is_opclause(const void *clause)
#define QTW_EXAMINE_SORTGROUP
static Node * get_rightop(const void *clause)
#define expression_tree_walker(n, w, c)
static Node * get_leftop(const void *clause)
#define IsA(nodeptr, _type_)
#define IS_OUTER_JOIN(jointype)
#define castNode(_type_, nodeptr)
#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_delete_current(lst, var_or_cell)
static ListCell * list_head(const List *l)
static void * list_nth(const List *list, int n)
static ListCell * lnext(const List *l, const ListCell *c)
#define qsort(a, b, c, d)
MemoryContextSwitchTo(old_ctx)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
bool restriction_is_or_clause(RestrictInfo *restrictinfo)
NullTestType nulltesttype
struct PathTarget * reltarget
List * non_unique_for_rels
Bitmapset * eclass_indexes
Relids incompatible_relids
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
Relids pull_varnos(PlannerInfo *root, Node *node)