| 740 | } |
| 741 | |
| 742 | bool HashJoin::fetchRecord(thread_db* tdbb, Impure* impure, FB_SIZE_T stream) const |
| 743 | { |
| 744 | HashTable* const hashTable = impure->irsb_hash_table; |
| 745 | |
| 746 | const BufferedStream* const arg = m_args[stream].buffer; |
| 747 | |
| 748 | ULONG position; |
| 749 | if (hashTable->iterate(stream, impure->irsb_leader_hash, position)) |
| 750 | { |
| 751 | arg->locate(tdbb, position); |
| 752 | |
| 753 | if (arg->getRecord(tdbb)) |
| 754 | return true; |
| 755 | } |
| 756 | |
| 757 | if (m_joinType == SEMI_JOIN || m_joinType == ANTI_JOIN) |
| 758 | return false; |
| 759 | |
| 760 | while (true) |
| 761 | { |
| 762 | if (stream == 0 || !fetchRecord(tdbb, impure, stream - 1)) |
| 763 | return false; |
| 764 | |
| 765 | hashTable->reset(stream, impure->irsb_leader_hash); |
| 766 | |
| 767 | if (hashTable->iterate(stream, impure->irsb_leader_hash, position)) |
| 768 | { |
| 769 | arg->locate(tdbb, position); |
| 770 | |
| 771 | if (arg->getRecord(tdbb)) |
| 772 | return true; |
| 773 | } |
| 774 | } |
| 775 | } |