| 96 | } |
| 97 | |
| 98 | void NestedLoopJoinProbe::initializeFilter( |
| 99 | const core::TypedExprPtr& filter, |
| 100 | const RowTypePtr& probeType, |
| 101 | const RowTypePtr& buildType) { |
| 102 | BOLT_CHECK_NULL(joinCondition_); |
| 103 | |
| 104 | std::vector<core::TypedExprPtr> filters = {filter}; |
| 105 | joinCondition_ = |
| 106 | std::make_unique<ExprSet>(std::move(filters), operatorCtx_->execCtx()); |
| 107 | |
| 108 | column_index_t filterChannel = 0; |
| 109 | std::vector<std::string> names; |
| 110 | std::vector<TypePtr> types; |
| 111 | const auto numFields = joinCondition_->expr(0)->distinctFields().size(); |
| 112 | names.reserve(numFields); |
| 113 | types.reserve(numFields); |
| 114 | |
| 115 | for (const auto& field : joinCondition_->expr(0)->distinctFields()) { |
| 116 | const auto& name = field->field(); |
| 117 | auto channel = probeType->getChildIdxIfExists(name); |
| 118 | if (channel.has_value()) { |
| 119 | auto channelValue = channel.value(); |
| 120 | filterProbeProjections_.emplace_back(channelValue, filterChannel++); |
| 121 | names.emplace_back(probeType->nameOf(channelValue)); |
| 122 | types.emplace_back(probeType->childAt(channelValue)); |
| 123 | continue; |
| 124 | } |
| 125 | channel = buildType->getChildIdxIfExists(name); |
| 126 | if (channel.has_value()) { |
| 127 | auto channelValue = channel.value(); |
| 128 | filterBuildProjections_.emplace_back(channelValue, filterChannel++); |
| 129 | names.emplace_back(buildType->nameOf(channelValue)); |
| 130 | types.emplace_back(buildType->childAt(channelValue)); |
| 131 | continue; |
| 132 | } |
| 133 | BOLT_FAIL( |
| 134 | "Join filter field {} not in probe or build input, filter: {}", |
| 135 | field->toString(), |
| 136 | filter->toString()); |
| 137 | } |
| 138 | |
| 139 | filterInputType_ = ROW(std::move(names), std::move(types)); |
| 140 | } |
| 141 | |
| 142 | BlockingReason NestedLoopJoinProbe::isBlocked(ContinueFuture* future) { |
| 143 | switch (state_) { |
nothing calls this directly
no test coverage detected