Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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 @@ -56,6 +57,7 @@ namespace arrow {

using internal::checked_cast;
using internal::checked_pointer_cast;
using internal::int128_t;
using internal::MakeLazyRange;

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
11 changes: 9 additions & 2 deletions 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 @@ -3541,8 +3548,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};
static std::vector<TimeUnit::type> units = {
TimeUnit::SECOND, TimeUnit::MILLI, 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