* cdbpathlocus_join * * Determine locus to describe the result of a join. Any necessary Motion has * already been applied to the sources. */
| 725 | * already been applied to the sources. |
| 726 | */ |
| 727 | CdbPathLocus |
| 728 | cdbpathlocus_join(JoinType jointype, CdbPathLocus a, CdbPathLocus b) |
| 729 | { |
| 730 | ListCell *acell; |
| 731 | ListCell *bcell; |
| 732 | CdbPathLocus resultlocus = {0}; |
| 733 | int numsegments; |
| 734 | |
| 735 | Assert(cdbpathlocus_is_valid(a)); |
| 736 | Assert(cdbpathlocus_is_valid(b)); |
| 737 | |
| 738 | /* |
| 739 | * Parallel locus never get here. |
| 740 | * There shouldn't be xxxWorkers locus or parallel_workers > 1 |
| 741 | * (Hashed locus could have parallel_worker > 0). |
| 742 | */ |
| 743 | Assert(!CdbPathLocus_IsHashedWorkers(a) && !CdbPathLocus_IsSegmentGeneralWorkers(a) && !CdbPathLocus_IsReplicatedWorkers(a)); |
| 744 | Assert(!CdbPathLocus_IsHashedWorkers(b) && !CdbPathLocus_IsSegmentGeneralWorkers(b) && !CdbPathLocus_IsReplicatedWorkers(b)); |
| 745 | Assert(a.parallel_workers == 0 && b.parallel_workers == 0); |
| 746 | |
| 747 | /* Do both input rels have same locus? */ |
| 748 | if (cdbpathlocus_equal(a, b)) |
| 749 | return a; |
| 750 | |
| 751 | /* |
| 752 | * SingleQE may have different segment counts. |
| 753 | */ |
| 754 | if (CdbPathLocus_IsSingleQE(a) && |
| 755 | CdbPathLocus_IsSingleQE(b)) |
| 756 | { |
| 757 | CdbPathLocus_MakeSingleQE(&resultlocus, |
| 758 | CdbPathLocus_CommonSegments(a, b)); |
| 759 | return resultlocus; |
| 760 | } |
| 761 | |
| 762 | /* |
| 763 | * Could get here if Replicated join Entry and we Gather Replicated to SingleQE |
| 764 | * with cte1 as (insert into rpt_table values (1, 2) returning *) |
| 765 | * select * from cte1 join gp_segment_configuration g on g.dbid = cte1.c1; |
| 766 | * We return SingleQE to ensure not to be elided Motion. |
| 767 | */ |
| 768 | if ((CdbPathLocus_IsSingleQE(a) && CdbPathLocus_IsEntry(b)) || |
| 769 | (CdbPathLocus_IsSingleQE(b) && CdbPathLocus_IsEntry(a))) |
| 770 | { |
| 771 | return CdbPathLocus_IsSingleQE(a) ? a : b; |
| 772 | } |
| 773 | |
| 774 | if (CdbPathLocus_IsGeneral(a)) |
| 775 | return b; |
| 776 | |
| 777 | if (CdbPathLocus_IsGeneral(b)) |
| 778 | return a; |
| 779 | |
| 780 | /* |
| 781 | * If one rel is SegmentGeneral, result stays with the other rel, |
| 782 | * but need to ensure the result is on the common segments. |
| 783 | * NB: the code check SegmentGeneral and Replicated is quite similar, |
| 784 | * but we have to put check-segmentgeneral first here. Consider one |
no test coverage detected