| 1092 | } |
| 1093 | |
| 1094 | Status PartitionedHashJoinNode::EvaluateNullProbe( |
| 1095 | RuntimeState* state, BufferedTupleStream* build) { |
| 1096 | DCHECK(build->is_pinned()); |
| 1097 | if (null_probe_rows_ == nullptr || null_probe_rows_->num_rows() == 0) { |
| 1098 | return Status::OK(); |
| 1099 | } |
| 1100 | DCHECK_EQ(null_probe_rows_->num_rows(), matched_null_probe_.size()); |
| 1101 | bool got_read_buffer; |
| 1102 | RETURN_IF_ERROR(null_probe_rows_->PrepareForRead(false, &got_read_buffer)); |
| 1103 | DCHECK(got_read_buffer) << "Probe stream should always have a read or write iterator"; |
| 1104 | |
| 1105 | ScalarExprEvaluator* const* join_conjunct_evals = other_join_conjunct_evals_.data(); |
| 1106 | int num_join_conjuncts = other_join_conjuncts_.size(); |
| 1107 | RowBatch probe_batch(&probe_row_desc(), runtime_state_->batch_size(), mem_tracker()); |
| 1108 | RowBatch build_batch(&build_row_desc(), state->batch_size(), mem_tracker()); |
| 1109 | |
| 1110 | // For each probe row, iterate over all rows in the build table. |
| 1111 | SCOPED_TIMER(null_aware_eval_timer_); |
| 1112 | int64_t probe_row_idx = 0; |
| 1113 | bool probe_stream_eos = false; |
| 1114 | while (!probe_stream_eos) { |
| 1115 | RETURN_IF_ERROR(null_probe_rows_->GetNext(&probe_batch, &probe_stream_eos)); |
| 1116 | for (int i = 0; i < probe_batch.num_rows(); ++i, ++probe_row_idx) { |
| 1117 | // This loop may run for a long time. Check for cancellation. |
| 1118 | RETURN_IF_CANCELLED(state); |
| 1119 | if (matched_null_probe_[probe_row_idx]) continue; |
| 1120 | BufferedTupleStream::ReadIterator build_itr; |
| 1121 | RETURN_IF_ERROR(build->PrepareForPinnedRead(&build_itr)); |
| 1122 | bool build_eos; |
| 1123 | do { |
| 1124 | RETURN_IF_ERROR(build->GetNext(&build_itr, &build_batch, &build_eos)); |
| 1125 | FOREACH_ROW(&build_batch, 0, iter) { |
| 1126 | CreateOutputRow(semi_join_staging_row_, probe_batch.GetRow(i), iter.Get()); |
| 1127 | if (ExecNode::EvalConjuncts( |
| 1128 | join_conjunct_evals, num_join_conjuncts, semi_join_staging_row_)) { |
| 1129 | matched_null_probe_[probe_row_idx] = true; |
| 1130 | break; |
| 1131 | } |
| 1132 | } |
| 1133 | build_batch.Reset(); |
| 1134 | RETURN_IF_CANCELLED(state); |
| 1135 | } while (!matched_null_probe_[probe_row_idx] && !build_eos); |
| 1136 | } |
| 1137 | probe_batch.Reset(); |
| 1138 | } |
| 1139 | DCHECK_EQ(probe_row_idx, null_probe_rows_->num_rows()); |
| 1140 | return Status::OK(); |
| 1141 | } |
| 1142 | |
| 1143 | Status PartitionedHashJoinNode::DoneProbing(RuntimeState* state, RowBatch* batch) { |
| 1144 | DCHECK_ENUM_EQ(probe_state_, ProbeState::PROBING_END_BATCH); |
nothing calls this directly
no test coverage detected