* generate_mergejoin_paths * Creates possible mergejoin paths for input outerpath. * * We generate mergejoins if mergejoin clauses are available. We have * two ways to generate the inner path for a mergejoin: sort the cheapest * inner path, or use an inner path that is already suitably ordered for the * merge. If we have several mergeclauses, it could be that there is no inner * path (or
| 1476 | * subsets of the mergeclause list, but that seems way too expensive.) |
| 1477 | */ |
| 1478 | static void |
| 1479 | generate_mergejoin_paths(PlannerInfo *root, |
| 1480 | RelOptInfo *joinrel, |
| 1481 | RelOptInfo *innerrel, |
| 1482 | Path *outerpath, |
| 1483 | JoinType jointype, |
| 1484 | JoinPathExtraData *extra, |
| 1485 | bool useallclauses, |
| 1486 | Path *inner_cheapest_total, |
| 1487 | List *merge_pathkeys, |
| 1488 | bool is_partial) |
| 1489 | { |
| 1490 | List *mergeclauses; |
| 1491 | List *innersortkeys; |
| 1492 | List *trialsortkeys; |
| 1493 | Path *cheapest_startup_inner; |
| 1494 | Path *cheapest_total_inner; |
| 1495 | JoinType save_jointype = jointype; |
| 1496 | int num_sortkeys; |
| 1497 | int sortkeycnt; |
| 1498 | |
| 1499 | /* The merge join executor code doesn't support LASJ_NOTIN */ |
| 1500 | if (jointype == JOIN_LASJ_NOTIN) |
| 1501 | return; |
| 1502 | |
| 1503 | if (jointype == JOIN_UNIQUE_OUTER || jointype == JOIN_UNIQUE_INNER) |
| 1504 | jointype = JOIN_INNER; |
| 1505 | |
| 1506 | if (jointype == JOIN_DEDUP_SEMI || jointype == JOIN_DEDUP_SEMI_REVERSE) |
| 1507 | jointype = JOIN_INNER; |
| 1508 | |
| 1509 | /* Look for useful mergeclauses (if any) */ |
| 1510 | mergeclauses = |
| 1511 | find_mergeclauses_for_outer_pathkeys(root, |
| 1512 | outerpath->pathkeys, |
| 1513 | extra->mergeclause_list); |
| 1514 | |
| 1515 | /* |
| 1516 | * Done with this outer path if no chance for a mergejoin. |
| 1517 | * |
| 1518 | * Special corner case: for "x FULL JOIN y ON true", there will be no join |
| 1519 | * clauses at all. Ordinarily we'd generate a clauseless nestloop path, |
| 1520 | * but since mergejoin is our only join type that supports FULL JOIN |
| 1521 | * without any join clauses, it's necessary to generate a clauseless |
| 1522 | * mergejoin path instead. |
| 1523 | */ |
| 1524 | if (mergeclauses == NIL) |
| 1525 | { |
| 1526 | if (jointype == JOIN_FULL) |
| 1527 | /* okay to try for mergejoin */ ; |
| 1528 | else |
| 1529 | return; |
| 1530 | } |
| 1531 | if (useallclauses && |
| 1532 | list_length(mergeclauses) != list_length(extra->mergeclause_list)) |
| 1533 | return; |
| 1534 | |
| 1535 | /* Compute the required ordering of the inner path */ |
no test coverage detected