Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cpp/src/arrow/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ set(ARROW_UTIL_SRCS
util/future.cc
util/hashing.cc
util/int_util.cc
util/int128_internal.cc
util/io_util.cc
util/list_util.cc
util/logger.cc
Expand Down
9 changes: 9 additions & 0 deletions cpp/src/arrow/array/diff.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "arrow/util/bit_util.h"
#include "arrow/util/checked_cast.h"
#include "arrow/util/float16.h"
#include "arrow/util/int128_internal.h"
#include "arrow/util/logging_internal.h"
#include "arrow/util/range.h"
#include "arrow/util/ree_util.h"
Expand All @@ -57,6 +58,7 @@ namespace arrow {
using internal::checked_cast;
using internal::checked_pointer_cast;
using internal::MakeLazyRange;
using internal::int128_t;

namespace {

Expand Down Expand Up @@ -855,6 +857,7 @@ class MakeFormatterImpl {
// Using unqualified `format` directly would produce ambiguous
// lookup because of `std::format` (ARROW-15520).
namespace avd = arrow_vendored::date;
using picoseconds = std::chrono::duration<int128_t, std::pico>;
using std::chrono::nanoseconds;
using std::chrono::microseconds;
using std::chrono::milliseconds;
Expand All @@ -863,6 +866,9 @@ class MakeFormatterImpl {
static avd::sys_days epoch{avd::jan / 1 / 1970};

switch (unit) {
case TimeUnit::PICO:
*os << avd::format(fmt, static_cast<picoseconds>(value) + epoch);
break;
case TimeUnit::NANO:
*os << avd::format(fmt, static_cast<nanoseconds>(value) + epoch);
break;
Expand All @@ -879,6 +885,9 @@ class MakeFormatterImpl {
return;
}
switch (unit) {
case TimeUnit::PICO:
*os << avd::format(fmt, static_cast<picoseconds>(value));
break;
case TimeUnit::NANO:
*os << avd::format(fmt, static_cast<nanoseconds>(value));
break;
Expand Down
15 changes: 11 additions & 4 deletions cpp/src/arrow/c/bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1221,21 +1221,28 @@ struct SchemaImporter {
ARROW_ASSIGN_OR_RAISE(auto unit, f_parser_.ParseTimeUnit());
if (unit == TimeUnit::SECOND || unit == TimeUnit::MILLI) {
return ProcessPrimitive(time32(unit));
} else {
} else if (unit != TimeUnit::PICO) {
return ProcessPrimitive(time64(unit));
}
return f_parser_.Invalid();
}

Status ProcessDuration() {
ARROW_ASSIGN_OR_RAISE(auto unit, f_parser_.ParseTimeUnit());
return ProcessPrimitive(duration(unit));
if (unit != TimeUnit::PICO) {
return ProcessPrimitive(duration(unit));
}
return f_parser_.Invalid();
}

Status ProcessTimestamp() {
ARROW_ASSIGN_OR_RAISE(auto unit, f_parser_.ParseTimeUnit());
RETURN_NOT_OK(f_parser_.CheckNext(':'));
type_ = timestamp(unit, std::string(f_parser_.Rest()));
return Status::OK();
if (unit != TimeUnit::PICO) {
type_ = timestamp(unit, std::string(f_parser_.Rest()));
return Status::OK();
}
return f_parser_.Invalid();
}

Status ProcessFixedSizeBinary() {
Expand Down
4 changes: 3 additions & 1 deletion cpp/src/arrow/compute/api_scalar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct EnumTraits<compute::JoinOptions::NullHandlingBehavior>
template <>
struct EnumTraits<TimeUnit::type>
: BasicEnumTraits<TimeUnit::type, TimeUnit::type::SECOND, TimeUnit::type::MILLI,
TimeUnit::type::MICRO, TimeUnit::type::NANO> {
TimeUnit::type::MICRO, TimeUnit::type::NANO, TimeUnit::type::PICO> {
static std::string name() { return "TimeUnit::type"; }
static std::string value_name(TimeUnit::type value) {
switch (value) {
Expand All @@ -70,6 +70,8 @@ struct EnumTraits<TimeUnit::type>
return "MICRO";
case TimeUnit::type::NANO:
return "NANO";
case TimeUnit::type::PICO:
return "PICO";
}
return "<INVALID>";
}
Expand Down
3 changes: 3 additions & 0 deletions cpp/src/arrow/compute/kernels/codegen_internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ TypeHolder CommonTemporal(const TypeHolder* begin, size_t count) {
case TimeUnit::MICRO:
case TimeUnit::NANO:
return time64(finest_unit);
case TimeUnit::PICO:
// Type not implemented.
return TypeHolder(nullptr);
}
}
return TypeHolder(nullptr);
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/arrow/compute/kernels/scalar_cast_temporal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ Status ExtractTemporal(KernelContext* ctx, const ExecSpan& batch, ExecResult* ou
case TimeUnit::NANO:
return TemporalComponentExtract<Op, std::chrono::nanoseconds, TimestampType,
OutType, Args...>::Exec(ctx, batch, out, args...);
case TimeUnit::PICO:
return Status::Invalid("Picoseconds not yet supported: ", ty);
}
return Status::Invalid("Unknown timestamp unit: ", ty);
}
Expand Down
11 changes: 7 additions & 4 deletions cpp/src/arrow/compute/kernels/scalar_cast_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2396,7 +2396,8 @@ TEST(Cast, TimestampToDate) {
CheckCast(timestamps, date_64);
CheckCast(timestamps_extreme, date_32_extreme);
CheckCast(timestamps_extreme, date_64_extreme);
for (auto u : TimeUnit::values()) {
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto u : units) {
auto unit = timestamp(u);
CheckCast(ArrayFromJSON(unit, kTimestampSecondsJson), date_32);
CheckCast(ArrayFromJSON(unit, kTimestampSecondsJson), date_64);
Expand Down Expand Up @@ -2438,15 +2439,16 @@ TEST_F(CastTimezone, ZonedTimestampToDate) {
1230422400000, 1230508800000, 1325376000000, null
])");

for (auto u : TimeUnit::values()) {
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto u : units) {
auto timestamps =
ArrayFromJSON(timestamp(u, "Australia/Broken_Hill"), kTimestampSecondsJson);
CheckCast(timestamps, date_32);
CheckCast(timestamps, date_64);
}

// Invalid timezone
for (auto u : TimeUnit::values()) {
for (auto u : units) {
auto timestamps =
ArrayFromJSON(timestamp(u, "Mars/Mariner_Valley"), kTimestampSecondsJson);
CheckCastFails(timestamps, CastOptions::Unsafe(date32()));
Expand Down Expand Up @@ -2583,7 +2585,8 @@ TEST(Cast, TimestampToTime) {
CheckCast(timestamps_s, times_ms);

// Invalid timezone
for (auto u : TimeUnit::values()) {
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto u : units) {
auto timestamps =
ArrayFromJSON(timestamp(u, "Mars/Mariner_Valley"), kTimestampSecondsJson);
if (u == TimeUnit::SECOND || u == TimeUnit::MILLI) {
Expand Down
5 changes: 4 additions & 1 deletion cpp/src/arrow/compute/kernels/scalar_if_else_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,10 @@ TEST_F(TestIfElseKernel, IfElseMultiType) {
}

TEST_F(TestIfElseKernel, TimestampTypes) {
for (const auto unit : TimeUnit::values()) {
for (const auto unit : {
TimeUnit::SECOND,
TimeUnit::NANO,
}) {
auto ty = timestamp(unit);
CheckWithDifferentShapes(ArrayFromJSON(boolean(), "[true, true, true, false]"),
ArrayFromJSON(ty, "[1, 2, 3, 4]"),
Expand Down
27 changes: 18 additions & 9 deletions cpp/src/arrow/compute/kernels/scalar_temporal_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,8 @@ TEST_F(ScalarTemporalTest, TestTemporalComponentExtractionAllTemporalTypes) {
}

TEST_F(ScalarTemporalTest, TestTemporalComponentExtractionWithDifferentUnits) {
for (auto u : TimeUnit::values()) {
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto u : units) {
auto unit = timestamp(u);
CheckScalarUnary("year", unit, times_seconds_precision, int64(), year);
CheckScalarUnary("is_leap_year", unit, times_seconds_precision, boolean(),
Expand Down Expand Up @@ -814,7 +815,8 @@ TEST_F(ScalarTemporalTest, TestZoned1) {
}

TEST_F(ScalarTemporalTest, TestZoned2) {
for (auto u : TimeUnit::values()) {
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto u : units) {
auto unit = timestamp(u, "Australia/Broken_Hill");
auto month = "[1, 3, 1, 5, 1, 12, 12, 12, 1, 1, 1, 1, 12, 12, 12, 1, null]";
auto day = "[1, 1, 1, 18, 1, 31, 30, 31, 1, 3, 4, 1, 31, 28, 29, 1, null]";
Expand Down Expand Up @@ -906,8 +908,9 @@ TEST_F(ScalarTemporalTest, TestNonexistentTimezone) {
auto nonexistent_timezones = {
"Mars/Mariner_Valley", "+25:00", "-25:00", "15:00", "5:00", "500",
"+05:00:00", "+050000"};
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto timezone : nonexistent_timezones) {
for (auto u : TimeUnit::values()) {
for (auto u : units) {
auto ts_type = timestamp(u, timezone);
auto timestamp_array = std::make_shared<NumericArray<TimestampType>>(
ts_type, 2, data_buffer, null_buffer, 0);
Expand Down Expand Up @@ -1026,7 +1029,8 @@ TEST_F(ScalarTemporalTest, DayOfWeek) {
}

TEST_F(ScalarTemporalTest, TestTemporalDifference) {
for (auto u : TimeUnit::values()) {
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto u : units) {
auto unit = timestamp(u);
auto arr1 = ArrayFromJSON(unit, times_seconds_precision);
auto arr2 = ArrayFromJSON(unit, times_seconds_precision2);
Expand Down Expand Up @@ -1879,8 +1883,9 @@ TEST_F(ScalarTemporalTest, TestLocalTimestamp) {
"2009-12-30 18:50:20", "2009-12-31 19:55:25", "2010-01-02 21:00:30",
"2010-01-03 22:05:35", "2005-12-31 23:10:40", "2005-12-31 00:15:45",
"2008-12-27 14:30:00", "2008-12-28 14:30:00", "2011-12-31 15:32:03", null])";
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};

for (auto u : TimeUnit::values()) {
for (auto u : units) {
CheckScalarUnary("local_timestamp", timestamp(u), times_seconds_precision,
timestamp(u), times_seconds_precision);
CheckScalarUnary("local_timestamp", timestamp(u, "UTC"), times_seconds_precision,
Expand Down Expand Up @@ -1912,8 +1917,9 @@ TEST_F(ScalarTemporalTest, TestAssumeTimezone) {
auto options_tbilisi = AssumeTimezoneOptions(timezone_tbilisi);
auto options_tbilisi_offset = AssumeTimezoneOptions(timezone_tbilisi_offset);
auto options_invalid = AssumeTimezoneOptions("Europe/Brusselsss");
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};

for (auto u : TimeUnit::values()) {
for (auto u : units) {
auto unit = timestamp(u);
auto unit_utc = timestamp(u, timezone_utc);
auto unit_kolkata = timestamp(u, timezone_kolkata);
Expand Down Expand Up @@ -1956,8 +1962,9 @@ TEST_F(ScalarTemporalTest, TestAssumeTimezoneAmbiguous) {
AssumeTimezoneOptions(timezone, AssumeTimezoneOptions::AMBIGUOUS_LATEST);
auto options_raise =
AssumeTimezoneOptions(timezone, AssumeTimezoneOptions::AMBIGUOUS_RAISE);
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};

for (auto u : TimeUnit::values()) {
for (auto u : units) {
auto unit = timestamp(u);
auto unit_local = timestamp(u, timezone);
ASSERT_RAISES(Invalid, AssumeTimezone(ArrayFromJSON(unit, times), options_raise));
Expand Down Expand Up @@ -1989,8 +1996,9 @@ TEST_F(ScalarTemporalTest, TestAssumeTimezoneNonexistent) {
auto options_earliest =
AssumeTimezoneOptions(timezone, AssumeTimezoneOptions::AMBIGUOUS_RAISE,
AssumeTimezoneOptions::NONEXISTENT_EARLIEST);
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};

for (auto u : TimeUnit::values()) {
for (auto u : units) {
auto unit = timestamp(u);
auto unit_local = timestamp(u, timezone);
ASSERT_RAISES(Invalid, AssumeTimezone(ArrayFromJSON(unit, times), options_raise));
Expand Down Expand Up @@ -2245,7 +2253,8 @@ TEST_F(ScalarTemporalTest, StrftimeInvalidLocale) {
}

TEST_F(ScalarTemporalTest, TestTemporalDifferenceZoned) {
for (auto u : TimeUnit::values()) {
auto units = {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO};
for (auto u : units) {
auto unit = timestamp(u, "Pacific/Marquesas");
auto arr1 = ArrayFromJSON(unit, times_seconds_precision);
auto arr2 = ArrayFromJSON(unit, times_seconds_precision2);
Expand Down
10 changes: 9 additions & 1 deletion cpp/src/arrow/type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ std::string ToString(TimeUnit::type unit) {
return "us";
case TimeUnit::NANO:
return "ns";
case TimeUnit::PICO:
return "ps";
default:
DCHECK(false);
return "";
Expand Down Expand Up @@ -1190,6 +1192,9 @@ std::ostream& operator<<(std::ostream& os, TimeUnit::type unit) {
case TimeUnit::NANO:
os << "ns";
break;
case TimeUnit::PICO:
os << "ps";
break;
}
return os;
}
Expand Down Expand Up @@ -2767,6 +2772,8 @@ static char TimeUnitFingerprint(TimeUnit::type unit) {
return 'u';
case TimeUnit::NANO:
return 'n';
case TimeUnit::PICO:
return 'p';
default:
DCHECK(false) << "Unexpected TimeUnit";
return '\0';
Expand Down Expand Up @@ -3542,7 +3549,8 @@ const std::vector<std::shared_ptr<DataType>>& PrimitiveTypes() {

const std::vector<TimeUnit::type>& TimeUnit::values() {
static std::vector<TimeUnit::type> units = {TimeUnit::SECOND, TimeUnit::MILLI,
TimeUnit::MICRO, TimeUnit::NANO};
TimeUnit::MICRO, TimeUnit::NANO,
TimeUnit::PICO};
return units;
}

Expand Down
2 changes: 1 addition & 1 deletion cpp/src/arrow/type_fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ struct Date64Scalar;

struct ARROW_EXPORT TimeUnit {
/// The unit for a time or timestamp DataType
enum type { SECOND = 0, MILLI = 1, MICRO = 2, NANO = 3 };
enum type { SECOND = 0, MILLI = 1, MICRO = 2, NANO = 3, PICO = 4 };

/// Iterate over all valid time units
static const std::vector<TimeUnit::type>& values();
Expand Down
Loading
Loading