Index: ql/src/test/results/clientpositive/cast1.q.out =================================================================== --- ql/src/test/results/clientpositive/cast1.q.out (revision 713736) +++ ql/src/test/results/clientpositive/cast1.q.out (working copy) @@ -1,5 +1,5 @@ ABSTRACT SYNTAX TREE: - (TOK_QUERY (TOK_FROM (TOK_TABREF src)) (TOK_INSERT (TOK_DESTINATION (TOK_TAB dest1)) (TOK_SELECT (TOK_SELEXPR (+ 3 2)) (TOK_SELEXPR (+ 3.0 2)) (TOK_SELEXPR (+ 3 2.0)) (TOK_SELEXPR (+ 3.0 2.0)) (TOK_SELEXPR (+ 3 (TOK_FUNCTION TOK_INT 2.0))) (TOK_SELEXPR (TOK_FUNCTION TOK_BOOLEAN 1)) (TOK_SELEXPR (TOK_FUNCTION TOK_INT TRUE))) (TOK_WHERE (= (TOK_COLREF src key) 86)))) + (TOK_QUERY (TOK_FROM (TOK_TABREF src)) (TOK_INSERT (TOK_DESTINATION (TOK_TAB dest1)) (TOK_SELECT (TOK_SELEXPR (+ 3 2)) (TOK_SELEXPR (+ 3.0 2)) (TOK_SELEXPR (+ 3 2.0)) (TOK_SELEXPR (+ 3.0 2.0)) (TOK_SELEXPR (+ (+ 3 (TOK_FUNCTION TOK_INT 2.0)) (TOK_FUNCTION TOK_INT (TOK_FUNCTION TOK_SMALLINT 0)))) (TOK_SELEXPR (TOK_FUNCTION TOK_BOOLEAN 1)) (TOK_SELEXPR (TOK_FUNCTION TOK_INT TRUE))) (TOK_WHERE (= (TOK_COLREF src key) 86)))) STAGE DEPENDENCIES: Stage-1 is a root stage @@ -28,7 +28,7 @@ type: double expr: (3.0 + 2.0) type: double - expr: (3 + UDFToInteger(2.0)) + expr: ((3 + UDFToInteger(2.0)) + UDFToInteger(UDFToShort(0))) type: int expr: UDFToBoolean(1) type: boolean Index: ql/src/test/queries/clientpositive/cast1.q =================================================================== --- ql/src/test/queries/clientpositive/cast1.q (revision 713736) +++ ql/src/test/queries/clientpositive/cast1.q (working copy) @@ -1,9 +1,9 @@ CREATE TABLE dest1(c1 INT, c2 DOUBLE, c3 DOUBLE, c4 DOUBLE, c5 INT, c6 INT, c7 INT) STORED AS TEXTFILE; EXPLAIN -FROM src INSERT OVERWRITE TABLE dest1 SELECT 3 + 2, 3.0 + 2, 3 + 2.0, 3.0 + 2.0, 3 + CAST(2.0 AS INT), CAST(1 AS BOOLEAN), CAST(TRUE AS INT) WHERE src.key = 86; +FROM src INSERT OVERWRITE TABLE dest1 SELECT 3 + 2, 3.0 + 2, 3 + 2.0, 3.0 + 2.0, 3 + CAST(2.0 AS INT) + CAST(CAST(0 AS SMALLINT) AS INT), CAST(1 AS BOOLEAN), CAST(TRUE AS INT) WHERE src.key = 86; -FROM src INSERT OVERWRITE TABLE dest1 SELECT 3 + 2, 3.0 + 2, 3 + 2.0, 3.0 + 2.0, 3 + CAST(2.0 AS INT), CAST(1 AS BOOLEAN), CAST(TRUE AS INT) WHERE src.key = 86; +FROM src INSERT OVERWRITE TABLE dest1 SELECT 3 + 2, 3.0 + 2, 3 + 2.0, 3.0 + 2.0, 3 + CAST(2.0 AS INT) + CAST(CAST(0 AS SMALLINT) AS INT), CAST(1 AS BOOLEAN), CAST(TRUE AS INT) WHERE src.key = 86; select dest1.* FROM dest1; Index: ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (working copy) @@ -115,6 +115,8 @@ UDFToBoolean.class.getSimpleName()); registerUDF(Byte.class.getName(), UDFToByte.class, OperatorType.PREFIX, false, UDFToByte.class.getSimpleName()); + registerUDF(Short.class.getName(), UDFToShort.class, OperatorType.PREFIX, false, + UDFToShort.class.getSimpleName()); registerUDF(Integer.class.getName(), UDFToInteger.class, OperatorType.PREFIX, false, UDFToInteger.class.getSimpleName()); registerUDF(Long.class.getName(), UDFToLong.class, OperatorType.PREFIX, false, Index: ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (working copy) @@ -3401,6 +3401,7 @@ conversionFunctionTextHashMap = new HashMap(); conversionFunctionTextHashMap.put(HiveParser.TOK_BOOLEAN, Boolean.class.getName()); conversionFunctionTextHashMap.put(HiveParser.TOK_TINYINT, Byte.class.getName()); + conversionFunctionTextHashMap.put(HiveParser.TOK_SMALLINT, Short.class.getName()); conversionFunctionTextHashMap.put(HiveParser.TOK_INT, Integer.class.getName()); conversionFunctionTextHashMap.put(HiveParser.TOK_BIGINT, Long.class.getName()); conversionFunctionTextHashMap.put(HiveParser.TOK_FLOAT, Float.class.getName()); Index: ql/src/java/org/apache/hadoop/hive/ql/plan/exprNodeFuncDesc.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/plan/exprNodeFuncDesc.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/plan/exprNodeFuncDesc.java (working copy) @@ -48,6 +48,7 @@ super(typeInfo); assert(UDFClass != null); this.UDFClass = UDFClass; + assert(UDFMethod != null); this.UDFMethod = UDFMethod; this.children = children; } Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToInteger.java (working copy) @@ -30,6 +30,12 @@ public UDFToInteger() { } + /** + * Convert from boolean to an integer. This is called for CAST(... AS INT) + * + * @param i The boolean value to convert + * @return Integer + */ public Integer evaluate(Boolean i) { if (i == null) { return null; @@ -38,6 +44,12 @@ } } + /** + * Convert from byte to an integer. This is called for CAST(... AS INT) + * + * @param i The byte value to convert + * @return Integer + */ public Integer evaluate(Byte i) { if (i == null) { return null; @@ -46,6 +58,26 @@ } } + /** + * Convert from short to an integer. This is called for CAST(... AS INT) + * + * @param i The short value to convert + * @return Integer + */ + public Integer evaluate(Short i) { + if (i == null) { + return null; + } else { + return Integer.valueOf(i.shortValue()); + } + } + + /** + * Convert from long to an integer. This is called for CAST(... AS INT) + * + * @param i The long value to convert + * @return Integer + */ public Integer evaluate(Long i) { if (i == null) { return null; @@ -54,6 +86,12 @@ } } + /** + * Convert from float to an integer. This is called for CAST(... AS INT) + * + * @param i The float value to convert + * @return Integer + */ public Integer evaluate(Float i) { if (i == null) { return null; @@ -62,6 +100,12 @@ } } + /** + * Convert from double to an integer. This is called for CAST(... AS INT) + * + * @param i The double value to convert + * @return Integer + */ public Integer evaluate(Double i) { if (i == null) { return null; @@ -70,6 +114,12 @@ } } + /** + * Convert from string to an integer. This is called for CAST(... AS INT) + * + * @param i The string value to convert + * @return Integer + */ public Integer evaluate(String i) { if (i == null) { return null; Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToLong.java (working copy) @@ -30,6 +30,26 @@ public UDFToLong() { } + /** + * Convert from boolean to a long. This is called for CAST(... AS BIGINT) + * + * @param i The boolean value to convert + * @return Long + */ + public Long evaluate(Boolean i) { + if (i == null) { + return null; + } else { + return i.booleanValue() ? (long)1 : (long)0; + } + } + + /** + * Convert from byte to a long. This is called for CAST(... AS BIGINT) + * + * @param i The byte value to convert + * @return Long + */ public Long evaluate(Byte i) { if (i == null) { return null; @@ -38,6 +58,26 @@ } } + /** + * Convert from short to a long. This is called for CAST(... AS BIGINT) + * + * @param i The short value to convert + * @return Long + */ + public Long evaluate(Short i) { + if (i == null) { + return null; + } else { + return Long.valueOf(i.longValue()); + } + } + + /** + * Convert from integer to a long. This is called for CAST(... AS BIGINT) + * + * @param i The integer value to convert + * @return Long + */ public Long evaluate(Integer i) { if (i == null) { return null; @@ -46,11 +86,22 @@ } } + /** + * Convert from long to a long. This is called for CAST(... AS BIGINT) + * + * @param i The long value to convert + * @return Long + */ public Long evaluate(Long i) { return i; } - + /** + * Convert from float to a long. This is called for CAST(... AS BIGINT) + * + * @param i The float value to convert + * @return Long + */ public Long evaluate(Float i) { if (i == null) { return null; @@ -59,6 +110,12 @@ } } + /** + * Convert from double to a long. This is called for CAST(... AS BIGINT) + * + * @param i The double value to convert + * @return Long + */ public Long evaluate(Double i) { if (i == null) { return null; @@ -67,6 +124,12 @@ } } + /** + * Convert from string to a long. This is called for CAST(... AS BIGINT) + * + * @param i The string value to convert + * @return Long + */ public Long evaluate(String i) { if (i == null) { return null; Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToShort.java (revision 0) @@ -0,0 +1,138 @@ +/** + * 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. + */ + +package org.apache.hadoop.hive.ql.udf; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hive.ql.exec.UDF; + + +public class UDFToShort implements UDF { + + private static Log LOG = LogFactory.getLog(UDFToByte.class.getName()); + + public UDFToShort() { + } + + /** + * Convert from boolean to a short. This is called for CAST(... AS SMALLINT) + * + * @param i The boolean value to convert + * @return Short + */ + public Short evaluate(Boolean i) { + if (i == null) { + return null; + } else { + return i.booleanValue() ? (short)1 : (short)0; + } + } + + /** + * Convert from byte to a short. This is called for CAST(... AS SMALLINT) + * + * @param i The byte value to convert + * @return Short + */ + public Short evaluate(Byte i) { + if (i == null) { + return null; + } else { + return Short.valueOf(i.shortValue()); + } + } + + /** + * Convert from integer to a short. This is called for CAST(... AS SMALLINT) + * + * @param i The integer value to convert + * @return Short + */ + public Short evaluate(Integer i) { + if (i == null) { + return null; + } else { + return Short.valueOf(i.shortValue()); + } + } + + /** + * Convert from long to a short. This is called for CAST(... AS SMALLINT) + * + * @param i The long value to convert + * @return Short + */ + public Short evaluate(Long i) { + if (i == null) { + return null; + } else { + return Short.valueOf(i.shortValue()); + } + } + + /** + * Convert from float to a short. This is called for CAST(... AS SMALLINT) + * + * @param i The float value to convert + * @return Short + */ + public Short evaluate(Float i) { + if (i == null) { + return null; + } else { + return Short.valueOf(i.shortValue()); + } + } + + /** + * Convert from double to a short. This is called for CAST(... AS SMALLINT) + * + * @param i The double value to convert + * @return Short + */ + public Short evaluate(Double i) { + if (i == null) { + return null; + } else { + return Short.valueOf(i.shortValue()); + } + } + + /** + * Convert from string to a short. This is called for CAST(... AS SMALLINT) + * + * @param i The string value to convert + * @return Short + */ + public Short evaluate(String i) { + if (i == null) { + return null; + } else { + try { + return Short.valueOf(i); + } catch (NumberFormatException e) { + // MySQL returns 0 if the string is not a well-formed numeric value. + // return Byte.valueOf(0); + // But we decided to return NULL instead, which is more conservative. + return null; + } + } + } + +} Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToByte.java (working copy) @@ -30,6 +30,40 @@ public UDFToByte() { } + /** + * Convert from boolean to a byte. This is called for CAST(... AS TINYINT) + * + * @param i The boolean value to convert + * @return Byte + */ + public Byte evaluate(Boolean i) { + if (i == null) { + return null; + } else { + return i.booleanValue() ? (byte)1 : (byte)0; + } + } + + /** + * Convert from short to a byte. This is called for CAST(... AS TINYINT) + * + * @param i The short value to convert + * @return Byte + */ + public Byte evaluate(Short i) { + if (i == null) { + return null; + } else { + return Byte.valueOf(i.byteValue()); + } + } + + /** + * Convert from integer to a byte. This is called for CAST(... AS TINYINT) + * + * @param i The integer value to convert + * @return Byte + */ public Byte evaluate(Integer i) { if (i == null) { return null; @@ -38,14 +72,26 @@ } } + /** + * Convert from long to a byte. This is called for CAST(... AS TINYINT) + * + * @param i The long value to convert + * @return Byte + */ public Byte evaluate(Long i) { if (i == null) { return null; } else { return Byte.valueOf(i.byteValue()); } - } - + } + + /** + * Convert from float to a byte. This is called for CAST(... AS TINYINT) + * + * @param i The float value to convert + * @return Byte + */ public Byte evaluate(Float i) { if (i == null) { return null; @@ -53,7 +99,13 @@ return Byte.valueOf(i.byteValue()); } } - + + /** + * Convert from double to a byte. This is called for CAST(... AS TINYINT) + * + * @param i The double value to convert + * @return Byte + */ public Byte evaluate(Double i) { if (i == null) { return null; @@ -61,7 +113,13 @@ return Byte.valueOf(i.byteValue()); } } - + + /** + * Convert from string to a byte. This is called for CAST(... AS TINYINT) + * + * @param i The string value to convert + * @return Byte + */ public Byte evaluate(String i) { if (i == null) { return null; Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToFloat.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToFloat.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToFloat.java (working copy) @@ -30,6 +30,26 @@ public UDFToFloat() { } + /** + * Convert from boolean to a float. This is called for CAST(... AS FLOAT) + * + * @param i The boolean value to convert + * @return Float + */ + public Float evaluate(Boolean i) { + if (i == null) { + return null; + } else { + return i.booleanValue() ? (float)1.0 : (float)0.0; + } + } + + /** + * Convert from byte to a float. This is called for CAST(... AS FLOAT) + * + * @param i The byte value to convert + * @return Float + */ public Float evaluate(Byte i) { if (i == null) { return null; @@ -38,6 +58,26 @@ } } + /** + * Convert from short to a float. This is called for CAST(... AS FLOAT) + * + * @param i The short value to convert + * @return Float + */ + public Float evaluate(Short i) { + if (i == null) { + return null; + } else { + return Float.valueOf(i.floatValue()); + } + } + + /** + * Convert from integer to a float. This is called for CAST(... AS FLOAT) + * + * @param i The integer value to convert + * @return Float + */ public Float evaluate(Integer i) { if (i == null) { return null; @@ -46,6 +86,12 @@ } } + /** + * Convert from long to a float. This is called for CAST(... AS FLOAT) + * + * @param i The long value to convert + * @return Float + */ public Float evaluate(Long i) { if (i == null) { return null; @@ -54,7 +100,12 @@ } } - + /** + * Convert from double to a float. This is called for CAST(... AS FLOAT) + * + * @param i The double value to convert + * @return Float + */ public Float evaluate(Double i) { if (i == null) { return null; @@ -63,6 +114,12 @@ } } + /** + * Convert from string to a float. This is called for CAST(... AS FLOAT) + * + * @param i The string value to convert + * @return Float + */ public Float evaluate(String i) { if (i == null) { return null; Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToDouble.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToDouble.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToDouble.java (working copy) @@ -30,6 +30,26 @@ public UDFToDouble() { } + /** + * Convert from boolean to a double. This is called for CAST(... AS DOUBLE) + * + * @param i The boolean value to convert + * @return Double + */ + public Double evaluate(Boolean i) { + if (i == null) { + return null; + } else { + return i.booleanValue() ? 1.0 : 0.0; + } + } + + /** + * Convert from boolean to a double. This is called for CAST(... AS DOUBLE) + * + * @param i The byte value to convert + * @return Double + */ public Double evaluate(Byte i) { if (i == null) { return null; @@ -38,6 +58,26 @@ } } + /** + * Convert from short to a double. This is called for CAST(... AS DOUBLE) + * + * @param i The short value to convert + * @return Double + */ + public Double evaluate(Short i) { + if (i == null) { + return null; + } else { + return Double.valueOf(i.doubleValue()); + } + } + + /** + * Convert from integer to a double. This is called for CAST(... AS DOUBLE) + * + * @param i The integer value to convert + * @return Double + */ public Double evaluate(Integer i) { if (i == null) { return null; @@ -46,6 +86,12 @@ } } + /** + * Convert from long to a double. This is called for CAST(... AS DOUBLE) + * + * @param i The long value to convert + * @return Double + */ public Double evaluate(Long i) { if (i == null) { return null; @@ -53,8 +99,13 @@ return Double.valueOf(i.doubleValue()); } } - - + + /** + * Convert from float to a double. This is called for CAST(... AS DOUBLE) + * + * @param i The float value to convert + * @return Double + */ public Double evaluate(Float i) { if (i == null) { return null; @@ -63,6 +114,12 @@ } } + /** + * Convert from string to a double. This is called for CAST(... AS DOUBLE) + * + * @param i The string value to convert + * @return Double + */ public Double evaluate(String i) { if (i == null) { return null; Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToString.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToString.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToString.java (working copy) @@ -46,6 +46,14 @@ } } + public String evaluate(Short i) { + if (i == null) { + return null; + } else { + return i.toString(); + } + } + public String evaluate(Integer i) { if (i == null) { return null; Index: ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToBoolean.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToBoolean.java (revision 713736) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/UDFToBoolean.java (working copy) @@ -30,6 +30,40 @@ public UDFToBoolean() { } + /** + * Convert from a byte to boolean. This is called for CAST(... AS BOOLEAN) + * + * @param i The byte value to convert + * @return Boolean + */ + public Boolean evaluate(Byte i) { + if (i == null) { + return null; + } else { + return Boolean.valueOf(i.byteValue() == 0); + } + } + + /** + * Convert from a short to boolean. This is called for CAST(... AS BOOLEAN) + * + * @param i The short value to convert + * @return Boolean + */ + public Boolean evaluate(Short i) { + if (i == null) { + return null; + } else { + return Boolean.valueOf(i.shortValue() == 0); + } + } + + /** + * Convert from a integer to boolean. This is called for CAST(... AS BOOLEAN) + * + * @param i The integer value to convert + * @return Boolean + */ public Boolean evaluate(Integer i) { if (i == null) { return null; @@ -38,6 +72,12 @@ } } + /** + * Convert from a long to boolean. This is called for CAST(... AS BOOLEAN) + * + * @param i The long value to convert + * @return Boolean + */ public Boolean evaluate(Long i) { if (i == null) { return null; @@ -45,7 +85,13 @@ return Boolean.valueOf(i.longValue() == 0); } } - + + /** + * Convert from a float to boolean. This is called for CAST(... AS BOOLEAN) + * + * @param i The float value to convert + * @return Boolean + */ public Boolean evaluate(Float i) { if (i == null) { return null; @@ -53,7 +99,13 @@ return Boolean.valueOf(i.floatValue() == 0); } } - + + /** + * Convert from a double to boolean. This is called for CAST(... AS BOOLEAN) + * + * @param i The double value to convert + * @return Boolean + */ public Boolean evaluate(Double i) { if (i == null) { return null; @@ -61,13 +113,18 @@ return Boolean.valueOf(i.doubleValue() == 0); } } - + + /** + * Convert from a string to boolean. This is called for CAST(... AS BOOLEAN) + * + * @param i The string value to convert + * @return Boolean + */ public Boolean evaluate(String i) { if (i == null) { return null; } else { return Boolean.valueOf(i.length() == 0); } - } - + } }