package com.taobao.tddl.optimizer.costbased;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import com.taobao.tddl.common.model.ExtraCmd;
import com.taobao.tddl.optimizer.BaseOptimizerTest;
import com.taobao.tddl.optimizer.config.table.IndexMeta;
import com.taobao.tddl.optimizer.core.ast.QueryTreeNode.FilterType;
import com.taobao.tddl.optimizer.core.ast.query.TableNode;
import com.taobao.tddl.optimizer.core.expression.IFilter;
import com.taobao.tddl.optimizer.core.expression.ISelectable;
import com.taobao.tddl.optimizer.costbased.chooser.IndexChooser;
import com.taobao.tddl.optimizer.utils.FilterUtils;
public class FilterSpliterTest extends BaseOptimizerTest {
@Test
public void test_主键索引条件() {
TableNode table = new TableNode("TABLE1");
table.query("ID = 1");
build(table);
Map<FilterType, IFilter> result = FilterSpliter.splitByIndex(FilterUtils.toDNFNode(table.getWhereFilter()),
table);
Assert.assertEquals("TABLE1.ID = 1", result.get(FilterType.IndexQueryKeyFilter).toString());
Assert.assertEquals(null, result.get(FilterType.IndexQueryValueFilter));
Assert.assertEquals(null, result.get(FilterType.ResultFilter));
}
@Test
public void test_主键索引条件_特殊条件不走索引() {
TableNode table = new TableNode("TABLE1");
table.query("ID != 1 AND ID IS NULL AND ID IS NOT NULL AND ID LIKE '%A' AND ID = 2");
build(table);
Map<FilterType, IFilter> result = FilterSpliter.splitByIndex(FilterUtils.toDNFNode(table.getWhereFilter()),
table);
Assert.assertEquals("TABLE1.ID = 2", result.get(FilterType.IndexQueryKeyFilter).toString());
Assert.assertEquals("(TABLE1.ID != 1 AND TABLE1.ID IS NULL AND TABLE1.ID IS NOT NULL AND TABLE1.ID LIKE %A)",
result.get(FilterType.IndexQueryValueFilter).toString());
Assert.assertEquals(null, result.get(FilterType.ResultFilter));
}
@Test
public void test_二级索引条件() {
TableNode table = new TableNode("TABLE1");
table.query("NAME = 1");
build(table);
Map<FilterType, IFilter> result = FilterSpliter.splitByIndex(FilterUtils.toDNFNode(table.getWhereFilter()),
table);
Assert.assertEquals("TABLE1.NAME = 1", result.get(FilterType.IndexQueryKeyFilter).toString());
Assert.assertEquals(null, result.get(FilterType.IndexQueryValueFilter));
Assert.assertEquals(null, result.get(FilterType.ResultFilter));
}
@Test
public void test_混合索引条件() {
TableNode table = new TableNode("TABLE1");
table.query("NAME = 1 AND SCHOOL = 2 AND ID > 3");
build(table); // 会选择NAME做索引,因为=的选择度高,优先选择
Map<FilterType, IFilter> result = FilterSpliter.splitByIndex(FilterUtils.toDNFNode(table.getWhereFilter()),
table);
Assert.assertEquals("TABLE1.NAME = 1", result.get(FilterType.IndexQueryKeyFilter).toString());
Assert.assertEquals("TABLE1.ID > 3", result.get(FilterType.IndexQueryValueFilter).toString());
Assert.assertEquals("TABLE1.SCHOOL = 2", result.get(FilterType.ResultFilter).toString());
}
@Test
public void test_无索引条件() {
TableNode table = new TableNode("TABLE1");
table.query("SCHOOL = 2");
build(table); // 无索引,默认选择主键做遍历
Map<FilterType, IFilter> result = FilterSpliter.splitByIndex(FilterUtils.toDNFNode(table.getWhereFilter()),
table);
Assert.assertEquals(null, result.get(FilterType.IndexQueryKeyFilter));
Assert.assertEquals("TABLE1.SCHOOL = 2", result.get(FilterType.IndexQueryValueFilter).toString());
Assert.assertEquals(null, result.get(FilterType.ResultFilter));
}
private void build(TableNode table) {
table.build();
Map<String, Object> extraCmd = new HashMap<String, Object>();
extraCmd.put(ExtraCmd.CHOOSE_INDEX, true);
IndexMeta index = IndexChooser.findBestIndex(table.getTableMeta(),
new ArrayList<ISelectable>(),
FilterUtils.toDNFNode(table.getWhereFilter()),
table.getTableName(),
extraCmd);
table.useIndex(index);
}
}