From 63ff062ce005498480b57c9e43cc591dfe28b943 Mon Sep 17 00:00:00 2001 From: Nic Crane Date: Mon, 12 Sep 2022 11:09:44 +0100 Subject: [PATCH] ARROW-17639: [R] infer_type() fails for lists where the first element is NULL (#14062) This PR updates the internals of type inference on lists; instead of looking at the type of the first element, we instead iterate through all elements until we find a non-null element. Authored-by: Nic Crane Signed-off-by: Nic Crane --- r/src/type_infer.cpp | 11 +++++++++-- r/tests/testthat/test-type.R | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/r/src/type_infer.cpp b/r/src/type_infer.cpp index 616be0467f940..e30d0e1288717 100644 --- a/r/src/type_infer.cpp +++ b/r/src/type_infer.cpp @@ -165,8 +165,13 @@ std::shared_ptr InferArrowTypeFromVector(SEXP x) { cpp11::stop( "Requires at least one element to infer the values' type of a list vector"); } - - ptype = VECTOR_ELT(x, 0); + // Iterate through the vector until we get a non-null result + for (R_xlen_t i = 0; i < XLENGTH(x); i++) { + ptype = VECTOR_ELT(x, i); + if (!Rf_isNull(ptype)) { + break; + } + } } return arrow::list(InferArrowType(ptype)); @@ -198,6 +203,8 @@ std::shared_ptr InferArrowType(SEXP x) { return InferArrowTypeFromVector(x); case VECSXP: return InferArrowTypeFromVector(x); + case NILSXP: + return null(); default: cpp11::stop("Cannot infer type from vector"); } diff --git a/r/tests/testthat/test-type.R b/r/tests/testthat/test-type.R index d7c6da0792cf7..14f0ea7a8d580 100644 --- a/r/tests/testthat/test-type.R +++ b/r/tests/testthat/test-type.R @@ -293,3 +293,19 @@ test_that("type() is deprecated", { ) expect_equal(a_type, a$type) }) + +test_that("infer_type() infers type for lists starting with NULL - ARROW-17639", { + null_start_list <- list(NULL, c(2, 3), c(4, 5)) + + expect_equal( + infer_type(null_start_list), + list_of(float64()) + ) + + totally_null_list <- list(NULL, NULL, NULL) + + expect_equal( + infer_type(totally_null_list), + list_of(null()) + ) +})