| 221 | } |
| 222 | |
| 223 | Result<Datum> Execute(const std::vector<Datum>& args, int64_t passed_length) override { |
| 224 | util::tracing::Span span; |
| 225 | |
| 226 | auto func_kind = func.kind(); |
| 227 | const auto& func_name = func.name(); |
| 228 | START_COMPUTE_SPAN(span, func_name, |
| 229 | {{"function.name", func_name}, |
| 230 | {"function.options", options ? options->ToString() : "<NULLPTR>"}, |
| 231 | {"function.kind", func_kind}}); |
| 232 | |
| 233 | if (in_types.size() != args.size()) { |
| 234 | return Status::Invalid("Execution of '", func_name, "' expected ", in_types.size(), |
| 235 | " arguments but got ", args.size()); |
| 236 | } |
| 237 | if (!inited) { |
| 238 | ARROW_RETURN_NOT_OK(Init(NULLPTR, default_exec_context())); |
| 239 | } |
| 240 | ExecContext* ctx = kernel_ctx.exec_context(); |
| 241 | // Cast arguments if necessary |
| 242 | std::vector<Datum> args_with_cast(args.size()); |
| 243 | for (size_t i = 0; i != args.size(); ++i) { |
| 244 | const auto& in_type = in_types[i]; |
| 245 | auto arg = args[i]; |
| 246 | if (in_type != args[i].type()) { |
| 247 | ARROW_ASSIGN_OR_RAISE(arg, Cast(args[i], CastOptions::Safe(in_type), ctx)); |
| 248 | } |
| 249 | args_with_cast[i] = std::move(arg); |
| 250 | } |
| 251 | |
| 252 | detail::DatumAccumulator listener; |
| 253 | |
| 254 | ExecBatch input(std::move(args_with_cast), /*length=*/0); |
| 255 | if (input.num_values() == 0) { |
| 256 | if (passed_length != -1) { |
| 257 | input.length = passed_length; |
| 258 | } |
| 259 | } else { |
| 260 | bool all_same_length = false; |
| 261 | int64_t inferred_length = detail::InferBatchLength(input.values, &all_same_length); |
| 262 | input.length = inferred_length; |
| 263 | if (func_kind == Function::SCALAR) { |
| 264 | if (passed_length != -1 && passed_length != inferred_length) { |
| 265 | return Status::Invalid( |
| 266 | "Passed batch length for execution did not match actual" |
| 267 | " length of values for execution of scalar function '", |
| 268 | func_name, "'"); |
| 269 | } |
| 270 | } else if (func_kind == Function::VECTOR) { |
| 271 | auto vkernel = static_cast<const VectorKernel*>(kernel); |
| 272 | if (!all_same_length && vkernel->can_execute_chunkwise) { |
| 273 | return Status::Invalid("Arguments for execution of vector kernel function '", |
| 274 | func_name, "' must all be the same length"); |
| 275 | } |
| 276 | } |
| 277 | } |
| 278 | RETURN_NOT_OK(executor->Execute(input, &listener)); |
| 279 | const auto out = executor->WrapResults(input.values, listener.values()); |
| 280 | #ifndef NDEBUG |
nothing calls this directly
no test coverage detected