* add_paths_to_joinrel * Given a join relation and two component rels from which it can be made, * consider all possible paths that use the two component rels as outer * and inner rel respectively. Add these paths to the join rel's pathlist * if they survive comparison with other paths (and remove any existing * paths that are dominated by these paths). * * Modifies the pathlist
| 137 | * with sjinfo->jointype == JOIN_SEMI indicates that. |
| 138 | */ |
| 139 | void |
| 140 | add_paths_to_join_relation(PlannerInfo *root, |
| 141 | RelOptInfo *joinrel, |
| 142 | RelOptInfo *outerrel, |
| 143 | RelOptInfo *innerrel, |
| 144 | JoinType jointype, |
| 145 | SpecialJoinInfo *sjinfo, |
| 146 | List *restrictlist) |
| 147 | { |
| 148 | JoinPathExtraData extra; |
| 149 | bool mergejoin_allowed = true; |
| 150 | ListCell *lc; |
| 151 | Relids joinrelids; |
| 152 | |
| 153 | /* |
| 154 | * PlannerInfo doesn't contain the SpecialJoinInfos created for joins |
| 155 | * between child relations, even if there is a SpecialJoinInfo node for |
| 156 | * the join between the topmost parents. So, while calculating Relids set |
| 157 | * representing the restriction, consider relids of topmost parent of |
| 158 | * partitions. |
| 159 | */ |
| 160 | if (joinrel->reloptkind == RELOPT_OTHER_JOINREL) |
| 161 | joinrelids = joinrel->top_parent_relids; |
| 162 | else |
| 163 | joinrelids = joinrel->relids; |
| 164 | |
| 165 | extra.restrictlist = restrictlist; |
| 166 | extra.mergeclause_list = NIL; |
| 167 | extra.sjinfo = sjinfo; |
| 168 | extra.param_source_rels = NULL; |
| 169 | extra.redistribution_clauses = NIL; |
| 170 | extra.runtime_filter_tuples = -1; |
| 171 | |
| 172 | Assert(outerrel->pathlist && |
| 173 | outerrel->cheapest_total_path); |
| 174 | Assert(innerrel->pathlist && |
| 175 | innerrel->cheapest_total_path); |
| 176 | |
| 177 | /* |
| 178 | * Don't consider paths that have WorkTableScan as inner rel. If the outer |
| 179 | * rel has a WorkTableScan as well, we won't be able to produce a usable |
| 180 | * join so we need to error out. This case can happen when to RECURSIVE |
| 181 | * clauses are joined. RECURSIVE_CTE_FIXME: Revisit this when we gain |
| 182 | * rescannable motions. |
| 183 | */ |
| 184 | if (innerrel->cheapest_startup_path && cdbpath_contains_wts(innerrel->cheapest_startup_path)) |
| 185 | { |
| 186 | if (outerrel->cheapest_startup_path && cdbpath_contains_wts(outerrel->cheapest_startup_path)) |
| 187 | ereport(ERROR, |
| 188 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 189 | errmsg("joining nested RECURSIVE clauses is not supported"))); |
| 190 | return; |
| 191 | } |
| 192 | if (cdbpath_contains_wts(innerrel->cheapest_total_path)) |
| 193 | return; |
| 194 | |
| 195 | /* |
| 196 | * See if the inner relation is provably unique for this outer rel. |
no test coverage detected