diff --git a/velox/functions/sparksql/Arithmetic.h b/velox/functions/sparksql/Arithmetic.h index c77c317613d7..3e4027a98ba7 100644 --- a/velox/functions/sparksql/Arithmetic.h +++ b/velox/functions/sparksql/Arithmetic.h @@ -165,4 +165,44 @@ struct FloorFunction { } }; +template +struct AcoshFunction { + template + FOLLY_ALWAYS_INLINE void call(TInput& result, TInput a) { + result = std::acosh(a); + } +}; + +template +struct AsinhFunction { + template + FOLLY_ALWAYS_INLINE void call(TInput& result, TInput a) { + result = std::asinh(a); + } +}; + +template +struct AtanhFunction { + template + FOLLY_ALWAYS_INLINE void call(TInput& result, TInput a) { + result = std::atanh(a); + } +}; + +template +struct SecFunction { + template + FOLLY_ALWAYS_INLINE void call(TInput& result, TInput a) { + result = 1 / std::cos(a); + } +}; + +template +struct CscFunction { + template + FOLLY_ALWAYS_INLINE void call(TInput& result, TInput a) { + result = 1 / std::sin(a); + } +}; + } // namespace facebook::velox::functions::sparksql diff --git a/velox/functions/sparksql/RegisterArithmetic.cpp b/velox/functions/sparksql/RegisterArithmetic.cpp index ef7f4af93abf..b64b35f134e1 100644 --- a/velox/functions/sparksql/RegisterArithmetic.cpp +++ b/velox/functions/sparksql/RegisterArithmetic.cpp @@ -31,6 +31,11 @@ void registerArithmeticFunctions(const std::string& prefix) { registerUnaryNumeric({prefix + "unaryminus"}); // Math functions. registerUnaryNumeric({prefix + "abs"}); + registerFunction({prefix + "acosh"}); + registerFunction({prefix + "asinh"}); + registerFunction({prefix + "atanh"}); + registerFunction({prefix + "sec"}); + registerFunction({prefix + "csc"}); registerFunction({prefix + "exp"}); registerBinaryIntegral({prefix + "pmod"}); registerBinaryFloatingPoint({prefix + "pmod"}); diff --git a/velox/functions/sparksql/tests/ArithmeticTest.cpp b/velox/functions/sparksql/tests/ArithmeticTest.cpp index 3832f41c48c1..b38c064c0e30 100644 --- a/velox/functions/sparksql/tests/ArithmeticTest.cpp +++ b/velox/functions/sparksql/tests/ArithmeticTest.cpp @@ -195,6 +195,64 @@ TEST_F(ArithmeticTest, Divide) { EXPECT_TRUE(std::isnan(divide(kInf, -kInf).value_or(0))); } +TEST_F(ArithmeticTest, acosh) { + const auto acosh = [&](std::optional a) { + return evaluateOnce("acosh(c0)", a); + }; + + EXPECT_EQ(acosh(1), 0); + EXPECT_TRUE(std::isnan(acosh(0).value_or(0))); + EXPECT_EQ(acosh(kInf), kInf); + EXPECT_EQ(acosh(std::nullopt), std::nullopt); + EXPECT_TRUE(std::isnan(acosh(kNan).value_or(0))); +} + +TEST_F(ArithmeticTest, asinh) { + const auto asinh = [&](std::optional a) { + return evaluateOnce("asinh(c0)", a); + }; + + EXPECT_EQ(asinh(0), 0); + EXPECT_EQ(asinh(kInf), kInf); + EXPECT_EQ(asinh(-kInf), -kInf); + EXPECT_EQ(asinh(std::nullopt), std::nullopt); + EXPECT_TRUE(std::isnan(asinh(kNan).value_or(0))); +} + +TEST_F(ArithmeticTest, atanh) { + const auto atanh = [&](std::optional a) { + return evaluateOnce("atanh(c0)", a); + }; + + EXPECT_EQ(atanh(0), 0); + EXPECT_EQ(atanh(1), kInf); + EXPECT_EQ(atanh(-1), -kInf); + EXPECT_TRUE(std::isnan(atanh(1.1).value_or(0))); + EXPECT_TRUE(std::isnan(atanh(-1.1).value_or(0))); + EXPECT_EQ(atanh(std::nullopt), std::nullopt); + EXPECT_TRUE(std::isnan(atanh(kNan).value_or(0))); +} + +TEST_F(ArithmeticTest, sec) { + const auto sec = [&](std::optional a) { + return evaluateOnce("sec(c0)", a); + }; + + EXPECT_EQ(sec(0), 1); + EXPECT_EQ(sec(std::nullopt), std::nullopt); + EXPECT_TRUE(std::isnan(sec(kNan).value_or(0))); +} + +TEST_F(ArithmeticTest, csc) { + const auto csc = [&](std::optional a) { + return evaluateOnce("csc(c0)", a); + }; + + EXPECT_EQ(csc(0), kInf); + EXPECT_EQ(csc(std::nullopt), std::nullopt); + EXPECT_TRUE(std::isnan(csc(kNan).value_or(0))); +} + class CeilFloorTest : public SparkFunctionBaseTest { protected: template