| 375 | } |
| 376 | |
| 377 | Status NestedLoopJoinNode::GetNextLeftAntiJoin(RuntimeState* state, |
| 378 | RowBatch* output_batch) { |
| 379 | ScalarExprEvaluator* const* join_conjunct_evals = join_conjunct_evals_.data(); |
| 380 | size_t num_join_conjuncts = join_conjuncts_.size(); |
| 381 | DCHECK_EQ(num_join_conjuncts, join_conjunct_evals_.size()); |
| 382 | const int N = BitUtil::RoundUpToPowerOfTwo(state->batch_size()); |
| 383 | |
| 384 | while (!eos_) { |
| 385 | DCHECK(HasValidProbeRow()); |
| 386 | while (!build_row_iterator_.AtEnd()) { |
| 387 | DCHECK(current_probe_row_ != NULL); |
| 388 | CreateOutputRow(semi_join_staging_row_, current_probe_row_, |
| 389 | build_row_iterator_.GetRow()); |
| 390 | build_row_iterator_.Next(); |
| 391 | ++current_build_row_idx_; |
| 392 | // This loop can go on for a long time if the conjuncts are very selective. Do |
| 393 | // expensive query maintenance after every N iterations. |
| 394 | if ((current_build_row_idx_ & (N - 1)) == 0) { |
| 395 | RETURN_IF_CANCELLED(state); |
| 396 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 397 | } |
| 398 | if (EvalConjuncts( |
| 399 | join_conjunct_evals, num_join_conjuncts, semi_join_staging_row_)) { |
| 400 | // Found a match for the probe row. This row will not be in the result. |
| 401 | matched_probe_ = true; |
| 402 | break; |
| 403 | } |
| 404 | } |
| 405 | if (!matched_probe_) RETURN_IF_ERROR(ProcessUnmatchedProbeRow(state, output_batch)); |
| 406 | RETURN_IF_ERROR(NextProbeRow(state, output_batch)); |
| 407 | if (output_batch->AtCapacity()) break; |
| 408 | } |
| 409 | return Status::OK(); |
| 410 | } |
| 411 | |
| 412 | Status NestedLoopJoinNode::GetNextNullAwareLeftAntiJoin(RuntimeState* state, |
| 413 | RowBatch* output_batch) { |
nothing calls this directly
no test coverage detected