You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by jd...@apache.org on 2017/10/13 18:08:53 UTC
hive git commit: HIVE-17782: Inconsistent cast behavior from string
to numeric types with regards to leading/trailing spaces (Jason Dere,
reviewed by Ashutosh Chauhan)
Repository: hive
Updated Branches:
refs/heads/master 0c9b66763 -> ea89de719
HIVE-17782: Inconsistent cast behavior from string to numeric types with regards to leading/trailing spaces (Jason Dere, reviewed by Ashutosh Chauhan)
Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/ea89de71
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/ea89de71
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/ea89de71
Branch: refs/heads/master
Commit: ea89de719eea48639a3ecf556a74b810b54a8e3f
Parents: 0c9b667
Author: Jason Dere <jd...@hortonworks.com>
Authored: Fri Oct 13 11:07:32 2017 -0700
Committer: Jason Dere <jd...@hortonworks.com>
Committed: Fri Oct 13 11:07:32 2017 -0700
----------------------------------------------------------------------
.../hive/common/util/HiveStringUtils.java | 51 +++++
.../apache/hadoop/hive/ql/udf/UDFToByte.java | 2 +-
.../apache/hadoop/hive/ql/udf/UDFToInteger.java | 2 +-
.../apache/hadoop/hive/ql/udf/UDFToLong.java | 2 +-
.../apache/hadoop/hive/ql/udf/UDFToShort.java | 2 +-
ql/src/test/queries/clientpositive/cast2.q | 5 +
ql/src/test/results/clientpositive/cast2.q.out | 18 ++
.../hadoop/hive/serde2/lazy/LazyByte.java | 24 ++-
.../hadoop/hive/serde2/lazy/LazyInteger.java | 31 +++
.../hadoop/hive/serde2/lazy/LazyLong.java | 31 +++
.../hadoop/hive/serde2/lazy/LazyShort.java | 24 ++-
.../hive/serde2/lazy/TestLazyPrimitive.java | 197 +++++++++++++++++++
12 files changed, 383 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/common/src/java/org/apache/hive/common/util/HiveStringUtils.java
----------------------------------------------------------------------
diff --git a/common/src/java/org/apache/hive/common/util/HiveStringUtils.java b/common/src/java/org/apache/hive/common/util/HiveStringUtils.java
index dc3ee98..bf34600 100644
--- a/common/src/java/org/apache/hive/common/util/HiveStringUtils.java
+++ b/common/src/java/org/apache/hive/common/util/HiveStringUtils.java
@@ -1007,6 +1007,57 @@ public class HiveStringUtils {
return len;
}
+ /**
+ * Checks if b is an ascii character
+ */
+ public static boolean isAscii(byte b) {
+ return (b & 0x80) == 0;
+ }
+
+ /**
+ * Returns the number of leading whitespace characters in the utf-8 string
+ */
+ public static int findLeadingSpaces(byte[] bytes, int start, int length) {
+ int numSpaces;
+ for (numSpaces = 0; numSpaces < length; ++numSpaces) {
+ int curPos = start + numSpaces;
+ if (isAscii(bytes[curPos]) && Character.isWhitespace(bytes[curPos])) {
+ continue;
+ }
+ break; // non-space character
+ }
+ return (numSpaces - start);
+ }
+
+ /**
+ * Returns the number of trailing whitespace characters in the utf-8 string
+ */
+ public static int findTrailingSpaces(byte[] bytes, int start, int length) {
+ int numSpaces;
+ for (numSpaces = 0; numSpaces < length; ++numSpaces) {
+ int curPos = start + (length - (numSpaces + 1));
+ if (isAscii(bytes[curPos]) && Character.isWhitespace(bytes[curPos])) {
+ continue;
+ } else {
+ break; // non-space character
+ }
+ }
+ return numSpaces;
+ }
+
+ /**
+ * Finds trimmed length of utf-8 string
+ */
+ public static int findTrimmedLength(byte[] bytes, int start, int length, int leadingSpaces) {
+ int trailingSpaces = findTrailingSpaces(bytes, start, length);
+ length = length - leadingSpaces;
+ // If string is entirely whitespace, no need to apply trailingSpaces.
+ if (length > 0) {
+ length = length - trailingSpaces;
+ }
+ return length;
+ }
+
public static String normalizeIdentifier(String identifier) {
return identifier.trim().toLowerCase();
}
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java
index 12f530b..a5c49f3 100755
--- a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java
@@ -172,7 +172,7 @@ public class UDFToByte extends UDF {
return null;
}
try {
- byteWritable.set(LazyByte.parseByte(i.getBytes(), 0, i.getLength(), 10));
+ byteWritable.set(LazyByte.parseByte(i.getBytes(), 0, i.getLength(), 10, true));
return byteWritable;
} catch (NumberFormatException e) {
// MySQL returns 0 if the string is not a well-formed numeric value.
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java
index 1de7604..df756d0 100755
--- a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java
@@ -175,7 +175,7 @@ public class UDFToInteger extends UDF {
}
try {
intWritable.set(LazyInteger
- .parseInt(i.getBytes(), 0, i.getLength(), 10));
+ .parseInt(i.getBytes(), 0, i.getLength(), 10, true));
return intWritable;
} catch (NumberFormatException e) {
// MySQL returns 0 if the string is not a well-formed numeric value.
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java
index 11f6a6c..4821d67 100755
--- a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java
@@ -184,7 +184,7 @@ public class UDFToLong extends UDF {
}
try {
longWritable
- .set(LazyLong.parseLong(i.getBytes(), 0, i.getLength(), 10));
+ .set(LazyLong.parseLong(i.getBytes(), 0, i.getLength(), 10, true));
return longWritable;
} catch (NumberFormatException e) {
// MySQL returns 0 if the string is not a well-formed numeric value.
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java
index 5372549..df0fc96 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java
@@ -174,7 +174,7 @@ public class UDFToShort extends UDF {
}
try {
shortWritable.set(LazyShort.parseShort(i.getBytes(), 0, i.getLength(),
- 10));
+ 10, true));
return shortWritable;
} catch (NumberFormatException e) {
// MySQL returns 0 if the string is not a well-formed numeric value.
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/ql/src/test/queries/clientpositive/cast2.q
----------------------------------------------------------------------
diff --git a/ql/src/test/queries/clientpositive/cast2.q b/ql/src/test/queries/clientpositive/cast2.q
new file mode 100644
index 0000000..12228be
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/cast2.q
@@ -0,0 +1,5 @@
+
+select cast('1' as tinyint), cast('1' as smallint), cast('1' as int), cast('1' as bigint), cast('1' as float), cast('1' as double), cast('1' as decimal(10,2));
+
+-- Check that leading/trailing space is handled consistently for numeric types
+select cast(' 1 ' as tinyint), cast(' 1 ' as smallint), cast(' 1 ' as int), cast(' 1 ' as bigint), cast(' 1 ' as float), cast(' 1 ' as double), cast(' 1 ' as decimal(10,2));
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/ql/src/test/results/clientpositive/cast2.q.out
----------------------------------------------------------------------
diff --git a/ql/src/test/results/clientpositive/cast2.q.out b/ql/src/test/results/clientpositive/cast2.q.out
new file mode 100644
index 0000000..9fa3a9d
--- /dev/null
+++ b/ql/src/test/results/clientpositive/cast2.q.out
@@ -0,0 +1,18 @@
+PREHOOK: query: select cast('1' as tinyint), cast('1' as smallint), cast('1' as int), cast('1' as bigint), cast('1' as float), cast('1' as double), cast('1' as decimal(10,2))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select cast('1' as tinyint), cast('1' as smallint), cast('1' as int), cast('1' as bigint), cast('1' as float), cast('1' as double), cast('1' as decimal(10,2))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+1 1 1 1 1.0 1.0 1
+PREHOOK: query: select cast(' 1 ' as tinyint), cast(' 1 ' as smallint), cast(' 1 ' as int), cast(' 1 ' as bigint), cast(' 1 ' as float), cast(' 1 ' as double), cast(' 1 ' as decimal(10,2))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select cast(' 1 ' as tinyint), cast(' 1 ' as smallint), cast(' 1 ' as int), cast(' 1 ' as bigint), cast(' 1 ' as float), cast(' 1 ' as double), cast(' 1 ' as decimal(10,2))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+1 1 1 1 1.0 1.0 1
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyByte.java
----------------------------------------------------------------------
diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyByte.java b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyByte.java
index 1f9cead..405c905 100644
--- a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyByte.java
+++ b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyByte.java
@@ -95,7 +95,29 @@ public class LazyByte extends
* if the argument could not be parsed as a byte quantity.
*/
public static byte parseByte(byte[] bytes, int start, int length, int radix) {
- int intValue = LazyInteger.parseInt(bytes, start, length, radix);
+ return parseByte(bytes, start, length, radix, false);
+ }
+
+ /**
+ * Parses the string argument as if it was a byte value and returns the
+ * result. Throws NumberFormatException if the string does not represent a
+ * single byte quantity. The second argument specifies the radix to use when
+ * parsing the value.
+ *
+ * @param bytes
+ * @param start
+ * @param length
+ * a UTF-8 encoded string representation of a single byte quantity.
+ * @param radix
+ * the radix to use when parsing.
+ * @param trim
+ * whether to trim leading/trailing whitespace
+ * @return byte the value represented by the argument
+ * @throws NumberFormatException
+ * if the argument could not be parsed as a byte quantity.
+ */
+ public static byte parseByte(byte[] bytes, int start, int length, int radix, boolean trim) {
+ int intValue = LazyInteger.parseInt(bytes, start, length, radix, trim);
byte result = (byte) intValue;
if (result == intValue) {
return result;
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java
----------------------------------------------------------------------
diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java
index 22742aa..9687c6d 100644
--- a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java
+++ b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java
@@ -22,6 +22,7 @@ import java.io.OutputStream;
import org.apache.hadoop.hive.serde2.lazy.objectinspector.primitive.LazyIntObjectInspector;
import org.apache.hadoop.io.IntWritable;
+import org.apache.hive.common.util.HiveStringUtils;
/**
* LazyObject for storing a value of Integer.
@@ -98,12 +99,42 @@ public class LazyInteger extends
* if the argument could not be parsed as an int quantity.
*/
public static int parseInt(byte[] bytes, int start, int length, int radix) {
+ return parseInt(bytes, start, length, radix, false);
+ }
+
+ /**
+ * Parses the string argument as if it was an int value and returns the
+ * result. Throws NumberFormatException if the string does not represent an
+ * int quantity. The second argument specifies the radix to use when parsing
+ * the value.
+ *
+ * @param bytes
+ * @param start
+ * @param length
+ * a UTF-8 encoded string representation of an int quantity.
+ * @param radix
+ * the base to use for conversion.
+ * @param trim
+ * whether to trim leading/trailing whitespace
+ * @return the value represented by the argument
+ * @exception NumberFormatException
+ * if the argument could not be parsed as an int quantity.
+ */
+ public static int parseInt(byte[] bytes, int start, int length, int radix, boolean trim) {
if (bytes == null) {
throw new NumberFormatException("String is null");
}
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
throw new NumberFormatException("Invalid radix: " + radix);
}
+ if (trim) {
+ // Handle leading/trailing whitespace
+ int leadingSpaces = HiveStringUtils.findLeadingSpaces(bytes, start, length);
+ int trailingSpaces = HiveStringUtils.findTrailingSpaces(bytes, start, length);
+ start = start + leadingSpaces;
+ // min() needed in the case that entire string is whitespace
+ length = length - Math.min(length, leadingSpaces + trailingSpaces);
+ }
if (length == 0) {
throw new NumberFormatException("Empty string!");
}
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java
----------------------------------------------------------------------
diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java
index c0d52b9..91c7e5e 100644
--- a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java
+++ b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java
@@ -22,6 +22,7 @@ import java.io.OutputStream;
import org.apache.hadoop.hive.serde2.lazy.objectinspector.primitive.LazyLongObjectInspector;
import org.apache.hadoop.io.LongWritable;
+import org.apache.hive.common.util.HiveStringUtils;
/**
* LazyObject for storing a value of Long.
@@ -98,12 +99,42 @@ public class LazyLong extends
* if the argument could not be parsed as an long quantity.
*/
public static long parseLong(byte[] bytes, int start, int length, int radix) {
+ return parseLong(bytes, start, length, radix, false);
+ }
+
+ /**
+ * Parses the string argument as if it was an long value and returns the
+ * result. Throws NumberFormatException if the string does not represent an
+ * long quantity. The second argument specifies the radix to use when parsing
+ * the value.
+ *
+ * @param bytes
+ * @param start
+ * @param length
+ * a UTF-8 encoded string representation of a long quantity.
+ * @param radix
+ * the base to use for conversion.
+ * @param trim
+ * whether to trim leading/trailing whitespace
+ * @return the value represented by the argument
+ * @exception NumberFormatException
+ * if the argument could not be parsed as an long quantity.
+ */
+ public static long parseLong(byte[] bytes, int start, int length, int radix, boolean trim) {
if (bytes == null) {
throw new NumberFormatException("String is null");
}
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
throw new NumberFormatException("Invalid radix: " + radix);
}
+ if (trim) {
+ // Handle leading/trailing whitespace
+ int leadingSpaces = HiveStringUtils.findLeadingSpaces(bytes, start, length);
+ int trailingSpaces = HiveStringUtils.findTrailingSpaces(bytes, start, length);
+ start = start + leadingSpaces;
+ // min() needed in the case that entire string is whitespace
+ length = length - Math.min(length, leadingSpaces + trailingSpaces);
+ }
if (length == 0) {
throw new NumberFormatException("Empty string!");
}
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyShort.java
----------------------------------------------------------------------
diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyShort.java b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyShort.java
index b8b9488..39c2b60 100644
--- a/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyShort.java
+++ b/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyShort.java
@@ -95,7 +95,29 @@ public class LazyShort extends
* if the argument could not be parsed as a short quantity.
*/
public static short parseShort(byte[] bytes, int start, int length, int radix) {
- int intValue = LazyInteger.parseInt(bytes, start, length, radix);
+ return parseShort(bytes, start, length, radix, false);
+ }
+
+ /**
+ * Parses the string argument as if it was a short value and returns the
+ * result. Throws NumberFormatException if the string does not represent a
+ * single short quantity. The second argument specifies the radix to use when
+ * parsing the value.
+ *
+ * @param bytes
+ * @param start
+ * @param length
+ * a UTF-8 encoded string representation of a short quantity.
+ * @param radix
+ * the radix to use when parsing.
+ * @param trim
+ * whether to trim leading/trailing whitespace
+ * @return short the value represented by the argument
+ * @exception NumberFormatException
+ * if the argument could not be parsed as a short quantity.
+ */
+ public static short parseShort(byte[] bytes, int start, int length, int radix, boolean trim) {
+ int intValue = LazyInteger.parseInt(bytes, start, length, radix, trim);
short result = (short) intValue;
if (result == intValue) {
return result;
http://git-wip-us.apache.org/repos/asf/hive/blob/ea89de71/serde/src/test/org/apache/hadoop/hive/serde2/lazy/TestLazyPrimitive.java
----------------------------------------------------------------------
diff --git a/serde/src/test/org/apache/hadoop/hive/serde2/lazy/TestLazyPrimitive.java b/serde/src/test/org/apache/hadoop/hive/serde2/lazy/TestLazyPrimitive.java
index 3d7f11e..663d1f2 100644
--- a/serde/src/test/org/apache/hadoop/hive/serde2/lazy/TestLazyPrimitive.java
+++ b/serde/src/test/org/apache/hadoop/hive/serde2/lazy/TestLazyPrimitive.java
@@ -468,4 +468,201 @@ public class TestLazyPrimitive extends TestCase {
}
}
+ private void testIntCaseWithPass(String strVal, int intVal, boolean trim) {
+ Text text = new Text(strVal);
+ assertEquals(
+ intVal,
+ LazyInteger.parseInt(text.getBytes(), 0, text.getLength(), 10, trim));
+ }
+
+ private void testIntCaseWithFail(String strVal, boolean trim) {
+ Text text = new Text(strVal);
+ try {
+ LazyInteger.parseInt(text.getBytes(), 0, text.getLength(), 10, trim);
+ fail("Expected to fail while parsing '" + strVal + "'");
+ } catch (NumberFormatException err) {
+ // Error was expected
+ }
+ }
+
+ private void testLongCaseWithPass(String strVal, long longVal, boolean trim) {
+ Text text = new Text(strVal);
+ assertEquals(
+ longVal,
+ LazyLong.parseLong(text.getBytes(), 0, text.getLength(), 10, trim));
+ }
+
+ private void testLongCaseWithFail(String strVal, boolean trim) {
+ Text text = new Text(strVal);
+ try {
+ LazyLong.parseLong(text.getBytes(), 0, text.getLength(), 10, trim);
+ fail("Expected to fail while parsing '" + strVal + "'");
+ } catch (NumberFormatException err) {
+ // Error was expected
+ }
+ }
+
+ public void testLazyIntWithSpaces() throws Throwable {
+ Object[][] casesWithoutSpaces = {
+ {"0", 0},
+ {"-128", -128},
+ {"128", 128},
+ {"+128", 128},
+ {"-2147483648", -2147483648},
+ {"2147483647", 2147483647},
+ {"+2147483647", 2147483647},
+ };
+
+ Object[][] casesWithSpaces = {
+ {" 0", 0},
+ {"0 ", 0},
+ {" 0 ", 0},
+ {" -128", -128},
+ {"-128 ", -128},
+ {" -128 ", -128},
+ {" 128", 128},
+ {"128 ", 128},
+ {" 128 ", 128},
+ {" +128", 128},
+ {"+128 ", 128},
+ {" +128 ", 128},
+ {" +128 ", 128},
+ {" -2147483648", -2147483648},
+ {"-2147483648 ", -2147483648},
+ {" -2147483648 ", -2147483648},
+ {" 2147483647", 2147483647},
+ {"2147483647 ", 2147483647},
+ {" 2147483647 ", 2147483647},
+ {" +2147483647", 2147483647},
+ {"+2147483647 ", 2147483647},
+ {" +2147483647 ", 2147483647},
+ };
+
+ String[] casesWithErrors = {
+ "",
+ " ",
+ "one",
+ " one ",
+ "123:",
+ "123a",
+ " 123a ",
+ "a123",
+ " a123 ",
+ // Exceeds MAX_VALUE
+ "2147483648",
+ "-2147483649",
+ };
+
+ //
+ // trim=false
+ //
+ boolean trim = false;
+ for (Object[] testCase : casesWithoutSpaces) {
+ testIntCaseWithPass((String) testCase[0], ((Number) testCase[1]).intValue(), trim);
+ }
+ for (Object[] testCase : casesWithSpaces) {
+ // With trim=false, parsing cannot handle spaces
+ testIntCaseWithFail((String) testCase[0], trim);
+ }
+ for (String testCase : casesWithErrors) {
+ testIntCaseWithFail(testCase, trim);
+ }
+
+ //
+ // trim=true
+ //
+ trim = true;
+ for (Object[] testCase : casesWithoutSpaces) {
+ testIntCaseWithPass((String) testCase[0], ((Number) testCase[1]).intValue(), trim);
+ }
+ for (Object[] testCase : casesWithSpaces) {
+ // With trim=true, parsing can handle spaces
+ testIntCaseWithPass((String) testCase[0], ((Number) testCase[1]).intValue(), trim);
+ }
+ for (String testCase : casesWithErrors) {
+ testIntCaseWithFail(testCase, trim);
+ }
+ }
+
+ public void testLazyLongWithSpaces() throws Throwable {
+ Object[][] casesWithoutSpaces = {
+ {"0", 0},
+ {"-128", -128},
+ {"128", 128},
+ {"+128", 128},
+ {"-9223372036854775808", -9223372036854775808L},
+ {"9223372036854775807", 9223372036854775807L},
+ {"+9223372036854775807", 9223372036854775807L},
+ };
+
+ Object[][] casesWithSpaces = {
+ {" 0", 0},
+ {"0 ", 0},
+ {" 0 ", 0},
+ {" -128", -128},
+ {"-128 ", -128},
+ {" -128 ", -128},
+ {" 128", 128},
+ {"128 ", 128},
+ {" 128 ", 128},
+ {" +128", 128},
+ {"+128 ", 128},
+ {" +128 ", 128},
+ {" +128 ", 128},
+ {" -9223372036854775808", -9223372036854775808L},
+ {"-9223372036854775808 ", -9223372036854775808L},
+ {" -9223372036854775808 ", -9223372036854775808L},
+ {" 9223372036854775807", 9223372036854775807L},
+ {"9223372036854775807 ", 9223372036854775807L},
+ {" 9223372036854775807 ", 9223372036854775807L},
+ {" +9223372036854775807", 9223372036854775807L},
+ {"+9223372036854775807 ", 9223372036854775807L},
+ {" +9223372036854775807 ", 9223372036854775807L},
+ };
+
+ String[] casesWithErrors = {
+ "",
+ " ",
+ "one",
+ " one ",
+ "123:",
+ "123a",
+ " 123a ",
+ "a123",
+ " a123 ",
+ // Exceeds max value
+ "9223372036854775808",
+ "9223372036854775809",
+ };
+
+ //
+ // trim=false
+ //
+ boolean trim = false;
+ for (Object[] testCase : casesWithoutSpaces) {
+ testLongCaseWithPass((String) testCase[0], ((Number) testCase[1]).longValue(), trim);
+ }
+ for (Object[] testCase : casesWithSpaces) {
+ // With trim=false, parsing cannot handle spaces
+ testLongCaseWithFail((String) testCase[0], trim);
+ }
+ for (String testCase : casesWithErrors) {
+ testLongCaseWithFail(testCase, trim);
+ }
+
+ //
+ // trim=true
+ //
+ trim = true;
+ for (Object[] testCase : casesWithoutSpaces) {
+ testLongCaseWithPass((String) testCase[0], ((Number) testCase[1]).longValue(), trim);
+ }
+ for (Object[] testCase : casesWithSpaces) {
+ // With trim=true, parsing can handle spaces
+ testLongCaseWithPass((String) testCase[0], ((Number) testCase[1]).longValue(), trim);
+ }
+ for (String testCase : casesWithErrors) {
+ testLongCaseWithFail(testCase, trim);
+ }
+ }
}