paleolimbot commented on issue #36274:
URL: https://github.com/apache/arrow/issues/36274#issuecomment-1666930992
Sorry for the delay here...I was taking some time away from the keyboard.
It seems like you are interested in the reverse problem...the reprex above
demos taking an Arrow Table from R and doing a computation in C++ that doesn't
return a Table. Below I've tweaked it a bit to illustrate the reverse process
(i.e., if you have a Table in Arrow C++, how to communicate it back to the
Arrow R package to get a Table object):
``` r
# These are specific to my system (homebrew on MacOS M1)
arrow_include <- "-I/opt/homebrew/Cellar/apache-arrow/12.0.1/include"
arrow_libs <- "-L/opt/homebrew/Cellar/apache-arrow/12.0.1/lib -larrow"
Sys.setenv("PKG_CXXFLAGS" = arrow_include)
Sys.setenv("PKG_LIBS" = arrow_libs)
cpp11::cpp_source(code = '
#include <arrow/table.h>
#include <arrow/c/bridge.h>
#include <cpp11.hpp>
using namespace arrow;
// Version that returns a Result<> so we can use Arrow C++-style error
handling
// macros
Result<std::shared_ptr<Table>> array_stream_to_table(SEXP array_stream_xptr)
{
auto array_stream = reinterpret_cast<struct ArrowArrayStream*>(
R_ExternalPtrAddr(array_stream_xptr));
ARROW_ASSIGN_OR_RAISE(auto reader, ImportRecordBatchReader(array_stream))
return reader->ToTable();
}
Status table_to_array_stream(const std::shared_ptr<Table>& table, SEXP
array_stream_xptr) {
auto reader = std::make_shared<arrow::TableBatchReader>(table);
auto array_stream = reinterpret_cast<struct ArrowArrayStream*>(
R_ExternalPtrAddr(array_stream_xptr));
return ExportRecordBatchReader(reader, array_stream);
}
// Version that uses cpp11 error handling
[[cpp11::register]]
void slice_table(SEXP array_stream_xptr_in, int offset, int length, SEXP
array_stream_xptr_out) {
Result<std::shared_ptr<Table>> maybe_input =
array_stream_to_table(array_stream_xptr_in);
if (!maybe_input.ok()) {
cpp11::stop("Arrow C++ error: %s",
maybe_input.status().ToString().c_str());
}
std::shared_ptr<Table> input = *maybe_input;
std::shared_ptr<Table> output = input->Slice(offset, length);
Status status = table_to_array_stream(output, array_stream_xptr_out);
if (!status.ok()) {
cpp11::stop("Arrow C++ error: %s", status.ToString().c_str());
}
}
', cxx_std = "CXX17")
library(arrow, warn.conflicts = FALSE)
library(nanoarrow)
# Prepare input
tab <- arrow_table(x = 1:10)
array_stream_in = as_nanoarrow_array_stream(tab)
array_stream_out = nanoarrow_allocate_array_stream()
# Call C++ function
slice_table(array_stream_in, 2, 7, array_stream_out)
# convert output to Table
as_arrow_table(as_record_batch_reader(array_stream_out))
#> Table
#> 7 rows x 1 columns
#> $x <int32>
```
<sup>Created on 2023-08-06 with [reprex
v2.0.2](https://reprex.tidyverse.org)</sup>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]