DRILL-366: While casting VarChar to BigInt make sure the getByte() method is invoked with the appropriate byte offset.
CastFunctionsSrcVarLen.java: Use in.start as starting index to invoke getBytes() instead of 0. We always end up with the same row when we use 0 TestCastVarCharToBigInt.java, *.json Added a test case to read varchar and convert it to BigInt. Signed-off-by: Jacques Nadeau <jacq...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/ee9eaa13 Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/ee9eaa13 Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/ee9eaa13 Branch: refs/heads/master Commit: ee9eaa13c31838be5e080e7915efbd25f0a1e310 Parents: ed9dec7 Author: Mehant Baid <meha...@gmail.com> Authored: Tue Feb 11 20:07:20 2014 -0800 Committer: Jacques Nadeau <jacq...@apache.org> Committed: Mon Mar 3 23:22:17 2014 -0800 ---------------------------------------------------------------------- .../templates/CastFunctionsSrcVarLen.java | 18 ++-- .../physical/impl/TestCastVarCharToBigInt.java | 101 +++++++++++++++++++ .../cast/test_cast_varchar_to_bigint.json | 38 +++++++ .../src/test/resources/scan_json_test_cast.json | 9 ++ 4 files changed, 157 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/ee9eaa13/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java b/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java index 370597d..5855381 100644 --- a/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java +++ b/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java @@ -61,19 +61,19 @@ public class Cast${type.from}${type.to} implements DrillSimpleFunc{ out.value = ${type.javaType}.parse${type.parse}(new String(buf)); <#elseif type.to=="Int" || type.to == "BigInt"> - int i = 0; - int length = in.end - in.start; - - if (length==0) { + + if ((in.end - in.start) ==0) { //empty, not a valid number byte[] buf = new byte[in.end - in.start]; in.buffer.getBytes(in.start, buf, 0, in.end - in.start); throw new NumberFormatException(new String(buf)); } + + int readIndex = in.start; + + boolean negative = in.buffer.getByte(readIndex) == '-'; - boolean negative = in.buffer.getByte(0)=='-'; - - if (negative && ++i == length ) { + if (negative && ++readIndex == in.end) { //only one single '-' byte[] buf = new byte[in.end - in.start]; in.buffer.getBytes(in.start, buf, 0, in.end - in.start); @@ -85,8 +85,8 @@ public class Cast${type.from}${type.to} implements DrillSimpleFunc{ ${type.primeType} result = 0; int digit; - while (i < length) { - digit = Character.digit(in.buffer.getByte(i++),radix); + while (readIndex < in.end) { + digit = Character.digit(in.buffer.getByte(readIndex++),radix); //not valid digit. if (digit == -1) { byte[] buf = new byte[in.end - in.start]; http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/ee9eaa13/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestCastVarCharToBigInt.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestCastVarCharToBigInt.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestCastVarCharToBigInt.java new file mode 100644 index 0000000..ba8b9da --- /dev/null +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestCastVarCharToBigInt.java @@ -0,0 +1,101 @@ +/** + * 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.*; +import static org.junit.Assert.assertEquals; + +import mockit.Injectable; +import mockit.NonStrictExpectations; + +import org.apache.drill.common.config.DrillConfig; +import org.apache.drill.common.expression.ExpressionPosition; +import org.apache.drill.common.expression.SchemaPath; +import org.apache.drill.common.util.FileUtils; +import org.apache.drill.exec.client.DrillClient; +import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry; +import org.apache.drill.exec.memory.BufferAllocator; +import org.apache.drill.exec.memory.TopLevelAllocator; +import org.apache.drill.exec.ops.FragmentContext; +import org.apache.drill.exec.physical.PhysicalPlan; +import org.apache.drill.exec.physical.base.FragmentRoot; +import org.apache.drill.exec.physical.impl.OperatorCreatorRegistry; +import org.apache.drill.exec.physical.impl.ImplCreator; +import org.apache.drill.exec.physical.impl.SimpleRootExec; +import org.apache.drill.exec.planner.PhysicalPlanReader; +import org.apache.drill.exec.pop.PopUnitTestBase; +import org.apache.drill.exec.proto.BitControl; +import org.apache.drill.exec.proto.CoordinationProtos; +import org.apache.drill.exec.proto.ExecProtos.FragmentHandle; +import org.apache.drill.exec.proto.UserProtos; +import org.apache.drill.exec.record.RecordBatchLoader; +import org.apache.drill.exec.record.VectorWrapper; +import org.apache.drill.exec.rpc.user.QueryResultBatch; +import org.apache.drill.exec.rpc.user.UserServer.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.Float8Vector; + +import org.apache.drill.exec.vector.ValueVector; +import org.junit.Ignore; +import org.junit.Test; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import com.codahale.metrics.MetricRegistry; + +import java.util.List; + + +public class TestCastVarCharToBigInt extends PopUnitTestBase { + static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestCastVarCharToBigInt.class); + + @Test + public void testCastToBigInt() throws Exception { + try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet(); + Drillbit bit = new Drillbit(CONFIG, serviceSet); + DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) { + + // run query. + bit.run(); + client.connect(); + List<QueryResultBatch> results = client.runQuery(UserProtos.QueryType.PHYSICAL, + Files.toString(FileUtils.getResourceAsFile("/functions/cast/test_cast_varchar_to_bigint.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", FileUtils.getResourceAsFile("/scan_json_test_cast.json").toURI().toString()) + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, BigIntVector.class); + + for (VectorWrapper<?> v : batchLoader) { + + ValueVector.Accessor accessor = v.getValueVector().getAccessor(); + + assertEquals(accessor.getObject(0), 2008L); + assertEquals(accessor.getObject(1), 2007L); + assertEquals(accessor.getObject(2), 2006L); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/ee9eaa13/exec/java-exec/src/test/resources/functions/cast/test_cast_varchar_to_bigint.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/functions/cast/test_cast_varchar_to_bigint.json b/exec/java-exec/src/test/resources/functions/cast/test_cast_varchar_to_bigint.json new file mode 100644 index 0000000..36439c5 --- /dev/null +++ b/exec/java-exec/src/test/resources/functions/cast/test_cast_varchar_to_bigint.json @@ -0,0 +1,38 @@ +{ + head:{ + type:"APACHE_DRILL_PHYSICAL", + version:"1", + generator:{ + type:"manual" + } + }, + graph:[ + { + @id:1, + pop:"json-scan", + entries: [ + { + path : "#{TEST_FILE}" + } + ], + storageengine: { + "type": "json", + "dfsName": "file:///" + } + }, + { + pop:"project", + @id:2, + child: 1, + exprs: [ { + ref: "INTEGER", + expr: "cast(integer as bigint)" + } ] + }, + { + @id: 3, + child: 2, + pop: "screen" + } + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/ee9eaa13/exec/java-exec/src/test/resources/scan_json_test_cast.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/scan_json_test_cast.json b/exec/java-exec/src/test/resources/scan_json_test_cast.json new file mode 100644 index 0000000..dd9119a --- /dev/null +++ b/exec/java-exec/src/test/resources/scan_json_test_cast.json @@ -0,0 +1,9 @@ +{ + "integer" : "2008" +} +{ + "integer" : "2007" +} +{ + "integer" : "2006" +} \ No newline at end of file