| 454 | } |
| 455 | |
| 456 | void HashBuild::setupFilterForAntiJoins( |
| 457 | const folly::F14FastMap<column_index_t, column_index_t>& keyChannelMap) { |
| 458 | BOLT_DCHECK( |
| 459 | std::is_sorted(dependentChannels_.begin(), dependentChannels_.end())); |
| 460 | |
| 461 | ExprSet exprs({joinNode_->filter()}, operatorCtx_->execCtx()); |
| 462 | BOLT_DCHECK_EQ(exprs.exprs().size(), 1); |
| 463 | const auto& expr = exprs.expr(0); |
| 464 | filterPropagatesNulls_ = expr->propagatesNulls(); |
| 465 | if (filterPropagatesNulls_) { |
| 466 | const auto inputType = joinNode_->sources()[1]->outputType(); |
| 467 | for (const auto& field : expr->distinctFields()) { |
| 468 | const auto index = inputType->getChildIdxIfExists(field->field()); |
| 469 | if (!index.has_value()) { |
| 470 | continue; |
| 471 | } |
| 472 | auto keyIter = keyChannelMap.find(*index); |
| 473 | if (keyIter != keyChannelMap.end()) { |
| 474 | keyFilterChannels_.push_back(keyIter->second); |
| 475 | } else { |
| 476 | auto dependentIter = std::lower_bound( |
| 477 | dependentChannels_.begin(), dependentChannels_.end(), *index); |
| 478 | BOLT_DCHECK( |
| 479 | dependentIter != dependentChannels_.end() && |
| 480 | *dependentIter == *index); |
| 481 | dependentFilterChannels_.push_back( |
| 482 | dependentIter - dependentChannels_.begin()); |
| 483 | } |
| 484 | } |
| 485 | } |
| 486 | } |
| 487 | |
| 488 | void HashBuild::removeInputRowsForAntiJoinFilter() { |
| 489 | bool changed = false; |
nothing calls this directly
no test coverage detected