Skip to content

Commit

Permalink
Add support for INTERVAL input to year, month, hour, minute, second, …
Browse files Browse the repository at this point in the history
…millisecond Presto functions

Differential Revision: D58509062
  • Loading branch information
mbasmanova authored and facebook-github-bot committed Jun 13, 2024
1 parent 3eb9f01 commit b3c18a6
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 5 deletions.
17 changes: 12 additions & 5 deletions velox/docs/functions/presto/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -341,30 +341,36 @@ arbitrary large timestamps.
.. function:: hour(x) -> bigint

Returns the hour of the day from ``x``. The value ranges from 0 to 23.
Supported types for ``x`` are: DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE,
INTERVAL DAY TO SECOND¶.

.. function:: last_day_of_month(x) -> date

Returns the last day of the month.

.. function:: millisecond(x) -> int64

Returns the millisecond of the second from ``x``.
Returns the millisecond of the second from ``x``. Supported types for ``x`` are:
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, INTERVAL DAY TO SECOND¶.

.. function:: minute(x) -> bigint

Returns the minute of the hour from ``x``.
Returns the minute of the hour from ``x``. Supported types for ``x`` are:
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, INTERVAL DAY TO SECOND¶.

.. function:: month(x) -> bigint

Returns the month of the year from ``x``.
Returns the month of the year from ``x``. Supported types for ``x`` are:
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, INTERVAL YEAR TO MONTH.

.. function:: quarter(x) -> bigint

Returns the quarter of the year from ``x``. The value ranges from ``1`` to ``4``.

.. function:: second(x) -> bigint

Returns the second of the minute from ``x``.
Returns the second of the minute from ``x``. Supported types for ``x`` are:
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, INTERVAL DAY TO SECOND¶.

.. function:: timezone_hour(timestamp) -> bigint

Expand All @@ -386,7 +392,8 @@ arbitrary large timestamps.

.. function:: year(x) -> bigint

Returns the year from ``x``.
Returns the year from ``x``. Supported types for ``x`` are:
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, INTERVAL YEAR TO MONTH.

.. function:: year_of_week(x) -> bigint

Expand Down
66 changes: 66 additions & 0 deletions velox/functions/prestosql/DateTimeFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,17 @@ struct YearFunction : public InitSessionTimezone<T>,
}
};

template <typename T>
struct YearFromIntervalFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
int64_t& result,
const arg_type<IntervalYearMonth>& months) {
result = months / 12;
}
};

template <typename T>
struct QuarterFunction : public InitSessionTimezone<T>,
public TimestampWithTimezoneSupport<T> {
Expand Down Expand Up @@ -292,6 +303,17 @@ struct MonthFunction : public InitSessionTimezone<T>,
}
};

template <typename T>
struct MonthFromIntervalFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
int64_t& result,
const arg_type<IntervalYearMonth>& months) {
result = months % 12;
}
};

template <typename T>
struct DayFunction : public InitSessionTimezone<T>,
public TimestampWithTimezoneSupport<T> {
Expand Down Expand Up @@ -687,6 +709,17 @@ struct HourFunction : public InitSessionTimezone<T>,
}
};

template <typename T>
struct HourFromIntervalFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
int64_t& result,
const arg_type<IntervalDayTime>& millis) {
result = (millis % kMillisInDay) / kMillisInHour;
}
};

template <typename T>
struct MinuteFunction : public InitSessionTimezone<T>,
public TimestampWithTimezoneSupport<T> {
Expand All @@ -710,6 +743,17 @@ struct MinuteFunction : public InitSessionTimezone<T>,
}
};

template <typename T>
struct MinuteFromIntervalFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
int64_t& result,
const arg_type<IntervalDayTime>& millis) {
result = (millis % kMillisInHour) / kMillisInMinute;
}
};

template <typename T>
struct SecondFunction : public TimestampWithTimezoneSupport<T> {
VELOX_DEFINE_FUNCTION_TYPES(T);
Expand All @@ -732,6 +776,17 @@ struct SecondFunction : public TimestampWithTimezoneSupport<T> {
}
};

template <typename T>
struct SecondFromIntervalFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
int64_t& result,
const arg_type<IntervalDayTime>& millis) {
result = (millis % kMillisInMinute) / kMillisInSecond;
}
};

template <typename T>
struct MillisecondFunction : public TimestampWithTimezoneSupport<T> {
VELOX_DEFINE_FUNCTION_TYPES(T);
Expand All @@ -757,6 +812,17 @@ struct MillisecondFunction : public TimestampWithTimezoneSupport<T> {
}
};

template <typename T>
struct MillisecondFromIntervalFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
int64_t& result,
const arg_type<IntervalDayTime>& millis) {
result = millis % kMillisecondsInSecond;
}
};

