/**
* 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.queries;
import com.linkedin.pinot.common.data.FieldSpec;
import com.linkedin.pinot.common.data.Schema;
import com.linkedin.pinot.common.segment.ReadMode;
import com.linkedin.pinot.core.data.manager.offline.OfflineSegmentDataManager;
import com.linkedin.pinot.core.data.manager.offline.SegmentDataManager;
import com.linkedin.pinot.core.indexsegment.IndexSegment;
import com.linkedin.pinot.core.indexsegment.columnar.ColumnarSegmentLoader;
import com.linkedin.pinot.core.indexsegment.generator.SegmentGeneratorConfig;
import com.linkedin.pinot.core.segment.creator.SegmentIndexCreationDriver;
import com.linkedin.pinot.core.segment.creator.impl.SegmentIndexCreationDriverImpl;
import java.io.File;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeTest;
/**
* The <code>BaseSingleValueQueriesTest</code> class sets up the index segment for the single-value queries test.
* <p>There are totally 18 columns, 30000 records inside the original Avro file where 11 columns are selected to build
* the index segment. Selected columns information are as following:
* <ul>
* ColumnName, FieldType, DataType, Cardinality, IsSorted, HasInvertedIndex
* <li>column1, METRIC, INT, 6582, F, F</li>
* <li>column3, METRIC, INT, 21910, F, F</li>
* <li>column5, DIMENSION, STRING, 1, T, F</li>
* <li>column6, DIMENSION, INT, 608, F, T</li>
* <li>column7, DIMENSION, INT, 146, F, T</li>
* <li>column9, DIMENSION, INT, 1737, F, F</li>
* <li>column11, DIMENSION, STRING, 5, F, T</li>
* <li>column12, DIMENSION, STRING, 5, F, F</li>
* <li>column17, METRIC, INT, 24, F, T</li>
* <li>column18, METRIC, INT, 1440, F, T</li>
* <li>daysSinceEpoch, TIME, INT, 2, T, F</li>
* </ul>
*/
public abstract class BaseSingleValueQueriesTest extends BaseQueriesTest {
private static final String AVRO_DATA = "data/test_data-sv.avro";
private static final String SEGMENT_NAME = "testTable_126164076_167572854";
private static final File INDEX_DIR = new File(FileUtils.getTempDirectory(), "SingleValueQueriesTest");
// Hard-coded query filter.
private static final String QUERY_FILTER =
" WHERE column1 > 100000000"
+ " AND column3 BETWEEN 20000000 AND 1000000000"
+ " AND column5 = 'gFuH'"
+ " AND (column6 < 500000000 OR column11 NOT IN ('t', 'P'))"
+ " AND daysSinceEpoch = 126164076";
private IndexSegment _indexSegment;
// Contains 2 identical index segments.
private List<SegmentDataManager> _segmentDataManagers;
@BeforeTest
public void buildSegment()
throws Exception {
FileUtils.deleteQuietly(INDEX_DIR);
// Get resource file path.
URL resource = getClass().getClassLoader().getResource(AVRO_DATA);
Assert.assertNotNull(resource);
String filePath = resource.getFile();
// Build the segment schema.
Schema schema = new Schema.SchemaBuilder().setSchemaName("testTable")
.addMetric("column1", FieldSpec.DataType.INT)
.addMetric("column3", FieldSpec.DataType.INT)
.addSingleValueDimension("column5", FieldSpec.DataType.STRING)
.addSingleValueDimension("column6", FieldSpec.DataType.INT)
.addSingleValueDimension("column7", FieldSpec.DataType.INT)
.addSingleValueDimension("column9", FieldSpec.DataType.INT)
.addSingleValueDimension("column11", FieldSpec.DataType.STRING)
.addSingleValueDimension("column12", FieldSpec.DataType.STRING)
.addMetric("column17", FieldSpec.DataType.INT)
.addMetric("column18", FieldSpec.DataType.INT)
.addTime("daysSinceEpoch", TimeUnit.DAYS, FieldSpec.DataType.INT)
.build();
// Create the segment generator config.
SegmentGeneratorConfig segmentGeneratorConfig = new SegmentGeneratorConfig(schema);
segmentGeneratorConfig.setInputFilePath(filePath);
segmentGeneratorConfig.setTableName("testTable");
segmentGeneratorConfig.setOutDir(INDEX_DIR.getAbsolutePath());
segmentGeneratorConfig.setInvertedIndexCreationColumns(
Arrays.asList("column6", "column7", "column11", "column17", "column18"));
// Build the index segment.
SegmentIndexCreationDriver driver = new SegmentIndexCreationDriverImpl();
driver.init(segmentGeneratorConfig);
driver.build();
}
@BeforeClass
public void loadSegment()
throws Exception {
_indexSegment = ColumnarSegmentLoader.load(new File(INDEX_DIR, SEGMENT_NAME), ReadMode.heap);
_segmentDataManagers = Arrays.<SegmentDataManager>asList(new OfflineSegmentDataManager(_indexSegment),
new OfflineSegmentDataManager(_indexSegment));
}
@AfterClass
public void destroySegment() {
_indexSegment.destroy();
}
@AfterTest
public void deleteSegment() {
FileUtils.deleteQuietly(INDEX_DIR);
}
@Override
protected String getFilter() {
return QUERY_FILTER;
}
@Override
protected IndexSegment getIndexSegment() {
return _indexSegment;
}
@Override
protected List<SegmentDataManager> getSegmentDataManagers() {
return _segmentDataManagers;
}
}