From a5792a9312afcceccac676c3ed951b69c26a99a2 Mon Sep 17 00:00:00 2001 From: Laith Sakka Date: Thu, 5 Oct 2023 09:36:18 -0700 Subject: [PATCH] Fix: Explicit handle null pattern and escape in like function. (#6894) Summary: When value at constant vector is null we shall not call valueAt(). When i added a check in ConstantVector valueAt that value is not null i got other faluires I will address them in seperate PR then add the check. Differential Revision: D49917874 --- velox/expression/VectorFunction.h | 14 ++++++++++++++ velox/functions/lib/Re2Functions.cpp | 7 +++++++ velox/functions/lib/tests/Re2FunctionsTest.cpp | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/velox/expression/VectorFunction.h b/velox/expression/VectorFunction.h index 57f7fc516aa19..fce97137edc58 100644 --- a/velox/expression/VectorFunction.h +++ b/velox/expression/VectorFunction.h @@ -152,6 +152,20 @@ class AlwaysFailingVectorFunction final : public VectorFunction { std::exception_ptr exceptionPtr_; }; +// This functions is used when we know a function will never be called because +// it is default null with a literal null input value. For example like(c0, +// null). +class AlwaysNullDefaultNull final : public VectorFunction { + void apply( + const SelectivityVector&, + std::vector&, + const TypePtr&, + EvalCtx&, + VectorPtr&) const final { + VELOX_UNREACHABLE("Not expected to be called.") + } +}; + // Factory for functions which are template generated from simple functions. class SimpleFunctionAdapterFactory { public: diff --git a/velox/functions/lib/Re2Functions.cpp b/velox/functions/lib/Re2Functions.cpp index 6939a62bce32a..fd160ac33e6b7 100644 --- a/velox/functions/lib/Re2Functions.cpp +++ b/velox/functions/lib/Re2Functions.cpp @@ -947,6 +947,9 @@ std::shared_ptr makeLike( inputArgs[2].type->toString()); auto constantEscape = escape->as>(); + if (constantEscape->isNullAt(0)) { + return std::make_shared(); + } try { VELOX_USER_CHECK_EQ( @@ -966,6 +969,10 @@ std::shared_ptr makeLike( "{} requires second argument to be a constant of type VARCHAR", name, inputArgs[1].type->toString()); + if (constantPattern->isNullAt(0)) { + return std::make_shared(); + } + auto pattern = constantPattern->as>()->valueAt(0); if (!escapeChar) { PatternKind patternKind; diff --git a/velox/functions/lib/tests/Re2FunctionsTest.cpp b/velox/functions/lib/tests/Re2FunctionsTest.cpp index 1c640d57d612c..59a6e947d8447 100644 --- a/velox/functions/lib/tests/Re2FunctionsTest.cpp +++ b/velox/functions/lib/tests/Re2FunctionsTest.cpp @@ -593,6 +593,16 @@ TEST_F(Re2FunctionsTest, likePatternSuffix) { EXPECT_TRUE(like(input, generateString(kAnyWildcardCharacter) + input)); } +TEST_F(Re2FunctionsTest, nullConstantPatternOrEscape) { + // Test null pattern. + ASSERT_TRUE( + !evaluateOnce("like('a', cast (null as varchar))").has_value()); + + // Test null escape. + ASSERT_TRUE( + !evaluateOnce("like('a', 'a', cast(null as varchar))").has_value()); +} + TEST_F(Re2FunctionsTest, likePatternAndEscape) { auto like = ([&](std::optional str, std::optional pattern,