namespace {
inline std::optional<DateTimeUnit> fromDateTimeUnitString(
const StringView& unitString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,14 @@ void registerSimpleFunctions(const std::string& prefix) {

registerFunction<TimeZoneMinuteFunction, int64_t, TimestampWithTimezone>(
{prefix + "timezone_minute"});

registerFunction<YearFunction, int64_t, Timestamp>({prefix + "year"});
registerFunction<YearFunction, int64_t, Date>({prefix + "year"});
registerFunction<YearFunction, int64_t, TimestampWithTimezone>(
{prefix + "year"});
registerFunction<YearFromIntervalFunction, int64_t, IntervalYearMonth>(
{prefix + "year"});

registerFunction<WeekFunction, int64_t, Timestamp>(
{prefix + "week", prefix + "week_of_year"});
registerFunction<WeekFunction, int64_t, Date>(
Expand All @@ -97,16 +101,21 @@ void registerSimpleFunctions(const std::string& prefix) {
registerFunction<QuarterFunction, int64_t, Date>({prefix + "quarter"});
registerFunction<QuarterFunction, int64_t, TimestampWithTimezone>(
{prefix + "quarter"});

registerFunction<MonthFunction, int64_t, Timestamp>({prefix + "month"});
registerFunction<MonthFunction, int64_t, Date>({prefix + "month"});
registerFunction<MonthFunction, int64_t, TimestampWithTimezone>(
{prefix + "month"});
registerFunction<MonthFromIntervalFunction, int64_t, IntervalYearMonth>(
{prefix + "month"});

registerFunction<DayFunction, int64_t, Timestamp>(
{prefix + "day", prefix + "day_of_month"});
registerFunction<DayFunction, int64_t, Date>(
{prefix + "day", prefix + "day_of_month"});
registerFunction<DayFromIntervalFunction, int64_t, IntervalDayTime>(
{prefix + "day", prefix + "day_of_month"});

registerFunction<DateMinusInterval, Date, Date, IntervalDayTime>(
{prefix + "minus"});
registerFunction<DateMinusInterval, Date, Date, IntervalYearMonth>(
Expand Down Expand Up @@ -147,30 +156,44 @@ void registerSimpleFunctions(const std::string& prefix) {
{prefix + "yow", prefix + "year_of_week"});
registerFunction<YearOfWeekFunction, int64_t, TimestampWithTimezone>(
{prefix + "yow", prefix + "year_of_week"});

registerFunction<HourFunction, int64_t, Timestamp>({prefix + "hour"});
registerFunction<HourFunction, int64_t, Date>({prefix + "hour"});
registerFunction<HourFunction, int64_t, TimestampWithTimezone>(
{prefix + "hour"});
registerFunction<HourFromIntervalFunction, int64_t, IntervalDayTime>(
{prefix + "hour"});

registerFunction<LastDayOfMonthFunction, Date, Timestamp>(
{prefix + "last_day_of_month"});
registerFunction<LastDayOfMonthFunction, Date, Date>(
{prefix + "last_day_of_month"});
registerFunction<LastDayOfMonthFunction, Date, TimestampWithTimezone>(
{prefix + "last_day_of_month"});

registerFunction<MinuteFunction, int64_t, Timestamp>({prefix + "minute"});
registerFunction<MinuteFunction, int64_t, Date>({prefix + "minute"});
registerFunction<MinuteFunction, int64_t, TimestampWithTimezone>(
{prefix + "minute"});
registerFunction<MinuteFromIntervalFunction, int64_t, IntervalDayTime>(
{prefix + "minute"});

registerFunction<SecondFunction, int64_t, Timestamp>({prefix + "second"});
registerFunction<SecondFunction, int64_t, Date>({prefix + "second"});
registerFunction<SecondFunction, int64_t, TimestampWithTimezone>(
{prefix + "second"});
registerFunction<SecondFromIntervalFunction, int64_t, IntervalDayTime>(
{prefix + "second"});

registerFunction<MillisecondFunction, int64_t, Timestamp>(
{prefix + "millisecond"});
registerFunction<MillisecondFunction, int64_t, Date>(
{prefix + "millisecond"});
registerFunction<MillisecondFunction, int64_t, TimestampWithTimezone>(
{prefix + "millisecond"});
registerFunction<MillisecondFromIntervalFunction, int64_t, IntervalDayTime>(
{prefix + "millisecond"});

registerFunction<DateTruncFunction, Timestamp, Varchar, Timestamp>(
{prefix + "date_trunc"});
registerFunction<DateTruncFunction, Date, Varchar, Date>(
Expand Down
34 changes: 34 additions & 0 deletions velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,40 @@ TEST_F(DateTimeFunctionsTest, millisecondTimestampWithTimezone) {
"millisecond(c0)", -980, "+05:30"));
}

TEST_F(DateTimeFunctionsTest, extractFromIntervalDayTime) {
const auto millis = 5 * kMillisInDay + 7 * kMillisInHour +
11 * kMillisInMinute + 13 * kMillisInSecond + 17;

auto extract = [&](const std::string& unit, int64_t millis) {
return evaluateOnce<int64_t>(
fmt::format("{}(c0)", unit),
INTERVAL_DAY_TIME(),
std::optional(millis))
.value();
};

EXPECT_EQ(17, extract("millisecond", millis));
EXPECT_EQ(13, extract("second", millis));
EXPECT_EQ(11, extract("minute", millis));
EXPECT_EQ(7, extract("hour", millis));
EXPECT_EQ(5, extract("day", millis));
}

TEST_F(DateTimeFunctionsTest, extractFromIntervalYearMonth) {
const auto months = 3 * 12 + 4;

auto extract = [&](const std::string& unit, int32_t months) {
return evaluateOnce<int64_t>(
fmt::format("{}(c0)", unit),
INTERVAL_YEAR_MONTH(),
std::optional(months))
.value();
};

EXPECT_EQ(3, extract("year", months));
EXPECT_EQ(4, extract("month", months));
}

TEST_F(DateTimeFunctionsTest, dateTrunc) {
const auto dateTrunc = [&](const std::string& unit,
std::optional<Timestamp> timestamp) {
Expand Down

0 comments on commit b3c18a6

Please sign in to comment.