package com.taobao.tddl.optimizer.utils;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import com.taobao.tddl.optimizer.core.ASTNodeFactory;
import com.taobao.tddl.optimizer.core.expression.IBooleanFilter;
import com.taobao.tddl.optimizer.core.expression.IFilter;
import com.taobao.tddl.optimizer.core.expression.IFilter.OPERATION;
import com.taobao.tddl.optimizer.core.expression.ILogicalFilter;
import com.taobao.tddl.optimizer.exceptions.EmptyResultFilterException;
/**
* @author jianghang 2013-11-13 下午4:57:52
* @since 5.0.0
*/
public class FilterUtilsTest {
@Test
public void testDNF() {
// ( ( A and D ) or B) and C
IFilter filter = and(or(and(filter("A"), filter("D")), filter("B")), filter("C"));
// 结果: ((A and D) and C) or (B and C),没有拉平
Assert.assertEquals(or(newAnd(and(filter("A"), filter("D")), filter("C")), and(filter("B"), filter("C"))),
FilterUtils.toDNF(filter));
// 结果: (A and D and C) or (B and C), 拉平处理
Assert.assertEquals(or(and(and(filter("A"), filter("D")), filter("C")), and(filter("B"), filter("C"))),
FilterUtils.toDNFAndFlat(filter));
Assert.assertEquals(Arrays.asList(Arrays.asList(filter("A"), filter("D"), filter("C")),
Arrays.asList(filter("B"), filter("C"))),
FilterUtils.toDNFNodesArray(FilterUtils.toDNF(filter)));
}
@Test
public void testMerge() {
try {
// 1 < A < 10
IFilter filter = and(filter("A", 1, OPERATION.GT), filter("A", 10, OPERATION.LT));
Assert.assertEquals("(A > 1 AND A < 10)", FilterUtils.merge(filter).toString());
// 1 < A <= 10, 2 <= A < 11
filter = and(filter("A", 1, OPERATION.GT), filter("A", 10, OPERATION.LT_EQ));
filter = newAnd(and(filter("A", 2, OPERATION.GT_EQ), filter("A", 11, OPERATION.LT)), filter);
Assert.assertEquals("(A >= 2 AND A <= 10)", FilterUtils.merge(filter).toString());
} catch (EmptyResultFilterException e) {
Assert.fail();
}
try {
// 1 < A , A < 0
IFilter filter = and(filter("A", 1, OPERATION.GT), filter("A", 0, OPERATION.LT));
FilterUtils.merge(filter);
Assert.fail();// 不可能到这一步
} catch (EmptyResultFilterException e) {
}
try {
// A > 1 or A < 3
IFilter filter = or(filter("A", 1, OPERATION.GT), filter("A", 3, OPERATION.LT));
Assert.assertEquals("1", FilterUtils.merge(filter).toString());
// A > 1 or A > 3
filter = or(filter("A", 1, OPERATION.GT), filter("A", 3, OPERATION.GT));
Assert.assertEquals("A > 1", FilterUtils.merge(filter).toString());
// A > 1 or A = 5
filter = or(filter("A", 1, OPERATION.GT), filter("A", 5, OPERATION.EQ));
Assert.assertEquals("A > 1", FilterUtils.merge(filter).toString());
} catch (EmptyResultFilterException e) {
Assert.fail();
}
}
@Test
public void testCreateFilter() {
String where = "id > 1 and id <= 10";
IFilter filter = FilterUtils.createFilter(where);
System.out.println(filter);
where = "name = 'hello' and id in ('1','2')";
filter = FilterUtils.createFilter(where);
System.out.println(filter);
where = "gmt_create = '2013-11-11 11:11:11'";
filter = FilterUtils.createFilter(where);
System.out.println(filter);
where = "1+1";
filter = FilterUtils.createFilter(where);
System.out.println(filter);
}
private IFilter filter(Comparable column) {
IBooleanFilter booleanFilter = ASTNodeFactory.getInstance().createBooleanFilter();
booleanFilter.setColumn(column).setValue(1).setOperation(OPERATION.EQ);
return booleanFilter;
}
private IFilter newAnd(IFilter left, IFilter right) {
ILogicalFilter and = ASTNodeFactory.getInstance().createLogicalFilter().setOperation(OPERATION.AND);
and.addSubFilter(left);
and.addSubFilter(right);
return and;
}
private IFilter filter(Comparable column, Comparable value, OPERATION op) {
IBooleanFilter booleanFilter = ASTNodeFactory.getInstance().createBooleanFilter();
booleanFilter.setColumn(ASTNodeFactory.getInstance().createColumn().setColumnName((String) column))
.setValue(value)
.setOperation(op);
return booleanFilter;
}
private IFilter and(IFilter left, IFilter right) {
return FilterUtils.and(left, right);
}
private IFilter or(IFilter left, IFilter right) {
return FilterUtils.or(left, right);
}
}