| 136 | } |
| 137 | |
| 138 | bool MergeJoin::internalGetRecord(thread_db* tdbb) const |
| 139 | { |
| 140 | JRD_reschedule(tdbb); |
| 141 | |
| 142 | Request* const request = tdbb->getRequest(); |
| 143 | Impure* const impure = request->getImpure<Impure>(m_impure); |
| 144 | |
| 145 | if (!(impure->irsb_flags & irsb_open)) |
| 146 | return false; |
| 147 | |
| 148 | // If there is a record group already formed, fetch the next combination |
| 149 | |
| 150 | if (fetchRecord(tdbb, m_args.getCount() - 1)) |
| 151 | return true; |
| 152 | |
| 153 | // Assuming we are done with the current value group, advance each |
| 154 | // stream one record. If any comes up dry, we're done. |
| 155 | const NestConst<SortedStream>* highest_ptr = m_args.begin(); |
| 156 | FB_SIZE_T highest_index = 0; |
| 157 | |
| 158 | for (FB_SIZE_T i = 0; i < m_args.getCount(); i++) |
| 159 | { |
| 160 | const NestConst<SortedStream>* const ptr = &m_args[i]; |
| 161 | const SortedStream* const sort_rsb = *ptr; |
| 162 | const NestValueArray* const sort_key = m_keys[i]; |
| 163 | Impure::irsb_mrg_repeat* const tail = &impure->irsb_mrg_rpt[i]; |
| 164 | |
| 165 | MergeFile* const mfb = &tail->irsb_mrg_file; |
| 166 | |
| 167 | // reset equality group record positions |
| 168 | |
| 169 | tail->irsb_mrg_equal = 0; |
| 170 | tail->irsb_mrg_equal_current = 0; |
| 171 | tail->irsb_mrg_equal_end = 0; |
| 172 | |
| 173 | // If there is a record waiting, use it. Otherwise get another. |
| 174 | |
| 175 | SLONG record = tail->irsb_mrg_last_fetched; |
| 176 | if (record >= 0) |
| 177 | { |
| 178 | tail->irsb_mrg_last_fetched = -1; |
| 179 | const UCHAR* const last_data = getData(tdbb, mfb, record); |
| 180 | mfb->mfb_current_block = 0; |
| 181 | |
| 182 | UCHAR* const first_data = getData(tdbb, mfb, 0); |
| 183 | if (first_data != last_data) |
| 184 | memcpy(first_data, last_data, sort_rsb->getLength()); |
| 185 | |
| 186 | mfb->mfb_equal_records = 1; |
| 187 | record = 0; |
| 188 | } |
| 189 | else |
| 190 | { |
| 191 | mfb->mfb_current_block = 0; |
| 192 | mfb->mfb_equal_records = 0; |
| 193 | if ((record = getRecordByIndex(tdbb, i)) < 0) |
| 194 | return false; |
| 195 | } |
nothing calls this directly
no test coverage detected