| 530 | } |
| 531 | |
| 532 | static Status Exec(KernelContext* ctx, const ExecSpan& batch, ExecResult* out) { |
| 533 | const ElementWiseAggregateOptions& options = MinMaxState::Get(ctx); |
| 534 | const size_t scalar_count = static_cast<size_t>( |
| 535 | std::count_if(batch.values.begin(), batch.values.end(), |
| 536 | [](const ExecValue& v) { return v.is_scalar(); })); |
| 537 | |
| 538 | ArrayData* output = out->array_data().get(); |
| 539 | |
| 540 | // At least one array, two or more arguments |
| 541 | std::vector<const ArraySpan*> arrays; |
| 542 | for (const auto& value : batch.values) { |
| 543 | if (!value.is_array()) continue; |
| 544 | arrays.push_back(&value.array); |
| 545 | } |
| 546 | |
| 547 | bool initialize_output = true; |
| 548 | if (scalar_count > 0) { |
| 549 | ARROW_ASSIGN_OR_RAISE(std::shared_ptr<Scalar> temp_scalar, |
| 550 | ExecScalar(batch, options, out->type()->GetSharedPtr())); |
| 551 | if (temp_scalar->is_valid) { |
| 552 | const auto value = UnboxScalar<OutType>::Unbox(*temp_scalar); |
| 553 | initialize_output = false; |
| 554 | OutValue* out = output->GetMutableValues<OutValue>(1); |
| 555 | std::fill(out, out + batch.length, value); |
| 556 | } else if (!options.skip_nulls) { |
| 557 | // Abort early |
| 558 | ARROW_ASSIGN_OR_RAISE(auto array, MakeArrayFromScalar(*temp_scalar, batch.length, |
| 559 | ctx->memory_pool())); |
| 560 | out->value = std::move(array->data()); |
| 561 | return Status::OK(); |
| 562 | } |
| 563 | } |
| 564 | |
| 565 | if (initialize_output) { |
| 566 | OutValue* out = output->GetMutableValues<OutValue>(1); |
| 567 | std::fill(out, out + batch.length, Op::template antiextreme<OutValue>()); |
| 568 | } |
| 569 | |
| 570 | // Precompute the validity buffer |
| 571 | if (options.skip_nulls && initialize_output) { |
| 572 | // OR together the validity buffers of all arrays |
| 573 | if (std::all_of(arrays.begin(), arrays.end(), |
| 574 | [](const ArraySpan* arr) { return arr->MayHaveNulls(); })) { |
| 575 | for (const ArraySpan* arr : arrays) { |
| 576 | if (!arr->MayHaveNulls()) continue; |
| 577 | if (!output->buffers[0]) { |
| 578 | ARROW_ASSIGN_OR_RAISE(output->buffers[0], ctx->AllocateBitmap(batch.length)); |
| 579 | ::arrow::internal::CopyBitmap(arr->buffers[0].data, arr->offset, batch.length, |
| 580 | output->buffers[0]->mutable_data(), |
| 581 | /*dest_offset=*/0); |
| 582 | } else { |
| 583 | ::arrow::internal::BitmapOr(output->buffers[0]->data(), /*left_offset=*/0, |
| 584 | arr->buffers[0].data, arr->offset, batch.length, |
| 585 | /*out_offset=*/0, |
| 586 | output->buffers[0]->mutable_data()); |
| 587 | } |
| 588 | } |
| 589 | } |
nothing calls this directly
no test coverage detected