39 bool only_pushed_down);
49 List *parent_restrictlist);
80 List **joinrels =
root->join_rel_level;
87 root->join_cur_level = level;
96 foreach(r, joinrels[level - 1])
155 int other_level = level - k;
164 foreach(r, joinrels[k])
179 if (k == other_level)
224 if (joinrels[level] ==
NIL)
230 foreach(r, joinrels[level - 1])
257 if (joinrels[level] ==
NIL &&
259 !
root->hasLateralRTEs)
260 elog(
ERROR,
"failed to build any %d-way joins", level);
325 foreach(l, other_rels)
362 bool must_be_leftjoin;
379 unique_ified =
false;
380 must_be_leftjoin =
false;
382 foreach(l,
root->join_info_list)
439 match_sjinfo = sjinfo;
447 match_sjinfo = sjinfo;
478 match_sjinfo = sjinfo;
489 match_sjinfo = sjinfo;
532 must_be_leftjoin =
true;
545 if (must_be_leftjoin &&
546 (match_sjinfo == NULL ||
554 if (
root->hasLateralRTEs)
574 if (lateral_fwd && lateral_rev)
588 else if (lateral_rev)
616 if (join_lateral_rels)
624 foreach(l,
root->join_info_list)
647 *sjinfo_p = match_sjinfo;
648 *reversed_p = reversed;
667 sjinfo->type = T_SpecialJoinInfo;
747 sjinfo = &sjinfo_data;
756 sjinfo, pushed_down_joins,
802 List **pushed_down_joins)
805 if (sjinfo == NULL || sjinfo->
ojrelid == 0)
847 foreach(lc,
root->join_info_list)
851 if (othersj == sjinfo ||
866 if (pushed_down_joins != NULL)
867 *pushed_down_joins =
lappend(*pushed_down_joins, othersj);
931 if (
root->agg_clause_list ==
NIL ||
939 rel1_empty = (grouped_rel1 == NULL ||
IS_DUMMY_REL(grouped_rel1));
940 rel2_empty = (grouped_rel2 == NULL ||
IS_DUMMY_REL(grouped_rel2));
944 if (grouped_rel == NULL)
953 if (agg_info == NULL)
962 (rel1_empty == rel2_empty))
969 if (rel1_empty != rel2_empty)
979 rel1_empty ? rel1 : grouped_rel1,
980 rel2_empty ? rel2 : grouped_rel2,
981 sjinfo, restrictlist);
983 grouped_rel2->agg_info->apply_at :
984 grouped_rel1->agg_info->apply_at;
1015 if (rel1_empty == rel2_empty)
1022 agg_apply_at = rel1_empty ?
1046 rel1_empty ? rel1 : grouped_rel1,
1047 rel2_empty ? rel2 : grouped_rel2,
1048 sjinfo, restrictlist);
1057 rel1_empty ? rel1 : grouped_rel1,
1058 rel2_empty ? rel2 : grouped_rel2,
1152 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1153 errmsg(
"FULL JOIN is only supported with merge-joinable or hash-joinable join conditions")));
1257 bool result =
false;
1275 foreach(l,
root->placeholder_list)
1292 foreach(l,
root->join_info_list)
1374 foreach(l,
root->placeholder_list)
1383 foreach(l,
root->join_info_list)
1427 foreach(lc,
root->initial_rels)
1445 &sjinfo, &reversed))
1558 bool only_pushed_down)
1568 foreach(lc, restrictlist)
1580 if (con->constisnull)
1612 List *parent_restrictlist)
1626 if (joinrel->part_scheme == NULL || joinrel->
nparts == 0)
1649 Assert(joinrel->part_scheme == rel1->part_scheme &&
1650 joinrel->part_scheme == rel2->part_scheme);
1668 for (cnt_parts = 0; cnt_parts < joinrel->
nparts; cnt_parts++)
1675 List *child_restrictlist;
1685 lcr1 =
lnext(parts1, lcr1);
1686 lcr2 =
lnext(parts2, lcr2);
1690 child_rel1 = rel1->part_rels[cnt_parts];
1691 child_rel2 = rel2->part_rels[cnt_parts];
1694 rel1_empty = (child_rel1 == NULL ||
IS_DUMMY_REL(child_rel1));
1695 rel2_empty = (child_rel2 == NULL ||
IS_DUMMY_REL(child_rel2));
1708 if (rel1_empty || rel2_empty)
1717 if (rel1_empty && rel2_empty)
1722 elog(
ERROR,
"unrecognized join type: %d",
1732 if (child_rel1 == NULL || child_rel2 == NULL)
1783 child_restrictlist =
1785 (
Node *) parent_restrictlist,
1786 nappinfos, appinfos);
1789 child_joinrel = joinrel->part_rels[cnt_parts];
1793 joinrel, child_restrictlist,
1794 child_sjinfo, nappinfos, appinfos);
1795 joinrel->part_rels[cnt_parts] = child_joinrel;
1804 nappinfos, appinfos)));
1808 child_joinrel, child_sjinfo,
1809 child_restrictlist);
1813 child_joinrel, child_sjinfo,
1814 child_restrictlist);
1844 int right_nappinfos;
1861 left_nappinfos, left_appinfos);
1866 left_nappinfos, left_appinfos);
1876 pfree(left_appinfos);
1877 pfree(right_appinfos);
1925 pfree(child_sjinfo);
1942 if (joinrel->
nparts == -1)
1948 Assert(joinrel->boundinfo == NULL);
1949 Assert(joinrel->part_rels == NULL);
1967 rel1->boundinfo, rel2->boundinfo))
1969 boundinfo = rel1->boundinfo;
1981 if (boundinfo == NULL)
1991 joinrel->boundinfo = boundinfo;
1992 joinrel->
nparts = nparts;
1993 joinrel->part_rels =
1999 Assert(joinrel->boundinfo);
2000 Assert(joinrel->part_rels);
2035 for (cnt_parts = 0; cnt_parts < joinrel->
nparts; cnt_parts++)
2037 RelOptInfo *child_joinrel = joinrel->part_rels[cnt_parts];
2053 *parts1 =
lappend(*parts1, NULL);
2054 *parts2 =
lappend(*parts2, NULL);
2111 *parts1 =
lappend(*parts1, child_rel1);
2112 *parts2 =
lappend(*parts2, child_rel2);
AppendRelInfo ** find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)
Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)
Relids adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos)
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
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_add_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
void set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo, List *restrictlist)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
bool have_relevant_joinclause(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
void add_paths_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, SpecialJoinInfo *sjinfo, List *restrictlist)
static void populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *sjinfo, List *restrictlist)
static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo, List *parent_restrictlist)
static void make_rels_by_clauseless_joins(PlannerInfo *root, RelOptInfo *old_rel, List *other_rels)
bool is_dummy_rel(RelOptInfo *rel)
void join_search_one_level(PlannerInfo *root, int level)
static bool restriction_is_constant_false(List *restrictlist, RelOptInfo *joinrel, bool only_pushed_down)
static void get_matching_part_pairs(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *rel1, RelOptInfo *rel2, List **parts1, List **parts2)
RelOptInfo * make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
static bool has_legal_joinclause(PlannerInfo *root, RelOptInfo *rel)
static void compute_partition_bounds(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo, List **parts1, List **parts2)
Relids add_outer_joins_to_relids(PlannerInfo *root, Relids input_relids, SpecialJoinInfo *sjinfo, List **pushed_down_joins)
static SpecialJoinInfo * build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo, Relids left_relids, Relids right_relids)
void mark_dummy_rel(RelOptInfo *rel)
bool have_join_order_restriction(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
void init_dummy_sjinfo(SpecialJoinInfo *sjinfo, Relids left_relids, Relids right_relids)
static void free_child_join_sjinfo(SpecialJoinInfo *child_sjinfo, SpecialJoinInfo *parent_sjinfo)
static void make_grouped_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, RelOptInfo *joinrel, SpecialJoinInfo *sjinfo, List *restrictlist)
static bool join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, Relids joinrelids, SpecialJoinInfo **sjinfo_p, bool *reversed_p)
static void make_rels_by_clause_joins(PlannerInfo *root, RelOptInfo *old_rel, List *other_rels, int first_rel_idx)
List * lappend(List *list, void *datum)
Datum subpath(PG_FUNCTION_ARGS)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext GetMemoryChunkContext(void *pointer)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, PartitionBoundInfo b1, PartitionBoundInfo b2)
PartitionBoundInfo partition_bounds_merge(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype, List **outer_parts, List **inner_parts)
void set_cheapest(RelOptInfo *parent_rel)
AppendPath * create_append_path(PlannerInfo *root, RelOptInfo *rel, List *subpaths, List *partial_subpaths, List *pathkeys, Relids required_outer, int parallel_workers, bool parallel_aware, double rows)
void add_path(RelOptInfo *parent_rel, Path *new_path)
#define IS_DUMMY_APPEND(p)
#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)
#define IS_SIMPLE_REL(rel)
#define IS_PARTITIONED_REL(rel)
#define IS_GROUPED_REL(rel)
#define REL_HAS_ALL_PART_PROPS(rel)
@ RELOPT_OTHER_MEMBER_REL
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define foreach_current_index(var_or_cell)
#define for_each_from(cell, lst, N)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
RelOptInfo * create_unique_paths(PlannerInfo *root, RelOptInfo *rel, SpecialJoinInfo *sjinfo)
static bool DatumGetBool(Datum X)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
RelOptInfo * build_grouped_rel(PlannerInfo *root, RelOptInfo *rel)
RelOptInfo * build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, RelOptInfo *inner_rel, RelOptInfo *parent_joinrel, List *restrictlist, SpecialJoinInfo *sjinfo, int nappinfos, AppendRelInfo **appinfos)
Relids min_join_parameterization(PlannerInfo *root, Relids joinrelids, RelOptInfo *outer_rel, RelOptInfo *inner_rel)
RelOptInfo * find_join_rel(PlannerInfo *root, Relids relids)
RelOptInfo * build_join_rel(PlannerInfo *root, Relids joinrelids, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo, List *pushed_down_joins, List **restrictlist_ptr)
RelAggInfo * create_rel_agg_info(PlannerInfo *root, RelOptInfo *rel, bool calculate_grouped_rows)
void check_stack_depth(void)
struct FmgrInfo * partsupfunc
struct PathTarget * target
struct PathTarget * reltarget
struct RelAggInfo * agg_info
Relids lateral_referencers
struct RelOptInfo * grouped_rel
Relids direct_lateral_relids
bool consider_partitionwise_join