diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java index d62a6b6..9384909 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java @@ -163,6 +163,7 @@ import org.apache.hadoop.hive.ql.udf.generic.GenericUDFEWAHBitmapEmpty; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFEWAHBitmapOr; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFElt; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFField; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFFormatNumber; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFFromUtcTimestamp; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFHash; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFIf; @@ -454,6 +455,7 @@ public final class FunctionRegistry { registerGenericUDF("sentences", GenericUDFSentences.class); registerGenericUDF("map_keys", GenericUDFMapKeys.class); registerGenericUDF("map_values", GenericUDFMapValues.class); + registerGenericUDF("format_number", GenericUDFFormatNumber.class); registerGenericUDF("printf", GenericUDFPrintf.class); registerGenericUDF("from_utc_timestamp", GenericUDFFromUtcTimestamp.class); 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 new file mode 100644 index 0000000..6be66dc --- /dev/null +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFormatNumber.java @@ -0,0 +1,219 @@ +/** + * 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.generic; + +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDFArgumentException; +import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; +import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.serde.Constants; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector; +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.DoubleObjectInspector; +import org.apache.hadoop.io.Text; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.lang.Number; +import java.lang.NumberFormatException; + +/** + * Generic UDF for format_number function + * FORMAT_NUMBER(X, D). + * This is supposed to function like MySQL's FORMAT, + * http://dev.mysql.com/doc/refman/5.1/en/string-functions.html# + * function_format + * + * @see org.apache.hadoop.hive.ql.udf.generic.GenericUDF + */ +@Description(name = "format_number", + value = "_FUNC_(X, D) - Formats the number X to " + + "a format like '#,###,###.##', rounded to D decimal places," + + " and returns the result as a string. If D is 0, the result" + + " has no decimal point or fractional part." + + " This is supposed to function like MySQL's FORMAT", + extended = "Example:\n" + + " > SELECT _FUNC_(12332.123456, 4) FROM src LIMIT 1;\n" + + " '12,332.1235'") +public class GenericUDFFormatNumber extends GenericUDF { + private ObjectInspector[] argumentOIs; + private final Text resultText = new Text(); + private final StringBuilder pattern = new StringBuilder(""); + private final DecimalFormat numberFormat = new DecimalFormat(""); + private int lastDValue = -1; + + @Override + public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { + if (arguments.length != 2) { + throw new UDFArgumentLengthException( + "The function FORMAT_NUMBER(X, D) needs two arguments."); + } + + switch (arguments[0].getCategory()) { + case PRIMITIVE: + break; + default: + throw new UDFArgumentTypeException(0, "Argument 1" + + " of function FORMAT_NUMBER must be \"" + + Constants.TINYINT_TYPE_NAME + "\"" + + " or \"" + Constants.SMALLINT_TYPE_NAME + "\"" + + " or \"" + Constants.INT_TYPE_NAME + "\"" + + " or \"" + Constants.BIGINT_TYPE_NAME + "\"" + + " or \"" + Constants.DOUBLE_TYPE_NAME + "\"" + + " or \"" + Constants.FLOAT_TYPE_NAME + "\", but \"" + + arguments[0].getTypeName() + "\" was found."); + } + + switch (arguments[1].getCategory()) { + case PRIMITIVE: + break; + default: + throw new UDFArgumentTypeException(1, "Argument 2" + + " of function FORMAT_NUMBER must be \"" + + Constants.TINYINT_TYPE_NAME + "\"" + + " or \"" + Constants.SMALLINT_TYPE_NAME + "\"" + + " or \"" + Constants.INT_TYPE_NAME + "\"" + + " or \"" + Constants.BIGINT_TYPE_NAME + "\", but \"" + + arguments[1].getTypeName() + "\" was found."); + } + + PrimitiveObjectInspector xObjectInspector = (PrimitiveObjectInspector)arguments[0]; + PrimitiveObjectInspector dObjectInspector = (PrimitiveObjectInspector)arguments[1]; + + switch (xObjectInspector.getPrimitiveCategory()) { + case VOID: + case BYTE: + case SHORT: + case INT: + case LONG: + case FLOAT: + case DOUBLE: + break; + default: + throw new UDFArgumentTypeException(0, "Argument 1" + + " of function FORMAT_NUMBER must be \"" + + Constants.TINYINT_TYPE_NAME + "\"" + + " or \"" + Constants.SMALLINT_TYPE_NAME + "\"" + + " or \"" + Constants.INT_TYPE_NAME + "\"" + + " or \"" + Constants.BIGINT_TYPE_NAME + "\"" + + " or \"" + Constants.DOUBLE_TYPE_NAME + "\"" + + " or \"" + Constants.FLOAT_TYPE_NAME + "\", but \"" + + arguments[0].getTypeName() + "\" was found."); + } + + switch (dObjectInspector.getPrimitiveCategory()) { + case VOID: + case BYTE: + case SHORT: + case INT: + case LONG: + break; + default: + throw new UDFArgumentTypeException(1, "Argument 2" + + " of function FORMAT_NUMBER must be \"" + + Constants.TINYINT_TYPE_NAME + "\"" + + " or \"" + Constants.SMALLINT_TYPE_NAME + "\"" + + " or \"" + Constants.INT_TYPE_NAME + "\"" + + " or \"" + Constants.BIGINT_TYPE_NAME + "\", but \"" + + arguments[1].getTypeName() + "\" was found."); + } + + argumentOIs = arguments; + return PrimitiveObjectInspectorFactory.writableStringObjectInspector; + } + + @Override + public Object evaluate(DeferredObject[] arguments) throws HiveException { + int dValue = ((IntObjectInspector) argumentOIs[1]).get(arguments[1].get()); + + if (dValue < 0) { + throw new HiveException("Argument 2 of function FORMAT_NUMBER must be >= 0, but \"" + + dValue + "\" was found"); + } + + if (dValue != lastDValue) { + // construct a new DecimalFormat only if a new dValue + pattern.delete(0, pattern.length()); + pattern.append("#,###,###,###,###,###,##0"); + + //decimal place + if (dValue > 0) { + pattern.append("."); + for (int i = 0; i < dValue; i++) { + pattern.append("0"); + } + } + DecimalFormat dFormat = new DecimalFormat(pattern.toString()); + lastDValue = dValue; + numberFormat.applyPattern(dFormat.toPattern()); + } + + double xDoubleValue = 0.0; + int xIntValue = 0; + long xLongValue = 0L; + + PrimitiveObjectInspector xObjectInspector = (PrimitiveObjectInspector)argumentOIs[0]; + switch (xObjectInspector.getPrimitiveCategory()) { + case VOID: + case FLOAT: + case DOUBLE: + xDoubleValue = ((DoubleObjectInspector) argumentOIs[0]).get(arguments[0].get()); + resultText.set(numberFormat.format(xDoubleValue)); + break; + case BYTE: + case SHORT: + case INT: + xIntValue = ((IntObjectInspector) argumentOIs[0]).get(arguments[0].get()); + resultText.set(numberFormat.format(xIntValue)); + break; + case LONG: + xLongValue = ((LongObjectInspector) argumentOIs[0]).get(arguments[0].get()); + resultText.set(numberFormat.format(xLongValue)); + break; + default: + throw new HiveException("Argument 1 of function FORMAT_NUMBER must be " + + Constants.TINYINT_TYPE_NAME + "\"" + + " or \"" + Constants.SMALLINT_TYPE_NAME + "\"" + + " or \"" + Constants.INT_TYPE_NAME + "\"" + + " or \"" + Constants.BIGINT_TYPE_NAME + "\"" + + " or \"" + Constants.DOUBLE_TYPE_NAME + "\"" + + " or \"" + Constants.FLOAT_TYPE_NAME + "\", but \"" + + argumentOIs[0].getTypeName() + "\" was found."); + } + return resultText; + } + + @Override + public String getDisplayString(String[] children) { + assert (children.length == 2); + StringBuilder sb = new StringBuilder(); + sb.append("format_number("); + for (int i = 0; i < children.length - 1; i++) { + sb.append(children[i]).append(", "); + } + sb.append(children[children.length - 1]).append(")"); + return sb.toString(); + } +} diff --git ql/src/test/queries/clientnegative/udf_format_number_wrong1.q ql/src/test/queries/clientnegative/udf_format_number_wrong1.q new file mode 100644 index 0000000..18c985c --- /dev/null +++ ql/src/test/queries/clientnegative/udf_format_number_wrong1.q @@ -0,0 +1,2 @@ +-- invalid argument length +SELECT format_number(12332.123456) FROM src LIMIT 1; diff --git ql/src/test/queries/clientnegative/udf_format_number_wrong2.q ql/src/test/queries/clientnegative/udf_format_number_wrong2.q new file mode 100644 index 0000000..7959c20 --- /dev/null +++ ql/src/test/queries/clientnegative/udf_format_number_wrong2.q @@ -0,0 +1,2 @@ +-- invalid argument length +SELECT format_number(12332.123456, 2, 3) FROM src LIMIT 1; diff --git ql/src/test/queries/clientnegative/udf_format_number_wrong3.q ql/src/test/queries/clientnegative/udf_format_number_wrong3.q new file mode 100644 index 0000000..7d90ef8 --- /dev/null +++ ql/src/test/queries/clientnegative/udf_format_number_wrong3.q @@ -0,0 +1,2 @@ +-- invalid argument(second argument should be >= 0) +SELECT format_number(12332.123456, -4) FROM src LIMIT 1; diff --git ql/src/test/queries/clientnegative/udf_format_number_wrong4.q ql/src/test/queries/clientnegative/udf_format_number_wrong4.q new file mode 100644 index 0000000..e545f4a --- /dev/null +++ ql/src/test/queries/clientnegative/udf_format_number_wrong4.q @@ -0,0 +1,2 @@ +-- invalid argument type +SELECT format_number(12332.123456, 4.01) FROM src LIMIT 1; diff --git ql/src/test/queries/clientnegative/udf_format_number_wrong5.q ql/src/test/queries/clientnegative/udf_format_number_wrong5.q new file mode 100644 index 0000000..a6f7177 --- /dev/null +++ ql/src/test/queries/clientnegative/udf_format_number_wrong5.q @@ -0,0 +1,2 @@ +-- invalid argument type +SELECT format_number(array(12332.123456, 321.23), 5) FROM src LIMIT 1; diff --git ql/src/test/queries/clientnegative/udf_format_number_wrong6.q ql/src/test/queries/clientnegative/udf_format_number_wrong6.q new file mode 100644 index 0000000..e5b11b9 --- /dev/null +++ ql/src/test/queries/clientnegative/udf_format_number_wrong6.q @@ -0,0 +1,2 @@ +-- invalid argument type +SELECT format_number(12332.123456, "4") FROM src LIMIT 1; diff --git ql/src/test/queries/clientnegative/udf_format_number_wrong7.q ql/src/test/queries/clientnegative/udf_format_number_wrong7.q new file mode 100644 index 0000000..aa4a3a4 --- /dev/null +++ ql/src/test/queries/clientnegative/udf_format_number_wrong7.q @@ -0,0 +1,2 @@ +-- invalid argument type(format_number returns the result as a string) +SELECT format_number(format_number(12332.123456, 4), 2) FROM src LIMIT 1; diff --git ql/src/test/queries/clientpositive/udf_format_number.q ql/src/test/queries/clientpositive/udf_format_number.q new file mode 100644 index 0000000..e2084cd --- /dev/null +++ ql/src/test/queries/clientpositive/udf_format_number.q @@ -0,0 +1,57 @@ +use default; +-- Test format_number() UDF + +DESCRIBE FUNCTION format_number; +DESCRIBE FUNCTION EXTENDED format_number; + +EXPLAIN +SELECT format_number(12332.123456, 4), + format_number(12332.1,4), + format_number(12332.2,0) FROM src limit 1; + +SELECT format_number(12332.123456, 4), + format_number(12332.1,4), + format_number(12332.2,0) +FROM src limit 1; + +-- positive numbers +SELECT format_number(0.123456789, 12), + format_number(12345678.123456789, 5), + format_number(1234567.123456789, 7), + format_number(123456.123456789, 0) +FROM src limit 1; + +-- negative numbers +SELECT format_number(-123456.123456789, 0), + format_number(-1234567.123456789, 2), + format_number(-0.123456789, 15), + format_number(-12345.123456789, 4) +FROM src limit 1; + +-- zeros +SELECT format_number(0.0, 4), + format_number(0.000000, 1), + format_number(000.0000, 1), + format_number(00000.0000, 1), + format_number(-00.0, 4) +FROM src limit 1; + +-- integers +SELECT format_number(0, 0), + format_number(1, 4), + format_number(12, 2), + format_number(123, 5), + format_number(1234, 7) +FROM src limit 1; + +-- long and double boundary +-- 9223372036854775807 is LONG_MAX +-- -9223372036854775807 is one more than LONG_MIN, +-- due to HIVE-2733, put it here to check LONG_MIN boundary +-- 4.9E-324 and 1.7976931348623157E308 are Double.MIN_VALUE and Double.MAX_VALUE +-- check them for Double boundary +SELECT format_number(-9223372036854775807, 10), + format_number(9223372036854775807, 20), + format_number(4.9E-324, 324), + format_number(1.7976931348623157E308, 308) +FROM src limit 1; diff --git ql/src/test/results/clientnegative/udf_format_number_wrong1.q.out ql/src/test/results/clientnegative/udf_format_number_wrong1.q.out new file mode 100644 index 0000000..c3cb800 --- /dev/null +++ ql/src/test/results/clientnegative/udf_format_number_wrong1.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10015]: Line 2:7 Arguments length mismatch '12332.123456': The function FORMAT_NUMBER(X, D) needs two arguments. diff --git ql/src/test/results/clientnegative/udf_format_number_wrong2.q.out ql/src/test/results/clientnegative/udf_format_number_wrong2.q.out new file mode 100644 index 0000000..1fe8a7c --- /dev/null +++ ql/src/test/results/clientnegative/udf_format_number_wrong2.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10015]: Line 2:7 Arguments length mismatch '3': The function FORMAT_NUMBER(X, D) needs two arguments. diff --git ql/src/test/results/clientnegative/udf_format_number_wrong3.q.out ql/src/test/results/clientnegative/udf_format_number_wrong3.q.out new file mode 100644 index 0000000..25486e1 --- /dev/null +++ ql/src/test/results/clientnegative/udf_format_number_wrong3.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10014]: Line 2:7 Wrong arguments '4': org.apache.hadoop.hive.ql.metadata.HiveException: Argument 2 of function FORMAT_NUMBER must be >= 0, but "-4" was found diff --git ql/src/test/results/clientnegative/udf_format_number_wrong4.q.out ql/src/test/results/clientnegative/udf_format_number_wrong4.q.out new file mode 100644 index 0000000..3953ef1 --- /dev/null +++ ql/src/test/results/clientnegative/udf_format_number_wrong4.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10016]: Line 2:35 Argument type mismatch '4.01': Argument 2 of function FORMAT_NUMBER must be "tinyint" or "smallint" or "int" or "bigint", but "double" was found. diff --git ql/src/test/results/clientnegative/udf_format_number_wrong5.q.out ql/src/test/results/clientnegative/udf_format_number_wrong5.q.out new file mode 100644 index 0000000..2878839 --- /dev/null +++ ql/src/test/results/clientnegative/udf_format_number_wrong5.q.out @@ -0,0 +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. diff --git ql/src/test/results/clientnegative/udf_format_number_wrong6.q.out ql/src/test/results/clientnegative/udf_format_number_wrong6.q.out new file mode 100644 index 0000000..d51991f --- /dev/null +++ ql/src/test/results/clientnegative/udf_format_number_wrong6.q.out @@ -0,0 +1 @@ +FAILED: SemanticException [Error 10016]: Line 2:35 Argument type mismatch '"4"': Argument 2 of function FORMAT_NUMBER must be "tinyint" or "smallint" or "int" or "bigint", but "string" 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 new file mode 100644 index 0000000..9af9eb7 --- /dev/null +++ ql/src/test/results/clientnegative/udf_format_number_wrong7.q.out @@ -0,0 +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. diff --git ql/src/test/results/clientpositive/show_functions.q.out ql/src/test/results/clientpositive/show_functions.q.out index 5ce8844..ac452e7 100644 --- ql/src/test/results/clientpositive/show_functions.q.out +++ ql/src/test/results/clientpositive/show_functions.q.out @@ -64,6 +64,7 @@ explode field find_in_set floor +format_number from_unixtime from_utc_timestamp get_json_object diff --git ql/src/test/results/clientpositive/udf_format_number.q.out ql/src/test/results/clientpositive/udf_format_number.q.out new file mode 100644 index 0000000..0bfc1f8 --- /dev/null +++ ql/src/test/results/clientpositive/udf_format_number.q.out @@ -0,0 +1,191 @@ +PREHOOK: query: use default +PREHOOK: type: SWITCHDATABASE +POSTHOOK: query: use default +POSTHOOK: type: SWITCHDATABASE +PREHOOK: query: -- Test format_number() UDF + +DESCRIBE FUNCTION format_number +PREHOOK: type: DESCFUNCTION +POSTHOOK: query: -- Test format_number() UDF + +DESCRIBE FUNCTION format_number +POSTHOOK: type: DESCFUNCTION +format_number(X, D) - Formats the number X to a format like '#,###,###.##', rounded to D decimal places, and returns the result as a string. If D is 0, the result has no decimal point or fractional part. This is supposed to function like MySQL's FORMAT +PREHOOK: query: DESCRIBE FUNCTION EXTENDED format_number +PREHOOK: type: DESCFUNCTION +POSTHOOK: query: DESCRIBE FUNCTION EXTENDED format_number +POSTHOOK: type: DESCFUNCTION +format_number(X, D) - Formats the number X to a format like '#,###,###.##', rounded to D decimal places, and returns the result as a string. If D is 0, the result has no decimal point or fractional part. This is supposed to function like MySQL's FORMAT +Example: + > SELECT format_number(12332.123456, 4) FROM src LIMIT 1; + '12,332.1235' +PREHOOK: query: EXPLAIN +SELECT format_number(12332.123456, 4), + format_number(12332.1,4), + format_number(12332.2,0) FROM src limit 1 +PREHOOK: type: QUERY +POSTHOOK: query: EXPLAIN +SELECT format_number(12332.123456, 4), + format_number(12332.1,4), + format_number(12332.2,0) FROM src limit 1 +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_TABREF (TOK_TABNAME src))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION format_number 12332.123456 4)) (TOK_SELEXPR (TOK_FUNCTION format_number 12332.1 4)) (TOK_SELEXPR (TOK_FUNCTION format_number 12332.2 0))) (TOK_LIMIT 1))) + +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + src + TableScan + alias: src + Select Operator + expressions: + expr: format_number(12332.123456, 4) + type: string + expr: format_number(12332.1, 4) + type: string + expr: format_number(12332.2, 0) + type: string + outputColumnNames: _col0, _col1, _col2 + Limit + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + + Stage: Stage-0 + Fetch Operator + limit: 1 + + +PREHOOK: query: SELECT format_number(12332.123456, 4), + format_number(12332.1,4), + format_number(12332.2,0) +FROM src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: SELECT format_number(12332.123456, 4), + format_number(12332.1,4), + format_number(12332.2,0) +FROM src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +12,332.1235 12,332.1000 12,332 +PREHOOK: query: -- positive numbers +SELECT format_number(0.123456789, 12), + format_number(12345678.123456789, 5), + format_number(1234567.123456789, 7), + format_number(123456.123456789, 0) +FROM src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: -- positive numbers +SELECT format_number(0.123456789, 12), + format_number(12345678.123456789, 5), + format_number(1234567.123456789, 7), + format_number(123456.123456789, 0) +FROM src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +0.123456789000 12,345,678.12346 1,234,567.1234568 123,456 +PREHOOK: query: -- negative numbers +SELECT format_number(-123456.123456789, 0), + format_number(-1234567.123456789, 2), + format_number(-0.123456789, 15), + format_number(-12345.123456789, 4) +FROM src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: -- negative numbers +SELECT format_number(-123456.123456789, 0), + format_number(-1234567.123456789, 2), + format_number(-0.123456789, 15), + format_number(-12345.123456789, 4) +FROM src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +-123,456 -1,234,567.12 -0.123456789000000 -12,345.1235 +PREHOOK: query: -- zeros +SELECT format_number(0.0, 4), + format_number(0.000000, 1), + format_number(000.0000, 1), + format_number(00000.0000, 1), + format_number(-00.0, 4) +FROM src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: -- zeros +SELECT format_number(0.0, 4), + format_number(0.000000, 1), + format_number(000.0000, 1), + format_number(00000.0000, 1), + format_number(-00.0, 4) +FROM src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +0.0000 0.0 0.0 0.0 -0.0000 +PREHOOK: query: -- integers +SELECT format_number(0, 0), + format_number(1, 4), + format_number(12, 2), + format_number(123, 5), + format_number(1234, 7) +FROM src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: -- integers +SELECT format_number(0, 0), + format_number(1, 4), + format_number(12, 2), + format_number(123, 5), + format_number(1234, 7) +FROM src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +0 1.0000 12.00 123.00000 1,234.0000000 +PREHOOK: query: -- long and double boundary +-- 9223372036854775807 is LONG_MAX +-- -9223372036854775807 is one more than LONG_MIN, +-- due to HIVE-2733, put it here to check LONG_MIN boundary +-- 4.9E-324 and 1.7976931348623157E308 are Double.MIN_VALUE and Double.MAX_VALUE +-- check them for Double boundary +SELECT format_number(-9223372036854775807, 10), + format_number(9223372036854775807, 20), + format_number(4.9E-324, 324), + format_number(1.7976931348623157E308, 308) +FROM src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: -- long and double boundary +-- 9223372036854775807 is LONG_MAX +-- -9223372036854775807 is one more than LONG_MIN, +-- due to HIVE-2733, put it here to check LONG_MIN boundary +-- 4.9E-324 and 1.7976931348623157E308 are Double.MIN_VALUE and Double.MAX_VALUE +-- check them for Double boundary +SELECT format_number(-9223372036854775807, 10), + format_number(9223372036854775807, 20), + format_number(4.9E-324, 324), + format_number(1.7976931348623157E308, 308) +FROM src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +-9,223,372,036,854,775,807.0000000000 9,223,372,036,854,775,807.00000000000000000000 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005 179,769,313,486,231,570,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000