| 1472 | if (!decodedFilterTableResult_.isNullAt(i) && |
| 1473 | decodedFilterTableResult_.valueAt<bool>(i)) { |
| 1474 | filterPassedRows.setValid(row, true); |
| 1475 | break; |
| 1476 | } |
| 1477 | } |
| 1478 | } |
| 1479 | } |
| 1480 | }); |
| 1481 | } |
| 1482 | } |
| 1483 | |
| 1484 | SelectivityVector HashProbe::evalFilterForNullAwareJoin( |
| 1485 | vector_size_t numRows, |
| 1486 | bool filterPropagateNulls) { |
| 1487 | auto* rawOutputProbeRowMapping = |
| 1488 | outputRowMapping_->asMutable<vector_size_t>(); |
| 1489 | |
| 1490 | // Subset of probe-side rows with a match that passed the filter. |
| 1491 | SelectivityVector filterPassedRows(input_->size(), false); |
| 1492 | |
| 1493 | // Subset of probe-side rows with non-null probe key and either no match or |
| 1494 | // no match that passed the filter. We need to combine these with all |
| 1495 | // build-side rows with null keys to see if a filter passes on any of these. |
| 1496 | SelectivityVector nullKeyProbeRows(input_->size(), false); |
| 1497 | |
| 1498 | // Subset of probe-sie rows with null probe key. We need to combine these |
| 1499 | // with all build-side rows to see if a filter passes on any of these. |
| 1500 | SelectivityVector crossJoinProbeRows(input_->size(), false); |
| 1501 | |
| 1502 | for (auto i = 0; i < numRows; ++i) { |
| 1503 | // Skip filter input row if it has any null probe side filter column. |
| 1504 | if (filterPropagateNulls && nullFilterInputRows_.isValid(i)) { |
| 1505 | continue; |
| 1506 | } |
| 1507 | |
| 1508 | const auto probeRow = rawOutputProbeRowMapping[i]; |
| 1509 | if (nonNullInputRows_.isValid(probeRow)) { |
| 1510 | if (filterPassed(i)) { |
| 1511 | filterPassedRows.setValid(probeRow, true); |
| 1512 | } else { |
| 1513 | nullKeyProbeRows.setValid(probeRow, true); |
| 1514 | } |
| 1515 | } else { |
| 1516 | crossJoinProbeRows.setValid(probeRow, true); |
| 1517 | } |
| 1518 | } |
| 1519 | |
| 1520 | if (buildSideHasNullKeys_) { |
| 1521 | BaseHashTable::NullKeyRowsIterator iter; |
| 1522 | nullKeyProbeRows.deselect(filterPassedRows); |
| 1523 | applyFilterOnTableRowsForNullAwareJoin( |
| 1524 | nullKeyProbeRows, filterPassedRows, [&](char** data, int32_t maxRows) { |
| 1525 | return table_->listNullKeyRows(&iter, maxRows, data); |
| 1526 | }); |
| 1527 | } |
| 1528 | BaseHashTable::RowsIterator iter; |
| 1529 | crossJoinProbeRows.deselect(filterPassedRows); |
| 1530 | applyFilterOnTableRowsForNullAwareJoin( |
| 1531 | crossJoinProbeRows, filterPassedRows, [&](char** data, int32_t maxRows) { |
nothing calls this directly
no test coverage detected