This is not run in parallel by default, so it's safe to call into R here; however, it is not safe to throw an exception here because the caller might be waiting for other conversions to finish in the background. To avoid this, use StatusUnwindProtect() to communicate the error back to ValueOrStop() (which reconstructs the exception and re-throws it).
| 276 | // avoid this, use StatusUnwindProtect() to communicate the error back to |
| 277 | // ValueOrStop() (which reconstructs the exception and re-throws it). |
| 278 | Status Extend(SEXP values, int64_t size, int64_t offset = 0) { |
| 279 | try { |
| 280 | cpp11::sexp as_array_result = cpp11::package("arrow")["as_arrow_array"]( |
| 281 | values, cpp11::named_arg("type") = cpp11::as_sexp(options().type), |
| 282 | cpp11::named_arg("from_vec_to_array") = cpp11::as_sexp<bool>(true)); |
| 283 | |
| 284 | // Check that the R method returned an Array |
| 285 | if (!Rf_inherits(as_array_result, "Array")) { |
| 286 | return Status::Invalid("as_arrow_array() did not return object of type Array"); |
| 287 | } |
| 288 | |
| 289 | auto array = cpp11::as_cpp<std::shared_ptr<arrow::Array>>(as_array_result); |
| 290 | |
| 291 | // We need the type to be equal because the schema has already been finalized |
| 292 | if (!array->type()->Equals(options().type)) { |
| 293 | return Status::Invalid( |
| 294 | "as_arrow_array() returned an Array with an incorrect type"); |
| 295 | } |
| 296 | |
| 297 | arrays_.push_back(std::move(array)); |
| 298 | return Status::OK(); |
| 299 | } catch (cpp11::unwind_exception& e) { |
| 300 | return StatusUnwindProtect(e.token, "calling as_arrow_array()"); |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | // This is sometimes run in parallel so we can't call into R |
| 305 | Result<std::shared_ptr<ChunkedArray>> ToChunkedArray() { |