blob: a0aac19c76f2c4d9fe66f0e04dce33695765fa57 [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.physical.impl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.apache.drill.common.expression.ExpressionPosition;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.util.DrillFileUtils;
import org.apache.drill.exec.client.DrillClient;
import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
import org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.Float4Holder;
import org.apache.drill.exec.expr.holders.Float8Holder;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.expr.holders.VarBinaryHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
import org.apache.drill.exec.ops.FragmentContextImpl;
import org.apache.drill.exec.physical.PhysicalPlan;
import org.apache.drill.exec.physical.base.FragmentRoot;
import org.apache.drill.exec.planner.PhysicalPlanReader;
import org.apache.drill.exec.planner.PhysicalPlanReaderTestFactory;
import org.apache.drill.exec.pop.PopUnitTestBase;
import org.apache.drill.exec.proto.BitControl.PlanFragment;
import org.apache.drill.exec.record.RecordBatchLoader;
import org.apache.drill.exec.record.VectorAccessible;
import org.apache.drill.exec.record.VectorWrapper;
import org.apache.drill.exec.rpc.user.QueryDataBatch;
import org.apache.drill.exec.rpc.UserClientConnection;
import org.apache.drill.exec.server.Drillbit;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.server.RemoteServiceSet;
import org.apache.drill.exec.vector.BigIntVector;
import org.apache.drill.exec.vector.Float4Vector;
import org.apache.drill.exec.vector.Float8Vector;
import org.apache.drill.exec.vector.IntVector;
import org.apache.drill.exec.vector.VarBinaryVector;
import org.apache.drill.exec.vector.VarCharVector;
import org.junit.Test;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.mockito.Mockito;
public class TestCastFunctions extends PopUnitTestBase {
@Test
// cast to bigint.
public void testCastBigInt() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastBigInt.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
final BigIntVector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast", ExpressionPosition.UNKNOWN), BigIntVector.class);
final BigIntVector.Accessor a0 = c0.getAccessor();
int count = 0;
for(int i = 0; i < c0.getAccessor().getValueCount(); i++) {
BigIntHolder holder0 = new BigIntHolder();
a0.get(i, holder0);
assertEquals(1256, holder0.value);
++count;
}
assertEquals(5, count);
}
exec.close();
context.close();
if (context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
assertTrue(!context.getExecutorState().isFailed());
}
@Test
//cast to int
public void testCastInt() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastInt.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
final IntVector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast", ExpressionPosition.UNKNOWN), IntVector.class);
final IntVector.Accessor a0 = c0.getAccessor();
int count = 0;
for(int i = 0; i < c0.getAccessor().getValueCount(); i++) {
final IntHolder holder0 = new IntHolder();
a0.get(i, holder0);
assertEquals(1256, holder0.value);
++count;
}
assertEquals(5, count);
}
exec.close();
context.close();
if (context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
assertTrue(!context.getExecutorState().isFailed());
}
@Test
//cast to float4
public void testCastFloat4() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastFloat4.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
final Float4Vector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast2", ExpressionPosition.UNKNOWN), Float4Vector.class);
final Float4Vector.Accessor a0 = c0.getAccessor();
int count = 0;
for(int i = 0; i < c0.getAccessor().getValueCount(); i++) {
final Float4Holder holder0 = new Float4Holder();
a0.get(i, holder0);
assertEquals(12.56, holder0.value, 0.001);
++count;
}
assertEquals(5, count);
}
exec.close();
context.close();
if (context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
assertTrue(!context.getExecutorState().isFailed());
}
@Test
//cast to float8
public void testCastFloat8() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastFloat8.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
final Float8Vector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast2", ExpressionPosition.UNKNOWN), Float8Vector.class);
final Float8Vector.Accessor a0 = c0.getAccessor();
int count = 0;
for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
final Float8Holder holder0 = new Float8Holder();
a0.get(i, holder0);
assertEquals(12.56, holder0.value, 0.001);
++count;
}
assertEquals(5, count);
}
exec.close();
context.close();
if (context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
assertTrue(!context.getExecutorState().isFailed());
}
@Test
//cast to varchar(length)
public void testCastVarChar() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastVarChar.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
final VarCharVector c0 = exec.getValueVectorById(new SchemaPath("int_lit_cast", ExpressionPosition.UNKNOWN), VarCharVector.class);
final VarCharVector.Accessor a0 = c0.getAccessor();
int count = 0;
for(int i = 0; i < c0.getAccessor().getValueCount(); i++) {
final VarCharHolder holder0 = new VarCharHolder();
a0.get(i, holder0);
assertEquals("123", StringFunctionHelpers.toStringFromUTF8(holder0.start, holder0.end, holder0.buffer));
++count;
}
assertEquals(5, count);
}
exec.close();
context.close();
if (context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
assertTrue(!context.getExecutorState().isFailed());
}
@Test
//cast to varbinary(length)
public void testCastVarBinary() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastVarBinary.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
final VarBinaryVector c0 = exec.getValueVectorById(new SchemaPath("int_lit_cast", ExpressionPosition.UNKNOWN), VarBinaryVector.class);
final VarBinaryVector.Accessor a0 = c0.getAccessor();
int count = 0;
for(int i = 0; i < c0.getAccessor().getValueCount(); i++) {
final VarBinaryHolder holder0 = new VarBinaryHolder();
a0.get(i, holder0);
assertEquals("123", StringFunctionHelpers.toStringFromUTF8(holder0.start, holder0.end, holder0.buffer));
++count;
}
assertEquals(5, count);
}
exec.close();
context.close();
if (context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
assertTrue(!context.getExecutorState().isFailed());
}
@Test
//nested: cast is nested in another cast, or another function.
public void testCastNested() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastNested.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
final IntVector c0 = exec.getValueVectorById(new SchemaPath("add_cast", ExpressionPosition.UNKNOWN),IntVector.class);
final IntVector.Accessor a0 = c0.getAccessor();
int count = 0;
for(int i = 0; i < c0.getAccessor().getValueCount(); i++) {
final IntHolder holder0 = new IntHolder();
a0.get(i, holder0);
assertEquals(300, holder0.value);
++count;
}
assertEquals(5, count);
}
exec.close();
context.close();
if (context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
assertTrue(!context.getExecutorState().isFailed());
}
@Test(expected = NumberFormatException.class)
public void testCastNumException() throws Throwable {
final DrillbitContext bitContext = mockDrillbitContext();
final UserClientConnection connection = Mockito.mock(UserClientConnection.class);
final PhysicalPlanReader reader = PhysicalPlanReaderTestFactory.defaultPhysicalPlanReader(CONFIG);
final PhysicalPlan plan = reader.readPhysicalPlan(Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastNumException.json"), Charsets.UTF_8).read());
final FunctionImplementationRegistry registry = new FunctionImplementationRegistry(CONFIG);
final FragmentContextImpl context = new FragmentContextImpl(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
final SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
while(exec.next()) {
}
exec.close();
context.close();
assertTrue(context.getExecutorState().isFailed());
if(context.getExecutorState().getFailureCause() != null) {
throw context.getExecutorState().getFailureCause();
}
}
@Test
public void testCastFromNullablCol() throws Throwable {
final RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
try(final Drillbit bit = new Drillbit(CONFIG, serviceSet);
final DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) {
bit.run();
client.connect();
final List<QueryDataBatch> results = client.runQuery(org.apache.drill.exec.proto.UserBitShared.QueryType.PHYSICAL,
Files.asCharSource(DrillFileUtils.getResourceAsFile("/functions/cast/testCastVarCharNull.json"), Charsets.UTF_8).read().replace("#{TEST_FILE}", "/jsoninput/input1.json"));
final QueryDataBatch batch = results.get(0);
final RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator());
batchLoader.load(batch.getHeader().getDef(), batch.getData());
final Object [][] result = getRunResult(batchLoader);
final Object [][] expected = new Object[2][2];
expected[0][0] = "2001";
expected[0][1] = "1.2";
expected[1][0] = "-2002";
expected[1][1] = "-1.2";
assertEquals(result.length, expected.length);
assertEquals(result[0].length, expected[0].length);
for (int i = 0; i<result.length; i++ ) {
for (int j = 0; j<result[0].length; j++) {
assertEquals(String.format("Column %s at row %s have wrong result", j, i), result[i][j].toString(), expected[i][j]);
}
}
batchLoader.clear();
for(final QueryDataBatch b : results){
b.release();
}
}
}
private Object[][] getRunResult(VectorAccessible va) {
int size = 0;
for (final VectorWrapper v : va) {
size++;
}
final Object[][] res = new Object [va.getRecordCount()][size];
for (int j = 0; j < va.getRecordCount(); j++) {
int i = 0;
for (final VectorWrapper v : va) {
final Object o = v.getValueVector().getAccessor().getObject(j);
if (o instanceof byte[]) {
res[j][i++] = new String((byte[]) o);
} else {
res[j][i++] = o;
}
}
}
return res;
}
}