This is an automated email from the ASF dual-hosted git repository.

paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 741826a  feat(r): Add conversion from integer type to `character()` 
(#345)
741826a is described below

commit 741826a2ad9a8fdfcd527a1df8af49711f0e77e7
Author: Dewey Dunnington <[email protected]>
AuthorDate: Tue Jan 2 09:09:58 2024 -0400

    feat(r): Add conversion from integer type to `character()` (#345)
    
    Closes #324.
---
 r/src/convert_array.c                 | 16 +++++++++++++---
 r/src/materialize_chr.h               | 29 +++++++++++++++++++++++++++++
 r/tests/testthat/test-convert-array.R | 35 ++++++++++++++++++++++++++++++-----
 3 files changed, 72 insertions(+), 8 deletions(-)

diff --git a/r/src/convert_array.c b/r/src/convert_array.c
index 375bfa0..ac5326a 100644
--- a/r/src/convert_array.c
+++ b/r/src/convert_array.c
@@ -108,16 +108,26 @@ static SEXP convert_array_chr(SEXP array_xptr, SEXP 
ptype_sexp) {
   }
 
   // If array_xptr is an extension, use default conversion
-  if (schema_view.extension_name.size_bytes > 0) {
+  int source_can_altrep;
+  switch (schema_view.type) {
+    case NANOARROW_TYPE_STRING:
+    case NANOARROW_TYPE_LARGE_STRING:
+      source_can_altrep = 1;
+      break;
+    default:
+      source_can_altrep = 0;
+  }
+
+  if (!source_can_altrep || schema_view.extension_name.size_bytes > 0) {
     // Default conversion requires a ptype: resolve it if not already specified
     if (ptype_sexp == R_NilValue) {
       ptype_sexp = 
PROTECT(nanoarrow_c_infer_ptype(array_xptr_get_schema(array_xptr)));
       SEXP default_result =
-          PROTECT(convert_array_default(array_xptr, VECTOR_TYPE_OTHER, 
ptype_sexp));
+          PROTECT(convert_array_default(array_xptr, VECTOR_TYPE_CHR, 
ptype_sexp));
       UNPROTECT(2);
       return default_result;
     } else {
-      return convert_array_default(array_xptr, VECTOR_TYPE_OTHER, ptype_sexp);
+      return convert_array_default(array_xptr, VECTOR_TYPE_CHR, ptype_sexp);
     }
   }
 
diff --git a/r/src/materialize_chr.h b/r/src/materialize_chr.h
index 2d57fdc..dfe9823 100644
--- a/r/src/materialize_chr.h
+++ b/r/src/materialize_chr.h
@@ -21,10 +21,17 @@
 #include <R.h>
 #include <Rinternals.h>
 
+#include <inttypes.h>
+#include <stdint.h>
+
 #include "materialize_common.h"
 #include "nanoarrow.h"
 
 static inline int nanoarrow_materialize_chr(struct RConverter* converter) {
+  if (converter->src.array_view->array->dictionary != NULL) {
+    return ENOTSUP;
+  }
+
   struct ArrayViewSlice* src = &converter->src;
   struct VectorSlice* dst = &converter->dst;
 
@@ -35,6 +42,28 @@ static inline int nanoarrow_materialize_chr(struct 
RConverter* converter) {
       }
       return NANOARROW_OK;
 
+    case NANOARROW_TYPE_INT8:
+    case NANOARROW_TYPE_UINT8:
+    case NANOARROW_TYPE_INT16:
+    case NANOARROW_TYPE_UINT16:
+    case NANOARROW_TYPE_INT32:
+    case NANOARROW_TYPE_UINT32:
+    case NANOARROW_TYPE_INT64: {
+      char buf[64];
+      for (R_xlen_t i = 0; i < dst->length; i++) {
+        if (ArrowArrayViewIsNull(src->array_view, src->offset + i)) {
+          SET_STRING_ELT(dst->vec_sexp, dst->offset + i, NA_STRING);
+        } else {
+          int n_chars =
+              snprintf(buf, sizeof(buf), "%" PRId64,
+                       ArrowArrayViewGetIntUnsafe(src->array_view, src->offset 
+ i));
+          SET_STRING_ELT(dst->vec_sexp, dst->offset + i,
+                         Rf_mkCharLenCE(buf, n_chars, CE_UTF8));
+        }
+      }
+      return NANOARROW_OK;
+    }
+
     case NANOARROW_TYPE_STRING:
     case NANOARROW_TYPE_LARGE_STRING:
       break;
diff --git a/r/tests/testthat/test-convert-array.R 
b/r/tests/testthat/test-convert-array.R
index 49265a8..5731ce1 100644
--- a/r/tests/testthat/test-convert-array.R
+++ b/r/tests/testthat/test-convert-array.R
@@ -364,6 +364,31 @@ test_that("convert to vector works for valid integer()", {
   )
 })
 
+test_that("convert to works for integer() -> character()", {
+  skip_if_not_installed("arrow")
+
+  arrow_int_types <- list(
+    int8 = arrow::int8(),
+    uint8 = arrow::uint8(),
+    int16 = arrow::int16(),
+    uint16 = arrow::uint16(),
+    int32 = arrow::int32(),
+    uint32 = arrow::uint32(),
+    int64 = arrow::int64()
+  )
+
+  ints <- c(NA, 0:10)
+  for (nm in names(arrow_int_types)) {
+    expect_identical(
+      convert_array(
+        as_nanoarrow_array(ints, schema = arrow_int_types[[!!nm]]),
+        character()
+      ),
+      as.character(ints)
+    )
+  }
+})
+
 test_that("convert to vector works for null -> logical()", {
   array <- nanoarrow_array_init(na_na())
   array$length <- 10
@@ -636,8 +661,8 @@ test_that("convert to vector works for character()", {
 
   # check an array that we can't convert
   expect_error(
-    convert_array(as_nanoarrow_array(1:5), character()),
-    "Can't convert array <int32> to R vector of type character"
+    convert_array(as_nanoarrow_array(1:5), list()),
+    "Can't convert array <int32> to R vector of type list"
   )
 })
 
@@ -788,7 +813,7 @@ test_that("convert to vector works for list -> 
vctrs::list_of", {
 
   # With bad ptype
   expect_error(
-    convert_array(array_list, vctrs::list_of(.ptype = character())),
+    convert_array(array_list, vctrs::list_of(.ptype = list())),
     "Can't convert `item`"
   )
 
@@ -825,7 +850,7 @@ test_that("convert to vector works for large_list -> 
vctrs::list_of", {
 
   # With bad ptype
   expect_error(
-    convert_array(array_list, vctrs::list_of(.ptype = character())),
+    convert_array(array_list, vctrs::list_of(.ptype = list())),
     "Can't convert `item`"
   )
 })
@@ -854,7 +879,7 @@ test_that("convert to vector works for fixed_size_list -> 
vctrs::list_of", {
 
   # With bad ptype
   expect_error(
-    convert_array(array_list, vctrs::list_of(.ptype = character())),
+    convert_array(array_list, vctrs::list_of(.ptype = list())),
     "Can't convert `item`"
   )
 })

Reply via email to