* sort_inner_and_outer * Create mergejoin join paths by explicitly sorting both the outer and * inner join relations on each available merge ordering. * * 'joinrel' is the join relation * 'outerrel' is the outer join relation * 'innerrel' is the inner join relation * 'jointype' is the type of join to do * 'extra' contains additional input values */
| 1269 | * 'extra' contains additional input values |
| 1270 | */ |
| 1271 | static void |
| 1272 | sort_inner_and_outer(PlannerInfo *root, |
| 1273 | RelOptInfo *joinrel, |
| 1274 | RelOptInfo *outerrel, |
| 1275 | RelOptInfo *innerrel, |
| 1276 | JoinType jointype, |
| 1277 | JoinPathExtraData *extra) |
| 1278 | { |
| 1279 | JoinType save_jointype = jointype; |
| 1280 | Path *outer_path; |
| 1281 | Path *inner_path; |
| 1282 | Path *cheapest_partial_outer = NULL; |
| 1283 | Path *cheapest_safe_inner = NULL; |
| 1284 | List *all_pathkeys; |
| 1285 | ListCell *l; |
| 1286 | |
| 1287 | if (jointype == JOIN_DEDUP_SEMI || jointype == JOIN_DEDUP_SEMI_REVERSE) |
| 1288 | jointype = JOIN_INNER; |
| 1289 | |
| 1290 | /* |
| 1291 | * We only consider the cheapest-total-cost input paths, since we are |
| 1292 | * assuming here that a sort is required. We will consider |
| 1293 | * cheapest-startup-cost input paths later, and only if they don't need a |
| 1294 | * sort. |
| 1295 | * |
| 1296 | * This function intentionally does not consider parameterized input |
| 1297 | * paths, except when the cheapest-total is parameterized. If we did so, |
| 1298 | * we'd have a combinatorial explosion of mergejoin paths of dubious |
| 1299 | * value. This interacts with decisions elsewhere that also discriminate |
| 1300 | * against mergejoins with parameterized inputs; see comments in |
| 1301 | * src/backend/optimizer/README. |
| 1302 | */ |
| 1303 | outer_path = outerrel->cheapest_total_path; |
| 1304 | inner_path = innerrel->cheapest_total_path; |
| 1305 | |
| 1306 | /* |
| 1307 | * If either cheapest-total path is parameterized by the other rel, we |
| 1308 | * can't use a mergejoin. (There's no use looking for alternative input |
| 1309 | * paths, since these should already be the least-parameterized available |
| 1310 | * paths.) |
| 1311 | */ |
| 1312 | if (PATH_PARAM_BY_REL(outer_path, innerrel) || |
| 1313 | PATH_PARAM_BY_REL(inner_path, outerrel)) |
| 1314 | return; |
| 1315 | |
| 1316 | /* |
| 1317 | * If unique-ification is requested, do it and then handle as a plain |
| 1318 | * inner join. |
| 1319 | */ |
| 1320 | if (jointype == JOIN_UNIQUE_OUTER) |
| 1321 | { |
| 1322 | outer_path = (Path *) create_unique_path(root, outerrel, |
| 1323 | outer_path, extra->sjinfo); |
| 1324 | Assert(outer_path); |
| 1325 | jointype = JOIN_INNER; |
| 1326 | } |
| 1327 | else if (jointype == JOIN_UNIQUE_INNER) |
| 1328 | { |
no test coverage detected