| 463 | // For "first" and "last" functions: override finalize and return the actual value |
| 464 | template <FirstOrLast first_or_last> |
| 465 | void AddFirstOrLastAggKernel(ScalarAggregateFunction* func, |
| 466 | ScalarAggregateFunction* first_last_func) { |
| 467 | auto sig = KernelSignature::Make({InputType::Any()}, FirstType); |
| 468 | auto init = [first_last_func]( |
| 469 | KernelContext* ctx, |
| 470 | const KernelInitArgs& args) -> Result<std::unique_ptr<KernelState>> { |
| 471 | ARROW_ASSIGN_OR_RAISE(auto kernel, first_last_func->DispatchExact(args.inputs)); |
| 472 | KernelInitArgs new_args{kernel, args.inputs, args.options}; |
| 473 | return kernel->init(ctx, new_args); |
| 474 | }; |
| 475 | |
| 476 | auto finalize = [](KernelContext* ctx, Datum* out) -> Status { |
| 477 | Datum temp; |
| 478 | RETURN_NOT_OK(checked_cast<ScalarAggregator*>(ctx->state())->Finalize(ctx, &temp)); |
| 479 | const auto& result = temp.scalar_as<StructScalar>(); |
| 480 | DCHECK(result.is_valid); |
| 481 | *out = result.value[static_cast<uint8_t>(first_or_last)]; |
| 482 | return Status::OK(); |
| 483 | }; |
| 484 | |
| 485 | AddAggKernel(std::move(sig), std::move(init), std::move(finalize), func, |
| 486 | SimdLevel::NONE, /*ordered=*/true); |
| 487 | } |
| 488 | |
| 489 | // ---------------------------------------------------------------------- |
| 490 | // MinMax implementation |