diff --git ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFormatNumber.java ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFormatNumber.java index dee3137..3586b8d 100644 --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFormatNumber.java +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFormatNumber.java @@ -20,6 +20,7 @@ import java.text.DecimalFormat; +import org.apache.hadoop.hive.common.type.HiveDecimal; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; @@ -32,6 +33,7 @@ import org.apache.hadoop.hive.serde2.objectinspector.primitive.FloatObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.LongObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.HiveDecimalObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; import org.apache.hadoop.io.Text; @@ -78,7 +80,8 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen + " or \"" + serdeConstants.INT_TYPE_NAME + "\"" + " or \"" + serdeConstants.BIGINT_TYPE_NAME + "\"" + " or \"" + serdeConstants.DOUBLE_TYPE_NAME + "\"" - + " or \"" + serdeConstants.FLOAT_TYPE_NAME + "\", but \"" + + " or \"" + serdeConstants.FLOAT_TYPE_NAME + "\"" + + " or \"" + serdeConstants.DECIMAL_TYPE_NAME + "\", but \"" + arguments[0].getTypeName() + "\" was found."); } @@ -104,8 +107,9 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen case SHORT: case INT: case LONG: - case FLOAT: case DOUBLE: + case FLOAT: + case DECIMAL: break; default: throw new UDFArgumentTypeException(0, "Argument 1" @@ -115,7 +119,8 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen + " or \"" + serdeConstants.INT_TYPE_NAME + "\"" + " or \"" + serdeConstants.BIGINT_TYPE_NAME + "\"" + " or \"" + serdeConstants.DOUBLE_TYPE_NAME + "\"" - + " or \"" + serdeConstants.FLOAT_TYPE_NAME + "\", but \"" + + " or \"" + serdeConstants.FLOAT_TYPE_NAME + "\"" + + " or \"" + serdeConstants.DECIMAL_TYPE_NAME + "\", but \"" + arguments[0].getTypeName() + "\" was found."); } @@ -168,6 +173,7 @@ public Object evaluate(DeferredObject[] arguments) throws HiveException { double xDoubleValue = 0.0; float xFloatValue = 0.0f; + HiveDecimal xDecimalValue = null; int xIntValue = 0; long xLongValue = 0L; @@ -182,6 +188,11 @@ public Object evaluate(DeferredObject[] arguments) throws HiveException { xFloatValue = ((FloatObjectInspector) argumentOIs[0]).get(arguments[0].get()); resultText.set(numberFormat.format(xFloatValue)); break; + case DECIMAL: + xDecimalValue = ((HiveDecimalObjectInspector) argumentOIs[0]) + .getPrimitiveJavaObject(arguments[0].get()); + resultText.set(numberFormat.format(xDecimalValue.bigDecimalValue())); + break; case BYTE: case SHORT: case INT: @@ -199,7 +210,8 @@ public Object evaluate(DeferredObject[] arguments) throws HiveException { + " or \"" + serdeConstants.INT_TYPE_NAME + "\"" + " or \"" + serdeConstants.BIGINT_TYPE_NAME + "\"" + " or \"" + serdeConstants.DOUBLE_TYPE_NAME + "\"" - + " or \"" + serdeConstants.FLOAT_TYPE_NAME + "\", but \"" + + " or \"" + serdeConstants.FLOAT_TYPE_NAME + "\"" + + " or \"" + serdeConstants.DECIMAL_TYPE_NAME + "\", but \"" + argumentOIs[0].getTypeName() + "\" was found."); } return resultText; diff --git ql/src/test/queries/clientpositive/udf_format_number.q ql/src/test/queries/clientpositive/udf_format_number.q index 0afd075..630533d 100644 --- ql/src/test/queries/clientpositive/udf_format_number.q +++ ql/src/test/queries/clientpositive/udf_format_number.q @@ -63,3 +63,11 @@ SELECT format_number(CAST(12332.123456 AS FLOAT), 4), format_number(CAST(12332.1 AS FLOAT), 4), format_number(CAST(-12332.2 AS FLOAT), 0) FROM src tablesample (1 rows); + +-- decimals +SELECT format_number(12332.123456BD, 4), + format_number(12332.123456BD, 2), + format_number(12332.1BD, 4), + format_number(-12332.2BD, 0), + format_number(CAST(12332.567 AS DECIMAL(8, 1)), 4) +FROM src tablesample (1 rows); diff --git ql/src/test/results/clientnegative/udf_format_number_wrong5.q.out ql/src/test/results/clientnegative/udf_format_number_wrong5.q.out index 2878839..6d7a3c1 100644 --- ql/src/test/results/clientnegative/udf_format_number_wrong5.q.out +++ ql/src/test/results/clientnegative/udf_format_number_wrong5.q.out @@ -1 +1 @@ -FAILED: SemanticException [Error 10016]: Line 2:21 Argument type mismatch '321.23': Argument 1 of function FORMAT_NUMBER must be "tinyint" or "smallint" or "int" or "bigint" or "double" or "float", but "array" was found. +FAILED: SemanticException [Error 10016]: Line 2:21 Argument type mismatch '321.23': Argument 1 of function FORMAT_NUMBER must be "tinyint" or "smallint" or "int" or "bigint" or "double" or "float" or "decimal", but "array" was found. diff --git ql/src/test/results/clientnegative/udf_format_number_wrong7.q.out ql/src/test/results/clientnegative/udf_format_number_wrong7.q.out index 9af9eb7..58704ac 100644 --- ql/src/test/results/clientnegative/udf_format_number_wrong7.q.out +++ ql/src/test/results/clientnegative/udf_format_number_wrong7.q.out @@ -1 +1 @@ -FAILED: SemanticException [Error 10016]: Line 2:21 Argument type mismatch '4': Argument 1 of function FORMAT_NUMBER must be "tinyint" or "smallint" or "int" or "bigint" or "double" or "float", but "string" was found. +FAILED: SemanticException [Error 10016]: Line 2:21 Argument type mismatch '4': Argument 1 of function FORMAT_NUMBER must be "tinyint" or "smallint" or "int" or "bigint" or "double" or "float" or "decimal", but "string" was found. diff --git ql/src/test/results/clientpositive/udf_format_number.q.out ql/src/test/results/clientpositive/udf_format_number.q.out index c95e7cc..636cdae 100644 --- ql/src/test/results/clientpositive/udf_format_number.q.out +++ ql/src/test/results/clientpositive/udf_format_number.q.out @@ -188,3 +188,24 @@ POSTHOOK: type: QUERY POSTHOOK: Input: default@src #### A masked pattern was here #### 12,332.1230 12,332.0996 -12,332 +PREHOOK: query: -- decimals +SELECT format_number(12332.123456BD, 4), + format_number(12332.123456BD, 2), + format_number(12332.1BD, 4), + format_number(-12332.2BD, 0), + format_number(CAST(12332.567 AS DECIMAL(8, 1)), 4) +FROM src tablesample (1 rows) +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: -- decimals +SELECT format_number(12332.123456BD, 4), + format_number(12332.123456BD, 2), + format_number(12332.1BD, 4), + format_number(-12332.2BD, 0), + format_number(CAST(12332.567 AS DECIMAL(8, 1)), 4) +FROM src tablesample (1 rows) +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +12,332.1235 12,332.12 12,332.1000 -12,332 12,332.6000