-1 in result means outputting all corresponding fields as nulls
| 714 | // -1 in result means outputting all corresponding fields as nulls |
| 715 | // |
| 716 | void HashJoinSimpleInt(JoinType join_type, const std::vector<int32_t>& l, |
| 717 | const std::vector<bool>& null_in_key_l, |
| 718 | const std::vector<int32_t>& r, |
| 719 | const std::vector<bool>& null_in_key_r, |
| 720 | std::vector<int32_t>* result_l, std::vector<int32_t>* result_r, |
| 721 | int64_t output_length_limit, bool* length_limit_reached) { |
| 722 | *length_limit_reached = false; |
| 723 | |
| 724 | bool switch_sides = false; |
| 725 | switch (join_type) { |
| 726 | case JoinType::RIGHT_SEMI: |
| 727 | join_type = JoinType::LEFT_SEMI; |
| 728 | switch_sides = true; |
| 729 | break; |
| 730 | case JoinType::RIGHT_ANTI: |
| 731 | join_type = JoinType::LEFT_ANTI; |
| 732 | switch_sides = true; |
| 733 | break; |
| 734 | case JoinType::RIGHT_OUTER: |
| 735 | join_type = JoinType::LEFT_OUTER; |
| 736 | switch_sides = true; |
| 737 | break; |
| 738 | default: |
| 739 | break; |
| 740 | } |
| 741 | const std::vector<int32_t>& build = switch_sides ? l : r; |
| 742 | const std::vector<int32_t>& probe = switch_sides ? r : l; |
| 743 | const std::vector<bool>& null_in_key_build = |
| 744 | switch_sides ? null_in_key_l : null_in_key_r; |
| 745 | const std::vector<bool>& null_in_key_probe = |
| 746 | switch_sides ? null_in_key_r : null_in_key_l; |
| 747 | std::vector<int32_t>* result_build = switch_sides ? result_l : result_r; |
| 748 | std::vector<int32_t>* result_probe = switch_sides ? result_r : result_l; |
| 749 | |
| 750 | std::unordered_multimap<int64_t, int64_t> map_build; |
| 751 | for (size_t i = 0; i < build.size(); ++i) { |
| 752 | map_build.insert(std::make_pair(build[i], i)); |
| 753 | } |
| 754 | std::vector<bool> match_build; |
| 755 | match_build.resize(build.size()); |
| 756 | for (size_t i = 0; i < build.size(); ++i) { |
| 757 | match_build[i] = false; |
| 758 | } |
| 759 | |
| 760 | for (int32_t i = 0; i < static_cast<int32_t>(probe.size()); ++i) { |
| 761 | std::vector<int32_t> match_probe; |
| 762 | if (!null_in_key_probe[i]) { |
| 763 | auto range = map_build.equal_range(probe[i]); |
| 764 | for (auto it = range.first; it != range.second; ++it) { |
| 765 | if (!null_in_key_build[it->second]) { |
| 766 | match_probe.push_back(static_cast<int32_t>(it->second)); |
| 767 | match_build[it->second] = true; |
| 768 | } |
| 769 | } |
| 770 | } |
| 771 | switch (join_type) { |
| 772 | case JoinType::LEFT_SEMI: |
| 773 | if (!match_probe.empty()) { |