| 532 | } |
| 533 | |
| 534 | void HashBuild::addInput(RowVectorPtr input) { |
| 535 | checkRunning(); |
| 536 | |
| 537 | if (!ensureInputFits(input, {nullptr, 0})) { |
| 538 | BOLT_CHECK_NOT_NULL(input_); |
| 539 | BOLT_CHECK(future_.valid()); |
| 540 | return; |
| 541 | } |
| 542 | |
| 543 | BOLT_TEST_ADJUST("bytedance::bolt::exec::HashBuild::addInput", this); |
| 544 | |
| 545 | activeRows_.resize(input->size()); |
| 546 | activeRows_.setAll(); |
| 547 | |
| 548 | auto& hashers = table_->hashers(); |
| 549 | |
| 550 | for (auto i = 0; i < hashers.size(); ++i) { |
| 551 | auto key = input->childAt(hashers[i]->channel())->loadedVector(); |
| 552 | hashers[i]->decode(*key, activeRows_); |
| 553 | } |
| 554 | |
| 555 | // Update statistics for null keys in join operator. |
| 556 | // We use activeRows_ to store which rows have some null keys, |
| 557 | // and reset it after using it. |
| 558 | // Only process when input is not spilled, to avoid overcounting. |
| 559 | if (!isInputFromSpill()) { |
| 560 | auto lockedStats = stats_.wlock(); |
| 561 | deselectRowsWithNulls(hashers, activeRows_); |
| 562 | lockedStats->numNullKeys += |
| 563 | activeRows_.size() - activeRows_.countSelected(); |
| 564 | activeRows_.setAll(); |
| 565 | } |
| 566 | |
| 567 | if (!isRightJoin(joinType_) && !isFullJoin(joinType_) && |
| 568 | !isRightSemiProjectJoin(joinType_) && |
| 569 | !isLeftNullAwareJoinWithFilter(joinNode_)) { |
| 570 | deselectRowsWithNulls(hashers, activeRows_); |
| 571 | if (nullAware_ && !joinHasNullKeys_ && |
| 572 | activeRows_.countSelected() < input->size()) { |
| 573 | joinHasNullKeys_ = true; |
| 574 | } |
| 575 | } else if (nullAware_ && !joinHasNullKeys_) { |
| 576 | for (auto& hasher : hashers) { |
| 577 | auto& decoded = hasher->decodedVector(); |
| 578 | if (decoded.mayHaveNulls()) { |
| 579 | auto* nulls = decoded.nulls(&activeRows_); |
| 580 | if (nulls && bits::countNulls(nulls, 0, activeRows_.end()) > 0) { |
| 581 | joinHasNullKeys_ = true; |
| 582 | break; |
| 583 | } |
| 584 | } |
| 585 | } |
| 586 | } |
| 587 | |
| 588 | for (auto i = 0; i < dependentChannels_.size(); ++i) { |
| 589 | decoders_[i]->decode( |
| 590 | *input->childAt(dependentChannels_[i])->loadedVector(), activeRows_); |
| 591 | } |
nothing calls this directly
no test coverage detected