/**
* Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com)
*
* 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.linkedin.pinot.query.pruner;
import com.linkedin.pinot.common.data.FieldSpec;
import com.linkedin.pinot.common.request.BrokerRequest;
import com.linkedin.pinot.common.utils.request.FilterQueryTree;
import com.linkedin.pinot.common.utils.request.RequestUtils;
import com.linkedin.pinot.core.query.pruner.ColumnValueSegmentPruner;
import com.linkedin.pinot.core.segment.index.ColumnMetadata;
import com.linkedin.pinot.pql.parsers.Pql2Compiler;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import junit.framework.Assert;
import org.testng.annotations.Test;
/**
* Unit tests for {@link ColumnValueSegmentPruner} class.
*/
public class ColumnValueSegmentPrunerTest {
private static final Pql2Compiler COMPILER = new Pql2Compiler();
private static final Map<String, ColumnMetadata> COLUMN_METADATA_MAP = new HashMap<>();
static {
COLUMN_METADATA_MAP.put("time", new ColumnMetadata.Builder().setColumnName("time")
.setFieldType(FieldSpec.FieldType.TIME)
.setDataType(FieldSpec.DataType.INT)
.setTimeUnit(TimeUnit.DAYS)
.setMinValue(10)
.setMaxValue(20)
.build());
COLUMN_METADATA_MAP.put("foo", new ColumnMetadata.Builder().setColumnName("foo")
.setFieldType(FieldSpec.FieldType.DIMENSION)
.setDataType(FieldSpec.DataType.STRING)
.build());
}
@Test
public void test() {
// Query without time predicate
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE foo = 'bar'"));
// Equality predicate
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time = 0"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time = 10"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time = 20"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time = 30"));
// Range predicate
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time < 10"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time <= 10"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time >= 10"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time > 20"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time BETWEEN 20 AND 30"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time BETWEEN 30 AND 40"));
// Invalid range predicate
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time BETWEEN 20 AND 10"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time BETWEEN 30 AND 20"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time BETWEEN 10 AND 10"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time BETWEEN 20 AND 20"));
// AND operator
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time = 0 AND time > 10"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time > 0 AND time < 10"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time >= 0 AND time <= 10"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time > 20 AND time < 10"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time >= 20 AND time < 30"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time > 0 AND time BETWEEN 0 AND 10"));
// OR operator
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time = 0 OR time > 10"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time = 0 OR time < 10"));
Assert.assertFalse(runPruner("SELECT COUNT(*) FROM table WHERE time >= 0 OR time <= 10"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time > 30 OR time < 10"));
Assert.assertTrue(runPruner("SELECT COUNT(*) FROM table WHERE time BETWEEN 0 AND 5 OR time BETWEEN 30 AND 35"));
}
private boolean runPruner(String query) {
BrokerRequest brokerRequest = COMPILER.compileToBrokerRequest(query);
FilterQueryTree filterQueryTree = RequestUtils.generateFilterQueryTree(brokerRequest);
ColumnValueSegmentPruner pruner = new ColumnValueSegmentPruner();
return pruner.pruneSegment(filterQueryTree, COLUMN_METADATA_MAP);
}
}