From 27b55d1ff1b8cef4f47403a3d48652b75831518e Mon Sep 17 00:00:00 2001 From: Masha Basmanova Date: Thu, 5 Oct 2023 06:26:24 -0700 Subject: [PATCH] Add ends_with Presto function (#6908) Summary: Pull Request resolved: https://github.com/facebookincubator/velox/pull/6908 Reviewed By: xiaoxmeng Differential Revision: D49948988 Pulled By: mbasmanova fbshipit-source-id: c64daed4a7e95b954b10c7034fbd8a1b4753321f --- velox/docs/functions/presto/string.rst | 4 ++++ velox/functions/prestosql/StringFunctions.h | 18 ++++++++++++++++++ .../StringFunctionsRegistration.cpp | 2 ++ .../prestosql/tests/StringFunctionsTest.cpp | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/velox/docs/functions/presto/string.rst b/velox/docs/functions/presto/string.rst index 9c36f45aad75d..cf2e19c972f71 100644 --- a/velox/docs/functions/presto/string.rst +++ b/velox/docs/functions/presto/string.rst @@ -33,6 +33,10 @@ String Functions This function provides the same functionality as the SQL-standard concatenation operator (``||``). +.. function:: ends_with(string, substring) -> boolean + + Returns whether ``string`` ends_with with ``substring``. + .. function:: from_utf8(binary) -> varchar Decodes a UTF-8 encoded string from ``binary``. Invalid UTF-8 sequences diff --git a/velox/functions/prestosql/StringFunctions.h b/velox/functions/prestosql/StringFunctions.h index ae2574cc87336..391b8996a169d 100644 --- a/velox/functions/prestosql/StringFunctions.h +++ b/velox/functions/prestosql/StringFunctions.h @@ -239,6 +239,24 @@ struct StartsWithFunction { } }; +template +struct EndsWithFunction { + VELOX_DEFINE_FUNCTION_TYPES(T); + + FOLLY_ALWAYS_INLINE void call( + out_type& result, + const arg_type& x, + const arg_type& y) { + if (x.size() < y.size()) { + result = false; + return; + } + + result = + (memcmp(x.data() + (x.size() - y.size()), y.data(), y.size()) == 0); + } +}; + /// Pad functions /// lpad(string, size, padString) → varchar /// Left pads string to size characters with padString. If size is diff --git a/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp b/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp index 05246377b258b..8d10256786f7c 100644 --- a/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp +++ b/velox/functions/prestosql/registration/StringFunctionsRegistration.cpp @@ -46,6 +46,8 @@ void registerSimpleFunctions(const std::string& prefix) { registerFunction( {prefix + "starts_with"}); + registerFunction( + {prefix + "ends_with"}); registerFunction( {prefix + "substr"}); diff --git a/velox/functions/prestosql/tests/StringFunctionsTest.cpp b/velox/functions/prestosql/tests/StringFunctionsTest.cpp index ef4e488bf87c8..8ee452314ede7 100644 --- a/velox/functions/prestosql/tests/StringFunctionsTest.cpp +++ b/velox/functions/prestosql/tests/StringFunctionsTest.cpp @@ -870,6 +870,24 @@ TEST_F(StringFunctionsTest, startsWith) { ASSERT_FALSE(startsWith("", " ")); } +TEST_F(StringFunctionsTest, endsWith) { + auto endsWith = [&](const std::string& x, const std::string& y) { + return evaluateOnce( + "ends_with(c0, c1)", std::optional(x), std::optional(y)) + .value(); + }; + + ASSERT_TRUE(endsWith("", "")); + ASSERT_TRUE(endsWith("Hello world!", "")); + ASSERT_TRUE(endsWith("Hello world!", "world!")); + ASSERT_TRUE(endsWith("Hello world!", "lo world!")); + ASSERT_TRUE(endsWith("Hello world!", "Hello world!")); + + ASSERT_FALSE(endsWith("Hello world!", " Hello world!")); + ASSERT_FALSE(endsWith("Hello world!", "hello")); + ASSERT_FALSE(endsWith("", " ")); +} + // Test strpos function template void StringFunctionsTest::testStringPositionAllFlatVector(