DRILL-4346: Handle NumberFormatException when casting empty string to int in hbase/maprdb
- Made replacing of functions casting for nullable input varbinary and var16char types are working (in CastFunctions.java setting 'drill.exec.functions.cast_empty_string_to_null = true' didn't work); - Added new generated classes for casting varbinary and var16char to int (CastEmptyStringVarTypesToNullableNumeric template and Casts.tdd data); - Created a test (in TestHBaseQueries.java) for checking an empty string to integer casting in maprdb/hbase table; - Small design changes according to comments in review (import statements, prefixes ...). This closes #384 Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/b9960f89 Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/b9960f89 Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/b9960f89 Branch: refs/heads/master Commit: b9960f89e72810d109e712ef7e740919502e72d9 Parents: cca17cb Author: vataga <[email protected]> Authored: Tue Feb 2 13:18:49 2016 +0200 Committer: Parth Chandra <[email protected]> Committed: Fri Feb 26 09:53:27 2016 -0800 ---------------------------------------------------------------------- .../org/apache/drill/hbase/HBaseTestsSuite.java | 7 +- .../apache/drill/hbase/TestHBaseQueries.java | 16 +++ .../apache/drill/hbase/TestTableGenerator.java | 27 ++++ exec/java-exec/src/main/codegen/data/Casts.tdd | 59 ++++++--- ...astEmptyStringVarTypesToNullableNumeric.java | 92 +++++++++++++ .../templates/CastFunctionsSrcVarLen.java | 4 +- .../templates/CastVarCharToNullableNumeric.java | 85 ------------ .../templates/Decimal/CastVarCharDecimal.java | 16 +-- .../expr/fn/FunctionImplementationRegistry.java | 21 +-- .../expr/fn/impl/StringFunctionHelpers.java | 4 +- .../common/expression/fn/CastFunctions.java | 132 +++++++++++++------ 11 files changed, 299 insertions(+), 164 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java ---------------------------------------------------------------------- diff --git a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java index fe11265..8f59b67 100644 --- a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java +++ b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/HBaseTestsSuite.java @@ -61,6 +61,7 @@ public class HBaseTestsSuite { protected static final String TEST_TABLE_FLOAT_OB_DESC = "TestTableFloatOBDesc"; protected static final String TEST_TABLE_BIGINT_OB_DESC = "TestTableBigIntOBDesc"; protected static final String TEST_TABLE_INT_OB_DESC = "TestTableIntOBDesc"; + protected static final String TEST_TABLE_NULL_STR = "TestTableNullStr"; private static Configuration conf; @@ -159,7 +160,8 @@ public class HBaseTestsSuite { && admin.tableExists(TEST_TABLE_DOUBLE_OB_DESC) && admin.tableExists(TEST_TABLE_FLOAT_OB_DESC) && admin.tableExists(TEST_TABLE_BIGINT_OB_DESC) - && admin.tableExists(TEST_TABLE_INT_OB_DESC); + && admin.tableExists(TEST_TABLE_INT_OB_DESC) + && admin.tableExists(TEST_TABLE_NULL_STR); } private static void createTestTables() throws Exception { @@ -183,6 +185,7 @@ public class HBaseTestsSuite { TestTableGenerator.generateHBaseDatasetFloatOBDesc(admin, TEST_TABLE_FLOAT_OB_DESC, 1); TestTableGenerator.generateHBaseDatasetBigIntOBDesc(admin, TEST_TABLE_BIGINT_OB_DESC, 1); TestTableGenerator.generateHBaseDatasetIntOBDesc(admin, TEST_TABLE_INT_OB_DESC, 1); + TestTableGenerator.generateHBaseDatasetNullStr(admin, TEST_TABLE_NULL_STR, 1); } private static void cleanupTestTables() throws IOException { @@ -212,6 +215,8 @@ public class HBaseTestsSuite { admin.deleteTable(TEST_TABLE_BIGINT_OB_DESC); admin.disableTable(TEST_TABLE_INT_OB_DESC); admin.deleteTable(TEST_TABLE_INT_OB_DESC); + admin.disableTable(TEST_TABLE_NULL_STR); + admin.deleteTable(TEST_TABLE_NULL_STR); } public static int getZookeeperPort() { http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseQueries.java ---------------------------------------------------------------------- diff --git a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseQueries.java b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseQueries.java index 3f412c7..ce7d585 100644 --- a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseQueries.java +++ b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestHBaseQueries.java @@ -18,7 +18,9 @@ package org.apache.drill.hbase; import java.util.Arrays; +import java.util.List; +import org.apache.drill.exec.rpc.user.QueryDataBatch; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.client.HBaseAdmin; @@ -90,4 +92,18 @@ public class TestHBaseQueries extends BaseHBaseTest { } catch (Exception e) { } // ignore } } + @Test + public void testCastEmptyStrings() throws Exception { + try { + test("alter system set `drill.exec.functions.cast_empty_string_to_null` = true;"); + setColumnWidths(new int[] {5, 4}); + List<QueryDataBatch> resultList = runHBaseSQLlWithResults("SELECT row_key,\n" + + " CAST(t.f.c1 as INT) c1, CAST(t.f.c2 as BIGINT) c2, CAST(t.f.c3 as INT) c3,\n" + + " CAST(t.f.c4 as INT) c4 FROM hbase.TestTableNullStr t where row_key='a1'"); + printResult(resultList); + } + finally { + test("alter system reset `drill.exec.functions.cast_empty_string_to_null`;"); + } + } } http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java ---------------------------------------------------------------------- diff --git a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java index 77e9d64..f4f3e93 100644 --- a/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java +++ b/contrib/storage-hbase/src/test/java/org/apache/drill/hbase/TestTableGenerator.java @@ -610,4 +610,31 @@ public class TestTableGenerator { admin.flush(tableName); } + + public static void generateHBaseDatasetNullStr(HBaseAdmin admin, String tableName, int numberRegions) throws Exception { + if (admin.tableExists(tableName)) { + admin.disableTable(tableName); + admin.deleteTable(tableName); + } + + HTableDescriptor desc = new HTableDescriptor(tableName); + desc.addFamily(new HColumnDescriptor("f")); + if (numberRegions > 1) { + admin.createTable(desc, Arrays.copyOfRange(SPLIT_KEYS, 0, numberRegions-1)); + } else { + admin.createTable(desc); + } + + HTable table = new HTable(admin.getConfiguration(), tableName); + + Put p = new Put("a1".getBytes()); + p.add("f".getBytes(), "c1".getBytes(), "".getBytes()); + p.add("f".getBytes(), "c2".getBytes(), "".getBytes()); + p.add("f".getBytes(), "c3".getBytes(), "5".getBytes()); + p.add("f".getBytes(), "c4".getBytes(), "".getBytes()); + table.put(p); + + table.flushCommits(); + table.close(); + } } http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/exec/java-exec/src/main/codegen/data/Casts.tdd ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/codegen/data/Casts.tdd b/exec/java-exec/src/main/codegen/data/Casts.tdd index 6b5420f..307c0f2 100644 --- a/exec/java-exec/src/main/codegen/data/Casts.tdd +++ b/exec/java-exec/src/main/codegen/data/Casts.tdd @@ -168,25 +168,44 @@ {from: "Decimal38Sparse", to: "Decimal18", major: "DownwardDecimalComplexDecimalSimple", javatype: "long"}, {from: "Decimal38Sparse", to: "Decimal9", major: "DownwardDecimalComplexDecimalSimple", javatype: "int"}, - {from: "VarChar", to: "Int", major: "EmptyString", javaType:"Integer", primeType:"int"}, - {from: "VarChar", to: "BigInt", major: "EmptyString", javaType: "Long", primeType: "long"}, - {from: "VarChar", to: "Float4", major: "EmptyString", javaType:"Float", parse:"Float"}, - {from: "VarChar", to: "Float8", major: "EmptyString", javaType:"Double", parse:"Double"}, - - {from: "VarChar", to: "Decimal9", major: "EmptyStringVarCharDecimalSimple", javatype: "int"}, - {from: "VarChar", to: "Decimal18", major: "EmptyStringVarCharDecimalSimple", javatype: "long"}, - {from: "VarChar", to: "Decimal28Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "5"}, - {from: "VarChar", to: "Decimal38Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "6"}, - - {from: "NullableVarChar", to: "Int", major: "EmptyString", javaType:"Integer", primeType:"int"}, - {from: "NullableVarChar", to: "BigInt", major: "EmptyString", javaType: "Long", primeType: "long"}, - {from: "NullableVarChar", to: "Float4", major: "EmptyString", javaType:"Float", parse:"Float"}, - {from: "NullableVarChar", to: "Float8", major: "EmptyString", javaType:"Double", parse:"Double"}, - - {from: "NullableVarChar", to: "Decimal9", major: "EmptyStringVarCharDecimalSimple", javatype: "int"}, - {from: "NullableVarChar", to: "Decimal18", major: "EmptyStringVarCharDecimalSimple", javatype: "long"}, - {from: "NullableVarChar", to: "Decimal28Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "5"}, - {from: "NullableVarChar", to: "Decimal38Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "6"}, - + {from: "VarChar", to: "NullableInt", major: "EmptyString", javaType:"Integer", primeType:"int"}, + {from: "VarChar", to: "NullableBigInt", major: "EmptyString", javaType: "Long", primeType: "long"}, + {from: "VarChar", to: "NullableFloat4", major: "EmptyString", javaType:"Float", parse:"Float"}, + {from: "VarChar", to: "NullableFloat8", major: "EmptyString", javaType:"Double", parse:"Double"}, + + {from: "VarChar", to: "NullableDecimal9", major: "EmptyStringVarCharDecimalSimple", javatype: "int"}, + {from: "VarChar", to: "NullableDecimal18", major: "EmptyStringVarCharDecimalSimple", javatype: "long"}, + {from: "VarChar", to: "NullableDecimal28Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "5"}, + {from: "VarChar", to: "NullableDecimal38Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "6"}, + + {from: "NullableVarChar", to: "NullableInt", major: "EmptyString", javaType:"Integer", primeType:"int"}, + {from: "NullableVarChar", to: "NullableBigInt", major: "EmptyString", javaType: "Long", primeType: "long"}, + {from: "NullableVarChar", to: "NullableFloat4", major: "EmptyString", javaType:"Float", parse:"Float"}, + {from: "NullableVarChar", to: "NullableFloat8", major: "EmptyString", javaType:"Double", parse:"Double"}, + + {from: "NullableVarChar", to: "NullableDecimal9", major: "EmptyStringVarCharDecimalSimple", javatype: "int"}, + {from: "NullableVarChar", to: "NullableDecimal18", major: "EmptyStringVarCharDecimalSimple", javatype: "long"}, + {from: "NullableVarChar", to: "NullableDecimal28Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "5"}, + {from: "NullableVarChar", to: "NullableDecimal38Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "6"}, + + {from: "NullableVar16Char", to: "NullableInt", major: "EmptyString", javaType:"Integer", primeType:"int"}, + {from: "NullableVar16Char", to: "NullableBigInt", major: "EmptyString", javaType: "Long", primeType: "long"}, + {from: "NullableVar16Char", to: "NullableFloat4", major: "EmptyString", javaType:"Float", parse:"Float"}, + {from: "NullableVar16Char", to: "NullableFloat8", major: "EmptyString", javaType:"Double", parse:"Double"}, + + {from: "NullableVar16Char", to: "NullableDecimal9", major: "EmptyStringVarCharDecimalSimple", javatype: "int"}, + {from: "NullableVar16Char", to: "NullableDecimal18", major: "EmptyStringVarCharDecimalSimple", javatype: "long"}, + {from: "NullableVar16Char", to: "NullableDecimal28Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "5"}, + {from: "NullableVar16Char", to: "NullableDecimal38Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "6"}, + + {from: "NullableVarBinary", to: "NullableInt", major: "EmptyString", javaType:"Integer", primeType:"int"}, + {from: "NullableVarBinary", to: "NullableBigInt", major: "EmptyString", javaType: "Long", primeType: "long"}, + {from: "NullableVarBinary", to: "NullableFloat4", major: "EmptyString", javaType:"Float", parse:"Float"}, + {from: "NullableVarBinary", to: "NullableFloat8", major: "EmptyString", javaType:"Double", parse:"Double"}, + + {from: "NullableVarBinary", to: "NullableDecimal9", major: "EmptyStringVarCharDecimalSimple", javatype: "int"}, + {from: "NullableVarBinary", to: "NullableDecimal18", major: "EmptyStringVarCharDecimalSimple", javatype: "long"}, + {from: "NullableVarBinary", to: "NullableDecimal28Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "5"}, + {from: "NullableVarBinary", to: "NullableDecimal38Sparse", major: "EmptyStringVarCharDecimalComplex", arraySize: "6"}, ] } http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java b/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java new file mode 100644 index 0000000..68ebccc --- /dev/null +++ b/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java @@ -0,0 +1,92 @@ +/** + * 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. + */ +<@pp.dropOutputFile /> + +<#macro doError> + { + 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, com.google.common.base.Charsets.UTF_8)); + } +</#macro> + +<#list cast.types as type> +<#if type.major == "EmptyString"> + +<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/CastEmptyString${type.from}To${type.to}.java" /> +<#include "/@includes/license.ftl" /> + + package org.apache.drill.exec.expr.fn.impl.gcast; + + import org.apache.drill.exec.expr.DrillSimpleFunc; + import org.apache.drill.exec.expr.annotations.FunctionTemplate; + import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling; + import org.apache.drill.exec.expr.annotations.Output; + import org.apache.drill.exec.expr.annotations.Param; + import org.apache.drill.exec.expr.holders.*; + import org.apache.drill.exec.record.RecordBatch; + import javax.inject.Inject; + import io.netty.buffer.DrillBuf; + +/** + * This file is generated with Freemarker using the template exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java + */ + +@SuppressWarnings("unused") +@FunctionTemplate(name = "castEmptyString${type.from}To${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.INTERNAL) +public class CastEmptyString${type.from}To${type.to} implements DrillSimpleFunc{ + + @Param ${type.from}Holder in; + @Output ${type.to}Holder out; + + public void setup() {} + + public void eval() { + <#if type.to == "NullableFloat4" || type.to == "NullableFloat8"> + if(<#if type.from == "NullableVarChar" || type.from == "NullableVar16Char" || + type.from == "NullableVarBinary">in.isSet == 0 || </#if>in.end == in.start) { + out.isSet = 0; + } else{ + out.isSet = 1; + byte[]buf=new byte[in.end-in.start]; + in.buffer.getBytes(in.start,buf,0,in.end-in.start); + out.value=${type.javaType}.parse${type.parse}(new String(buf,com.google.common.base.Charsets.UTF_8)); + } + <#elseif type.to=="NullableInt"> + if(<#if type.from == "NullableVarChar" || type.from == "NullableVar16Char" || + type.from == "NullableVarBinary">in.isSet == 0 || </#if>in.end == in.start) { + out.isSet = 0; + } else { + out.isSet = 1; + out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varTypesToInt(in.start, in.end, in.buffer); + } + <#elseif type.to == "NullableBigInt"> + if(<#if type.from == "NullableVarChar" || type.from == "NullableVar16Char" || + type.from == "NullableVarBinary">in.isSet == 0 || </#if> + in.end == in.start) { + out.isSet = 0; + } else { + out.isSet = 1; + out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varTypesToLong(in.start, in.end, in.buffer); + } + </#if> + } +} + +</#if> <#-- type.major --> +</#list> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/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 ec543e3..85768de 100644 --- a/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java +++ b/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java @@ -63,10 +63,10 @@ public class Cast${type.from}${type.to} implements DrillSimpleFunc{ out.value = ${type.javaType}.parse${type.parse}(new String(buf, com.google.common.base.Charsets.UTF_8)); <#elseif type.to=="Int" > - out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varCharToInt(in.start, in.end, in.buffer); + out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varTypesToInt(in.start, in.end, in.buffer); <#elseif type.to == "BigInt"> - out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varCharToLong(in.start, in.end, in.buffer); + out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varTypesToLong(in.start, in.end, in.buffer); </#if> } } http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/exec/java-exec/src/main/codegen/templates/CastVarCharToNullableNumeric.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/codegen/templates/CastVarCharToNullableNumeric.java b/exec/java-exec/src/main/codegen/templates/CastVarCharToNullableNumeric.java deleted file mode 100644 index 2b009be..0000000 --- a/exec/java-exec/src/main/codegen/templates/CastVarCharToNullableNumeric.java +++ /dev/null @@ -1,85 +0,0 @@ -/** - * 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. - */ -<@pp.dropOutputFile /> - -<#macro doError> -{ - 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, com.google.common.base.Charsets.UTF_8)); -} -</#macro> - -<#list cast.types as type> -<#if type.major == "EmptyString"> - -<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/CastEmptyString${type.from}ToNullable${type.to}.java" /> - -<#include "/@includes/license.ftl" /> - -package org.apache.drill.exec.expr.fn.impl.gcast; - -import org.apache.drill.exec.expr.DrillSimpleFunc; -import org.apache.drill.exec.expr.annotations.FunctionTemplate; -import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling; -import org.apache.drill.exec.expr.annotations.Output; -import org.apache.drill.exec.expr.annotations.Param; -import org.apache.drill.exec.expr.holders.*; -import org.apache.drill.exec.record.RecordBatch; -import javax.inject.Inject; -import io.netty.buffer.DrillBuf; - -@SuppressWarnings("unused") -@FunctionTemplate(name = "castEmptyString${type.from}ToNullable${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.INTERNAL) -public class CastEmptyString${type.from}ToNullable${type.to} implements DrillSimpleFunc{ - - @Param ${type.from}Holder in; - @Output Nullable${type.to}Holder out; - - public void setup() {} - - public void eval() { - <#if type.to == "Float4" || type.to == "Float8"> - if(<#if type.from == "NullableVarChar"> in.isSet == 0 || </#if> in.end == in.start) { - out.isSet = 0; - } else{ - out.isSet = 1; - byte[]buf=new byte[in.end-in.start]; - in.buffer.getBytes(in.start,buf,0,in.end-in.start); - out.value=${type.javaType}.parse${type.parse}(new String(buf,com.google.common.base.Charsets.UTF_8)); - } - <#elseif type.to=="Int"> - if(<#if type.from == "NullableVarChar"> in.isSet == 0 || </#if> in.end == in.start) { - out.isSet = 0; - } else { - out.isSet = 1; - out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varCharToInt(in.start, in.end, in.buffer); - } - <#elseif type.to == "BigInt"> - if(<#if type.from == "NullableVarChar"> in.isSet == 0 || </#if> in.end == in.start) { - out.isSet = 0; - } else { - out.isSet = 1; - out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varCharToLong(in.start, in.end, in.buffer); - } - </#if> - } -} - -</#if> <#-- type.major --> -</#list> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/exec/java-exec/src/main/codegen/templates/Decimal/CastVarCharDecimal.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/codegen/templates/Decimal/CastVarCharDecimal.java b/exec/java-exec/src/main/codegen/templates/Decimal/CastVarCharDecimal.java index 2fe55eb..e2dbaea 100644 --- a/exec/java-exec/src/main/codegen/templates/Decimal/CastVarCharDecimal.java +++ b/exec/java-exec/src/main/codegen/templates/Decimal/CastVarCharDecimal.java @@ -24,7 +24,7 @@ <#if type.major == "VarCharDecimalSimple"> <@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/Cast${type.from}${type.to}.java"/> <#elseif type.major == "EmptyStringVarCharDecimalSimple"> -<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/CastEmptyString${type.from}ToNullable${type.to}.java"/> +<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/CastEmptyString${type.from}To${type.to}.java"/> </#if> <#include "/@includes/license.ftl" /> @@ -53,8 +53,8 @@ import java.nio.ByteBuffer; @FunctionTemplate(name ="cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.DECIMAL_CAST, nulls=NullHandling.NULL_IF_NULL) public class Cast${type.from}${type.to} implements DrillSimpleFunc { <#elseif type.major == "EmptyStringVarCharDecimalSimple"> -@FunctionTemplate(name ="castEmptyString${type.from}ToNullable${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.DECIMAL_CAST, nulls=NullHandling.INTERNAL) -public class CastEmptyString${type.from}ToNullable${type.to} implements DrillSimpleFunc { +@FunctionTemplate(name ="castEmptyString${type.from}To${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.DECIMAL_CAST, nulls=NullHandling.INTERNAL) +public class CastEmptyString${type.from}To${type.to} implements DrillSimpleFunc { </#if> @Param ${type.from}Holder in; @Param BigIntHolder precision; @@ -63,7 +63,7 @@ public class CastEmptyString${type.from}ToNullable${type.to} implements DrillSim <#if type.major == "VarCharDecimalSimple"> @Output ${type.to}Holder out; <#elseif type.major == "EmptyStringVarCharDecimalSimple"> - @Output Nullable${type.to}Holder out; + @Output ${type.to}Holder out; </#if> public void setup() { @@ -198,7 +198,7 @@ public class CastEmptyString${type.from}ToNullable${type.to} implements DrillSim <#if type.major == "VarCharDecimalComplex"> <@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/Cast${type.from}${type.to}.java"/> <#elseif type.major == "EmptyStringVarCharDecimalComplex"> -<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/CastEmptyString${type.from}ToNullable${type.to}.java"/> +<@pp.changeOutputFile name="/org/apache/drill/exec/expr/fn/impl/gcast/CastEmptyString${type.from}To${type.to}.java"/> </#if> <#include "/@includes/license.ftl" /> @@ -226,8 +226,8 @@ import java.nio.ByteBuffer; @FunctionTemplate(name = "cast${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.DECIMAL_CAST, nulls=NullHandling.NULL_IF_NULL) public class Cast${type.from}${type.to} implements DrillSimpleFunc { <#elseif type.major == "EmptyStringVarCharDecimalComplex"> -@FunctionTemplate(name = "castEmptyString${type.from}ToNullable${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.DECIMAL_CAST, nulls=NullHandling.INTERNAL) -public class CastEmptyString${type.from}ToNullable${type.to} implements DrillSimpleFunc { +@FunctionTemplate(name = "castEmptyString${type.from}To${type.to?upper_case}", scope = FunctionTemplate.FunctionScope.DECIMAL_CAST, nulls=NullHandling.INTERNAL) +public class CastEmptyString${type.from}To${type.to} implements DrillSimpleFunc { </#if> @Param ${type.from}Holder in; @Inject DrillBuf buffer; @@ -237,7 +237,7 @@ public class CastEmptyString${type.from}ToNullable${type.to} implements DrillSim <#if type.major == "VarCharDecimalComplex"> @Output ${type.to}Holder out; <#elseif type.major == "EmptyStringVarCharDecimalComplex"> - @Output Nullable${type.to}Holder out; + @Output ${type.to}Holder out; </#if> public void setup() { http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java index a57f116..5985f0e 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java @@ -28,7 +28,9 @@ import org.apache.drill.common.expression.FunctionCall; import org.apache.drill.common.expression.fn.CastFunctions; import org.apache.drill.common.scanner.ClassPathScanner; import org.apache.drill.common.scanner.persistence.ScanResult; +import org.apache.drill.common.types.TypeProtos.DataMode; import org.apache.drill.common.types.TypeProtos.MajorType; +import org.apache.drill.common.types.TypeProtos.MinorType; import org.apache.drill.exec.ExecConstants; import org.apache.drill.exec.planner.sql.DrillOperatorTable; import org.apache.drill.exec.resolver.FunctionResolver; @@ -115,15 +117,16 @@ public class FunctionImplementationRegistry implements FunctionLookupContext { // Check if this Function Replacement is needed; if yes, return a new name. otherwise, return the original name private String functionReplacement(FunctionCall functionCall) { String funcName = functionCall.getName(); - if (optionManager != null - && optionManager.getOption(ExecConstants.CAST_TO_NULLABLE_NUMERIC).bool_val - && functionCall.args.size() > 0 - && CastFunctions.isReplacementNeeded(functionCall.args.get(0).getMajorType().getMinorType(), - funcName)) { - org.apache.drill.common.types.TypeProtos.DataMode dataMode = - functionCall.args.get(0).getMajorType().getMode(); - funcName = CastFunctions.getReplacingCastFunction(funcName, dataMode); - } + if (functionCall.args.size() > 0) { + MajorType majorType = functionCall.args.get(0).getMajorType(); + DataMode dataMode = majorType.getMode(); + MinorType minorType = majorType.getMinorType(); + if (optionManager != null + && optionManager.getOption(ExecConstants.CAST_TO_NULLABLE_NUMERIC).bool_val + && CastFunctions.isReplacementNeeded(funcName, minorType)) { + funcName = CastFunctions.getReplacingCastFunction(funcName, dataMode, minorType); + } + } return funcName; } http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java index 3d0f170..06c9212 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java @@ -34,7 +34,7 @@ public class StringFunctionHelpers { static final long MAX_LONG = -Long.MAX_VALUE / RADIX; static final int MAX_INT = -Integer.MAX_VALUE / RADIX; - public static long varCharToLong(final int start, final int end, DrillBuf buffer){ + public static long varTypesToLong(final int start, final int end, DrillBuf buffer){ if ((end - start) ==0) { //empty, not a valid number return nfeL(start, end, buffer); @@ -95,7 +95,7 @@ public class StringFunctionHelpers { throw new NumberFormatException(new String(buf, com.google.common.base.Charsets.UTF_8)); } - public static int varCharToInt(final int start, final int end, DrillBuf buffer){ + public static int varTypesToInt(final int start, final int end, DrillBuf buffer){ if ((end - start) ==0) { //empty, not a valid number return nfeI(start, end, buffer); http://git-wip-us.apache.org/repos/asf/drill/blob/b9960f89/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java ---------------------------------------------------------------------- diff --git a/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java b/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java index 34997ab..af25dd7 100644 --- a/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java +++ b/logical/src/main/java/org/apache/drill/common/expression/fn/CastFunctions.java @@ -21,7 +21,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.apache.drill.common.types.TypeProtos; +import org.apache.drill.common.types.TypeProtos.DataMode; import org.apache.drill.common.types.TypeProtos.MinorType; public class CastFunctions { @@ -31,10 +31,17 @@ public class CastFunctions { * "drill.exec.functions.cast_empty_string_to_null" is set to true). */ private static Set<String> CAST_FUNC_REPLACEMENT_NEEDED = new HashSet<>(); /** Map from the replaced functions to the new ones (for non-nullable VARCHAR). */ - private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE = new HashMap<>(); + private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR = new HashMap<>(); + /** Map from the replaced functions to the new ones (for non-nullable VAR16CHAR). */ + private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR = new HashMap<>(); + /** Map from the replaced functions to the new ones (for non-nullable VARBINARY). */ + private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY = new HashMap<>(); /** Map from the replaced functions to the new ones (for nullable VARCHAR). */ - private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NULLABLE = new HashMap<>(); - + private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR = new HashMap<>(); + /** Map from the replaced functions to the new ones (for nullable VAR16CHAR). */ + private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR = new HashMap<>(); + /** Map from the replaced functions to the new ones (for nullable VARBINARY). */ + private static Map<String, String> CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY = new HashMap<>(); static { TYPE2FUNC.put(MinorType.UNION, "castUNION"); TYPE2FUNC.put(MinorType.BIGINT, "castBIGINT"); @@ -69,29 +76,65 @@ public class CastFunctions { CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE)); CAST_FUNC_REPLACEMENT_NEEDED.add(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE)); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringVarCharToNullableINT"); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringVarCharToNullableBIGINT"); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringVarCharToNullableFLOAT4"); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringVarCharToNullableFLOAT8"); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringVarCharToNullableDECIMAL9"); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringVarCharToNullableDECIMAL18"); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringVarCharToNullableDECIMAL28SPARSE"); - CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringVarCharToNullableDECIMAL38SPARSE"); - - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringNullableVarCharToNullableINT"); - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringNullableVarCharToNullableBIGINT"); - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringNullableVarCharToNullableFLOAT4"); - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringNullableVarCharToNullableFLOAT8"); - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringNullableVarCharToNullableDECIMAL9"); - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringNullableVarCharToNullableDECIMAL18"); - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringNullableVarCharToNullableDECIMAL28SPARSE"); - CAST_FUNC_REPLACEMENT_FROM_NULLABLE.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringNullableVarCharToNullableDECIMAL38SPARSE"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringVarCharToNullableINT"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringVarCharToNullableBIGINT"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringVarCharToNullableFLOAT4"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringVarCharToNullableFLOAT8"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringVarCharToNullableDECIMAL9"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringVarCharToNullableDECIMAL18"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringVarCharToNullableDECIMAL28SPARSE"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringVarCharToNullableDECIMAL38SPARSE"); + + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringVar16CharToNullableINT"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringVar16CharToNullableBIGINT"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringVar16CharToNullableFLOAT4"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringVar16CharToNullableFLOAT8"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringVar16CharToNullableDECIMAL9"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringVar16CharToNullableDECIMAL18"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringVar16CharToNullableDECIMAL28SPARSE"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringVar16CharToNullableDECIMAL38SPARSE"); + + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringVarBinaryToNullableINT"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringVarBinaryToNullableBIGINT"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringVarBinaryToNullableFLOAT4"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringVarBinaryToNullableFLOAT8"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringVarBinaryToNullableDECIMAL9"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringVarBinaryToNullableDECIMAL18"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringVarBinaryToNullableDECIMAL28SPARSE"); + CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringVarBinaryToNullableDECIMAL38SPARSE"); + + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringNullableVarCharToNullableINT"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringNullableVarCharToNullableBIGINT"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringNullableVarCharToNullableFLOAT4"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringNullableVarCharToNullableFLOAT8"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringNullableVarCharToNullableDECIMAL9"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringNullableVarCharToNullableDECIMAL18"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringNullableVarCharToNullableDECIMAL28SPARSE"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringNullableVarCharToNullableDECIMAL38SPARSE"); + + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringNullableVar16CharToNullableINT"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringNullableVar16CharToNullableBIGINT"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringNullableVar16CharToNullableFLOAT4"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringNullableVar16CharToNullableFLOAT8"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringNullableVar16CharToNullableDECIMAL9"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringNullableVar16CharToNullableDECIMAL18"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringNullableVar16CharToNullableDECIMAL28SPARSE"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringNullableVar16CharToNullableDECIMAL38SPARSE"); + + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.INT), "castEmptyStringNullableVarBinaryToNullableINT"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.BIGINT), "castEmptyStringNullableVarBinaryToNullableBIGINT"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.FLOAT4), "castEmptyStringNullableVarBinaryToNullableFLOAT4"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.FLOAT8), "castEmptyStringNullableVarBinaryToNullableFLOAT8"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL9), "castEmptyStringNullableVarBinaryToNullableDECIMAL9"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL18), "castEmptyStringNullableVarBinaryToNullableDECIMAL18"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL28SPARSE), "castEmptyStringNullableVarBinaryToNullableDECIMAL28SPARSE"); + CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.put(TYPE2FUNC.get(MinorType.DECIMAL38SPARSE), "castEmptyStringNullableVarBinaryToNullableDECIMAL38SPARSE"); } /** * Given the target type, get the appropriate cast function * @param targetMinorType the target data type - * @return + * @return the name of cast function */ public static String getCastFunc(MinorType targetMinorType) { String func = TYPE2FUNC.get(targetMinorType); @@ -107,15 +150,16 @@ public class CastFunctions { * Get a replacing cast function for the original function, based on the specified data mode * @param originalCastFunction original cast function * @param dataMode data mode of the input data - * @return + * @param inputType input (minor) type for cast + * @return the name of replaced cast function */ - public static String getReplacingCastFunction(String originalCastFunction, org.apache.drill.common.types.TypeProtos.DataMode dataMode) { - if(dataMode == TypeProtos.DataMode.OPTIONAL) { - return getReplacingCastFunctionFromNullable(originalCastFunction); + public static String getReplacingCastFunction(String originalCastFunction, DataMode dataMode, MinorType inputType) { + if(dataMode == DataMode.OPTIONAL) { + return getReplacingCastFunctionFromNullable(originalCastFunction, inputType); } - if(dataMode == TypeProtos.DataMode.REQUIRED) { - return getReplacingCastFunctionFromNonNullable(originalCastFunction); + if(dataMode == DataMode.REQUIRED) { + return getReplacingCastFunctionFromNonNullable(originalCastFunction, inputType); } throw new RuntimeException( @@ -125,24 +169,38 @@ public class CastFunctions { /** * Check if a replacing cast function is available for the the original function * @param originalfunction original cast function - * @return + * @param inputType input (minor) type for cast + * @return true if replacement is needed, false - if isn't */ - public static boolean isReplacementNeeded(MinorType inputType, String originalfunction) { - return inputType == MinorType.VARCHAR && CAST_FUNC_REPLACEMENT_NEEDED.contains(originalfunction); + public static boolean isReplacementNeeded(String originalfunction, MinorType inputType) { + return (inputType == MinorType.VARCHAR || inputType == MinorType.VARBINARY || inputType == MinorType.VAR16CHAR) && + CAST_FUNC_REPLACEMENT_NEEDED.contains(originalfunction); } - private static String getReplacingCastFunctionFromNonNullable(String originalCastFunction) { - if(CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.containsKey(originalCastFunction)) { - return CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE.get(originalCastFunction); + private static String getReplacingCastFunctionFromNonNullable(String originalCastFunction, MinorType inputType) { + if(inputType == MinorType.VARCHAR && CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.containsKey(originalCastFunction)) { + return CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARCHAR.get(originalCastFunction); + } + if(inputType == MinorType.VAR16CHAR && CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.containsKey(originalCastFunction)) { + return CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VAR16CHAR.get(originalCastFunction); + } + if(inputType == MinorType.VARBINARY && CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.containsKey(originalCastFunction)) { + return CAST_FUNC_REPLACEMENT_FROM_NONNULLABLE_VARBINARY.get(originalCastFunction); } throw new RuntimeException( String.format("replacing cast function for %s is not defined", originalCastFunction)); } - private static String getReplacingCastFunctionFromNullable(String originalCastFunction) { - if(CAST_FUNC_REPLACEMENT_FROM_NULLABLE.containsKey(originalCastFunction)) { - return CAST_FUNC_REPLACEMENT_FROM_NULLABLE.get(originalCastFunction); + private static String getReplacingCastFunctionFromNullable(String originalCastFunction, MinorType inputType) { + if(inputType == MinorType.VARCHAR && CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.containsKey(originalCastFunction)) { + return CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARCHAR.get(originalCastFunction); + } + if(inputType == MinorType.VAR16CHAR && CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.containsKey(originalCastFunction)) { + return CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VAR16CHAR.get(originalCastFunction); + } + if(inputType == MinorType.VARBINARY && CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.containsKey(originalCastFunction)) { + return CAST_FUNC_REPLACEMENT_FROM_NULLABLE_VARBINARY.get(originalCastFunction); } throw new RuntimeException(
