diff --git ql/src/test/queries/clientpositive/cast_to_int.q ql/src/test/queries/clientpositive/cast_to_int.q new file mode 100644 index 0000000..729ffdc --- /dev/null +++ ql/src/test/queries/clientpositive/cast_to_int.q @@ -0,0 +1,30 @@ +-- cast string floats to integer types +select + cast('1' as float), + cast('1.4' as float), + cast('1.6' as float), + cast('1' as int), + cast('1.4' as int), + cast('1.6' as int), + cast('1' as tinyint), + cast('1.4' as tinyint), + cast('1.6' as tinyint), + cast('1' as smallint), + cast('1.4' as smallint), + cast('1.6' as smallint), + cast('1' as bigint), + cast('1.4' as bigint), + cast('1.6' as bigint), + cast (cast('1' as float) as int), + cast(cast ('1.4' as float) as int), + cast(cast ('1.6' as float) as int), + cast('+1e5' as int), + cast('2147483647' as int), + cast('-2147483648' as int), + cast('32767' as smallint), + cast('-32768' as smallint), + cast('-128' as tinyint), + cast('127' as tinyint), + cast('1.0a' as int), + cast('-1.-1' as int) +from src limit 1; diff --git ql/src/test/results/clientpositive/cast_to_int.q.out ql/src/test/results/clientpositive/cast_to_int.q.out new file mode 100644 index 0000000..04da595 --- /dev/null +++ ql/src/test/results/clientpositive/cast_to_int.q.out @@ -0,0 +1,67 @@ +PREHOOK: query: -- cast string floats to integer types +select + cast('1' as float), + cast('1.4' as float), + cast('1.6' as float), + cast('1' as int), + cast('1.4' as int), + cast('1.6' as int), + cast('1' as tinyint), + cast('1.4' as tinyint), + cast('1.6' as tinyint), + cast('1' as smallint), + cast('1.4' as smallint), + cast('1.6' as smallint), + cast('1' as bigint), + cast('1.4' as bigint), + cast('1.6' as bigint), + cast (cast('1' as float) as int), + cast(cast ('1.4' as float) as int), + cast(cast ('1.6' as float) as int), + cast('+1e5' as int), + cast('2147483647' as int), + cast('-2147483648' as int), + cast('32767' as smallint), + cast('-32768' as smallint), + cast('-128' as tinyint), + cast('127' as tinyint), + cast('1.0a' as int), + cast('-1.-1' as int) +from src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: -- cast string floats to integer types +select + cast('1' as float), + cast('1.4' as float), + cast('1.6' as float), + cast('1' as int), + cast('1.4' as int), + cast('1.6' as int), + cast('1' as tinyint), + cast('1.4' as tinyint), + cast('1.6' as tinyint), + cast('1' as smallint), + cast('1.4' as smallint), + cast('1.6' as smallint), + cast('1' as bigint), + cast('1.4' as bigint), + cast('1.6' as bigint), + cast (cast('1' as float) as int), + cast(cast ('1.4' as float) as int), + cast(cast ('1.6' as float) as int), + cast('+1e5' as int), + cast('2147483647' as int), + cast('-2147483648' as int), + cast('32767' as smallint), + cast('-32768' as smallint), + cast('-128' as tinyint), + cast('127' as tinyint), + cast('1.0a' as int), + cast('-1.-1' as int) +from src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +1.0 1.4 1.6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 NULL 2147483647 -2147483648 32767 -32768 -128 127 NULL NULL diff --git serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java index 243f2b7..36fe2ed 100644 --- serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java +++ serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyInteger.java @@ -136,11 +136,15 @@ public static int parseInt(byte[] bytes, int start, int length, int radix) { */ private static int parse(byte[] bytes, int start, int length, int offset, int radix, boolean negative) { + byte separator = '.'; int max = Integer.MIN_VALUE / radix; int result = 0, end = start + length; while (offset < end) { int digit = LazyUtils.digit(bytes[offset++], radix); if (digit == -1) { + if (bytes[offset-1] == separator) { + break; + } throw new NumberFormatException(LazyUtils.convertToString(bytes, start, length)); } @@ -155,6 +159,15 @@ private static int parse(byte[] bytes, int start, int length, int offset, } result = next; } + + while (offset < end) { + int digit = LazyUtils.digit(bytes[offset++], radix); + if (digit == -1) { + throw new NumberFormatException(LazyUtils.convertToString(bytes, start, + length)); + } + } + if (!negative) { result = -result; if (result < 0) { diff --git serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java index 15ea4f2..e937940 100644 --- serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java +++ serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyLong.java @@ -138,11 +138,15 @@ public static long parseLong(byte[] bytes, int start, int length, int radix) { */ private static long parse(byte[] bytes, int start, int length, int offset, int radix, boolean negative) { + byte separator = '.'; long max = Long.MIN_VALUE / radix; long result = 0, end = start + length; while (offset < end) { int digit = LazyUtils.digit(bytes[offset++], radix); if (digit == -1 || max > result) { + if (bytes[offset-1] == separator) { + break; + } throw new NumberFormatException(LazyUtils.convertToString(bytes, start, length)); } @@ -153,6 +157,15 @@ private static long parse(byte[] bytes, int start, int length, int offset, } result = next; } + + while (offset < end) { + int digit = LazyUtils.digit(bytes[offset++], radix); + if (digit == -1) { + throw new NumberFormatException(LazyUtils.convertToString(bytes, start, + length)); + } + } + if (!negative) { result = -result; if (result < 0) {