From 312326effa72026db10579fc820225fc4a8a79ed Mon Sep 17 00:00:00 2001 From: Laith Sakka Date: Wed, 4 Oct 2023 10:31:29 -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(). This added check in ConstantVector and also make sure like function handles null explicitly. Differential Revision: D49917874 --- velox/functions/lib/Re2Functions.cpp | 19 +++++++++++++++++++ .../functions/lib/tests/Re2FunctionsTest.cpp | 10 ++++++++++ velox/vector/ConstantVector.h | 1 + 3 files changed, 30 insertions(+) diff --git a/velox/functions/lib/Re2Functions.cpp b/velox/functions/lib/Re2Functions.cpp index 6939a62bce32a..bb9791c71cdea 100644 --- a/velox/functions/lib/Re2Functions.cpp +++ b/velox/functions/lib/Re2Functions.cpp @@ -470,6 +470,18 @@ class OptimizedLikeWithMemcmp final : public VectorFunction { vector_size_t reducedPatternLength_; }; +// This functions is constructed when the input is a constant null. +class AlwaysNull final : public VectorFunction { + void apply( + const SelectivityVector& rows, + std::vector& args, + const TypePtr& /* outputType */, + EvalCtx& context, + VectorPtr& resultRef) const final { + VELOX_UNREACHABLE("Not expected to be called.") + } +}; + class LikeWithRe2 final : public VectorFunction { public: LikeWithRe2(StringView pattern, std::optional escapeChar) { @@ -947,6 +959,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 +981,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, diff --git a/velox/vector/ConstantVector.h b/velox/vector/ConstantVector.h index 9eb41b6e6cad8..7b74805dcd19c 100644 --- a/velox/vector/ConstantVector.h +++ b/velox/vector/ConstantVector.h @@ -160,6 +160,7 @@ class ConstantVector final : public SimpleVector { } virtual const T valueAt(vector_size_t /*idx*/) const override { + VELOX_DCHECK(!isNullAt(0)); VELOX_DCHECK(initialized_); SimpleVector::checkElementSize(); return value();