You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by we...@apache.org on 2018/11/14 13:40:19 UTC

[arrow] branch master updated: ARROW-3614: [R] Support for timestamps

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

wesm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new dc5df8f  ARROW-3614: [R] Support for timestamps
dc5df8f is described below

commit dc5df8fdb69570ef813413e13bc788f009661f81
Author: Javier Luraschi <ja...@hotmail.com>
AuthorDate: Wed Nov 14 08:39:51 2018 -0500

    ARROW-3614: [R] Support for timestamps
    
    Support for `TimeStamp` in R bindings: https://issues.apache.org/jira/browse/ARROW-3614
    
    CC: @romainfrancois
    
    Author: Javier Luraschi <ja...@hotmail.com>
    
    Closes #2887 from javierluraschi/bugfix/timestamp and squashes the following commits:
    
    21b070ad8 <Javier Luraschi> fix decimal type R binding
    2e7293f82 <Javier Luraschi> update tests to validate default unit is micro for timestamps
    bc0aa372f <Javier Luraschi> fix lint warnings
    9bfd00f44 <Javier Luraschi> ARROW-3702:  map posixct to arrow timestamps
    3b8b5fe22 <Javier Luraschi> ARROW-3614:  Support for timestamps
---
 r/src/array.cpp                      | 39 +++++++++++++++++++++++++++---------
 r/tests/testthat/test-Array.R        |  6 ++++--
 r/tests/testthat/test-chunkedarray.R |  3 ++-
 3 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/r/src/array.cpp b/r/src/array.cpp
index a83929c..3af4934 100644
--- a/r/src/array.cpp
+++ b/r/src/array.cpp
@@ -297,8 +297,10 @@ inline int64_t time_cast<double>(double value) {
   return static_cast<int64_t>(value * 1000);
 }
 
+inline int64_t timestamp_cast(int value) { return static_cast<int64_t>(value) * 1000000; }
+
 template <int RTYPE>
