blob: d153dbffa0f0b05901b8032259e7bd4b5025e1f0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.drill.exec.planner.logical;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.BitSet;
import org.apache.calcite.adapter.java.JavaTypeFactory;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.drill.exec.planner.logical.partition.FindPartitionConditions;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.drill.test.BaseTest;
import org.junit.Test;
public class FilterSplitTest extends BaseTest {
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(FilterSplitTest.class);
final JavaTypeFactory t = new JavaTypeFactoryImpl();
final RexBuilder builder = new RexBuilder(t);
final RelDataType intType = t.createSqlType(SqlTypeName.INTEGER);
final RelDataType sType = t.createSqlType(SqlTypeName.VARCHAR, 20);
@Test
public void simpleCompound() {
// a < 1 AND dir0 in (2,3)
RexNode n = and(
lt(c(0), lit(1)),
or(
eq(c(1), lit(2)),
eq(c(1), lit(3))
)
);
BitSet bs = new BitSet();
bs.set(1);
FindPartitionConditions c = new FindPartitionConditions(bs, builder);
c.analyze(n);
RexNode partNode = c.getFinalCondition();
assertEquals(n.toString(), "AND(<($0, 1), OR(=($1, 2), =($1, 3)))");
assertEquals(partNode.toString(), "OR(=($1, 2), =($1, 3))");
}
@Test
public void twoLevelDir() {
// (dir0 = 1 and dir1 = 2) OR (dir0 = 3 and dir1 = 4)
RexNode n = or(
and(
eq(c(1), lit(1)),
eq(c(2), lit(2))
),
and(
eq(c(1), lit(3)),
eq(c(2), lit(4))
)
);
BitSet bs = new BitSet();
bs.set(1);
bs.set(2);
FindPartitionConditions c = new FindPartitionConditions(bs, builder);
c.analyze(n);
RexNode partNode = c.getFinalCondition();
assertEquals("OR(AND(=($1, 1), =($2, 2)), AND(=($1, 3), =($2, 4)))", n.toString());
assertEquals("OR(AND(=($1, 1), =($2, 2)), AND(=($1, 3), =($2, 4)))", partNode.toString());
}
@Test
public void AndOrMix() {
// b = 3 OR dir0 = 1 and a = 2
RexNode n = or(
eq(c(2), lit(3)),
and(
eq(c(0), lit(1)),
eq(c(1), lit(2))
)
);
BitSet bs = new BitSet();
bs.set(0);
FindPartitionConditions c = new FindPartitionConditions(bs, builder);
c.analyze(n);
RexNode partNode = c.getFinalCondition();
assertEquals("OR(=($2, 3), AND(=($0, 1), =($1, 2)))", n.toString());
assertEquals(null, partNode);
}
@Test
public void NotOnAnd() {
// not (dir0 = 1 AND b = 2)
RexNode n = not(
and (
eq(c(0), lit(1)),
eq(c(1), lit(2))
)
);
BitSet bs = new BitSet();
bs.set(0);
FindPartitionConditions c = new FindPartitionConditions(bs, builder);
c.analyze(n);
RexNode partNode = c.getFinalCondition();
assertEquals("NOT(AND(=($0, 1), =($1, 2)))", n.toString());
assertEquals(null, partNode);
}
@Test
public void AndNot() {
// (not dir0 = 1) AND b = 2)
RexNode n = and(
not(
eq(c(0), lit(1))
),
eq(c(1), lit(2))
);
BitSet bs = new BitSet();
bs.set(0);
FindPartitionConditions c = new FindPartitionConditions(bs, builder);
c.analyze(n);
RexNode partNode = c.getFinalCondition();
assertEquals("AND(NOT(=($0, 1)), =($1, 2))", n.toString());
assertEquals("NOT(=($0, 1))", partNode.toString());
}
@Test
public void badOr() {
// (dir0 = 1 and dir1 = 2) OR (a < 5)
RexNode n = or(
and(
eq(c(1), lit(1)),
eq(c(2), lit(2))
),
lt(c(0), lit(5))
);
BitSet bs = new BitSet();
bs.set(1);
bs.set(2);
FindPartitionConditions c = new FindPartitionConditions(bs, builder);
c.analyze(n);
RexNode partNode = c.getFinalCondition();
assertEquals("OR(AND(=($1, 1), =($2, 2)), <($0, 5))", n.toString());
assertTrue(partNode == null);
}
@Test
public void badFunc() {
// (dir0 = 1 and dir1 = 2) OR (a < 5)
RexNode n = fn(
cs(0),
cs(1)
);
BitSet bs = new BitSet();
bs.set(1);
bs.set(2);
FindPartitionConditions c = new FindPartitionConditions(bs, builder);
c.analyze(n);
RexNode partNode = c.getFinalCondition();
assertEquals("||($0, $1)", n.toString());
assertTrue(partNode == null);
}
private RexNode and(RexNode...nodes){
return builder.makeCall(SqlStdOperatorTable.AND, nodes);
}
private RexNode fn(RexNode...nodes){
return builder.makeCall(SqlStdOperatorTable.CONCAT, nodes);
}
private RexNode or(RexNode...nodes){
return builder.makeCall(SqlStdOperatorTable.OR, nodes);
}
private RexNode not(RexNode...nodes){
return builder.makeCall(SqlStdOperatorTable.NOT, nodes);
}
private RexNode lt(RexNode left, RexNode right){
return builder.makeCall(SqlStdOperatorTable.LESS_THAN, left, right);
}
private RexNode eq(RexNode left, RexNode right){
return builder.makeCall(SqlStdOperatorTable.EQUALS, left, right);
}
private RexNode lit(int value){
return builder.makeLiteral(value, intType, true);
}
private RexNode c(int index){
return builder.makeInputRef(intType, index);
}
private RexNode cs(int index){
return builder.makeInputRef(sType, index);
}
private RexNode str(String s){
return builder.makeLiteral(s);
}
}