diff --git a/velox/docs/functions/presto/datetime.rst b/velox/docs/functions/presto/datetime.rst index a46c9d2b1b87..9237be4a61a8 100644 --- a/velox/docs/functions/presto/datetime.rst +++ b/velox/docs/functions/presto/datetime.rst @@ -252,6 +252,8 @@ arbitrary large timestamps. Returns the day of the month from ``x``. + The supported types for ``x`` are DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, INTERVAL DAY TO SECOND. + .. function:: day_of_month(x) -> bigint This is an alias for :func:`day`. diff --git a/velox/functions/prestosql/DateTimeFunctions.h b/velox/functions/prestosql/DateTimeFunctions.h index 9a2841059de0..ac1bbd9b7c11 100644 --- a/velox/functions/prestosql/DateTimeFunctions.h +++ b/velox/functions/prestosql/DateTimeFunctions.h @@ -330,6 +330,17 @@ struct DayFunction : public InitSessionTimezone, } }; +template +struct DayFromIntervalFunction { + VELOX_DEFINE_FUNCTION_TYPES(T); + + FOLLY_ALWAYS_INLINE void call( + int64_t& result, + const arg_type& interval) { + result = interval / kMillisInDay; + } +}; + template struct LastDayOfMonthFunction : public InitSessionTimezone, public TimestampWithTimezoneSupport { diff --git a/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp b/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp index 668196c36c39..944ae247ce02 100644 --- a/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp +++ b/velox/functions/prestosql/registration/DateTimeFunctionsRegistration.cpp @@ -59,6 +59,8 @@ void registerSimpleFunctions(const std::string& prefix) { {prefix + "day", prefix + "day_of_month"}); registerFunction( {prefix + "day", prefix + "day_of_month"}); + registerFunction( + {prefix + "day", prefix + "day_of_month"}); registerFunction( {prefix + "minus"}); registerFunction( diff --git a/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp b/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp index 4aa86b25bf97..c9e0d5625c42 100644 --- a/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp +++ b/velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp @@ -268,8 +268,18 @@ TEST_F(DateTimeFunctionsTest, parseDatetimeSignatures) { } TEST_F(DateTimeFunctionsTest, dayOfXxxSignatures) { - for (const auto& name : - {"day_of_year", "doy", "day_of_month", "day_of_week", "dow"}) { + for (const auto& name : {"day", "day_of_month"}) { + SCOPED_TRACE(name); + auto signatures = getSignatureStrings(name); + ASSERT_EQ(4, signatures.size()); + + ASSERT_EQ(1, signatures.count("(timestamp with time zone) -> bigint")); + ASSERT_EQ(1, signatures.count("(date) -> bigint")); + ASSERT_EQ(1, signatures.count("(timestamp) -> bigint")); + ASSERT_EQ(1, signatures.count("(interval day to second) -> bigint")); + } + + for (const auto& name : {"day_of_year", "doy", "day_of_week", "dow"}) { SCOPED_TRACE(name); auto signatures = getSignatureStrings(name); ASSERT_EQ(3, signatures.size()); @@ -804,6 +814,24 @@ TEST_F(DateTimeFunctionsTest, dayOfMonthDate) { EXPECT_EQ(2, day(-18262)); } +TEST_F(DateTimeFunctionsTest, dayOfMonthInterval) { + const auto day = [&](int64_t millis) { + auto result = evaluateOnce( + "day_of_month(c0)", {millis}, {INTERVAL_DAY_TIME()}); + + auto result2 = evaluateOnce( + "day(c0)", {millis}, {INTERVAL_DAY_TIME()}); + + EXPECT_EQ(result, result2); + return result; + }; + + EXPECT_EQ(1, day(kMillisInDay)); + EXPECT_EQ(1, day(kMillisInDay + kMillisInHour)); + EXPECT_EQ(10, day(10 * kMillisInDay + 7 * kMillisInHour)); + EXPECT_EQ(-10, day(-10 * kMillisInDay - 7 * kMillisInHour)); +} + TEST_F(DateTimeFunctionsTest, plusMinusDateIntervalYearMonth) { const auto makeInput = [&](const std::string& date, int32_t interval) { return makeRowVector({