DRILL-1526: Move casting logic to utility methods.
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/17a4d921 Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/17a4d921 Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/17a4d921 Branch: refs/heads/master Commit: 17a4d921417ff914cb81588926b692d1aea09e56 Parents: 38c5d4e Author: Jacques Nadeau <jacq...@apache.org> Authored: Thu Aug 28 18:51:25 2014 -0700 Committer: Mehant Baid <meha...@gmail.com> Committed: Wed Oct 15 18:24:13 2014 -0700 ---------------------------------------------------------------------- .../templates/CastFunctionsSrcVarLen.java | 65 +---------- .../expr/fn/impl/StringFunctionHelpers.java | 115 +++++++++++++++++++ 2 files changed, 119 insertions(+), 61 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/17a4d921/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 d8ce44a..57740c9 100644 --- a/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java +++ b/exec/java-exec/src/main/codegen/templates/CastFunctionsSrcVarLen.java @@ -62,68 +62,11 @@ public class Cast${type.from}${type.to} implements DrillSimpleFunc{ //TODO: need capture format exception, and issue SQLERR code. out.value = ${type.javaType}.parse${type.parse}(new String(buf, com.google.common.base.Charsets.UTF_8)); - <#elseif type.to=="Int" || type.to == "BigInt"> - - if ((in.end - in.start) ==0) { - //empty, not a valid number - byte[] buf = new byte[in.end - in.start]; - in.buffer.getBytes(in.start, buf, 0, in.end - in.start); - throw new NumberFormatException(new String(buf, com.google.common.base.Charsets.UTF_8)); - } - - int readIndex = in.start; - - boolean negative = in.buffer.getByte(readIndex) == '-'; - - if (negative && ++readIndex == in.end) { - //only one single '-' - byte[] buf = new byte[in.end - in.start]; - in.buffer.getBytes(in.start, buf, 0, in.end - in.start); - throw new NumberFormatException(new String(buf, com.google.common.base.Charsets.UTF_8)); - } - - int radix = 10; - ${type.primeType} max = -${type.javaType}.MAX_VALUE / radix; - ${type.primeType} result = 0; - int digit; - - while (readIndex < in.end) { - digit = Character.digit(in.buffer.getByte(readIndex++),radix); - //not valid digit. - if (digit == -1) { - byte[] buf = new byte[in.end - in.start]; - in.buffer.getBytes(in.start, buf, 0, in.end - in.start); - throw new NumberFormatException(new String(buf, com.google.common.base.Charsets.UTF_8)); - } - //overflow - if (max > result) { - 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)); - } - - ${type.primeType} next = result * radix - digit; - - //overflow - if (next > result) { - 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)); - } - result = next; - } - if (!negative) { - result = -result; - //overflow - if (result < 0) { - 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)); - } - } - - out.value = result; + <#elseif type.to=="Int" > + out.value = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.varCharToInt(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); </#if> } } http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/17a4d921/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 b514adb..3219a9c 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 @@ -28,6 +28,121 @@ import com.google.common.base.Charsets; public class StringFunctionHelpers { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(StringFunctionHelpers.class); + static final int RADIX = 10; + 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){ + if ((end - start) ==0) { + //empty, not a valid number + return nfeL(start, end, buffer); + } + + int readIndex = start; + + boolean negative = buffer.getByte(readIndex) == '-'; + + if (negative && ++readIndex == end) { + //only one single '-' + return nfeL(start, end, buffer); + } + + + long result = 0; + int digit; + + while (readIndex < end) { + digit = Character.digit(buffer.getByte(readIndex++),RADIX); + //not valid digit. + if (digit == -1) { + return nfeL(start, end, buffer); + } + //overflow + if (MAX_LONG > result) { + return nfeL(start, end, buffer); + } + + long next = result * RADIX - digit; + + //overflow + if (next > result) { + return nfeL(start, end, buffer); + } + result = next; + } + if (!negative) { + result = -result; + //overflow + if (result < 0) { + return nfeL(start, end, buffer); + } + } + + return result; + } + + private static int nfeL(int start, int end, DrillBuf buffer){ + byte[] buf = new byte[end - start]; + buffer.getBytes(start, buf, 0, end - start); + throw new NumberFormatException(new String(buf, com.google.common.base.Charsets.UTF_8)); + } + + private static int nfeI(int start, int end, DrillBuf buffer){ + byte[] buf = new byte[end - start]; + buffer.getBytes(start, buf, 0, end - start); + 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){ + if ((end - start) ==0) { + //empty, not a valid number + return nfeI(start, end, buffer); + } + + int readIndex = start; + + boolean negative = buffer.getByte(readIndex) == '-'; + + if (negative && ++readIndex == end) { + //only one single '-' + return nfeI(start, end, buffer); + } + + int radix = 10; + int max = MAX_INT / radix; + int result = 0; + int digit; + + while (readIndex < end) { + digit = Character.digit(buffer.getByte(readIndex++),radix); + //not valid digit. + if (digit == -1) { + return nfeI(start, end, buffer); + } + //overflow + if (max > result) { + return nfeI(start, end, buffer); + } + + int next = result * radix - digit; + + //overflow + if (next > result) { + return nfeI(start, end, buffer); + } + result = next; + } + if (!negative) { + result = -result; + //overflow + if (result < 0) { + return nfeI(start, end, buffer); + } + } + + return result; + } + // Assumes Alpha as [A-Za-z0-9] // white space is treated as everything else. public static void initCap(int start, int end, DrillBuf inBuf, DrillBuf outBuf) {