| 1479 | |
| 1480 | struct GroupedDistinctImpl : public GroupedCountDistinctImpl { |
| 1481 | Result<Datum> Finalize() override { |
| 1482 | ARROW_ASSIGN_OR_RAISE(auto uniques, grouper_->GetUniques()); |
| 1483 | ARROW_ASSIGN_OR_RAISE( |
| 1484 | auto groupings, Grouper::MakeGroupings(*uniques[1].array_as<UInt32Array>(), |
| 1485 | static_cast<uint32_t>(num_groups_), ctx_)); |
| 1486 | ARROW_ASSIGN_OR_RAISE( |
| 1487 | auto list, Grouper::ApplyGroupings(*groupings, *uniques[0].make_array(), ctx_)); |
| 1488 | const auto& values = list->values(); |
| 1489 | DCHECK_EQ(values->offset(), 0); |
| 1490 | auto* offsets = list->value_offsets()->mutable_data_as<int32_t>(); |
| 1491 | if (options_.mode == CountOptions::ALL || |
| 1492 | (options_.mode == CountOptions::ONLY_VALID && values->null_count() == 0)) { |
| 1493 | return list; |
| 1494 | } else if (options_.mode == CountOptions::ONLY_VALID) { |
| 1495 | int32_t prev_offset = offsets[0]; |
| 1496 | for (int64_t i = 0; i < list->length(); i++) { |
| 1497 | const int32_t slot_length = offsets[i + 1] - prev_offset; |
| 1498 | const int64_t null_count = |
| 1499 | slot_length - arrow::internal::CountSetBits(values->null_bitmap()->data(), |
| 1500 | prev_offset, slot_length); |
| 1501 | DCHECK_LE(null_count, 1); |
| 1502 | const int32_t offset = null_count > 0 ? slot_length - 1 : slot_length; |
| 1503 | prev_offset = offsets[i + 1]; |
| 1504 | offsets[i + 1] = offsets[i] + offset; |
| 1505 | } |
| 1506 | auto filter = |
| 1507 | std::make_shared<BooleanArray>(values->length(), values->null_bitmap()); |
| 1508 | ARROW_ASSIGN_OR_RAISE( |
| 1509 | auto new_values, |
| 1510 | Filter(std::move(values), filter, FilterOptions(FilterOptions::DROP), ctx_)); |
| 1511 | return std::make_shared<ListArray>(list->type(), list->length(), |
| 1512 | list->value_offsets(), new_values.make_array()); |
| 1513 | } |
| 1514 | // ONLY_NULL |
| 1515 | if (values->null_count() == 0) { |
| 1516 | std::fill(offsets + 1, offsets + list->length() + 1, offsets[0]); |
| 1517 | } else { |
| 1518 | int32_t prev_offset = offsets[0]; |
| 1519 | for (int64_t i = 0; i < list->length(); i++) { |
| 1520 | const int32_t slot_length = offsets[i + 1] - prev_offset; |
| 1521 | const int64_t null_count = |
| 1522 | slot_length - arrow::internal::CountSetBits(values->null_bitmap()->data(), |
| 1523 | prev_offset, slot_length); |
| 1524 | const int32_t offset = null_count > 0 ? 1 : 0; |
| 1525 | prev_offset = offsets[i + 1]; |
| 1526 | offsets[i + 1] = offsets[i] + offset; |
| 1527 | } |
| 1528 | } |
| 1529 | ARROW_ASSIGN_OR_RAISE( |
| 1530 | auto new_values, |
| 1531 | MakeArrayOfNull(out_type_, |
| 1532 | list->length() > 0 ? offsets[list->length()] - offsets[0] : 0, |
| 1533 | pool_)); |
| 1534 | return std::make_shared<ListArray>(list->type(), list->length(), |
| 1535 | list->value_offsets(), std::move(new_values)); |
| 1536 | } |
| 1537 | |
| 1538 | std::shared_ptr<DataType> out_type() const override { return list(out_type_); } |
nothing calls this directly
no test coverage detected