@@ -33,6 +33,16 @@ class TestLikeHolder : public ::testing::Test {
3333 std::make_shared<LiteralNode>(arrow::utf8 (), LiteralHolder (pattern), false );
3434 return FunctionNode (" like" , {field, pattern_node}, arrow::boolean ());
3535 }
36+
37+ FunctionNode BuildLike (std::string pattern, char escape_char) {
38+ auto field = std::make_shared<FieldNode>(arrow::field (" in" , arrow::utf8 ()));
39+ auto pattern_node =
40+ std::make_shared<LiteralNode>(arrow::utf8 (), LiteralHolder (pattern), false );
41+ auto escape_char_node = std::make_shared<LiteralNode>(
42+ arrow::int8 (), LiteralHolder ((int8_t )escape_char), false );
43+ return FunctionNode (" like" , {field, pattern_node, escape_char_node},
44+ arrow::boolean ());
45+ }
3646};
3747
3848TEST_F (TestLikeHolder, TestMatchAny) {
@@ -125,6 +135,80 @@ TEST_F(TestLikeHolder, TestOptimise) {
125135
126136 fnode = LikeHolder::TryOptimize (BuildLike (" x_yz%" ));
127137 EXPECT_EQ (fnode.descriptor ()->name (), " like" );
138+
139+ // no optimisation for escaped pattern.
140+ fnode = LikeHolder::TryOptimize (BuildLike (" \\ %xyz" , ' \\ ' ));
141+ EXPECT_EQ (fnode.descriptor ()->name (), " like" );
142+ EXPECT_EQ (fnode.ToString (),
143+ " bool like((string) in, (const string) \\ %xyz, (const int8) \\ )" );
144+ }
145+
146+ TEST_F (TestLikeHolder, TestMatchOneEscape) {
147+ std::shared_ptr<LikeHolder> like_holder;
148+
149+ auto status = LikeHolder::Make (" ab\\ _" , " \\ " , &like_holder);
150+ EXPECT_EQ (status.ok (), true ) << status.message ();
151+
152+ auto & like = *like_holder;
153+
154+ EXPECT_TRUE (like (" ab_" ));
155+
156+ EXPECT_FALSE (like (" abc" ));
157+ EXPECT_FALSE (like (" abd" ));
158+ EXPECT_FALSE (like (" a" ));
159+ EXPECT_FALSE (like (" abcd" ));
160+ EXPECT_FALSE (like (" dabc" ));
161+ }
162+
163+ TEST_F (TestLikeHolder, TestMatchManyEscape) {
164+ std::shared_ptr<LikeHolder> like_holder;
165+
166+ auto status = LikeHolder::Make (" ab\\ %" , " \\ " , &like_holder);
167+ EXPECT_EQ (status.ok (), true ) << status.message ();
168+
169+ auto & like = *like_holder;
170+
171+ EXPECT_TRUE (like (" ab%" ));
172+
173+ EXPECT_FALSE (like (" abc" ));
174+ EXPECT_FALSE (like (" abd" ));
175+ EXPECT_FALSE (like (" a" ));
176+ EXPECT_FALSE (like (" abcd" ));
177+ EXPECT_FALSE (like (" dabc" ));
178+ }
179+
180+ TEST_F (TestLikeHolder, TestMatchEscape) {
181+ std::shared_ptr<LikeHolder> like_holder;
182+
183+ auto status = LikeHolder::Make (" ab\\\\ " , " \\ " , &like_holder);
184+ EXPECT_EQ (status.ok (), true ) << status.message ();
185+
186+ auto & like = *like_holder;
187+
188+ EXPECT_TRUE (like (" ab\\ " ));
189+
190+ EXPECT_FALSE (like (" abc" ));
128191}
129192
193+ TEST_F (TestLikeHolder, TestEmptyEscapeChar) {
194+ std::shared_ptr<LikeHolder> like_holder;
195+
196+ auto status = LikeHolder::Make (" ab\\ _" , " " , &like_holder);
197+ EXPECT_EQ (status.ok (), true ) << status.message ();
198+
199+ auto & like = *like_holder;
200+
201+ EXPECT_TRUE (like (" ab\\ c" ));
202+ EXPECT_TRUE (like (" ab\\ _" ));
203+
204+ EXPECT_FALSE (like (" ab\\ _d" ));
205+ EXPECT_FALSE (like (" ab__" ));
206+ }
207+
208+ TEST_F (TestLikeHolder, TestMultipleEscapeChar) {
209+ std::shared_ptr<LikeHolder> like_holder;
210+
211+ auto status = LikeHolder::Make (" ab\\ _" , " \\\\ " , &like_holder);
212+ EXPECT_EQ (status.ok (), false ) << status.message ();
213+ }
130214} // namespace gandiva
0 commit comments