/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.sql;
import com.facebook.presto.spi.PrestoException;
import io.airlift.joni.Regex;
import io.airlift.slice.Slice;
import io.airlift.slice.Slices;
import org.testng.annotations.Test;
import static com.facebook.presto.type.LikeFunctions.castCharToLikePattern;
import static com.facebook.presto.type.LikeFunctions.isLikePattern;
import static com.facebook.presto.type.LikeFunctions.like;
import static com.facebook.presto.type.LikeFunctions.likePattern;
import static com.facebook.presto.type.LikeFunctions.unescapeLiteralLikePattern;
import static io.airlift.slice.Slices.utf8Slice;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue;
public class TestLikeFunctions
{
@Test
public void testLikeBasic()
{
Regex regex = likePattern(utf8Slice("f%b__"));
assertTrue(like(utf8Slice("foobar"), regex));
}
@Test
public void testLikeSpacesInPattern()
{
Regex regex = likePattern(utf8Slice("ala "));
assertTrue(like(utf8Slice("ala "), regex));
assertFalse(like(utf8Slice("ala"), regex));
regex = castCharToLikePattern(5L, utf8Slice("ala"));
assertTrue(like(utf8Slice("ala "), regex));
assertFalse(like(utf8Slice("ala"), regex));
}
@Test
public void testLikeNewlineInPattern()
{
Regex regex = likePattern(utf8Slice("%o\nbar"));
assertTrue(like(utf8Slice("foo\nbar"), regex));
}
@Test
public void testLikeNewlineBeforeMatch()
{
Regex regex = likePattern(utf8Slice("%b%"));
assertTrue(like(utf8Slice("foo\nbar"), regex));
}
@Test
public void testLikeNewlineInMatch()
{
Regex regex = likePattern(utf8Slice("f%b%"));
assertTrue(like(utf8Slice("foo\nbar"), regex));
}
@Test(timeOut = 1000)
public void testLikeUtf8Pattern()
{
Regex regex = likePattern(utf8Slice("%\u540d\u8a89%"), utf8Slice("\\"));
assertFalse(like(utf8Slice("foo"), regex));
}
@SuppressWarnings("NumericCastThatLosesPrecision")
@Test(timeOut = 1000)
public void testLikeInvalidUtf8Value()
{
Slice value = Slices.wrappedBuffer(new byte[] {'a', 'b', 'c', (byte) 0xFF, 'x', 'y'});
Regex regex = likePattern(utf8Slice("%b%"), utf8Slice("\\"));
assertTrue(like(value, regex));
}
@Test
public void testBackslashesNoSpecialTreatment()
throws Exception
{
Regex regex = likePattern(utf8Slice("\\abc\\/\\\\"));
assertTrue(like(utf8Slice("\\abc\\/\\\\"), regex));
}
@Test
public void testSelfEscaping()
throws Exception
{
Regex regex = likePattern(utf8Slice("\\\\abc\\%"), utf8Slice("\\"));
assertTrue(like(utf8Slice("\\abc%"), regex));
}
@Test
public void testAlternateEscapedCharacters()
throws Exception
{
Regex regex = likePattern(utf8Slice("xxx%x_abcxx"), utf8Slice("x"));
assertTrue(like(utf8Slice("x%_abcx"), regex));
}
@Test
public void testInvalidLikePattern()
{
assertThrows(PrestoException.class, () -> likePattern(utf8Slice("#"), utf8Slice("#")));
assertThrows(PrestoException.class, () -> likePattern(utf8Slice("abc#abc"), utf8Slice("#")));
assertThrows(PrestoException.class, () -> likePattern(utf8Slice("abc#"), utf8Slice("#")));
}
@Test
public void testIsLikePattern()
{
assertFalse(isLikePattern(utf8Slice("abc"), null));
assertFalse(isLikePattern(utf8Slice("abc#_def"), utf8Slice("#")));
assertFalse(isLikePattern(utf8Slice("abc##def"), utf8Slice("#")));
assertFalse(isLikePattern(utf8Slice("abc#%def"), utf8Slice("#")));
assertTrue(isLikePattern(utf8Slice("abc%def"), null));
assertTrue(isLikePattern(utf8Slice("abcdef_"), null));
assertTrue(isLikePattern(utf8Slice("abcdef##_"), utf8Slice("#")));
assertTrue(isLikePattern(utf8Slice("%abcdef#_"), utf8Slice("#")));
assertThrows(PrestoException.class, () -> isLikePattern(utf8Slice("#"), utf8Slice("#")));
assertThrows(PrestoException.class, () -> isLikePattern(utf8Slice("abc#abc"), utf8Slice("#")));
assertThrows(PrestoException.class, () -> isLikePattern(utf8Slice("abc#"), utf8Slice("#")));
}
@Test
public void testUnescapeValidLikePattern()
{
assertEquals(unescapeLiteralLikePattern(utf8Slice("abc"), null), utf8Slice("abc"));
assertEquals(unescapeLiteralLikePattern(utf8Slice("abc#_"), utf8Slice("#")), utf8Slice("abc_"));
assertEquals(unescapeLiteralLikePattern(utf8Slice("a##bc#_"), utf8Slice("#")), utf8Slice("a#bc_"));
assertEquals(unescapeLiteralLikePattern(utf8Slice("a###_bc"), utf8Slice("#")), utf8Slice("a#_bc"));
}
}