diff --git a/r/src/array_to_vector.cpp b/r/src/array_to_vector.cpp index f790ab87da6..f0a7af8f29c 100644 --- a/r/src/array_to_vector.cpp +++ b/r/src/array_to_vector.cpp @@ -960,6 +960,17 @@ bool ArraysCanFitInteger(ArrayVector arrays) { return all_can_fit; } +bool GetBoolOption(const std::string& name, bool default_) { + SEXP getOption = Rf_install("getOption"); + cpp11::sexp call = Rf_lang2(getOption, Rf_mkString(name.c_str())); + cpp11::sexp res = Rf_eval(call, R_BaseEnv); + if (TYPEOF(res) == LGLSXP) { + return LOGICAL(res)[0] == TRUE; + } else { + return default_; + } +} + std::shared_ptr Converter::Make(const std::shared_ptr& type, ArrayVector arrays) { if (arrays.empty()) { @@ -1068,8 +1079,8 @@ std::shared_ptr Converter::Make(const std::shared_ptr& type return std::make_shared>(std::move(arrays)); case Type::INT64: - // Prefer integer if it fits - if (ArraysCanFitInteger(arrays)) { + // Prefer integer if it fits, unless option arrow.int64_downcast is `false` + if (GetBoolOption("arrow.int64_downcast", true) && ArraysCanFitInteger(arrays)) { return std::make_shared>( std::move(arrays)); } else { diff --git a/r/src/arrow_cpp11.h b/r/src/arrow_cpp11.h index 1b69468b3bf..859b0491cd0 100644 --- a/r/src/arrow_cpp11.h +++ b/r/src/arrow_cpp11.h @@ -292,6 +292,8 @@ std::vector from_r_list(cpp11::list args) { return vec; } +bool GetBoolOption(const std::string& name, bool default_); + } // namespace r } // namespace arrow diff --git a/r/tests/testthat/test-Array.R b/r/tests/testthat/test-Array.R index d708cb9676f..59c6dd9866a 100644 --- a/r/tests/testthat/test-Array.R +++ b/r/tests/testthat/test-Array.R @@ -749,3 +749,17 @@ test_that("Array$ApproxEquals", { expect_true(a$ApproxEquals(b)) expect_false(a$ApproxEquals(vec)) }) + +test_that("auto int64 conversion to int can be disabled (ARROW-10093)", { + op <- options(arrow.int64_downcast = FALSE); on.exit(options(op)) + + a <- Array$create(1:10, int64()) + expect_true(inherits(a$as_vector(), "integer64")) + + batch <- RecordBatch$create(x = a) + expect_true(inherits(as.data.frame(batch)$x, "integer64")) + + tab <- Table$create(x = a) + expect_true(inherits(as.data.frame(batch)$x, "integer64")) +}) +