| 564 | } |
| 565 | |
| 566 | Status NestedLoopJoinNode::ProcessUnmatchedBuildRows( |
| 567 | RuntimeState* state, RowBatch* output_batch) { |
| 568 | if (!process_unmatched_build_rows_) { |
| 569 | // Reset the build row iterator to start processing the unmatched build rows. |
| 570 | build_row_iterator_ = build_batches_->Iterator(); |
| 571 | current_build_row_idx_ = 0; |
| 572 | process_unmatched_build_rows_ = true; |
| 573 | } |
| 574 | ScalarExprEvaluator* const* conjunct_evals = conjunct_evals_.data(); |
| 575 | size_t num_conjuncts = conjuncts_.size(); |
| 576 | DCHECK_EQ(num_conjuncts, conjunct_evals_.size()); |
| 577 | DCHECK(matching_build_rows_ != NULL); |
| 578 | |
| 579 | const int N = BitUtil::RoundUpToPowerOfTwo(state->batch_size()); |
| 580 | while (!build_row_iterator_.AtEnd()) { |
| 581 | // This loop can go on for a long time if the conjuncts are very selective. Do query |
| 582 | // maintenance every N iterations. |
| 583 | if ((current_build_row_idx_ & (N - 1)) == 0) { |
| 584 | if (ReachedLimit()) { |
| 585 | eos_ = true; |
| 586 | return Status::OK(); |
| 587 | } |
| 588 | RETURN_IF_CANCELLED(state); |
| 589 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 590 | } |
| 591 | |
| 592 | if (matching_build_rows_->Get(current_build_row_idx_)) { |
| 593 | build_row_iterator_.Next(); |
| 594 | ++current_build_row_idx_; |
| 595 | continue; |
| 596 | } |
| 597 | // Current build row is unmatched. |
| 598 | TupleRow* output_row = output_batch->GetRow(output_batch->AddRow()); |
| 599 | if (join_op_ == TJoinOp::FULL_OUTER_JOIN || join_op_ == TJoinOp::RIGHT_OUTER_JOIN) { |
| 600 | CreateOutputRow(output_row, NULL, build_row_iterator_.GetRow()); |
| 601 | } else { |
| 602 | DCHECK(join_op_ == TJoinOp::RIGHT_ANTI_JOIN) << "Unsupported join operator: " << |
| 603 | join_op_; |
| 604 | output_batch->CopyRow(build_row_iterator_.GetRow(), output_row); |
| 605 | } |
| 606 | build_row_iterator_.Next(); |
| 607 | ++current_build_row_idx_; |
| 608 | // Evaluate conjuncts that don't affect the matching rows of the join on the |
| 609 | // result row. |
| 610 | if (EvalConjuncts(conjunct_evals, num_conjuncts, output_row)) { |
| 611 | VLOG_ROW << "match row: " << PrintRow(output_row, *row_desc()); |
| 612 | output_batch->CommitLastRow(); |
| 613 | IncrementNumRowsReturned(1); |
| 614 | if (output_batch->AtCapacity()) return Status::OK(); |
| 615 | } |
| 616 | } |
| 617 | eos_ = true; |
| 618 | return Status::OK(); |
| 619 | } |
| 620 | |
| 621 | Status NestedLoopJoinNode::FindBuildMatches( |
| 622 | RuntimeState* state, RowBatch* output_batch, bool* return_output_batch) { |
nothing calls this directly
no test coverage detected