Skip to content

Commit

Permalink
Add minute, second Spark function (#8831)
Browse files Browse the repository at this point in the history
Summary:
Addresses facebookincubator/velox#8830

Pull Request resolved: facebookincubator/velox#8831

Reviewed By: Yuhta

Differential Revision: D54305016

Pulled By: mbasmanova

fbshipit-source-id: bf5c7e2bfcb6195dc859cca42febe08c656e0576
  • Loading branch information
acvictor authored and facebook-github-bot committed Feb 28, 2024
1 parent 09f56d5 commit 2078f23
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 0 deletions.
12 changes: 12 additions & 0 deletions velox/docs/functions/spark/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ These functions support TIMESTAMP and DATE input types.
``day`` need to be from 1 to 31, and matches the number of days in each month.
days of ``year-month-day - 1970-01-01`` need to be in the range of INTEGER type.

.. spark:function:: minute(timestamp) -> integer
Returns the minutes of ``timestamp``.::

SELECT minute('2009-07-30 12:58:59'); -- 58

.. spark:function:: quarter(date) -> integer
Returns the quarter of ``date``. The value ranges from ``1`` to ``4``. ::
Expand Down Expand Up @@ -154,6 +160,12 @@ These functions support TIMESTAMP and DATE input types.
SELECT next_day('2015-07-23', "tu"); -- '2015-07-28'
SELECT next_day('2015-07-23', "we"); -- '2015-07-29'

.. spark:function:: second(timestamp) -> integer
Returns the seconds of ``timestamp``.::

SELECT second('2009-07-30 12:58:59'); -- 59

.. spark:function:: to_unix_timestamp(string) -> integer
Alias for ``unix_timestamp(string) -> integer``.
Expand Down
22 changes: 22 additions & 0 deletions velox/functions/sparksql/DateTimeFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,4 +580,26 @@ struct HourFunction : public InitSessionTimezone<T> {
result = getDateTime(timestamp, this->timeZone_).tm_hour;
}
};

template <typename T>
struct MinuteFunction : public InitSessionTimezone<T> {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
int32_t& result,
const arg_type<Timestamp>& timestamp) {
result = getDateTime(timestamp, this->timeZone_).tm_min;
}
};

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

FOLLY_ALWAYS_INLINE void call(
int32_t& result,
const arg_type<Timestamp>& timestamp) {
result = getDateTime(timestamp, nullptr).tm_sec;
}
};
} // namespace facebook::velox::functions::sparksql
4 changes: 4 additions & 0 deletions velox/functions/sparksql/Register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,10 @@ void registerFunctions(const std::string& prefix) {

registerFunction<HourFunction, int32_t, Timestamp>({prefix + "hour"});

registerFunction<MinuteFunction, int32_t, Timestamp>({prefix + "minute"});

registerFunction<SecondFunction, int32_t, Timestamp>({prefix + "second"});

// Register bloom filter function
registerFunction<BloomFilterMightContainFunction, bool, Varbinary, int64_t>(
{prefix + "might_contain"});
Expand Down
42 changes: 42 additions & 0 deletions velox/functions/sparksql/tests/DateTimeFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,48 @@ TEST_F(DateTimeFunctionsTest, hour) {
EXPECT_EQ(2, hour("1969-01-01 13:23:00.001"));
}

TEST_F(DateTimeFunctionsTest, minute) {
const auto minute = [&](std::string_view timestampStr) {
const auto timeStamp = std::make_optional(
util::fromTimestampString(timestampStr.data(), timestampStr.length()));
return evaluateOnce<int32_t>("minute(c0)", timeStamp);
};

EXPECT_EQ(23, minute("2024-01-08 00:23:00.001"));
EXPECT_EQ(59, minute("2024-01-08 00:59:59.999"));
EXPECT_EQ(10, minute("2015-04-08 13:10:15"));
EXPECT_EQ(43, minute("1969-01-01 13:43:00.001"));

// Set time zone to Pacific/Apia (13 hours ahead of UTC).
setQueryTimeZone("Pacific/Apia");

EXPECT_EQ(23, minute("2024-01-08 00:23:00.001"));
EXPECT_EQ(59, minute("2024-01-08 00:59:59.999"));
EXPECT_EQ(10, minute("2015-04-08 13:10:15"));
EXPECT_EQ(43, minute("1969-01-01 13:43:00.001"));

// Set time zone to Asia/Kolkata (5.5 hours ahead of UTC).
setQueryTimeZone("Asia/Kolkata");

EXPECT_EQ(53, minute("2024-01-08 00:23:00.001"));
EXPECT_EQ(29, minute("2024-01-08 00:59:59.999"));
EXPECT_EQ(40, minute("2015-04-08 13:10:15"));
EXPECT_EQ(13, minute("1969-01-01 13:43:00.001"));
}

TEST_F(DateTimeFunctionsTest, second) {
const auto second = [&](std::string_view timestampStr) {
const auto timeStamp = std::make_optional(
util::fromTimestampString(timestampStr.data(), timestampStr.length()));
return evaluateOnce<int32_t>("second(c0)", timeStamp);
};

EXPECT_EQ(0, second("2024-01-08 00:23:00.001"));
EXPECT_EQ(59, second("2024-01-08 00:59:59.999"));
EXPECT_EQ(15, second("2015-04-08 13:10:15"));
EXPECT_EQ(0, second("1969-01-01 13:43:00.001"));
}

TEST_F(DateTimeFunctionsTest, fromUnixtime) {
const auto getUnixTime = [&](const StringView& str) {
Timestamp t = util::fromTimestampString(str);
Expand Down

0 comments on commit 2078f23

Please sign in to comment.