http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestDecimal.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestDecimal.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestDecimal.java new file mode 100644 index 0000000..5163a48 --- /dev/null +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestDecimal.java @@ -0,0 +1,357 @@ +/** + * 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.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; +import java.util.List; + +import org.apache.drill.common.config.DrillConfig; +import org.apache.drill.common.util.FileUtils; +import org.apache.drill.exec.client.DrillClient; +import org.apache.drill.exec.pop.PopUnitTestBase; +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.server.Drillbit; +import org.apache.drill.exec.server.RemoteServiceSet; +import org.apache.drill.exec.vector.ValueVector; +import org.apache.drill.exec.vector.VarCharVector; +import org.junit.Ignore; +import org.junit.Test; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +public class TestDecimal extends PopUnitTestBase{ + DrillConfig c = DrillConfig.create(); + + @Test + public void testSimpleDecimal() throws Exception { + + /* Function checks casting from VarChar to Decimal9, Decimal18 and vice versa + * Also tests instances where the scale might have to truncated when scale provided < input fraction + */ + 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("/decimal/cast_simple_decimal.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/input_simple_decimal.json") + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, VarCharVector.class); + + String decimal9Output[] = {"99.0000", "11.1234", "0.1000", "-0.1200", "-123.1234", "-1.0001"}; + String decimal18Output[] = {"123456789.000000000", "11.123456789", "0.100000000", "-0.100400000", "-987654321.123456789", "-2.030100000"}; + + Iterator<VectorWrapper<?>> itr = batchLoader.iterator(); + + // Check the output of decimal9 + ValueVector.Accessor dec9Accessor = itr.next().getValueVector().getAccessor(); + ValueVector.Accessor dec18Accessor = itr.next().getValueVector().getAccessor(); + + + for (int i = 0; i < dec9Accessor.getValueCount(); i++) { + assertEquals(dec9Accessor.getObject(i), decimal9Output[i]); + assertEquals(dec18Accessor.getObject(i), decimal18Output[i]); + } + assertEquals(6, dec9Accessor.getValueCount()); + assertEquals(6, dec18Accessor.getValueCount()); + } + } + + @Test + public void testCastFromFloat() throws Exception { + + // Function checks for casting from Float, Double to Decimal data types + 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("/decimal/cast_float_decimal.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/input_simple_decimal.json") + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, VarCharVector.class); + + String decimal9Output[] = {"99.0000", "11.1234", "0.1000", "-0.1200", "-123.1234", "-1.0001"}; + String decimal38Output[] = {"123456789.0000", "11.1234", "0.1000", "-0.1004", "-987654321.1234", "-2.0301"}; + + Iterator<VectorWrapper<?>> itr = batchLoader.iterator(); + + // Check the output of decimal9 + ValueVector.Accessor dec9Accessor = itr.next().getValueVector().getAccessor(); + ValueVector.Accessor dec38Accessor = itr.next().getValueVector().getAccessor(); + + + for (int i = 0; i < dec9Accessor.getValueCount(); i++) { + assertEquals(dec9Accessor.getObject(i).toString(), decimal9Output[i]); + assertEquals(dec38Accessor.getObject(i).toString(), decimal38Output[i]); + } + assertEquals(6, dec9Accessor.getValueCount()); + assertEquals(6, dec38Accessor.getValueCount()); + } + } + + @Test + public void testSimpleDecimalArithmetic() throws Exception { + + // Function checks arithmetic operations on Decimal18 + 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("/decimal/simple_decimal_arithmetic.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/input_simple_decimal.json") + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, VarCharVector.class); + + String addOutput[] = {"123456888.0", "22.2", "0.2", "-0.2", "-987654444.2","-3.0"}; + String subtractOutput[] = {"123456690.0", "0.0", "0.0", "0.0", "-987654198.0", "-1.0"}; + String multiplyOutput[] = {"12222222111.00" , "123.21" , "0.01", "0.01", "121580246927.41", "2.00"}; + + Iterator<VectorWrapper<?>> itr = batchLoader.iterator(); + + // Check the output of add + ValueVector.Accessor addAccessor = itr.next().getValueVector().getAccessor(); + ValueVector.Accessor subAccessor = itr.next().getValueVector().getAccessor(); + ValueVector.Accessor mulAccessor = itr.next().getValueVector().getAccessor(); + + for (int i = 0; i < addAccessor.getValueCount(); i++) { + assertEquals(addAccessor.getObject(i), addOutput[i]); + assertEquals(subAccessor.getObject(i), subtractOutput[i]); + assertEquals(mulAccessor.getObject(i), multiplyOutput[i]); + + } + assertEquals(6, addAccessor.getValueCount()); + assertEquals(6, subAccessor.getValueCount()); + assertEquals(6, mulAccessor.getValueCount()); + } + } + + @Test + public void testComplexDecimal() throws Exception { + + /* Function checks casting between varchar and decimal38sparse + * Also checks arithmetic on decimal38sparse + */ + 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("/decimal/test_decimal_complex.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/input_complex_decimal.json") + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, VarCharVector.class); + + String addOutput[] = {"-99999998877.700000000", "11.423456789", "123456789.100000000", "-0.119998000", "100000000112.423456789" , "-99999999879.907000000", "123456789123456801.300000000"}; + String subtractOutput[] = {"-100000001124.300000000", "10.823456789", "-123456788.900000000", "-0.120002000", "99999999889.823456789", "-100000000122.093000000", "123456789123456776.700000000"}; + String multiplyOutput[] = {"-112330000001123.300000000000000000", "3.337037036700000000" , "12345678.900000000000000000", "-0.000000240000000000" , "11130000000125.040740615700000000" , "-12109300000121.093000000000000000", "1518518506218518504.700000000000000000" }; + + Iterator<VectorWrapper<?>> itr = batchLoader.iterator(); + + ValueVector.Accessor addAccessor = itr.next().getValueVector().getAccessor(); + ValueVector.Accessor subAccessor = itr.next().getValueVector().getAccessor(); + ValueVector.Accessor mulAccessor = itr.next().getValueVector().getAccessor(); + + for (int i = 0; i < addAccessor.getValueCount(); i++) { + assertEquals(addAccessor.getObject(i), addOutput[i]); + assertEquals(subAccessor.getObject(i), subtractOutput[i]); + assertEquals(mulAccessor.getObject(i), multiplyOutput[i]); + } + assertEquals(7, addAccessor.getValueCount()); + assertEquals(7, subAccessor.getValueCount()); + assertEquals(7, mulAccessor.getValueCount()); + } + } + + @Test + public void testComplexDecimalSort() throws Exception { + + // Function checks if sort output on complex decimal type works + 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("/decimal/test_decimal_sort_complex.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/input_sort_complex_decimal.json") + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, VarCharVector.class); + + String sortOutput[] = {"-100000000001.000000000000", + "-100000000001.000000000000", + "-145456789.120123000000", + "-0.120000000000", + "0.100000000001", + "11.123456789012", + "1278789.100000000000", + "145456789.120123000000", + "100000000001.123456789001", + "123456789123456789.000000000000"}; + + Iterator<VectorWrapper<?>> itr = batchLoader.iterator(); + + // Check the output of sort + VectorWrapper<?> v = itr.next(); + ValueVector.Accessor accessor = v.getValueVector().getAccessor(); + + for (int i = 0; i < accessor.getValueCount(); i++) { + assertEquals(accessor.getObject(i), sortOutput[i]); + } + assertEquals(10, accessor.getValueCount()); + } + } + + @Test + public void testDenseSparseConversion() throws Exception { + + /* Function checks the following workflow + * VarChar -> Sparse -> Dense -> Sort(Dense) -> Sparse -> VarChar + */ + 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("/decimal/test_decimal_dense_sparse.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/input_complex_decimal.json") + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, VarCharVector.class); + + String sortOutput[] = {"-100000000001.000000000000", "-100000000001.000000000000", "-0.120000000000", "0.100000000001", "11.123456789012", "100000000001.123456789001", "123456789123456789.000000000000"}; + + Iterator<VectorWrapper<?>> itr = batchLoader.iterator(); + + // Check the output of sort + VectorWrapper<?> v = itr.next(); + ValueVector.Accessor accessor = v.getValueVector().getAccessor(); + + for (int i = 0; i < accessor.getValueCount(); i++) { + assertEquals(accessor.getObject(i), sortOutput[i]); + } + assertEquals(7, accessor.getValueCount()); + } + } + + @Test + public void testDenseSparseConversion1() throws Exception { + + /* Function checks the following cast sequence. + * VarChar -> Decimal28Sparse + * Decimal28Sparse -> Decimal28Dense + * Decimal28Dense -> Decimal38Dense + * + * Goal is to test the similar casting functionality 28Dense -> 38Dense + * + */ + 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("/decimal/test_decimal_sparse_dense_dense.json"), Charsets.UTF_8) + .replace("#{TEST_FILE}", "/input_simple_decimal.json") + ); + + RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator()); + + QueryResultBatch batch = results.get(0); + assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData())); + + batchLoader.getValueAccessorById(0, VarCharVector.class); + + String output[] = {"99.0000", "11.1234", "0.1000", "-0.1200", "-123.1234", "-1.0001"}; + + Iterator<VectorWrapper<?>> itr = batchLoader.iterator(); + + // Check the output of sort + VectorWrapper<?> v = itr.next(); + ValueVector.Accessor accessor = v.getValueVector().getAccessor(); + + for (int i = 0; i < accessor.getValueCount(); i++) { + assertEquals(accessor.getObject(i).toString(), output[i]); + } + assertEquals(6, accessor.getValueCount()); + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/decimal/cast_float_decimal.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/decimal/cast_float_decimal.json b/exec/java-exec/src/test/resources/decimal/cast_float_decimal.json new file mode 100644 index 0000000..33732ae --- /dev/null +++ b/exec/java-exec/src/test/resources/decimal/cast_float_decimal.json @@ -0,0 +1,47 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + }, { + "pop" : "project", + "@id" : 2, + "exprs" : [ { + "ref" : "F4", + "expr" : " (cast(DEC9 as float4)) " + }, + { "ref" : "F8", "expr": "(cast(DEC18 as float8))" } + ], + + "child" : 1 + }, +{ + "pop" : "project", + "@id" : 4, + "exprs" : [ { + "ref" : "DECIMAL9", + "expr" : " cast(F4 as decimal9(9, 4)) " + }, + {"ref": "DECIMAL38", "expr" : "cast(F8 as decimal38sparse(38, 4))"} + ], + + "child" : 2 + }, +{ + "pop" : "screen", + "@id" : 5, + "child" : 4 + } ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/decimal/cast_simple_decimal.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/decimal/cast_simple_decimal.json b/exec/java-exec/src/test/resources/decimal/cast_simple_decimal.json new file mode 100644 index 0000000..279de3c --- /dev/null +++ b/exec/java-exec/src/test/resources/decimal/cast_simple_decimal.json @@ -0,0 +1,47 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + }, { + "pop" : "project", + "@id" : 2, + "exprs" : [ { + "ref" : "DECIMAL9", + "expr" : " (cast(DEC9 as decimal9(9, 4))) " + }, + { "ref" : "DECIMAL18", "expr": "(cast(DEC18 as decimal18(18, 9)))" } + ], + + "child" : 1 + }, +{ + "pop" : "project", + "@id" : 4, + "exprs" : [ { + "ref" : "DECIMAL9", + "expr" : " cast(DECIMAL9 as varchar(100)) " + }, + {"ref": "DECIMAL18", "expr" : "cast(DECIMAL18 as varchar(100))"} + ], + + "child" : 2 + }, +{ + "pop" : "screen", + "@id" : 5, + "child" : 4 + } ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/decimal/simple_decimal_arithmetic.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/decimal/simple_decimal_arithmetic.json b/exec/java-exec/src/test/resources/decimal/simple_decimal_arithmetic.json new file mode 100644 index 0000000..ca31d88 --- /dev/null +++ b/exec/java-exec/src/test/resources/decimal/simple_decimal_arithmetic.json @@ -0,0 +1,55 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + }, { + "pop" : "project", + "@id" : 2, + "exprs" : [ + { "ref" : "DECIMAL18_1", "expr": "(cast(DEC18 as decimal18(18, 1)))" }, + { "ref" : "DECIMAL18_2", "expr": "(cast(DEC9 as decimal18(18, 1)))" } + ], + + "child" : 1 + }, + { + "pop" : "project", + "@id" : 3, + "exprs" : [ + { "ref": "DEC18ADD", "expr" : "DECIMAL18_1 + DECIMAL18_2"}, + { "ref": "DEC18SUB", "expr" : "DECIMAL18_1 - DECIMAL18_2"}, + { "ref": "DEC18MUL", "expr" : "DECIMAL18_1 * DECIMAL18_2"} + ], + + "child" : 2 + }, + { + "pop" : "project", + "@id" : 4, + "exprs" : [ + {"ref": "DECIMAL18ADD", "expr" : "cast(DEC18ADD as varchar(100))" }, + {"ref": "DECIMAL18SUB", "expr" : "cast(DEC18SUB as varchar(100))" }, + {"ref": "DECIMAL18MUL", "expr" : "cast(DEC18MUL as varchar(100))" } + ], + + "child" : 3 + }, + { + "pop" : "screen", + "@id" : 5, + "child" : 4 + } ] + } http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/decimal/test_decimal_complex.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/decimal/test_decimal_complex.json b/exec/java-exec/src/test/resources/decimal/test_decimal_complex.json new file mode 100644 index 0000000..b2f1929 --- /dev/null +++ b/exec/java-exec/src/test/resources/decimal/test_decimal_complex.json @@ -0,0 +1,61 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + },{ + "pop" : "project", + "@id" : 2, + "exprs" : [ { + "ref" : "DE", + "expr" : " (cast(B as decimal38sparse(38, 9))) " + }, + {"ref" : "DE1", "expr": " cast(A as decimal38sparse(38, 9))" } + ], + + "child" : 1 + }, + { + "pop" : "project", + "@id" : 3, + "exprs" : [ { + "ref" : "DEC38ADD", + "expr" : " (DE + DE1) " + }, + {"ref" : "DEC38SUB" , "expr" : " (DE - DE1) " }, + {"ref" : "DEC38MUL" , "expr" : " (DE * DE1) " } + ], + + "child" : 2 + }, + { + "pop" : "project", + "@id" : 4, + "exprs" : [ { + "ref" : "DEC38ADD", + "expr" : " cast(DEC38ADD as varchar(100)) " + }, + {"ref" : "DEC38SUB" , "expr" : " cast(DEC38SUB as varchar(100)) " }, + {"ref" : "DEC38MUL" , "expr" : " cast(DEC38MUL as varchar(100)) " } + ], + + "child" : 3 + }, + { + "pop" : "screen", + "@id" : 5, + "child" : 4 + } ] + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/decimal/test_decimal_dense_sparse.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/decimal/test_decimal_dense_sparse.json b/exec/java-exec/src/test/resources/decimal/test_decimal_dense_sparse.json new file mode 100644 index 0000000..bc10f50 --- /dev/null +++ b/exec/java-exec/src/test/resources/decimal/test_decimal_dense_sparse.json @@ -0,0 +1,78 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + }, { + + "pop" : "project", + "@id" : 2, + "exprs" : [ { + "ref" : "SPARSE", + "expr" : " (cast(B as decimal38sparse(38, 12))) " + } + ], + + "child" : 1 + }, +{ + "pop" : "project", + "@id" : 3, + "exprs" : [ { + "ref" : "DENSE", + "expr" : " cast(SPARSE as decimal38dense(38, 12)) " + } + ], + + "child" : 2 + }, +{ + @id:4, + child: 3, + pop:"sort", + orderings: [ + {expr: "DENSE"} + ] + }, + { + @id:5, + child: 4, + pop:"selection-vector-remover" + }, +{ + "pop" : "project", + "@id" : 6, + "exprs" : [ + { "ref" : "SPARSE", "expr" : "cast(DENSE as decimal38sparse(38, 12))" } + ], + + "child" : 5 + }, +{ + "pop" : "project", + "@id" : 7, + "exprs" : [ + { "ref" : "STRINGSPARSE", "expr" : "cast(SPARSE as varchar(100))" } + ], + + "child" : 6 + }, +{ + "pop" : "screen", + "@id" : 8, + "child" : 7 + } ] +} + http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/decimal/test_decimal_sort_complex.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/decimal/test_decimal_sort_complex.json b/exec/java-exec/src/test/resources/decimal/test_decimal_sort_complex.json new file mode 100644 index 0000000..1fbe106 --- /dev/null +++ b/exec/java-exec/src/test/resources/decimal/test_decimal_sort_complex.json @@ -0,0 +1,56 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + },{ + "pop" : "project", + "@id" : 2, + "exprs" : [ { + "ref" : "DEC", + "expr" : " (cast(B as decimal38sparse(38, 12)))" + } + ], + "child" : 1 + }, + { + @id:3, + child: 2, + pop:"sort", + orderings: [ + {expr: "DEC"} + ] + }, + { + @id:4, + child: 3, + pop:"selection-vector-remover" + }, + { + "pop" : "project", + "@id" : 5, + "exprs" : [ { + "ref" : "DESTR", + "expr" : " (cast(DEC as varchar(100)))" + } + ], + "child" : 4 + }, + { + "pop" : "screen", + "@id" : 6, + "child" : 5 + } ] + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/decimal/test_decimal_sparse_dense_dense.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/decimal/test_decimal_sparse_dense_dense.json b/exec/java-exec/src/test/resources/decimal/test_decimal_sparse_dense_dense.json new file mode 100644 index 0000000..03add9a --- /dev/null +++ b/exec/java-exec/src/test/resources/decimal/test_decimal_sparse_dense_dense.json @@ -0,0 +1,56 @@ +{ + "head" : { + "version" : 1, + "generator" : { + "type" : "org.apache.drill.exec.planner.logical.DrillImplementor", + "info" : "" + }, + "type" : "APACHE_DRILL_PHYSICAL", + "resultMode" : "EXEC" + }, + graph:[ + { + @id:1, + pop:"fs-scan", + format: {type: "json"}, + storage:{type: "file", connection: "classpath:///"}, + files:["#{TEST_FILE}"] + }, { + "pop" : "project", + "@id" : 2, + "exprs" : [ { + "ref" : "DECIMAL28SPARSE", + "expr" : " (cast(DEC9 as decimal28sparse(28, 4))) " + } + ], + + "child" : 1 + }, +{ + "pop" : "project", + "@id" : 3, + "exprs" : [ { + "ref" : "DECIMAL28DENSE", + "expr" : " cast(DECIMAL28SPARSE as decimal28dense(28, 4)) " + } + ], + + "child" : 2 + }, +{ + "pop" : "project", + "@id" : 4, + "exprs" : [ { + "ref" : "DECIMAL38DENSE", + "expr" : " cast(DECIMAL28DENSE as decimal38dense(38, 4)) " + } + ], + + "child" : 3 + }, +{ + "pop" : "screen", + "@id" : 5, + "child" : 4 + } ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/input_complex_decimal.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/input_complex_decimal.json b/exec/java-exec/src/test/resources/input_complex_decimal.json new file mode 100644 index 0000000..a0838a9 --- /dev/null +++ b/exec/java-exec/src/test/resources/input_complex_decimal.json @@ -0,0 +1,28 @@ +{ +"B": "-100000000001", +"A": "1123.3" +} +{ +"B": "11.1234567890123456", +"A": "0.3" +} +{ +"B": "0.100000000001", +"A": "123456789" +} +{ +"B": "-0.12", +"A": "0.000002" +} +{ +"B": "100000000001.123456789001", +"A": "111.3" +} +{ +"B": "-100000000001", +"A": "121.093" +} +{ +"B": "123456789123456789", +"A": "12.3" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/input_simple_decimal.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/input_simple_decimal.json b/exec/java-exec/src/test/resources/input_simple_decimal.json new file mode 100644 index 0000000..b7c9481 --- /dev/null +++ b/exec/java-exec/src/test/resources/input_simple_decimal.json @@ -0,0 +1,24 @@ +{ +"DEC9": "99", +"DEC18": "123456789" +} +{ +"DEC9": "11.1234567890123456", +"DEC18": "11.123456789" +} +{ +"DEC9": "0.100000000001", +"DEC18":"0.100000000001" +} +{ +"DEC9": "-0.12", +"DEC18":"-0.1004" +} +{ +"DEC9": "-123.1234", +"DEC18": "-987654321.1234567891" +} +{ +"DEC9": "-1.0001", +"DEC18":"-2.0301" +} http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/exec/java-exec/src/test/resources/input_sort_complex_decimal.json ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/resources/input_sort_complex_decimal.json b/exec/java-exec/src/test/resources/input_sort_complex_decimal.json new file mode 100644 index 0000000..9a5b061 --- /dev/null +++ b/exec/java-exec/src/test/resources/input_sort_complex_decimal.json @@ -0,0 +1,30 @@ +{ +"B": "-100000000001" +} +{ +"B": "11.1234567890123456" +} +{ +"B": "0.100000000001" +} +{ +"B": "-0.12" +} +{ +"B": "100000000001.123456789001" +} +{ +"B": "-100000000001" +} +{ +"B": "123456789123456789" +} +{ +"B": "145456789.120123" +} +{ +"B" : "1278789.1" +} +{ +"B": "-145456789.120123" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 8291844..2cac418 100644 --- a/pom.xml +++ b/pom.xml @@ -363,6 +363,12 @@ <dependencies> <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-handler</artifactId> + <version>4.0.7.Final</version> + </dependency> + + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>14.0.1</version> http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java ---------------------------------------------------------------------- diff --git a/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java b/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java index 3a1bdcd..70125b2 100644 --- a/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java +++ b/protocol/src/main/java/org/apache/drill/common/types/TypeProtos.java @@ -87,37 +87,37 @@ public final class TypeProtos { */ BIGINT(6, 6), /** - * <code>DECIMAL4 = 7;</code> + * <code>DECIMAL9 = 7;</code> * * <pre> - * a decimal supporting precision between 1 and 8 (4 bits for decimal location, 1 sign) + * a decimal supporting precision between 1 and 9 * </pre> */ - DECIMAL4(7, 7), + DECIMAL9(7, 7), /** - * <code>DECIMAL8 = 8;</code> + * <code>DECIMAL18 = 8;</code> * * <pre> - * a decimal supporting precision between 9 and 18 (5 bits for decimal location, 1 sign) + * a decimal supporting precision between 10 and 18 * </pre> */ - DECIMAL8(8, 8), + DECIMAL18(8, 8), /** - * <code>DECIMAL12 = 9;</code> + * <code>DECIMAL28SPARSE = 9;</code> * * <pre> - * a decimal supporting precision between 19 and 28 (5 bits for decimal location, 1 sign) + * a decimal supporting precision between 19 and 28 * </pre> */ - DECIMAL12(9, 9), + DECIMAL28SPARSE(9, 9), /** - * <code>DECIMAL16 = 10;</code> + * <code>DECIMAL38SPARSE = 10;</code> * * <pre> - * a decimal supporting precision between 29 and 37 (6 bits for decimal location, 1 sign) + * a decimal supporting precision between 29 and 38 * </pre> */ - DECIMAL16(10, 10), + DECIMAL38SPARSE(10, 10), /** * <code>MONEY = 11;</code> * @@ -130,7 +130,7 @@ public final class TypeProtos { * <code>DATE = 12;</code> * * <pre> - * days since 4713bc + * days since 4713bc * </pre> */ DATE(12, 12), @@ -275,6 +275,22 @@ public final class TypeProtos { */ UINT8(30, 32), /** + * <code>DECIMAL28DENSE = 33;</code> + * + * <pre> + * dense decimal representation, supporting precision between 19 and 28 + * </pre> + */ + DECIMAL28DENSE(31, 33), + /** + * <code>DECIMAL38DENSE = 34;</code> + * + * <pre> + * dense decimal representation, supporting precision between 28 and 38 + * </pre> + */ + DECIMAL38DENSE(32, 34), + /** * <code>NULL = 37;</code> * * <pre> @@ -284,7 +300,7 @@ public final class TypeProtos { * MSGPACK4 = 36; // msgpack encoded complex type. (up to 2^32 in length) * </pre> */ - NULL(31, 37), + NULL(33, 37), /** * <code>INTERVALYEAR = 38;</code> * @@ -292,7 +308,7 @@ public final class TypeProtos { * Interval type specifying YEAR to MONTH * </pre> */ - INTERVALYEAR(32, 38), + INTERVALYEAR(34, 38), /** * <code>INTERVALDAY = 39;</code> * @@ -300,7 +316,7 @@ public final class TypeProtos { * Interval type specifying DAY to SECONDS * </pre> */ - INTERVALDAY(33, 39), + INTERVALDAY(35, 39), ; /** @@ -360,37 +376,37 @@ public final class TypeProtos { */ public static final int BIGINT_VALUE = 6; /** - * <code>DECIMAL4 = 7;</code> + * <code>DECIMAL9 = 7;</code> * * <pre> - * a decimal supporting precision between 1 and 8 (4 bits for decimal location, 1 sign) + * a decimal supporting precision between 1 and 9 * </pre> */ - public static final int DECIMAL4_VALUE = 7; + public static final int DECIMAL9_VALUE = 7; /** - * <code>DECIMAL8 = 8;</code> + * <code>DECIMAL18 = 8;</code> * * <pre> - * a decimal supporting precision between 9 and 18 (5 bits for decimal location, 1 sign) + * a decimal supporting precision between 10 and 18 * </pre> */ - public static final int DECIMAL8_VALUE = 8; + public static final int DECIMAL18_VALUE = 8; /** - * <code>DECIMAL12 = 9;</code> + * <code>DECIMAL28SPARSE = 9;</code> * * <pre> - * a decimal supporting precision between 19 and 28 (5 bits for decimal location, 1 sign) + * a decimal supporting precision between 19 and 28 * </pre> */ - public static final int DECIMAL12_VALUE = 9; + public static final int DECIMAL28SPARSE_VALUE = 9; /** - * <code>DECIMAL16 = 10;</code> + * <code>DECIMAL38SPARSE = 10;</code> * * <pre> - * a decimal supporting precision between 29 and 37 (6 bits for decimal location, 1 sign) + * a decimal supporting precision between 29 and 38 * </pre> */ - public static final int DECIMAL16_VALUE = 10; + public static final int DECIMAL38SPARSE_VALUE = 10; /** * <code>MONEY = 11;</code> * @@ -403,7 +419,7 @@ public final class TypeProtos { * <code>DATE = 12;</code> * * <pre> - * days since 4713bc + * days since 4713bc * </pre> */ public static final int DATE_VALUE = 12; @@ -548,6 +564,22 @@ public final class TypeProtos { */ public static final int UINT8_VALUE = 32; /** + * <code>DECIMAL28DENSE = 33;</code> + * + * <pre> + * dense decimal representation, supporting precision between 19 and 28 + * </pre> + */ + public static final int DECIMAL28DENSE_VALUE = 33; + /** + * <code>DECIMAL38DENSE = 34;</code> + * + * <pre> + * dense decimal representation, supporting precision between 28 and 38 + * </pre> + */ + public static final int DECIMAL38DENSE_VALUE = 34; + /** * <code>NULL = 37;</code> * * <pre> @@ -587,10 +619,10 @@ public final class TypeProtos { case 4: return SMALLINT; case 5: return INT; case 6: return BIGINT; - case 7: return DECIMAL4; - case 8: return DECIMAL8; - case 9: return DECIMAL12; - case 10: return DECIMAL16; + case 7: return DECIMAL9; + case 8: return DECIMAL18; + case 9: return DECIMAL28SPARSE; + case 10: return DECIMAL38SPARSE; case 11: return MONEY; case 12: return DATE; case 13: return TIME; @@ -611,6 +643,8 @@ public final class TypeProtos { case 30: return UINT2; case 31: return UINT4; case 32: return UINT8; + case 33: return DECIMAL28DENSE; + case 34: return DECIMAL38DENSE; case 37: return NULL; case 38: return INTERVALYEAR; case 39: return INTERVALDAY; @@ -1745,21 +1779,22 @@ public final class TypeProtos { "inor_type\030\001 \001(\0162\021.common.MinorType\022\036\n\004mo" + "de\030\002 \001(\0162\020.common.DataMode\022\r\n\005width\030\003 \001(" + "\005\022\021\n\tprecision\030\004 \001(\005\022\r\n\005scale\030\005 \001(\005\022\020\n\010t" + - "imeZone\030\006 \001(\005*\306\003\n\tMinorType\022\010\n\004LATE\020\000\022\007\n" + + "imeZone\030\006 \001(\005*\373\003\n\tMinorType\022\010\n\004LATE\020\000\022\007\n" + "\003MAP\020\001\022\r\n\tREPEATMAP\020\002\022\013\n\007TINYINT\020\003\022\014\n\010SM" + "ALLINT\020\004\022\007\n\003INT\020\005\022\n\n\006BIGINT\020\006\022\014\n\010DECIMAL" + - "4\020\007\022\014\n\010DECIMAL8\020\010\022\r\n\tDECIMAL12\020\t\022\r\n\tDECI" + - "MAL16\020\n\022\t\n\005MONEY\020\013\022\010\n\004DATE\020\014\022\010\n\004TIME\020\r\022\n" + - "\n\006TIMETZ\020\016\022\017\n\013TIMESTAMPTZ\020\017\022\r\n\tTIMESTAMP", - "\020\020\022\014\n\010INTERVAL\020\021\022\n\n\006FLOAT4\020\022\022\n\n\006FLOAT8\020\023" + - "\022\007\n\003BIT\020\024\022\r\n\tFIXEDCHAR\020\025\022\017\n\013FIXED16CHAR\020" + - "\026\022\017\n\013FIXEDBINARY\020\027\022\013\n\007VARCHAR\020\030\022\r\n\tVAR16" + - "CHAR\020\031\022\r\n\tVARBINARY\020\032\022\t\n\005UINT1\020\035\022\t\n\005UINT" + - "2\020\036\022\t\n\005UINT4\020\037\022\t\n\005UINT8\020 \022\010\n\004NULL\020%\022\020\n\014I" + - "NTERVALYEAR\020&\022\017\n\013INTERVALDAY\020\'*4\n\010DataMo" + - "de\022\014\n\010OPTIONAL\020\000\022\014\n\010REQUIRED\020\001\022\014\n\010REPEAT" + - "ED\020\002B-\n\035org.apache.drill.common.typesB\nT" + - "ypeProtosH\001" + "9\020\007\022\r\n\tDECIMAL18\020\010\022\023\n\017DECIMAL28SPARSE\020\t\022" + + "\023\n\017DECIMAL38SPARSE\020\n\022\t\n\005MONEY\020\013\022\010\n\004DATE\020" + + "\014\022\010\n\004TIME\020\r\022\n\n\006TIMETZ\020\016\022\017\n\013TIMESTAMPTZ\020\017", + "\022\r\n\tTIMESTAMP\020\020\022\014\n\010INTERVAL\020\021\022\n\n\006FLOAT4\020" + + "\022\022\n\n\006FLOAT8\020\023\022\007\n\003BIT\020\024\022\r\n\tFIXEDCHAR\020\025\022\017\n" + + "\013FIXED16CHAR\020\026\022\017\n\013FIXEDBINARY\020\027\022\013\n\007VARCH" + + "AR\020\030\022\r\n\tVAR16CHAR\020\031\022\r\n\tVARBINARY\020\032\022\t\n\005UI" + + "NT1\020\035\022\t\n\005UINT2\020\036\022\t\n\005UINT4\020\037\022\t\n\005UINT8\020 \022\022" + + "\n\016DECIMAL28DENSE\020!\022\022\n\016DECIMAL38DENSE\020\"\022\010" + + "\n\004NULL\020%\022\020\n\014INTERVALYEAR\020&\022\017\n\013INTERVALDA" + + "Y\020\'*4\n\010DataMode\022\014\n\010OPTIONAL\020\000\022\014\n\010REQUIRE" + + "D\020\001\022\014\n\010REPEATED\020\002B-\n\035org.apache.drill.co" + + "mmon.typesB\nTypeProtosH\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a5ee8f84/protocol/src/main/protobuf/Types.proto ---------------------------------------------------------------------- diff --git a/protocol/src/main/protobuf/Types.proto b/protocol/src/main/protobuf/Types.proto index 9ca1ca9..3871a40 100644 --- a/protocol/src/main/protobuf/Types.proto +++ b/protocol/src/main/protobuf/Types.proto @@ -29,12 +29,12 @@ enum MinorType { SMALLINT = 4; // two byte signed integer INT = 5; // four byte signed integer BIGINT = 6; // eight byte signed integer - DECIMAL4 = 7; // a decimal supporting precision between 1 and 8 (4 bits for decimal location, 1 sign) - DECIMAL8 = 8; // a decimal supporting precision between 9 and 18 (5 bits for decimal location, 1 sign) - DECIMAL12 = 9; // a decimal supporting precision between 19 and 28 (5 bits for decimal location, 1 sign) - DECIMAL16 = 10; // a decimal supporting precision between 29 and 37 (6 bits for decimal location, 1 sign) + DECIMAL9 = 7; // a decimal supporting precision between 1 and 9 + DECIMAL18 = 8; // a decimal supporting precision between 10 and 18 + DECIMAL28SPARSE = 9; // a decimal supporting precision between 19 and 28 + DECIMAL38SPARSE = 10; // a decimal supporting precision between 29 and 38 MONEY = 11; // signed decimal with two digit precision - DATE = 12; // days since 4713bc + DATE = 12; // days since 4713bc TIME = 13; // time in micros before or after 2000/1/1 TIMETZ = 14; // time in micros before or after 2000/1/1 with timezone TIMESTAMPTZ = 15; // unix epoch time in millis @@ -53,6 +53,8 @@ enum MinorType { UINT2 = 30; // unsigned 2 byte integer UINT4 = 31; // unsigned 4 byte integer UINT8 = 32; // unsigned 8 byte integer + DECIMAL28DENSE = 33; // dense decimal representation, supporting precision between 19 and 28 + DECIMAL38DENSE = 34; // dense decimal representation, supporting precision between 28 and 38 // PROTO2 = 33; // protobuf encoded complex type. (up to 2^16 in length) // PROTO4 = 34; // protobuf encoded complex type. (up to 2^32 in length) // MSGPACK2 = 35; // msgpack encoded complex type. (up to 2^16 in length)
