[[arrow::export]]
| 1453 | |
| 1454 | // [[arrow::export]] |
| 1455 | std::shared_ptr<arrow::Table> Table__from_dots(SEXP lst, SEXP schema_sxp, |
| 1456 | bool use_threads) { |
| 1457 | bool infer_schema = !Rf_inherits(schema_sxp, "Schema"); |
| 1458 | |
| 1459 | int num_fields; |
| 1460 | StopIfNotOk(arrow::r::count_fields(lst, &num_fields)); |
| 1461 | |
| 1462 | // schema + metadata |
| 1463 | std::shared_ptr<arrow::Schema> schema; |
| 1464 | StopIfNotOk(arrow::r::InferSchemaFromDots(lst, schema_sxp, num_fields, schema)); |
| 1465 | StopIfNotOk(arrow::r::AddMetadataFromDots(lst, num_fields, schema)); |
| 1466 | |
| 1467 | if (!infer_schema && schema->num_fields() != num_fields) { |
| 1468 | cpp11::stop("incompatible. schema has %d fields, and %d columns are supplied", |
| 1469 | schema->num_fields(), num_fields); |
| 1470 | } |
| 1471 | |
| 1472 | // table |
| 1473 | std::vector<std::shared_ptr<arrow::ChunkedArray>> columns(num_fields); |
| 1474 | |
| 1475 | if (!infer_schema) { |
| 1476 | auto check_name = [&](int j, SEXP, cpp11::r_string name) { |
| 1477 | std::string cpp_name(name); |
| 1478 | if (schema->field(j)->name() != cpp_name) { |
| 1479 | cpp11::stop("field at index %d has name '%s' != '%s'", j + 1, |
| 1480 | schema->field(j)->name().c_str(), cpp_name.c_str()); |
| 1481 | } |
| 1482 | }; |
| 1483 | arrow::r::TraverseDots(lst, num_fields, check_name); |
| 1484 | } |
| 1485 | |
| 1486 | // must be careful to avoid R stop() until the tasks |
| 1487 | // are finished, i.e. after tasks.Finish() |
| 1488 | arrow::r::RTasks tasks(use_threads); |
| 1489 | |
| 1490 | arrow::Status status = arrow::Status::OK(); |
| 1491 | |
| 1492 | auto flatten_lst = arrow::r::FlattenDots(lst, num_fields); |
| 1493 | std::vector<std::unique_ptr<arrow::r::RConverter>> converters(num_fields); |
| 1494 | |
| 1495 | // init converters |
| 1496 | for (int j = 0; j < num_fields && status.ok(); j++) { |
| 1497 | SEXP x = flatten_lst[j]; |
| 1498 | |
| 1499 | if (Rf_inherits(x, "ChunkedArray")) { |
| 1500 | columns[j] = cpp11::as_cpp<std::shared_ptr<arrow::ChunkedArray>>(x); |
| 1501 | } else if (Rf_inherits(x, "Array")) { |
| 1502 | columns[j] = std::make_shared<arrow::ChunkedArray>( |
| 1503 | cpp11::as_cpp<std::shared_ptr<arrow::Array>>(x)); |
| 1504 | } else if (arrow::r::altrep::is_unmaterialized_arrow_altrep(x)) { |
| 1505 | columns[j] = arrow::r::altrep::vec_to_arrow_altrep_bypass(x); |
| 1506 | } else { |
| 1507 | arrow::r::RConversionOptions options; |
| 1508 | options.strict = !infer_schema; |
| 1509 | options.type = schema->field(j)->type(); |
| 1510 | options.size = arrow::r::vec_size(x); |
| 1511 | |
| 1512 | // If we can handle this in C++ we do so; otherwise we use the |
no test coverage detected