| 806 | } |
| 807 | |
| 808 | void NestedLoopJoinProbe::beginBuildMismatch() { |
| 809 | BOLT_CHECK(needsBuildMismatch(joinType_)); |
| 810 | |
| 811 | // Check the state of peer operators. Only the last driver (operator) running |
| 812 | // this code will survive and move on to process build mismatches. |
| 813 | std::vector<ContinuePromise> promises; |
| 814 | std::vector<std::shared_ptr<Driver>> peers; |
| 815 | if (!operatorCtx_->task()->allPeersFinished( |
| 816 | planNodeId(), operatorCtx_->driver(), &future_, promises, peers)) { |
| 817 | BOLT_CHECK(future_.valid()); |
| 818 | setState(ProbeOperatorState::kWaitForPeers); |
| 819 | return; |
| 820 | } |
| 821 | |
| 822 | lastProbe_ = true; |
| 823 | |
| 824 | // From now on, buildIndex_ is used to indexing into buildMismatched_ |
| 825 | BOLT_CHECK_EQ(buildIndex_, 0); |
| 826 | |
| 827 | // Colect and merge the build mismatch selectivity vectors from all peers. |
| 828 | for (auto& peer : peers) { |
| 829 | auto* op = peer->findOperator(planNodeId()); |
| 830 | auto* probe = dynamic_cast<NestedLoopJoinProbe*>(op); |
| 831 | BOLT_CHECK_NOT_NULL(probe); |
| 832 | for (auto i = 0; i < buildMatched_.size(); ++i) { |
| 833 | buildMatched_[i].select(probe->buildMatched_[i]); |
| 834 | probeSideEmpty_ &= probe->probeSideEmpty_; |
| 835 | } |
| 836 | } |
| 837 | peers.clear(); |
| 838 | for (auto& matched : buildMatched_) { |
| 839 | matched.updateBounds(); |
| 840 | } |
| 841 | for (auto& promise : promises) { |
| 842 | promise.setValue(); |
| 843 | } |
| 844 | } |
| 845 | |
| 846 | RowVectorPtr NestedLoopJoinProbe::getBuildMismatchedOutput( |
| 847 | const RowVectorPtr& data, |
nothing calls this directly
no test coverage detected