/*
* 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.planner;
import com.facebook.presto.metadata.Metadata;
import com.facebook.presto.metadata.MetadataManager;
import com.facebook.presto.operator.project.InterpretedPageFilter;
import com.facebook.presto.operator.project.SelectedPositions;
import com.facebook.presto.spi.Page;
import com.facebook.presto.sql.parser.SqlParser;
import com.facebook.presto.sql.tree.ComparisonExpressionType;
import com.google.common.collect.ImmutableMap;
import org.testng.annotations.Test;
import static com.facebook.presto.SessionTestUtils.TEST_SESSION;
import static com.facebook.presto.operator.scalar.FunctionAssertions.createExpression;
import static java.lang.String.format;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
public class TestInterpretedPageFilterFunction
{
private static final SqlParser SQL_PARSER = new SqlParser();
private static final Metadata METADATA = MetadataManager.createTestMetadataManager();
@Test
public void testNullLiteral()
{
assertFilter("null", false);
}
@Test
public void testBooleanLiteral()
{
assertFilter("true", true);
assertFilter("false", false);
}
@Test
public void testNotExpression()
{
assertFilter("not true", false);
assertFilter("not false", true);
assertFilter("not null", false);
}
@Test
public void testAndExpression()
{
assertFilter("true and true", true);
assertFilter("true and false", false);
assertFilter("true and null", false);
assertFilter("false and true", false);
assertFilter("false and false", false);
assertFilter("false and null", false);
assertFilter("null and true", false);
assertFilter("null and false", false);
assertFilter("null and null", false);
}
@Test
public void testORExpression()
{
assertFilter("true or true", true);
assertFilter("true or false", true);
assertFilter("true or null", true);
assertFilter("false or true", true);
assertFilter("false or false", false);
assertFilter("false or null", false);
assertFilter("null or true", true);
assertFilter("null or false", false);
assertFilter("null or null", false);
}
@Test
public void testIsNullExpression()
{
assertFilter("null is null", true);
assertFilter("42 is null", false);
}
@Test
public void testIsNotNullExpression()
{
assertFilter("42 is not null", true);
assertFilter("null is not null", false);
}
@Test
public void testComparisonExpression()
{
assertFilter("42 = 42", true);
assertFilter("42 = 42.0", true);
assertFilter("42.42 = 42.42", true);
assertFilter("'foo' = 'foo'", true);
assertFilter("42 = 87", false);
assertFilter("42 = 22.2", false);
assertFilter("42.42 = 22.2", false);
assertFilter("'foo' = 'bar'", false);
assertFilter("42 != 87", true);
assertFilter("42 != 22.2", true);
assertFilter("42.42 != 22.22", true);
assertFilter("'foo' != 'bar'", true);
assertFilter("42 != 42", false);
assertFilter("42 != 42.0", false);
assertFilter("42.42 != 42.42", false);
assertFilter("'foo' != 'foo'", false);
assertFilter("42 < 88", true);
assertFilter("42 < 88.8", true);
assertFilter("42.42 < 88.8", true);
assertFilter("'bar' < 'foo'", true);
assertFilter("88 < 42", false);
assertFilter("88 < 42.42", false);
assertFilter("88.8 < 42.42", false);
assertFilter("'foo' < 'bar'", false);
assertFilter("42 <= 88", true);
assertFilter("42 <= 88.8", true);
assertFilter("42.42 <= 88.8", true);
assertFilter("'bar' <= 'foo'", true);
assertFilter("42 <= 42", true);
assertFilter("42 <= 42.0", true);
assertFilter("42.42 <= 42.42", true);
assertFilter("'foo' <= 'foo'", true);
assertFilter("88 <= 42", false);
assertFilter("88 <= 42.42", false);
assertFilter("88.8 <= 42.42", false);
assertFilter("'foo' <= 'bar'", false);
assertFilter("88 >= 42", true);
assertFilter("88.8 >= 42.0", true);
assertFilter("88.8 >= 42.42", true);
assertFilter("'foo' >= 'bar'", true);
assertFilter("42 >= 88", false);
assertFilter("42.42 >= 88.0", false);
assertFilter("42.42 >= 88.88", false);
assertFilter("'bar' >= 'foo'", false);
assertFilter("88 >= 42", true);
assertFilter("88.8 >= 42.0", true);
assertFilter("88.8 >= 42.42", true);
assertFilter("'foo' >= 'bar'", true);
assertFilter("42 >= 42", true);
assertFilter("42 >= 42.0", true);
assertFilter("42.42 >= 42.42", true);
assertFilter("'foo' >= 'foo'", true);
assertFilter("42 >= 88", false);
assertFilter("42.42 >= 88.0", false);
assertFilter("42.42 >= 88.88", false);
assertFilter("'bar' >= 'foo'", false);
}
@Test
public void testComparisonExpressionWithNulls()
{
for (ComparisonExpressionType type : ComparisonExpressionType.values()) {
if (type == ComparisonExpressionType.IS_DISTINCT_FROM) {
// IS DISTINCT FROM has different NULL semantics
continue;
}
assertFilter(format("NULL %s NULL", type.getValue()), false);
assertFilter(format("42 %s NULL", type.getValue()), false);
assertFilter(format("NULL %s 42", type.getValue()), false);
assertFilter(format("11.1 %s NULL", type.getValue()), false);
assertFilter(format("NULL %s 11.1", type.getValue()), false);
}
}
private static void assertFilter(String expression, boolean expectedValue)
{
InterpretedPageFilter filterFunction = new InterpretedPageFilter(
createExpression(expression, METADATA, ImmutableMap.of()),
ImmutableMap.of(),
ImmutableMap.of(),
METADATA,
SQL_PARSER,
TEST_SESSION);
SelectedPositions selectedPositions = filterFunction.filter(TEST_SESSION.toConnectorSession(), new Page(1));
assertEquals(selectedPositions.size(), expectedValue ? 1 : 0);
if (expectedValue) {
if (selectedPositions.isList()) {
assertEquals(selectedPositions.getPositions()[selectedPositions.getOffset()], 0);
}
else {
assertEquals(selectedPositions.getOffset(), 0);
}
}
else {
assertTrue(selectedPositions.isEmpty());
}
}
}