Skip to content

Commit

Permalink
Add quarter function support in spark sql (7111)
Browse files Browse the repository at this point in the history
  • Loading branch information
rui-mo authored and PHILO-HE committed Oct 29, 2023
1 parent bd97e01 commit ee1283a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
28 changes: 28 additions & 0 deletions velox/functions/sparksql/DateTimeFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,4 +372,32 @@ struct AddMonthsFunction {
result = daysSinceEpoch;
}
};

template <typename T>
struct QuarterFunction : public InitSessionTimezone<T>,
public TimestampWithTimezoneSupport<T> {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE int32_t getQuarter(const std::tm& time) {
return time.tm_mon / 3 + 1;
}

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

FOLLY_ALWAYS_INLINE void call(int32_t& result, const arg_type<Date>& date) {
result = getQuarter(getDateTime(date));
}

FOLLY_ALWAYS_INLINE void call(
int32_t& result,
const arg_type<TimestampWithTimezone>& timestampWithTimezone) {
auto timestamp = this->toTimestamp(timestampWithTimezone);
result = getQuarter(getDateTime(timestamp, nullptr));
}
};

} // namespace facebook::velox::functions::sparksql
3 changes: 3 additions & 0 deletions velox/functions/sparksql/Register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ void registerFunctions(const std::string& prefix) {
registerFunction<DayOfWeekFunction, int32_t, Date>(
{prefix + "dow", prefix + "dayofweek"});

registerFunction<QuarterFunction, int32_t, Timestamp>({prefix + "quarter"});
registerFunction<QuarterFunction, int32_t, Date>({prefix + "quarter"});

// Register bloom filter function
registerFunction<BloomFilterMightContainFunction, bool, Varbinary, int64_t>(
{prefix + "might_contain"});
Expand Down
38 changes: 38 additions & 0 deletions velox/functions/sparksql/tests/DateTimeFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,5 +431,43 @@ TEST_F(DateTimeFunctionsTest, addMonths) {
addMonths("2023-07-10", kMax),
fmt::format("Integer overflow in add_months(2023-07-10, {})", kMax));
}

TEST_F(DateTimeFunctionsTest, quarter) {
const auto quarter = [&](std::optional<Timestamp> date) {
return evaluateOnce<int32_t>("quarter(c0)", date);
};
EXPECT_EQ(std::nullopt, quarter(std::nullopt));
EXPECT_EQ(1, quarter(Timestamp(0, 0)));
EXPECT_EQ(4, quarter(Timestamp(-1, 9000)));
EXPECT_EQ(4, quarter(Timestamp(4000000000, 0)));
EXPECT_EQ(4, quarter(Timestamp(4000000000, 123000000)));
EXPECT_EQ(2, quarter(Timestamp(990000000, 321000000)));
EXPECT_EQ(3, quarter(Timestamp(998423705, 321000000)));

setQueryTimeZone("Pacific/Apia");

EXPECT_EQ(std::nullopt, quarter(std::nullopt));
EXPECT_EQ(4, quarter(Timestamp(0, 0)));
EXPECT_EQ(4, quarter(Timestamp(-1, Timestamp::kMaxNanos)));
EXPECT_EQ(4, quarter(Timestamp(4000000000, 0)));
EXPECT_EQ(4, quarter(Timestamp(4000000000, 123000000)));
EXPECT_EQ(2, quarter(Timestamp(990000000, 321000000)));
EXPECT_EQ(3, quarter(Timestamp(998423705, 321000000)));
}

TEST_F(DateTimeFunctionsTest, quarterDate) {
const auto quarter = [&](std::optional<int32_t> date) {
return evaluateOnce<int32_t, int32_t>("quarter(c0)", {date}, {DATE()});
};
EXPECT_EQ(std::nullopt, quarter(std::nullopt));
EXPECT_EQ(1, quarter(0));
EXPECT_EQ(4, quarter(-1));
EXPECT_EQ(4, quarter(-40));
EXPECT_EQ(2, quarter(110));
EXPECT_EQ(3, quarter(200));
EXPECT_EQ(1, quarter(18262));
EXPECT_EQ(1, quarter(-18262));
}

} // namespace
} // namespace facebook::velox::functions::sparksql::test

0 comments on commit ee1283a

Please sign in to comment.