MCPcopy Create free account
hub / github.com/apache/arrow / CallRScalarUDF

Function CallRScalarUDF

r/src/compute.cpp:669–734  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

667}
668
669arrow::Status CallRScalarUDF(arrow::compute::KernelContext* context,
670 const arrow::compute::ExecSpan& span,
671 arrow::compute::ExecResult* result) {
672 if (result->is_array_span()) {
673 return arrow::Status::NotImplemented("ArraySpan result from R scalar UDF");
674 }
675
676 return SafeCallIntoRVoid(
677 [&]() {
678 auto kernel =
679 reinterpret_cast<const arrow::compute::ScalarKernel*>(context->kernel());
680 auto state = std::dynamic_pointer_cast<RScalarUDFKernelState>(kernel->data);
681
682 cpp11::writable::list args_sexp(span.num_values());
683
684 for (int i = 0; i < span.num_values(); i++) {
685 const arrow::compute::ExecValue& exec_val = span[i];
686 if (exec_val.is_array()) {
687 args_sexp[i] = cpp11::to_r6<arrow::Array>(exec_val.array.ToArray());
688 } else if (exec_val.is_scalar()) {
689 args_sexp[i] = cpp11::to_r6<arrow::Scalar>(exec_val.scalar->GetSharedPtr());
690 }
691 }
692
693 cpp11::sexp batch_length_sexp = cpp11::as_sexp(static_cast<double>(span.length));
694
695 std::shared_ptr<arrow::DataType> output_type = result->type()->GetSharedPtr();
696 cpp11::sexp output_type_sexp = cpp11::to_r6<arrow::DataType>(output_type);
697 cpp11::writable::list udf_context = {batch_length_sexp, output_type_sexp};
698 udf_context.names() = {"batch_length", "output_type"};
699
700 cpp11::sexp func_result_sexp =
701 cpp11::function(state->exec_func_)(udf_context, args_sexp);
702
703 if (Rf_inherits(func_result_sexp, "Array")) {
704 auto array = cpp11::as_cpp<std::shared_ptr<arrow::Array>>(func_result_sexp);
705
706 // Error for an Array result of the wrong type
707 if (!result->type()->Equals(array->type())) {
708 return cpp11::stop(
709 "Expected return Array or Scalar with type '%s' from user-defined "
710 "function but got Array with type '%s'",
711 result->type()->ToString().c_str(), array->type()->ToString().c_str());
712 }
713
714 result->value = std::move(array->data());
715 } else if (Rf_inherits(func_result_sexp, "Scalar")) {
716 auto scalar = cpp11::as_cpp<std::shared_ptr<arrow::Scalar>>(func_result_sexp);
717
718 // handle a Scalar result of the wrong type
719 if (!result->type()->Equals(scalar->type)) {
720 return cpp11::stop(
721 "Expected return Array or Scalar with type '%s' from user-defined "
722 "function but got Scalar with type '%s'",
723 result->type()->ToString().c_str(), scalar->type->ToString().c_str());
724 }
725
726 auto array = ValueOrStop(

Callers

nothing calls this directly

Calls 15

SafeCallIntoRVoidFunction · 0.85
as_sexpFunction · 0.85
stopFunction · 0.85
ValueOrStopFunction · 0.85
is_arrayMethod · 0.80
is_scalarMethod · 0.80
MakeArrayFromScalarFunction · 0.70
NotImplementedFunction · 0.50
num_valuesMethod · 0.45
ToArrayMethod · 0.45
typeMethod · 0.45
EqualsMethod · 0.45

Tested by

no test coverage detected