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(

Reply via email to