/** * 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.*; 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.junit.Test; public class FilterSplitTest { 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 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 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); } }