| 1310 | } |
| 1311 | |
| 1312 | void HashProbe::prepareFilterRowsForNullAwareJoin( |
| 1313 | const RowVector* filterInput, |
| 1314 | vector_size_t numRows, |
| 1315 | bool filterPropagateNulls) { |
| 1316 | BOLT_CHECK_LE(numRows, kBatchSize); |
| 1317 | if (filterTableInput_ == nullptr) { |
| 1318 | filterTableInput_ = |
| 1319 | BaseVector::create<RowVector>(filterInputType_, kBatchSize, pool()); |
| 1320 | } |
| 1321 | |
| 1322 | if (FOLLY_UNLIKELY(!filterInputRows_.hasSelections())) { |
| 1323 | BOLT_CHECK_NULL(filterInput); |
| 1324 | if (filterPropagateNulls) { |
| 1325 | nullFilterInputRows_.resizeFill(numRows, false); |
| 1326 | } |
| 1327 | return; |
| 1328 | } |
| 1329 | BOLT_CHECK_NOT_NULL(filterInput); |
| 1330 | |
| 1331 | if (filterPropagateNulls) { |
| 1332 | nullFilterInputRows_.resizeFill(numRows, false); |
| 1333 | auto* rawNullRows = nullFilterInputRows_.asMutableRange().bits(); |
| 1334 | for (auto& projection : filterInputProjections_) { |
| 1335 | filterInputColumnDecodedVector_.decode( |
| 1336 | *filterInput->childAt(projection.outputChannel), filterInputRows_); |
| 1337 | if (filterInputColumnDecodedVector_.mayHaveNulls()) { |
| 1338 | SelectivityVector nullsInActiveRows(numRows); |
| 1339 | memcpy( |
| 1340 | nullsInActiveRows.asMutableRange().bits(), |
| 1341 | filterInputColumnDecodedVector_.nulls(&filterInputRows_), |
| 1342 | bits::nbytes(numRows)); |
| 1343 | // All rows that are not active count as non-null here. |
| 1344 | bits::orWithNegatedBits( |
| 1345 | nullsInActiveRows.asMutableRange().bits(), |
| 1346 | filterInputRows_.asRange().bits(), |
| 1347 | 0, |
| 1348 | numRows); |
| 1349 | // NOTE: the false value of a raw null bit indicates null so we OR with |
| 1350 | // negative of the raw bit. |
| 1351 | bits::orWithNegatedBits( |
| 1352 | rawNullRows, nullsInActiveRows.asRange().bits(), 0, numRows); |
| 1353 | } |
| 1354 | } |
| 1355 | nullFilterInputRows_.updateBounds(); |
| 1356 | // TODO: consider to skip filtering on 'nullFilterInputRows_' as we know |
| 1357 | // it will never pass the filtering. |
| 1358 | } |
| 1359 | |
| 1360 | // NOTE: for null-aware anti join, we will skip filtering on the probe rows |
| 1361 | // with null join key columns(s) as we can apply filtering after they cross |
| 1362 | // join with the table rows later. |
| 1363 | if (!nonNullInputRows_.isAllSelected()) { |
| 1364 | auto* rawMapping = outputRowMapping_->asMutable<vector_size_t>(); |
| 1365 | for (int i = 0; i < numRows; ++i) { |
| 1366 | if (filterInputRows_.isValid(i) && |
nothing calls this directly
no test coverage detected