| 719 | } |
| 720 | |
| 721 | Status PartitionedHashJoinNode::OutputAllBuild(RowBatch* out_batch) { |
| 722 | DCHECK_ENUM_EQ(probe_state_, ProbeState::OUTPUTTING_UNMATCHED); |
| 723 | // This will only be called for partitions that are added to 'output_build_partitions_' |
| 724 | // in NextSpilledProbeRowBatch(), which adds one partition that is then processed until |
| 725 | // it is done by the loop in GetNext(). So, there must be exactly one partition in |
| 726 | // 'output_build_partitions_' here. |
| 727 | DCHECK_EQ(output_build_partitions_.size(), 1); |
| 728 | ScalarExprEvaluator* const* conjunct_evals = conjunct_evals_.data(); |
| 729 | const int num_conjuncts = conjuncts_.size(); |
| 730 | RowBatch::Iterator out_batch_iterator(out_batch, out_batch->num_rows()); |
| 731 | |
| 732 | bool eos = false; |
| 733 | while (!eos && !out_batch->AtCapacity()) { |
| 734 | if (output_unmatched_batch_iter_->AtEnd()) { |
| 735 | output_unmatched_batch_->TransferResourceOwnership(out_batch); |
| 736 | output_unmatched_batch_->Reset(); |
| 737 | // Need to flush any resources attached to 'out_batch' before calling |
| 738 | // build_rows()->GetNext(). E.g. if the previous call to GetNext() set the |
| 739 | // 'needs_deep_copy' flag, then calling GetNext() before we return the current |
| 740 | // batch leave the batch referencing invalid memory (see IMPALA-5815). |
| 741 | if (out_batch->AtCapacity()) break; |
| 742 | |
| 743 | RETURN_IF_ERROR(output_build_partitions_.front()->build_rows()->GetNext( |
| 744 | output_unmatched_batch_.get(), &eos)); |
| 745 | output_unmatched_batch_iter_.reset( |
| 746 | new RowBatch::Iterator(output_unmatched_batch_.get(), 0)); |
| 747 | } |
| 748 | |
| 749 | for (; !output_unmatched_batch_iter_->AtEnd() && !out_batch->AtCapacity(); |
| 750 | output_unmatched_batch_iter_->Next()) { |
| 751 | OutputBuildRow(out_batch, output_unmatched_batch_iter_->Get(), &out_batch_iterator); |
| 752 | if (ExecNode::EvalConjuncts( |
| 753 | conjunct_evals, num_conjuncts, out_batch_iterator.Get())) { |
| 754 | out_batch->CommitLastRow(); |
| 755 | out_batch_iterator.Next(); |
| 756 | } |
| 757 | } |
| 758 | } |
| 759 | |
| 760 | // If we reached eos and finished the last batch, then there are no other unmatched |
| 761 | // build rows for this partition. In that case we need to close the partition. |
| 762 | // Otherwise, we reached out_batch capacity and we need to continue to output |
| 763 | // unmatched build rows, without closing the partition. |
| 764 | if (eos && output_unmatched_batch_iter_->AtEnd()) { |
| 765 | output_build_partitions_.front()->Close(out_batch); |
| 766 | output_build_partitions_.pop_front(); |
| 767 | DCHECK(output_build_partitions_.empty()); |
| 768 | output_unmatched_batch_iter_.reset(); |
| 769 | output_unmatched_batch_->TransferResourceOwnership(out_batch); |
| 770 | output_unmatched_batch_->Reset(); |
| 771 | } |
| 772 | return Status::OK(); |
| 773 | } |
| 774 | |
| 775 | void PartitionedHashJoinNode::OutputUnmatchedBuildFromHashTable(RowBatch* out_batch) { |
| 776 | DCHECK_ENUM_EQ(probe_state_, ProbeState::OUTPUTTING_UNMATCHED); |
nothing calls this directly
no test coverage detected