| 619 | } |
| 620 | |
| 621 | Status NestedLoopJoinNode::FindBuildMatches( |
| 622 | RuntimeState* state, RowBatch* output_batch, bool* return_output_batch) { |
| 623 | *return_output_batch = false; |
| 624 | ScalarExprEvaluator* const* join_conjunct_evals = join_conjunct_evals_.data(); |
| 625 | size_t num_join_conjuncts = join_conjuncts_.size(); |
| 626 | DCHECK_EQ(num_join_conjuncts, join_conjunct_evals_.size()); |
| 627 | ScalarExprEvaluator* const* conjunct_evals = conjunct_evals_.data(); |
| 628 | size_t num_conjuncts = conjuncts_.size(); |
| 629 | DCHECK_EQ(num_conjuncts, conjunct_evals_.size()); |
| 630 | |
| 631 | const int N = BitUtil::RoundUpToPowerOfTwo(state->batch_size()); |
| 632 | while (!build_row_iterator_.AtEnd()) { |
| 633 | DCHECK(current_probe_row_ != NULL); |
| 634 | TupleRow* output_row = output_batch->GetRow(output_batch->AddRow()); |
| 635 | CreateOutputRow(output_row, current_probe_row_, build_row_iterator_.GetRow()); |
| 636 | build_row_iterator_.Next(); |
| 637 | ++current_build_row_idx_; |
| 638 | |
| 639 | // This loop can go on for a long time if the conjuncts are very selective. Do |
| 640 | // expensive query maintenance after every N iterations. |
| 641 | if ((current_build_row_idx_ & (N - 1)) == 0) { |
| 642 | if (ReachedLimit()) { |
| 643 | eos_ = true; |
| 644 | *return_output_batch = true; |
| 645 | return Status::OK(); |
| 646 | } |
| 647 | RETURN_IF_CANCELLED(state); |
| 648 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 649 | } |
| 650 | if (!EvalConjuncts(join_conjunct_evals, num_join_conjuncts, output_row)) { |
| 651 | continue; |
| 652 | } |
| 653 | matched_probe_ = true; |
| 654 | if (matching_build_rows_ != NULL) { |
| 655 | matching_build_rows_->Set(current_build_row_idx_ - 1, true); |
| 656 | } |
| 657 | if (!EvalConjuncts(conjunct_evals, num_conjuncts, output_row)) continue; |
| 658 | VLOG_ROW << "match row: " << PrintRow(output_row, *row_desc()); |
| 659 | output_batch->CommitLastRow(); |
| 660 | IncrementNumRowsReturned(1); |
| 661 | if (output_batch->AtCapacity()) { |
| 662 | *return_output_batch = true; |
| 663 | return Status::OK(); |
| 664 | } |
| 665 | } |
| 666 | return Status::OK(); |
| 667 | } |
| 668 | |
| 669 | Status NestedLoopJoinNode::NextProbeRow(RuntimeState* state, RowBatch* output_batch) { |
| 670 | current_probe_row_ = NULL; |
nothing calls this directly
no test coverage detected