From 279bc78a79f6220e3d87ada89edb0fdcfe9d204b Mon Sep 17 00:00:00 2001 From: Romain Francois Date: Wed, 8 Dec 2021 14:27:57 +0100 Subject: [PATCH 1/2] RPrimitiveConverter::Extend() --- r/src/r_to_arrow.cpp | 65 +++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/r/src/r_to_arrow.cpp b/r/src/r_to_arrow.cpp index 489cab80f60..8fd224836b3 100644 --- a/r/src/r_to_arrow.cpp +++ b/r/src/r_to_arrow.cpp @@ -583,6 +583,23 @@ int64_t get_TimeUnit_multiplier(TimeUnit::type unit) { } } +Result get_difftime_unit_multiplier(SEXP x) { + std::string unit(CHAR(STRING_ELT(Rf_getAttrib(x, symbols::units), 0))); + if (unit == "secs") { + return 1; + } else if (unit == "mins") { + return 60; + } else if (unit == "hours") { + return 3600; + } else if (unit == "days") { + return 86400; + } else if (unit == "weeks") { + return 604800; + } else { + return Status::Invalid("unknown difftime unit"); + } +} + template class RPrimitiveConverter::value>> : public PrimitiveConverter { @@ -595,21 +612,7 @@ class RPrimitiveConverter::value>> } // multiplier to get the number of seconds from the value stored in the R vector - int difftime_multiplier; - std::string unit(CHAR(STRING_ELT(Rf_getAttrib(x, symbols::units), 0))); - if (unit == "secs") { - difftime_multiplier = 1; - } else if (unit == "mins") { - difftime_multiplier = 60; - } else if (unit == "hours") { - difftime_multiplier = 3600; - } else if (unit == "days") { - difftime_multiplier = 86400; - } else if (unit == "weeks") { - difftime_multiplier = 604800; - } else { - return Status::Invalid("unknown difftime unit"); - } + ARROW_ASSIGN_OR_RAISE(int difftime_multiplier, get_difftime_unit_multiplier(x)); // then multiply the seconds by this to match the time unit auto multiplier = @@ -825,7 +828,37 @@ class RPrimitiveConverter::value>> : public PrimitiveConverter { public: Status Extend(SEXP x, int64_t size, int64_t offset = 0) override { - // TODO: look in lubridate + auto rtype = GetVectorType(x); + + // only handle R objects + if (rtype == DURATION) { + RETURN_NOT_OK(this->Reserve(size - offset)); + + ARROW_ASSIGN_OR_RAISE(int difftime_multiplier, get_difftime_unit_multiplier(x)); + + int64_t multiplier = get_TimeUnit_multiplier(this->primitive_type_->unit()) * difftime_multiplier; + + auto append_value = [this, multiplier](double value) { + auto converted = static_cast(value * multiplier); + this->primitive_builder_->UnsafeAppend(converted); + return Status::OK(); + }; + auto append_null = [this]() { + this->primitive_builder_->UnsafeAppendNull(); + return Status::OK(); + }; + + if (ALTREP(x)) { + return VisitVector(RVectorIterator_ALTREP(x, offset), size, append_null, + append_value); + } else { + return VisitVector(RVectorIterator(x, offset), size, append_null, + append_value); + } + + return Status::OK(); + } + return Status::NotImplemented("Extend"); } }; From bcb1ce9ca0d8a7792e4d61f4e35f1d6fd7967955 Mon Sep 17 00:00:00 2001 From: Romain Francois Date: Fri, 10 Dec 2021 11:20:12 +0100 Subject: [PATCH 2/2] comment --- r/src/r_to_arrow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/r/src/r_to_arrow.cpp b/r/src/r_to_arrow.cpp index 8fd224836b3..51483cdf861 100644 --- a/r/src/r_to_arrow.cpp +++ b/r/src/r_to_arrow.cpp @@ -607,6 +607,7 @@ class RPrimitiveConverter::value>> Status Extend(SEXP x, int64_t size, int64_t offset = 0) override { RETURN_NOT_OK(this->Reserve(size - offset)); auto rtype = GetVectorType(x); + // This probably also not accept duration if (rtype != TIME && rtype != DURATION) { return Status::Invalid("Invalid conversion to time"); }