-std::shared_ptr<Array> Date64Array_From_POSIXct(SEXP x) {
+std::shared_ptr<Array> TimeStampArray_From_POSIXct(SEXP x) {
   Rcpp::Vector<RTYPE> vec(x);
   auto p_vec = vec.begin();
   auto n = vec.size();
@@ -313,7 +315,7 @@ std::shared_ptr<Array> Date64Array_From_POSIXct(SEXP x) {
   R_xlen_t i = 0;
   for (; i < n; i++, ++p_vec, ++p_values) {
     if (Rcpp::Vector<RTYPE>::is_na(*p_vec)) break;
-    *p_values = time_cast(*p_vec);
+    *p_values = timestamp_cast(*p_vec);
   }
   if (i < n) {
     std::shared_ptr<Buffer> null_buffer;
@@ -332,7 +334,7 @@ std::shared_ptr<Array> Date64Array_From_POSIXct(SEXP x) {
         null_count++;
       } else {
         bitmap_writer.Set();
-        *p_values = time_cast(*p_vec);
+        *p_values = timestamp_cast(*p_vec);
       }
     }
 
@@ -340,10 +342,10 @@ std::shared_ptr<Array> Date64Array_From_POSIXct(SEXP x) {
     buffers[0] = std::move(null_buffer);
   }
 
-  auto data = ArrayData::Make(std::make_shared<Date64Type>(), n, std::move(buffers),
-                              null_count, 0);
+  auto data = ArrayData::Make(std::make_shared<TimestampType>(TimeUnit::MICRO, "GMT"), n,
+                              std::move(buffers), null_count, 0);
 
-  return std::make_shared<Date64Array>(data);
+  return std::make_shared<TimestampArray>(data);
 }
 
 std::shared_ptr<arrow::Array> Int64Array(SEXP x) {
@@ -472,7 +474,7 @@ std::shared_ptr<arrow::Array> Array__from_vector(SEXP x) {
         return arrow::r::SimpleArray<INTSXP, arrow::Date32Type>(x);
       }
       if (Rf_inherits(x, "POSIXct")) {
-        return arrow::r::Date64Array_From_POSIXct<INTSXP>(x);
+        return arrow::r::TimeStampArray_From_POSIXct<INTSXP>(x);
       }
       return arrow::r::SimpleArray<INTSXP, arrow::Int32Type>(x);
     case REALSXP:
@@ -480,7 +482,7 @@ std::shared_ptr<arrow::Array> Array__from_vector(SEXP x) {
         return arrow::r::SimpleArray<INTSXP, arrow::Date32Type>(x);
       }
       if (Rf_inherits(x, "POSIXct")) {
-        return arrow::r::Date64Array_From_POSIXct<REALSXP>(x);
+        return arrow::r::TimeStampArray_From_POSIXct<REALSXP>(x);
       }
       if (Rf_inherits(x, "integer64")) {
         return arrow::r::Int64Array(x);
@@ -748,6 +750,11 @@ struct Converter_Promotion {
 
 template <typename value_type>
 struct Converter_Time {
+  Converter_Time(int64_t n, int32_t multiplier, CharacterVector classes)
+      : data(no_init(n)), multiplier_(multiplier) {
+    data.attr("class") = classes;
+  }
+
   Converter_Time(int64_t n, int32_t multiplier)
       : data(no_init(n)), multiplier_(multiplier) {
     data.attr("class") = CharacterVector::create("hms", "difftime");
@@ -781,6 +788,13 @@ struct Converter_Time {
   int32_t multiplier_;
 };
 
+template <typename value_type>
+struct Converter_TimeStamp : Converter_Time<value_type> {
+  Converter_TimeStamp(int64_t n, int32_t multiplier)
+      : Converter_Time<value_type>(n, multiplier,
+                                   CharacterVector::create("POSIXct", "POSIXt")) {}
+};
+
 struct Converter_Int64 {
   Converter_Int64(R_xlen_t n) : data(no_init(n)) { data.attr("class") = "integer64"; }
 
@@ -952,10 +966,17 @@ SEXP ArrayVector__as_vector(int64_t n, const ArrayVector& arrays) {
               ? 1000000
               : 1000000000);
 
+    case Type::TIMESTAMP:
+      return ArrayVector_To_Vector<Converter_TimeStamp<int64_t>>(
+          n, arrays,
+          static_cast<TimeType*>(arrays[0]->type().get())->unit() == TimeUnit::MICRO
+              ? 1000000
+              : 1000000000);
+
     case Type::INT64:
       return ArrayVector_To_Vector<Converter_Int64>(n, arrays);
     case Type::DECIMAL:
-      ArrayVector_To_Vector<Converter_Decimal>(n, arrays);
+      return ArrayVector_To_Vector<Converter_Decimal>(n, arrays);
 
     default:
       break;
diff --git a/r/tests/testthat/test-Array.R b/r/tests/testthat/test-Array.R
index 717f89d..d06f88f 100644
--- a/r/tests/testthat/test-Array.R
+++ b/r/tests/testthat/test-Array.R
@@ -230,13 +230,15 @@ test_that("array supports Date (ARROW-3340)", {
 test_that("array supports POSIXct (ARROW-3340)", {
   times <- lubridate::ymd_hms("2018-10-07 19:04:05") + 1:10
   a <- array(times)
-  expect_equal(a$type(), date64())
+  expect_equal(a$type()$name(), "timestamp")
+  expect_equal(a$type()$unit(), unclass(TimeUnit$MICRO))
   expect_equal(a$length(), 10L)
   expect_equal(as.numeric(a$as_vector()), as.numeric(times))
 
   times[5] <- NA
   a <- array(times)
-  expect_equal(a$type(), date32())
+  expect_equal(a$type()$name(), "timestamp")
+  expect_equal(a$type()$unit(), unclass(TimeUnit$MICRO))
   expect_equal(a$length(), 10L)
   expect_equal(as.numeric(a$as_vector()), as.numeric(times))
   expect_true(a$IsNull(4))
diff --git a/r/tests/testthat/test-chunkedarray.R b/r/tests/testthat/test-chunkedarray.R
index 4c41f8a..088367a 100644
--- a/r/tests/testthat/test-chunkedarray.R
+++ b/r/tests/testthat/test-chunkedarray.R
@@ -138,7 +138,8 @@ test_that("ChunkedArray supports dates (ARROW-3716)", {
 test_that("ChunkedArray supports POSIXct (ARROW-3716)", {
   times <- lubridate::ymd_hms("2018-10-07 19:04:05") + 1:10
   a <- chunked_array(times, times)
-  expect_equal(a$type(), date64())
+  expect_equal(a$type()$name(), "timestamp")
+  expect_equal(a$type()$unit(), unclass(TimeUnit$MICRO))
   expect_equal(a$length(), 20L)
   expect_equal(as.numeric(a$as_vector()), as.numeric(c(times, times)))
 })