Index: contrib/src/test/results/clientpositive/udaf_example_min.q.out =================================================================== --- contrib/src/test/results/clientpositive/udaf_example_min.q.out (revision 0) +++ contrib/src/test/results/clientpositive/udaf_example_min.q.out (revision 0) @@ -0,0 +1,97 @@ +PREHOOK: query: CREATE TEMPORARY FUNCTION example_min AS 'org.apache.hadoop.hive.contrib.udaf.example.UDAFExampleMin' +PREHOOK: type: CREATEFUNCTION +POSTHOOK: query: CREATE TEMPORARY FUNCTION example_min AS 'org.apache.hadoop.hive.contrib.udaf.example.UDAFExampleMin' +POSTHOOK: type: CREATEFUNCTION +PREHOOK: query: DESCRIBE FUNCTION EXTENDED example_min +PREHOOK: type: DESCFUNCTION +POSTHOOK: query: DESCRIBE FUNCTION EXTENDED example_min +POSTHOOK: type: DESCFUNCTION +example_min(expr) - Returns the minimum value of expr +PREHOOK: query: EXPLAIN +SELECT example_min(substr(value,5)), + example_min(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +PREHOOK: type: QUERY +POSTHOOK: query: EXPLAIN +SELECT example_min(substr(value,5)), + example_min(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_TABREF src)) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION example_min (TOK_FUNCTION substr (TOK_TABLE_OR_COL value) 5))) (TOK_SELEXPR (TOK_FUNCTION example_min (TOK_FUNCTION IF (> (TOK_FUNCTION substr (TOK_TABLE_OR_COL value) 5) 250) TOK_NULL (TOK_FUNCTION substr (TOK_TABLE_OR_COL value) 5))))))) + +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: value + type: string + outputColumnNames: value + Group By Operator + aggregations: + expr: example_min(substr(value, 5)) + expr: example_min(if((substr(value, 5) > 250), null, substr(value, 5))) + bucketGroup: false + mode: hash + outputColumnNames: _col0, _col1 + Reduce Output Operator + sort order: + tag: -1 + value expressions: + expr: _col0 + type: string + expr: _col1 + type: string + Reduce Operator Tree: + Group By Operator + aggregations: + expr: example_min(VALUE._col0) + expr: example_min(VALUE._col1) + bucketGroup: false + mode: mergepartial + outputColumnNames: _col0, _col1 + Select Operator + expressions: + expr: _col0 + type: string + expr: _col1 + type: string + outputColumnNames: _col0, _col1 + 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 example_min(substr(value,5)), + example_min(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/contrib/scratchdir/hive_2010-02-03_15-56-27_091_4596988815419170888/10000 +POSTHOOK: query: SELECT example_min(substr(value,5)), + example_min(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/contrib/scratchdir/hive_2010-02-03_15-56-27_091_4596988815419170888/10000 +0 0 +PREHOOK: query: DROP TEMPORARY FUNCTION example_min +PREHOOK: type: DROPFUNCTION +POSTHOOK: query: DROP TEMPORARY FUNCTION example_min +POSTHOOK: type: DROPFUNCTION Index: contrib/src/test/results/clientpositive/udaf_example_max.q.out =================================================================== --- contrib/src/test/results/clientpositive/udaf_example_max.q.out (revision 0) +++ contrib/src/test/results/clientpositive/udaf_example_max.q.out (revision 0) @@ -0,0 +1,97 @@ +PREHOOK: query: CREATE TEMPORARY FUNCTION example_max AS 'org.apache.hadoop.hive.contrib.udaf.example.UDAFExampleMax' +PREHOOK: type: CREATEFUNCTION +POSTHOOK: query: CREATE TEMPORARY FUNCTION example_max AS 'org.apache.hadoop.hive.contrib.udaf.example.UDAFExampleMax' +POSTHOOK: type: CREATEFUNCTION +PREHOOK: query: DESCRIBE FUNCTION EXTENDED example_max +PREHOOK: type: DESCFUNCTION +POSTHOOK: query: DESCRIBE FUNCTION EXTENDED example_max +POSTHOOK: type: DESCFUNCTION +example_max(expr) - Returns the maximum value of expr +PREHOOK: query: EXPLAIN +SELECT example_max(substr(value,5)), + example_max(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +PREHOOK: type: QUERY +POSTHOOK: query: EXPLAIN +SELECT example_max(substr(value,5)), + example_max(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_TABREF src)) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION example_max (TOK_FUNCTION substr (TOK_TABLE_OR_COL value) 5))) (TOK_SELEXPR (TOK_FUNCTION example_max (TOK_FUNCTION IF (> (TOK_FUNCTION substr (TOK_TABLE_OR_COL value) 5) 250) TOK_NULL (TOK_FUNCTION substr (TOK_TABLE_OR_COL value) 5))))))) + +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: value + type: string + outputColumnNames: value + Group By Operator + aggregations: + expr: example_max(substr(value, 5)) + expr: example_max(if((substr(value, 5) > 250), null, substr(value, 5))) + bucketGroup: false + mode: hash + outputColumnNames: _col0, _col1 + Reduce Output Operator + sort order: + tag: -1 + value expressions: + expr: _col0 + type: string + expr: _col1 + type: string + Reduce Operator Tree: + Group By Operator + aggregations: + expr: example_max(VALUE._col0) + expr: example_max(VALUE._col1) + bucketGroup: false + mode: mergepartial + outputColumnNames: _col0, _col1 + Select Operator + expressions: + expr: _col0 + type: string + expr: _col1 + type: string + outputColumnNames: _col0, _col1 + 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 example_max(substr(value,5)), + example_max(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/contrib/scratchdir/hive_2010-02-03_16-15-04_638_1033240644659750207/10000 +POSTHOOK: query: SELECT example_max(substr(value,5)), + example_max(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/contrib/scratchdir/hive_2010-02-03_16-15-04_638_1033240644659750207/10000 +98 98 +PREHOOK: query: DROP TEMPORARY FUNCTION example_max +PREHOOK: type: DROPFUNCTION +POSTHOOK: query: DROP TEMPORARY FUNCTION example_max +POSTHOOK: type: DROPFUNCTION Index: contrib/src/test/queries/clientpositive/udaf_example_min.q =================================================================== --- contrib/src/test/queries/clientpositive/udaf_example_min.q (revision 0) +++ contrib/src/test/queries/clientpositive/udaf_example_min.q (revision 0) @@ -0,0 +1,16 @@ +add jar ../build/contrib/hive_contrib.jar; + +CREATE TEMPORARY FUNCTION example_min AS 'org.apache.hadoop.hive.contrib.udaf.example.UDAFExampleMin'; + +DESCRIBE FUNCTION EXTENDED example_min; + +EXPLAIN +SELECT example_min(substr(value,5)), + example_min(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src; + +SELECT example_min(substr(value,5)), + example_min(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src; + +DROP TEMPORARY FUNCTION example_min; Index: contrib/src/test/queries/clientpositive/udaf_example_max.q =================================================================== --- contrib/src/test/queries/clientpositive/udaf_example_max.q (revision 0) +++ contrib/src/test/queries/clientpositive/udaf_example_max.q (revision 0) @@ -0,0 +1,16 @@ +add jar ../build/contrib/hive_contrib.jar; + +CREATE TEMPORARY FUNCTION example_max AS 'org.apache.hadoop.hive.contrib.udaf.example.UDAFExampleMax'; + +DESCRIBE FUNCTION EXTENDED example_max; + +EXPLAIN +SELECT example_max(substr(value,5)), + example_max(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src; + +SELECT example_max(substr(value,5)), + example_max(IF(substr(value,5) > 250, NULL, substr(value,5))) +FROM src; + +DROP TEMPORARY FUNCTION example_max; Index: contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMin.java =================================================================== --- contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMin.java (revision 906284) +++ contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMin.java (working copy) @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.hadoop.hive.ql.udf; +package org.apache.hadoop.hive.contrib.udaf.example; import org.apache.hadoop.hive.ql.exec.UDAF; import org.apache.hadoop.hive.ql.exec.UDAFEvaluator; @@ -29,8 +29,8 @@ import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; -@Description(name = "min", value = "_FUNC_(expr) - Returns the minimum value of expr") -public class UDAFMin extends UDAF { +@Description(name = "example_min", value = "_FUNC_(expr) - Returns the minimum value of expr") +public class UDAFExampleMin extends UDAF { static public class MinShortEvaluator implements UDAFEvaluator { private short mMin; Property changes on: contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMin.java ___________________________________________________________________ Added: svn:mergeinfo Index: contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMax.java =================================================================== --- contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMax.java (revision 906284) +++ contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMax.java (working copy) @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.hadoop.hive.ql.udf; +package org.apache.hadoop.hive.contrib.udaf.example; import org.apache.hadoop.hive.ql.exec.UDAF; import org.apache.hadoop.hive.ql.exec.UDAFEvaluator; @@ -29,8 +29,8 @@ import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; -@Description(name = "max", value = "_FUNC_(expr) - Returns the maximum value of expr") -public class UDAFMax extends UDAF { +@Description(name = "example_max", value = "_FUNC_(expr) - Returns the maximum value of expr") +public class UDAFExampleMax extends UDAF { static public class MaxShortEvaluator implements UDAFEvaluator { private short mMax; Property changes on: contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example/UDAFExampleMax.java ___________________________________________________________________ Added: svn:mergeinfo Index: serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java =================================================================== --- serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java (revision 906284) +++ serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java (working copy) @@ -397,6 +397,33 @@ } /** + * Whether comparison is supported for this type. + * Currently all types that references any map are not comparable. + */ + public static boolean compareSupported(ObjectInspector oi) { + switch (oi.getCategory()) { + case PRIMITIVE: + return true; + case LIST: + ListObjectInspector loi = (ListObjectInspector) oi; + return compareSupported(loi.getListElementObjectInspector()); + case STRUCT: + StructObjectInspector soi = (StructObjectInspector) oi; + List fields = soi.getAllStructFieldRefs(); + for (int f = 0; f < fields.size(); f++) { + if (!compareSupported(fields.get(f).getFieldObjectInspector())) { + return false; + } + } + return true; + case MAP: + return false; + default: + return false; + } + } + + /** * Compare two objects with their respective ObjectInspectors. */ public static int compare(Object o1, ObjectInspector oi1, Object o2, Index: ql/src/test/results/clientnegative/udf_min.q.out =================================================================== --- ql/src/test/results/clientnegative/udf_min.q.out (revision 0) +++ ql/src/test/results/clientnegative/udf_min.q.out (revision 0) @@ -0,0 +1 @@ +FAILED: Error in semantic analysis: Cannot support comparison of map<> type or complex type containing map<>. Index: ql/src/test/results/clientnegative/udf_max.q.out =================================================================== --- ql/src/test/results/clientnegative/udf_max.q.out (revision 0) +++ ql/src/test/results/clientnegative/udf_max.q.out (revision 0) @@ -0,0 +1 @@ +FAILED: Error in semantic analysis: Cannot support comparison of map<> type or complex type containing map<>. Index: ql/src/test/results/clientpositive/udf_min.q.out =================================================================== --- ql/src/test/results/clientpositive/udf_min.q.out (revision 906284) +++ ql/src/test/results/clientpositive/udf_min.q.out (working copy) @@ -8,3 +8,55 @@ POSTHOOK: query: DESCRIBE FUNCTION EXTENDED min POSTHOOK: type: DESCFUNCTION min(expr) - Returns the minimum value of expr +PREHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-41-56_456_856412388022993829/10000 +POSTHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-41-56_456_856412388022993829/10000 +{"col1":0,"col2":"val_0"} {"col1":"0","col2":"val_0"} +PREHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-42-00_236_1435029127724516459/10000 +POSTHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-42-00_236_1435029127724516459/10000 +{"col1":0,"col2":"val_0"} {"col1":"0","col2":"val_0"} +PREHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-42-03_693_4768183409983873377/10000 +POSTHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-42-03_693_4768183409983873377/10000 +{"col1":0,"col2":"val_0"} {"col1":"0","col2":"val_0"} +PREHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-42-10_355_1063948234120488529/10000 +POSTHOOK: query: SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-42-10_355_1063948234120488529/10000 +{"col1":0,"col2":"val_0"} {"col1":"0","col2":"val_0"} Index: ql/src/test/results/clientpositive/udf_max.q.out =================================================================== --- ql/src/test/results/clientpositive/udf_max.q.out (revision 906284) +++ ql/src/test/results/clientpositive/udf_max.q.out (working copy) @@ -8,3 +8,55 @@ POSTHOOK: query: DESCRIBE FUNCTION EXTENDED max POSTHOOK: type: DESCFUNCTION max(expr) - Returns the maximum value of expr +PREHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-44-47_651_8497222492783440005/10000 +POSTHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-44-47_651_8497222492783440005/10000 +{"col1":498,"col2":"val_498"} {"col1":"98","col2":"val_98"} +PREHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-44-51_371_6375977486441092466/10000 +POSTHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-44-51_371_6375977486441092466/10000 +{"col1":498,"col2":"val_498"} {"col1":"98","col2":"val_98"} +PREHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-44-54_873_9150909181262885229/10000 +POSTHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-44-54_873_9150909181262885229/10000 +{"col1":498,"col2":"val_498"} {"col1":"98","col2":"val_98"} +PREHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-45-01_378_1491726702598521931/10000 +POSTHOOK: query: SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-45-01_378_1491726702598521931/10000 +{"col1":498,"col2":"val_498"} {"col1":"98","col2":"val_98"} Index: ql/src/test/results/compiler/plan/groupby3.q.xml =================================================================== --- ql/src/test/results/compiler/plan/groupby3.q.xml (revision 906284) +++ ql/src/test/results/compiler/plan/groupby3.q.xml (working copy) @@ -66,7 +66,7 @@ transient_lastDdlTime - 1264705772 + 1265240095 @@ -682,11 +682,7 @@ - - - org.apache.hadoop.hive.ql.udf.UDAFMax$MaxStringEvaluator - - + max @@ -747,11 +743,7 @@ - - - org.apache.hadoop.hive.ql.udf.UDAFMin$MinStringEvaluator - - + min @@ -1159,7 +1151,7 @@ - file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/144803262/10001 + file:/data/users/zshao/hadoop_hive_trunk/build/ql/scratchdir/hive_2010-02-03_15-34-56_784_7206588683002520939/10001 @@ -1597,7 +1589,7 @@ - + max @@ -1624,7 +1616,7 @@ - + min Index: ql/src/test/queries/clientnegative/udf_min.q =================================================================== --- ql/src/test/queries/clientnegative/udf_min.q (revision 0) +++ ql/src/test/queries/clientnegative/udf_min.q (revision 0) @@ -0,0 +1,2 @@ +SELECT min(map("key", key, "value", value)) +FROM src; Index: ql/src/test/queries/clientnegative/udf_max.q =================================================================== --- ql/src/test/queries/clientnegative/udf_max.q (revision 0) +++ ql/src/test/queries/clientnegative/udf_max.q (revision 0) @@ -0,0 +1,2 @@ +SELECT max(map("key", key, "value", value)) +FROM src; Index: ql/src/test/queries/clientpositive/udf_max.q =================================================================== --- ql/src/test/queries/clientpositive/udf_max.q (revision 906284) +++ ql/src/test/queries/clientpositive/udf_max.q (working copy) @@ -1,2 +1,34 @@ DESCRIBE FUNCTION max; DESCRIBE FUNCTION EXTENDED max; + + +set hive.map.aggr = false; +set hive.groupby.skewindata = false; + +SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src; + + +set hive.map.aggr = true; +set hive.groupby.skewindata = false; + +SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src; + + +set hive.map.aggr = false; +set hive.groupby.skewindata = true; + +SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src; + + +set hive.map.aggr = true; +set hive.groupby.skewindata = true; + +SELECT max(struct(CAST(key as INT), value)), + max(struct(key, value)) +FROM src; Index: ql/src/test/queries/clientpositive/udf_min.q =================================================================== --- ql/src/test/queries/clientpositive/udf_min.q (revision 906284) +++ ql/src/test/queries/clientpositive/udf_min.q (working copy) @@ -1,2 +1,34 @@ DESCRIBE FUNCTION min; DESCRIBE FUNCTION EXTENDED min; + + +set hive.map.aggr = false; +set hive.groupby.skewindata = false; + +SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src; + + +set hive.map.aggr = true; +set hive.groupby.skewindata = false; + +SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src; + + +set hive.map.aggr = false; +set hive.groupby.skewindata = true; + +SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src; + + +set hive.map.aggr = true; +set hive.groupby.skewindata = true; + +SELECT min(struct(CAST(key as INT), value)), + min(struct(key, value)) +FROM src; Index: ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (revision 906284) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (working copy) @@ -37,8 +37,6 @@ import org.apache.hadoop.hive.ql.parse.SemanticException; import org.apache.hadoop.hive.ql.plan.ExprNodeDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc; -import org.apache.hadoop.hive.ql.udf.UDAFMax; -import org.apache.hadoop.hive.ql.udf.UDAFMin; import org.apache.hadoop.hive.ql.udf.UDFAbs; import org.apache.hadoop.hive.ql.udf.UDFAcos; import org.apache.hadoop.hive.ql.udf.UDFAscii; @@ -128,6 +126,8 @@ import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFBridge; import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFCount; import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFMax; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFMin; import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFResolver; import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFStd; import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFStdSample; @@ -304,6 +304,9 @@ UDFToString.class.getSimpleName()); // Aggregate functions + registerGenericUDAF("max", new GenericUDAFMax()); + registerGenericUDAF("min", new GenericUDAFMin()); + registerGenericUDAF("sum", new GenericUDAFSum()); registerGenericUDAF("count", new GenericUDAFCount()); registerGenericUDAF("avg", new GenericUDAFAverage()); @@ -316,9 +319,6 @@ registerGenericUDAF("var_pop", new GenericUDAFVariance()); registerGenericUDAF("var_samp", new GenericUDAFVarianceSample()); - registerUDAF("max", UDAFMax.class); - registerUDAF("min", UDAFMin.class); - // Generic UDFs registerGenericUDF("array", GenericUDFArray.class); registerGenericUDF("map", GenericUDFMap.class); Index: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFMin.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFMin.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFMin.java (revision 0) @@ -0,0 +1,124 @@ +/** + * 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.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils; +import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils.ObjectInspectorCopyOption; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils; + +@Description(name = "min", value = "_FUNC_(expr) - Returns the minimum value of expr") +public class GenericUDAFMin implements GenericUDAFResolver { + + static final Log LOG = LogFactory.getLog(GenericUDAFMin.class.getName()); + + @Override + public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) + throws SemanticException { + if (parameters.length != 1) { + throw new UDFArgumentTypeException(parameters.length - 1, + "Exactly one argument is expected."); + } + ObjectInspector oi = TypeInfoUtils.getStandardJavaObjectInspectorFromTypeInfo(parameters[0]); + if (!ObjectInspectorUtils.compareSupported(oi)) { + throw new UDFArgumentTypeException(parameters.length - 1, + "Cannot support comparison of map<> type or complex type containing map<>."); + } + return new GenericUDAFMinEvaluator(); + } + + public static class GenericUDAFMinEvaluator extends GenericUDAFEvaluator { + + ObjectInspector inputOI; + ObjectInspector outputOI; + + @Override + public ObjectInspector init(Mode m, ObjectInspector[] parameters) + throws HiveException { + assert (parameters.length == 1); + super.init(m, parameters); + inputOI = parameters[0]; + // Copy to Java object because that saves object creation time. + // Note that on average the number of copies is log(N) so that's not + // very important. + outputOI = ObjectInspectorUtils.getStandardObjectInspector(inputOI, + ObjectInspectorCopyOption.JAVA); + return outputOI; + } + + /** class for storing the current max value */ + static class MinAgg implements AggregationBuffer { + Object o; + } + + @Override + public AggregationBuffer getNewAggregationBuffer() throws HiveException { + MinAgg result = new MinAgg(); + return result; + } + + @Override + public void reset(AggregationBuffer agg) throws HiveException { + MinAgg myagg = (MinAgg) agg; + myagg.o = null; + } + + boolean warned = false; + + @Override + public void iterate(AggregationBuffer agg, Object[] parameters) + throws HiveException { + assert (parameters.length == 1); + merge(agg, parameters[0]); + } + + @Override + public Object terminatePartial(AggregationBuffer agg) throws HiveException { + return terminate(agg); + } + + @Override + public void merge(AggregationBuffer agg, Object partial) + throws HiveException { + if (partial != null) { + MinAgg myagg = (MinAgg) agg; + int r = ObjectInspectorUtils.compare(myagg.o, outputOI, partial, inputOI); + if (myagg.o == null || r > 0) { + myagg.o = ObjectInspectorUtils.copyToStandardObject(partial, inputOI, + ObjectInspectorCopyOption.JAVA); + } + } + } + + @Override + public Object terminate(AggregationBuffer agg) throws HiveException { + MinAgg myagg = (MinAgg) agg; + return myagg.o; + } + + } + +} Index: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFMax.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFMax.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFMax.java (revision 0) @@ -0,0 +1,124 @@ +/** + * 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.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils; +import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils.ObjectInspectorCopyOption; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils; + +@Description(name = "max", value = "_FUNC_(expr) - Returns the maximum value of expr") +public class GenericUDAFMax implements GenericUDAFResolver { + + static final Log LOG = LogFactory.getLog(GenericUDAFMax.class.getName()); + + @Override + public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) + throws SemanticException { + if (parameters.length != 1) { + throw new UDFArgumentTypeException(parameters.length - 1, + "Exactly one argument is expected."); + } + ObjectInspector oi = TypeInfoUtils.getStandardJavaObjectInspectorFromTypeInfo(parameters[0]); + if (!ObjectInspectorUtils.compareSupported(oi)) { + throw new UDFArgumentTypeException(parameters.length - 1, + "Cannot support comparison of map<> type or complex type containing map<>."); + } + return new GenericUDAFMaxEvaluator(); + } + + public static class GenericUDAFMaxEvaluator extends GenericUDAFEvaluator { + + ObjectInspector inputOI; + ObjectInspector outputOI; + + @Override + public ObjectInspector init(Mode m, ObjectInspector[] parameters) + throws HiveException { + assert (parameters.length == 1); + super.init(m, parameters); + inputOI = parameters[0]; + // Copy to Java object because that saves object creation time. + // Note that on average the number of copies is log(N) so that's not + // very important. + outputOI = ObjectInspectorUtils.getStandardObjectInspector(inputOI, + ObjectInspectorCopyOption.JAVA); + return outputOI; + } + + /** class for storing the current max value */ + static class MaxAgg implements AggregationBuffer { + Object o; + } + + @Override + public AggregationBuffer getNewAggregationBuffer() throws HiveException { + MaxAgg result = new MaxAgg(); + return result; + } + + @Override + public void reset(AggregationBuffer agg) throws HiveException { + MaxAgg myagg = (MaxAgg) agg; + myagg.o = null; + } + + boolean warned = false; + + @Override + public void iterate(AggregationBuffer agg, Object[] parameters) + throws HiveException { + assert (parameters.length == 1); + merge(agg, parameters[0]); + } + + @Override + public Object terminatePartial(AggregationBuffer agg) throws HiveException { + return terminate(agg); + } + + @Override + public void merge(AggregationBuffer agg, Object partial) + throws HiveException { + if (partial != null) { + MaxAgg myagg = (MaxAgg) agg; + int r = ObjectInspectorUtils.compare(myagg.o, outputOI, partial, inputOI); + if (myagg.o == null || r < 0) { + myagg.o = ObjectInspectorUtils.copyToStandardObject(partial, inputOI, + ObjectInspectorCopyOption.JAVA); + } + } + } + + @Override + public Object terminate(AggregationBuffer agg) throws HiveException { + MaxAgg myagg = (MaxAgg) agg; + return myagg.o; + } + + } + +}