ARROW-420: Align DATE type with Java implementation

Change-Id: I2dc9e848f5bed9d717477792459dde6ea839b341
This commit is contained in:
Uwe L. Korn committed 2016-12-13 19:08:25 +01:00
1 parent 7e93075cd4
commit 6fca4da8aa
8 files changed
+75 -18

No files matched your search

+1
View File
@@ -148,6 +148,7 @@ template class NumericArray<Int16Type>;
template class NumericArray<Int32Type>;
template class NumericArray<Int64Type>;
template class NumericArray<TimestampType>;
template class NumericArray<DateType>;
template class NumericArray<HalfFloatType>;
template class NumericArray<FloatType>;
template class NumericArray<DoubleType>;
+1
View File
@@ -468,6 +468,7 @@ extern template class ARROW_EXPORT NumericArray<HalfFloatType>;
extern template class ARROW_EXPORT NumericArray<FloatType>;
extern template class ARROW_EXPORT NumericArray<DoubleType>;
extern template class ARROW_EXPORT NumericArray<TimestampType>;
extern template class ARROW_EXPORT NumericArray<DateType>;
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
+2
View File
@@ -199,6 +199,7 @@ template class PrimitiveBuilder<Int8Type>;
template class PrimitiveBuilder<Int16Type>;
template class PrimitiveBuilder<Int32Type>;
template class PrimitiveBuilder<Int64Type>;
template class PrimitiveBuilder<DateType>;
template class PrimitiveBuilder<TimestampType>;
template class PrimitiveBuilder<HalfFloatType>;
template class PrimitiveBuilder<FloatType>;
@@ -411,6 +412,7 @@ Status MakeBuilder(MemoryPool* pool, const std::shared_ptr<DataType>& type,
BUILDER_CASE(INT32, Int32Builder);
BUILDER_CASE(UINT64, UInt64Builder);
BUILDER_CASE(INT64, Int64Builder);
BUILDER_CASE(DATE, DateBuilder);
BUILDER_CASE(TIMESTAMP, TimestampBuilder);
BUILDER_CASE(BOOL, BooleanBuilder);
+1
View File
@@ -220,6 +220,7 @@ using Int16Builder = NumericBuilder<Int16Type>;
using Int32Builder = NumericBuilder<Int32Type>;
using Int64Builder = NumericBuilder<Int64Type>;
using TimestampBuilder = NumericBuilder<TimestampType>;
using DateBuilder = NumericBuilder<DateType>;
using HalfFloatBuilder = NumericBuilder<HalfFloatType>;
using FloatBuilder = NumericBuilder<FloatType>;
+1 -1
View File
@@ -413,7 +413,7 @@ struct ARROW_EXPORT UnionType : public DataType {
struct ARROW_EXPORT DateType : public FixedWidthType {
static constexpr Type::type type_id = Type::DATE;
using c_type = int32_t;
using c_type = int64_t;
DateType() : FixedWidthType(Type::DATE) {}
+3 -1
View File
@@ -87,13 +87,15 @@ _NUMERIC_TYPE_DECL(Double);
#undef _NUMERIC_TYPE_DECL
struct DateType;
class DateArray;
using DateArray = NumericArray<DateType>;
using DateBuilder = NumericBuilder<DateType>;
struct TimeType;
class TimeArray;
struct TimestampType;
using TimestampArray = NumericArray<TimestampType>;
using TimestampBuilder = NumericBuilder<TimestampType>;
struct IntervalType;
using IntervalArray = NumericArray<IntervalType>;
+8
View File
@@ -90,6 +90,14 @@ struct TypeTraits<Int64Type> {
static inline int bytes_required(int elements) { return elements * sizeof(int64_t); }
};
template <>
struct TypeTraits<DateType> {
using ArrayType = DateArray;
// using BuilderType = DateBuilder;
static inline int bytes_required(int elements) { return elements * sizeof(int64_t); }
};
template <>
struct TypeTraits<TimestampType> {
using ArrayType = TimestampArray;
+58 -16
View File
@@ -547,6 +547,17 @@ struct arrow_traits<arrow::Type::TIMESTAMP> {
typedef typename npy_traits<NPY_DATETIME>::value_type T;
};
template <>
struct arrow_traits<arrow::Type::DATE> {
static constexpr int npy_type = NPY_DATETIME;
static constexpr bool supports_nulls = true;
static constexpr int64_t na_value = std::numeric_limits<int64_t>::min();
static constexpr bool is_boolean = false;
static constexpr bool is_pandas_numeric_not_nullable = false;
static constexpr bool is_pandas_numeric_nullable = true;
typedef typename npy_traits<NPY_DATETIME>::value_type T;
};
template <>
struct arrow_traits<arrow::Type::STRING> {
static constexpr int npy_type = NPY_OBJECT;
@@ -567,24 +578,28 @@ static inline PyObject* make_pystring(const uint8_t* data, int32_t length) {
inline void set_numpy_metadata(int type, DataType* datatype, PyArrayObject* out) {
if (type == NPY_DATETIME) {
auto timestamp_type = static_cast<arrow::TimestampType*>(datatype);
// We only support ms resolution at the moment
PyArray_Descr* descr = PyArray_DESCR(out);
auto date_dtype = reinterpret_cast<PyArray_DatetimeDTypeMetaData*>(descr->c_metadata);
if (datatype->type == arrow::Type::TIMESTAMP) {
auto timestamp_type = static_cast<arrow::TimestampType*>(datatype);
switch (timestamp_type->unit) {
case arrow::TimestampType::Unit::SECOND:
date_dtype->meta.base = NPY_FR_s;
break;
case arrow::TimestampType::Unit::MILLI:
date_dtype->meta.base = NPY_FR_ms;
break;
case arrow::TimestampType::Unit::MICRO:
date_dtype->meta.base = NPY_FR_us;
break;
case arrow::TimestampType::Unit::NANO:
date_dtype->meta.base = NPY_FR_ns;
break;
switch (timestamp_type->unit) {
case arrow::TimestampType::Unit::SECOND:
date_dtype->meta.base = NPY_FR_s;
break;
case arrow::TimestampType::Unit::MILLI:
date_dtype->meta.base = NPY_FR_ms;
break;
case arrow::TimestampType::Unit::MICRO:
date_dtype->meta.base = NPY_FR_us;
break;
case arrow::TimestampType::Unit::NANO:
date_dtype->meta.base = NPY_FR_ns;
break;
}
} else {
// datatype->type == arrow::Type::DATE
date_dtype->meta.base = NPY_FR_D;
}
}
}
@@ -666,7 +681,7 @@ class ArrowDeserializer {
template <int T2>
inline typename std::enable_if<
arrow_traits<T2>::is_pandas_numeric_nullable, Status>::type
(T2 != arrow::Type::DATE) & arrow_traits<T2>::is_pandas_numeric_nullable, Status>::type
ConvertValues(const std::shared_ptr<arrow::ChunkedArray>& data) {
typedef typename arrow_traits<T2>::T T;
size_t chunk_offset = 0;
@@ -697,6 +712,32 @@ class ArrowDeserializer {
return Status::OK();
}
template <int T2>
inline typename std::enable_if<
T2 == arrow::Type::DATE, Status>::type
ConvertValues(const std::shared_ptr<arrow::ChunkedArray>& data) {
typedef typename arrow_traits<T2>::T T;
size_t chunk_offset = 0;
RETURN_NOT_OK(AllocateOutput(arrow_traits<T2>::npy_type));
for (int c = 0; c < data->num_chunks(); c++) {
const std::shared_ptr<Array> arr = data->chunk(c);
auto prim_arr = static_cast<arrow::PrimitiveArray*>(arr.get());
auto in_values = reinterpret_cast<const T*>(prim_arr->data()->data());
auto out_values = reinterpret_cast<T*>(PyArray_DATA(out_)) + chunk_offset;
for (int64_t i = 0; i < arr->length(); ++i) {
// There are 1000 * 60 * 60 * 24 = 86400000ms in a day
out_values[i] = arr->IsNull(i) ? arrow_traits<T2>::na_value : in_values[i] / 86400000;
}
chunk_offset += arr->length();
}
return Status::OK();
}
// Integer specialization
template <int T2>
inline typename std::enable_if<
@@ -879,6 +920,7 @@ Status ConvertColumnToPandas(const std::shared_ptr<Column>& col, PyObject* py_re
FROM_ARROW_CASE(FLOAT);
FROM_ARROW_CASE(DOUBLE);
FROM_ARROW_CASE(STRING);
FROM_ARROW_CASE(DATE);
FROM_ARROW_CASE(TIMESTAMP);
default:
return Status::NotImplemented("Arrow type reading not implemented");