Skip to content

Commit 484eb10

Browse files
MariamalmesferMariam-Almesfer
authored andcommitted
Add support for hour(timestamp_ntz)
1 parent 7f51f36 commit 484eb10

4 files changed

Lines changed: 44 additions & 0 deletions

File tree

velox/functions/sparksql/DateTimeFunctions.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "velox/functions/lib/DateTimeFormatter.h"
2222
#include "velox/functions/lib/TimeUtils.h"
2323
#include "velox/functions/sparksql/TimestampUtils.h"
24+
#include "velox/functions/sparksql/types/TimestampNTZType.h"
2425
#include "velox/type/TimestampConversion.h"
2526
#include "velox/type/tz/TimeZoneMap.h"
2627

@@ -886,12 +887,28 @@ struct NextDayFunction {
886887
template <typename T>
887888
struct HourFunction : public InitSessionTimezone<T> {
888889
VELOX_DEFINE_FUNCTION_TYPES(T);
890+
using InitSessionTimezone<T>::initialize;
891+
892+
FOLLY_ALWAYS_INLINE void initialize(
893+
const std::vector<TypePtr>& /*inputTypes*/,
894+
const core::QueryConfig& /*config*/,
895+
const arg_type<TimestampNTZ>* /*timestamp*/) {
896+
// TIMESTAMP_NTZ represents local wall-clock time and must not use
897+
// session timezone adjustment.
898+
this->timeZone_ = nullptr;
899+
}
889900

890901
FOLLY_ALWAYS_INLINE void call(
891902
int32_t& result,
892903
const arg_type<Timestamp>& timestamp) {
893904
result = getDateTime(timestamp, this->timeZone_).tm_hour;
894905
}
906+
907+
FOLLY_ALWAYS_INLINE void call(
908+
int32_t& result,
909+
const arg_type<TimestampNTZ>& timestamp) {
910+
result = getDateTime(Timestamp::fromMicros(timestamp), nullptr).tm_hour;
911+
}
895912
};
896913

897914
template <typename T>

velox/functions/sparksql/registration/Register.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "velox/functions/sparksql/registration/Register.h"
1717
#include "velox/expression/SimpleFunctionRegistry.h"
1818
#include "velox/expression/SpecialFormRegistry.h"
19+
#include "velox/functions/sparksql/types/TimestampNTZRegistration.h"
1920

2021
namespace facebook::velox::functions::sparksql {
2122

@@ -34,6 +35,7 @@ extern void registerStringFunctions(const std::string& prefix);
3435
extern void registerUrlFunctions(const std::string& prefix);
3536

3637
void registerFunctions(const std::string& prefix) {
38+
registerTimestampNTZType();
3739
registerArrayFunctions(prefix);
3840
registerBinaryFunctions(prefix);
3941
registerBitwiseFunctions(prefix);

velox/functions/sparksql/registration/RegisterDatetime.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ void registerDatetimeFunctions(const std::string& prefix) {
7676
registerFunction<GetTimestampFunction, Timestamp, Varchar, Varchar>(
7777
{prefix + "get_timestamp"});
7878
registerFunction<HourFunction, int32_t, Timestamp>({prefix + "hour"});
79+
registerFunction<HourFunction, int32_t, TimestampNTZ>({prefix + "hour"});
7980
registerFunction<MinuteFunction, int32_t, Timestamp>({prefix + "minute"});
8081
registerFunction<SecondFunction, int32_t, Timestamp>({prefix + "second"});
8182
registerFunction<MakeYMIntervalFunction, IntervalYearMonth>(

velox/functions/sparksql/tests/DateTimeFunctionsTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "velox/common/base/tests/GTestUtils.h"
1818
#include "velox/functions/sparksql/tests/SparkFunctionBaseTest.h"
19+
#include "velox/functions/sparksql/types/TimestampNTZType.h"
1920
#include "velox/type/Timestamp.h"
2021
#include "velox/type/tz/TimeZoneMap.h"
2122

@@ -943,6 +944,29 @@ TEST_F(DateTimeFunctionsTest, hour) {
943944
EXPECT_EQ(2, hour("1969-01-01 13:23:00.001"));
944945
}
945946

947+
TEST_F(DateTimeFunctionsTest, hourTimestampNTZ) {
948+
const auto hourNtz = [&](const StringView timestampStr) {
949+
auto micros = std::make_optional(parseTimestamp(timestampStr).toMicros());
950+
return evaluateOnce<int32_t>("hour(c0)", TIMESTAMP_NTZ(), micros);
951+
};
952+
953+
EXPECT_EQ(
954+
std::nullopt,
955+
evaluateOnce<int32_t>(
956+
"hour(c0)", TIMESTAMP_NTZ(), std::optional<int64_t>{}));
957+
958+
EXPECT_EQ(0, hourNtz("2024-01-08 00:23:00.001"));
959+
EXPECT_EQ(1, hourNtz("2024-01-08 01:23:00.001"));
960+
EXPECT_EQ(13, hourNtz("2024-01-20 13:23:00.001"));
961+
962+
// TIMESTAMP_NTZ should not be affected by session timezone.
963+
setQueryTimeZone("Pacific/Apia");
964+
965+
EXPECT_EQ(0, hourNtz("2024-01-08 00:23:00.001"));
966+
EXPECT_EQ(1, hourNtz("2024-01-08 01:23:00.001"));
967+
EXPECT_EQ(13, hourNtz("2024-01-20 13:23:00.001"));
968+
}
969+
946970
TEST_F(DateTimeFunctionsTest, minute) {
947971
const auto minute = [&](const StringView& timestampStr) {
948972
const auto timeStamp = std::make_optional(parseTimestamp(timestampStr));

0 commit comments

Comments
 (0)