Index: ql/src/test/results/clientpositive/implode_to_ordered_map.q.out =================================================================== --- ql/src/test/results/clientpositive/implode_to_ordered_map.q.out (revision 0) +++ ql/src/test/results/clientpositive/implode_to_ordered_map.q.out (revision 0) @@ -0,0 +1,89 @@ +PREHOOK: query: DROP TABLE lineitem +PREHOOK: type: DROPTABLE +POSTHOOK: query: DROP TABLE lineitem +POSTHOOK: type: DROPTABLE +PREHOOK: query: CREATE TABLE lineitem (L_ORDERKEY INT, + L_PARTKEY INT, + L_SUPPKEY INT, + L_LINENUMBER INT, + L_QUANTITY DOUBLE, + L_EXTENDEDPRICE DOUBLE, + L_DISCOUNT DOUBLE, + L_TAX DOUBLE, + L_RETURNFLAG STRING, + L_LINESTATUS STRING, + l_shipdate STRING, + L_COMMITDATE STRING, + L_RECEIPTDATE STRING, + L_SHIPINSTRUCT STRING, + L_SHIPMODE STRING, + L_COMMENT STRING) +ROW FORMAT DELIMITED +FIELDS TERMINATED BY '|' +PREHOOK: type: CREATETABLE +POSTHOOK: query: CREATE TABLE lineitem (L_ORDERKEY INT, + L_PARTKEY INT, + L_SUPPKEY INT, + L_LINENUMBER INT, + L_QUANTITY DOUBLE, + L_EXTENDEDPRICE DOUBLE, + L_DISCOUNT DOUBLE, + L_TAX DOUBLE, + L_RETURNFLAG STRING, + L_LINESTATUS STRING, + l_shipdate STRING, + L_COMMITDATE STRING, + L_RECEIPTDATE STRING, + L_SHIPINSTRUCT STRING, + L_SHIPMODE STRING, + L_COMMENT STRING) +ROW FORMAT DELIMITED +FIELDS TERMINATED BY '|' +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@lineitem +PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem +PREHOOK: type: LOAD +PREHOOK: Output: default@lineitem +POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem +POSTHOOK: type: LOAD +POSTHOOK: Output: default@lineitem +PREHOOK: query: SELECT + `L_ORDERKEY`, implode_to_ordered_map(l_shipdate, array(L_QUANTITY,L_EXTENDEDPRICE)) +FROM `lineitem` +GROUP BY `L_ORDERKEY` +PREHOOK: type: QUERY +PREHOOK: Input: default@lineitem +#### A masked pattern was here #### +POSTHOOK: query: SELECT + `L_ORDERKEY`, implode_to_ordered_map(l_shipdate, array(L_QUANTITY,L_EXTENDEDPRICE)) +FROM `lineitem` +GROUP BY `L_ORDERKEY` +POSTHOOK: type: QUERY +POSTHOOK: Input: default@lineitem +#### A masked pattern was here #### +1 {"1996-01-29":[8.0,13309.6],"1996-01-30":[32.0,49620.16],"1996-03-13":[17.0,21168.23],"1996-03-30":[24.0,22824.48],"1996-04-12":[36.0,45983.16],"1996-04-21":[28.0,28955.64]} +2 {"1997-01-28":[38.0,44694.46]} +3 {"1993-10-29":[26.0,28733.64],"1993-11-09":[49.0,46796.47],"1993-12-04":[2.0,2618.76],"1993-12-14":[28.0,32986.52],"1994-01-16":[27.0,39890.88],"1994-02-02":[45.0,54058.05]} +4 {"1996-01-10":[30.0,30690.9]} +5 {"1994-08-08":[50.0,73426.5],"1994-10-16":[26.0,50723.92],"1994-10-31":[15.0,23678.55]} +6 {"1992-04-27":[37.0,61998.31]} +7 {"1996-01-15":[46.0,81639.88],"1996-01-16":[35.0,43058.75],"1996-02-01":[9.0,11594.16],"1996-02-10":[5.0,6476.15],"1996-02-11":[38.0,73943.82],"1996-03-21":[28.0,31809.96],"1996-05-07":[12.0,13608.6]} +32 {"1995-07-21":[6.0,9159.66],"1995-08-04":[4.0,6582.96],"1995-08-07":[2.0,2210.32],"1995-08-14":[32.0,64605.44],"1995-08-28":[44.0,79059.64],"1995-10-23":[28.0,47227.6]} +33 {"1993-10-29":[31.0,40217.23],"1993-11-09":[41.0,75928.31],"1993-12-09":[5.0,7532.3]} +34 {"1998-10-09":[22.0,30875.02],"1998-10-23":[13.0,17554.68],"1998-10-30":[6.0,9681.24]} +35 {"1995-11-08":[34.0,65854.94],"1995-11-26":[25.0,29004.25],"1996-01-19":[7.0,13418.23],"1996-01-22":[34.0,68065.96],"1996-02-01":[28.0,47397.28],"1996-02-21":[24.0,32410.8]} +36 {"1996-02-03":[42.0,75043.92]} +37 {"1992-07-02":[39.0,70542.42],"1992-07-10":[43.0,78083.7],"1992-07-21":[40.0,62105.2]} +38 {"1996-09-29":[44.0,84252.52]} +39 {"1996-09-26":[46.0,82746.18],"1996-10-02":[32.0,48338.88],"1996-10-17":[43.0,63360.93],"1996-11-04":[26.0,43383.08],"1996-11-14":[44.0,53782.08],"1996-12-08":[40.0,54494.4]} +64 {"1994-09-30":[21.0,40675.95]} +65 {"1995-04-20":[26.0,42995.94],"1995-07-06":[21.0,27076.98],"1995-07-17":[22.0,39353.82]} +66 {"1994-02-19":[31.0,35126.41],"1994-02-21":[41.0,64061.68]} +67 {"1997-01-25":[29.0,40144.7],"1997-01-27":[12.0,13358.28],"1997-02-20":[5.0,8368.0],"1997-03-18":[44.0,66066.44],"1997-04-17":[4.0,6230.52],"1997-04-19":[23.0,35733.03]} +68 {"1998-06-19":[27.0,47000.25],"1998-06-24":[41.0,52735.84],"1998-06-26":[46.0,57738.28],"1998-06-27":[20.0,34454.4],"1998-07-04":[3.0,2925.18],"1998-08-11":[30.0,46906.8],"1998-08-13":[46.0,88089.08]} +69 {"1994-06-06":[3.0,4318.5],"1994-07-02":[17.0,22172.42],"1994-07-31":[42.0,44606.94],"1994-08-17":[48.0,58761.6],"1994-08-24":[32.0,37893.76],"1994-10-03":[23.0,32717.5]} +70 {"1994-01-12":[8.0,8736.96],"1994-01-26":[19.0,30602.35],"1994-02-13":[37.0,39520.81],"1994-03-03":[13.0,16277.95],"1994-03-17":[11.0,18477.03]} +71 {"1998-01-29":[39.0,49071.75],"1998-02-23":[45.0,61489.35],"1998-03-05":[34.0,58841.42],"1998-04-10":[25.0,47323.25],"1998-04-12":[33.0,54174.12],"1998-05-23":[3.0,5645.73]} +96 {"1994-06-03":[30.0,42761.7],"1994-07-19":[23.0,25278.61]} +97 {"1993-04-01":[13.0,19454.11],"1993-04-13":[37.0,56149.72],"1993-05-14":[19.0,31857.11]} +98 {"1994-12-01":[1.0,1752.74],"1994-12-24":[28.0,32373.88],"1994-12-30":[14.0,23109.8]} Index: ql/src/test/results/clientpositive/implode_to_map.q.out =================================================================== --- ql/src/test/results/clientpositive/implode_to_map.q.out (revision 0) +++ ql/src/test/results/clientpositive/implode_to_map.q.out (revision 0) @@ -0,0 +1,89 @@ +PREHOOK: query: DROP TABLE lineitem +PREHOOK: type: DROPTABLE +POSTHOOK: query: DROP TABLE lineitem +POSTHOOK: type: DROPTABLE +PREHOOK: query: CREATE TABLE lineitem (L_ORDERKEY INT, + L_PARTKEY INT, + L_SUPPKEY INT, + L_LINENUMBER INT, + L_QUANTITY DOUBLE, + L_EXTENDEDPRICE DOUBLE, + L_DISCOUNT DOUBLE, + L_TAX DOUBLE, + L_RETURNFLAG STRING, + L_LINESTATUS STRING, + l_shipdate STRING, + L_COMMITDATE STRING, + L_RECEIPTDATE STRING, + L_SHIPINSTRUCT STRING, + L_SHIPMODE STRING, + L_COMMENT STRING) +ROW FORMAT DELIMITED +FIELDS TERMINATED BY '|' +PREHOOK: type: CREATETABLE +POSTHOOK: query: CREATE TABLE lineitem (L_ORDERKEY INT, + L_PARTKEY INT, + L_SUPPKEY INT, + L_LINENUMBER INT, + L_QUANTITY DOUBLE, + L_EXTENDEDPRICE DOUBLE, + L_DISCOUNT DOUBLE, + L_TAX DOUBLE, + L_RETURNFLAG STRING, + L_LINESTATUS STRING, + l_shipdate STRING, + L_COMMITDATE STRING, + L_RECEIPTDATE STRING, + L_SHIPINSTRUCT STRING, + L_SHIPMODE STRING, + L_COMMENT STRING) +ROW FORMAT DELIMITED +FIELDS TERMINATED BY '|' +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: default@lineitem +PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem +PREHOOK: type: LOAD +PREHOOK: Output: default@lineitem +POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem +POSTHOOK: type: LOAD +POSTHOOK: Output: default@lineitem +PREHOOK: query: SELECT + `L_ORDERKEY`, implode_to_map(l_shipdate, array(L_QUANTITY,L_EXTENDEDPRICE)) +FROM `lineitem` +GROUP BY `L_ORDERKEY` +PREHOOK: type: QUERY +PREHOOK: Input: default@lineitem +#### A masked pattern was here #### +POSTHOOK: query: SELECT + `L_ORDERKEY`, implode_to_map(l_shipdate, array(L_QUANTITY,L_EXTENDEDPRICE)) +FROM `lineitem` +GROUP BY `L_ORDERKEY` +POSTHOOK: type: QUERY +POSTHOOK: Input: default@lineitem +#### A masked pattern was here #### +1 {"1996-03-13":[17.0,21168.23],"1996-01-29":[8.0,13309.6],"1996-01-30":[32.0,49620.16],"1996-03-30":[24.0,22824.48],"1996-04-12":[36.0,45983.16],"1996-04-21":[28.0,28955.64]} +2 {"1997-01-28":[38.0,44694.46]} +3 {"1994-02-02":[45.0,54058.05],"1993-12-04":[2.0,2618.76],"1993-10-29":[26.0,28733.64],"1994-01-16":[27.0,39890.88],"1993-11-09":[49.0,46796.47],"1993-12-14":[28.0,32986.52]} +4 {"1996-01-10":[30.0,30690.9]} +5 {"1994-10-31":[15.0,23678.55],"1994-08-08":[50.0,73426.5],"1994-10-16":[26.0,50723.92]} +6 {"1992-04-27":[37.0,61998.31]} +7 {"1996-02-01":[9.0,11594.16],"1996-03-21":[28.0,31809.96],"1996-05-07":[12.0,13608.6],"1996-02-10":[5.0,6476.15],"1996-02-11":[38.0,73943.82],"1996-01-15":[46.0,81639.88],"1996-01-16":[35.0,43058.75]} +32 {"1995-10-23":[28.0,47227.6],"1995-08-04":[4.0,6582.96],"1995-08-07":[2.0,2210.32],"1995-08-14":[32.0,64605.44],"1995-08-28":[44.0,79059.64],"1995-07-21":[6.0,9159.66]} +33 {"1993-12-09":[5.0,7532.3],"1993-10-29":[31.0,40217.23],"1993-11-09":[41.0,75928.31]} +34 {"1998-10-30":[6.0,9681.24],"1998-10-23":[13.0,17554.68],"1998-10-09":[22.0,30875.02]} +35 {"1996-02-01":[28.0,47397.28],"1995-11-26":[25.0,29004.25],"1996-01-22":[34.0,68065.96],"1996-02-21":[24.0,32410.8],"1995-11-08":[34.0,65854.94],"1996-01-19":[7.0,13418.23]} +36 {"1996-02-03":[42.0,75043.92]} +37 {"1992-07-02":[39.0,70542.42],"1992-07-21":[40.0,62105.2],"1992-07-10":[43.0,78083.7]} +38 {"1996-09-29":[44.0,84252.52]} +39 {"1996-10-17":[43.0,63360.93],"1996-10-02":[32.0,48338.88],"1996-12-08":[40.0,54494.4],"1996-09-26":[46.0,82746.18],"1996-11-14":[44.0,53782.08],"1996-11-04":[26.0,43383.08]} +64 {"1994-09-30":[21.0,40675.95]} +65 {"1995-04-20":[26.0,42995.94],"1995-07-06":[21.0,27076.98],"1995-07-17":[22.0,39353.82]} +66 {"1994-02-19":[31.0,35126.41],"1994-02-21":[41.0,64061.68]} +67 {"1997-03-18":[44.0,66066.44],"1997-04-19":[23.0,35733.03],"1997-04-17":[4.0,6230.52],"1997-01-27":[12.0,13358.28],"1997-01-25":[29.0,40144.7],"1997-02-20":[5.0,8368.0]} +68 {"1998-08-11":[30.0,46906.8],"1998-08-13":[46.0,88089.08],"1998-07-04":[3.0,2925.18],"1998-06-19":[27.0,47000.25],"1998-06-24":[41.0,52735.84],"1998-06-27":[20.0,34454.4],"1998-06-26":[46.0,57738.28]} +69 {"1994-07-31":[42.0,44606.94],"1994-08-17":[48.0,58761.6],"1994-10-03":[23.0,32717.5],"1994-08-24":[32.0,37893.76],"1994-07-02":[17.0,22172.42],"1994-06-06":[3.0,4318.5]} +70 {"1994-03-03":[13.0,16277.95],"1994-03-17":[11.0,18477.03],"1994-01-26":[19.0,30602.35],"1994-01-12":[8.0,8736.96],"1994-02-13":[37.0,39520.81]} +71 {"1998-05-23":[3.0,5645.73],"1998-01-29":[39.0,49071.75],"1998-02-23":[45.0,61489.35],"1998-04-10":[25.0,47323.25],"1998-04-12":[33.0,54174.12],"1998-03-05":[34.0,58841.42]} +96 {"1994-07-19":[23.0,25278.61],"1994-06-03":[30.0,42761.7]} +97 {"1993-05-14":[19.0,31857.11],"1993-04-01":[13.0,19454.11],"1993-04-13":[37.0,56149.72]} +98 {"1994-12-30":[14.0,23109.8],"1994-12-24":[28.0,32373.88],"1994-12-01":[1.0,1752.74]} Index: ql/src/test/queries/clientpositive/implode_to_map.q =================================================================== --- ql/src/test/queries/clientpositive/implode_to_map.q (revision 0) +++ ql/src/test/queries/clientpositive/implode_to_map.q (revision 0) @@ -0,0 +1,27 @@ + +DROP TABLE lineitem; +CREATE TABLE lineitem (L_ORDERKEY INT, + L_PARTKEY INT, + L_SUPPKEY INT, + L_LINENUMBER INT, + L_QUANTITY DOUBLE, + L_EXTENDEDPRICE DOUBLE, + L_DISCOUNT DOUBLE, + L_TAX DOUBLE, + L_RETURNFLAG STRING, + L_LINESTATUS STRING, + l_shipdate STRING, + L_COMMITDATE STRING, + L_RECEIPTDATE STRING, + L_SHIPINSTRUCT STRING, + L_SHIPMODE STRING, + L_COMMENT STRING) +ROW FORMAT DELIMITED +FIELDS TERMINATED BY '|'; + +LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem; + +SELECT + `L_ORDERKEY`, implode_to_map(l_shipdate, array(L_QUANTITY,L_EXTENDEDPRICE)) +FROM `lineitem` +GROUP BY `L_ORDERKEY`; Index: ql/src/test/queries/clientpositive/implode_to_ordered_map.q =================================================================== --- ql/src/test/queries/clientpositive/implode_to_ordered_map.q (revision 0) +++ ql/src/test/queries/clientpositive/implode_to_ordered_map.q (revision 0) @@ -0,0 +1,27 @@ + +DROP TABLE lineitem; +CREATE TABLE lineitem (L_ORDERKEY INT, + L_PARTKEY INT, + L_SUPPKEY INT, + L_LINENUMBER INT, + L_QUANTITY DOUBLE, + L_EXTENDEDPRICE DOUBLE, + L_DISCOUNT DOUBLE, + L_TAX DOUBLE, + L_RETURNFLAG STRING, + L_LINESTATUS STRING, + l_shipdate STRING, + L_COMMITDATE STRING, + L_RECEIPTDATE STRING, + L_SHIPINSTRUCT STRING, + L_SHIPMODE STRING, + L_COMMENT STRING) +ROW FORMAT DELIMITED +FIELDS TERMINATED BY '|'; + +LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem; + +SELECT + `L_ORDERKEY`, implode_to_ordered_map(l_shipdate, array(L_QUANTITY,L_EXTENDEDPRICE)) +FROM `lineitem` +GROUP BY `L_ORDERKEY`; Index: ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (revision 1369852) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (working copy) @@ -137,6 +137,8 @@ import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEWAHBitmap; import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator; import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFHistogramNumeric; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFImplodeToMap; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFImplodeToOrderedMap; 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.GenericUDAFParameterInfo; @@ -428,6 +430,9 @@ registerGenericUDAF("ngrams", new GenericUDAFnGrams()); registerGenericUDAF("context_ngrams", new GenericUDAFContextNGrams()); + registerGenericUDAF("implode_to_map", new GenericUDAFImplodeToMap()); + registerGenericUDAF("implode_to_ordered_map", new GenericUDAFImplodeToOrderedMap()); + registerGenericUDAF("ewah_bitmap", new GenericUDAFEWAHBitmap()); registerUDAF("percentile", UDAFPercentile.class); Index: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToMap.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToMap.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToMap.java (revision 0) @@ -0,0 +1,175 @@ +/** + * 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 java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; +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.ObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils; +import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.StandardMapObjectInspector; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; + +/** + * Convert two aggregated columns into a key-value map. + * + * The key must be a primitive type (int, boolean, float, string, ...) and the + * value may be a primitive or a complex type (structs, maps, arrays). + */ +@Description( + name = "implode_to_map", + value = "_FUNC_(key, value) - Convert two aggregated columns into a key-value map", + extended = "Example:\n" + + "> SELECT implode_to_map(key, value) FROM src;\n" + + "{\"k3\":100,\"k1\":14.0,\"k2\":200}\n" + + "The return value is a map. The key must be a primitive type " + + "(int, boolean, float, string, ...) and the value may " + + "be a primitive or a complex type (structs, maps, arrays).") +public class GenericUDAFImplodeToMap extends AbstractGenericUDAFResolver { + + static final Log LOG = LogFactory.getLog(GenericUDAFImplodeToMap.class.getName()); + + @Override + public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) + throws SemanticException { + + if (parameters.length != 2) { + throw new UDFArgumentTypeException(parameters.length - 1, + "Exactly one argument is expected."); + } + + if (parameters[0].getCategory() != ObjectInspector.Category.PRIMITIVE) { + throw new UDFArgumentTypeException(0, + "Only primitive type arguments are accepted for the key but " + + parameters[0].getTypeName() + + " was passed as parameter 1."); + } + + return new UDAFToMapEvaluator(); + } + + /** + * UDAFToMapEvaluator + */ + public static class UDAFToMapEvaluator extends GenericUDAFEvaluator { + + protected PrimitiveObjectInspector inputKeyOI; + protected ObjectInspector inputValueOI; + protected StandardMapObjectInspector loi; + + protected StandardMapObjectInspector internalMergeOI; + + @Override + public ObjectInspector init(Mode m, ObjectInspector[] parameters) + throws HiveException { + super.init(m, parameters); + if (m == Mode.PARTIAL1) { + inputKeyOI = (PrimitiveObjectInspector) parameters[0]; + inputValueOI = (ObjectInspector) parameters[1]; + return ObjectInspectorFactory.getStandardMapObjectInspector( + (PrimitiveObjectInspector) ObjectInspectorUtils.getStandardObjectInspector(inputKeyOI), + (ObjectInspector) ObjectInspectorUtils.getStandardObjectInspector(inputValueOI)); + } else { + if (!(parameters[0] instanceof StandardMapObjectInspector)) { + inputKeyOI = (PrimitiveObjectInspector) parameters[0]; + inputValueOI = (ObjectInspector) parameters[1]; + return ObjectInspectorFactory.getStandardMapObjectInspector( + (PrimitiveObjectInspector) ObjectInspectorUtils.getStandardObjectInspector(inputKeyOI), + (ObjectInspector) ObjectInspectorUtils.getStandardObjectInspector(inputValueOI)); + } else { + internalMergeOI = (StandardMapObjectInspector) parameters[0]; + inputKeyOI = (PrimitiveObjectInspector) internalMergeOI.getMapKeyObjectInspector(); + inputValueOI = (ObjectInspector) internalMergeOI.getMapValueObjectInspector(); + loi = (StandardMapObjectInspector) ObjectInspectorUtils.getStandardObjectInspector(internalMergeOI); + return loi; + } + } + } + + /** class for storing the map elements */ + static class MkMapAggregationBuffer implements AggregationBuffer { + Map container; + } + + @Override + public void reset(AggregationBuffer agg) throws HiveException { + ((MkMapAggregationBuffer) agg).container = new HashMap(144); + } + + @Override + public AggregationBuffer getNewAggregationBuffer() throws HiveException { + MkMapAggregationBuffer ret = new MkMapAggregationBuffer(); + reset(ret); + return ret; + } + + @Override + public void iterate(AggregationBuffer agg, Object[] parameters) + throws HiveException { + assert (parameters.length == 2); + Object key = parameters[0]; + Object value = parameters[1]; + if (key != null) { + MkMapAggregationBuffer myagg = (MkMapAggregationBuffer) agg; + putIntoMap(key, value, myagg); + } + } + + @Override + public Object terminatePartial(AggregationBuffer agg) + throws HiveException { + MkMapAggregationBuffer myagg = (MkMapAggregationBuffer) agg; + return myagg.container; + } + + @Override + public void merge(AggregationBuffer agg, Object partial) + throws HiveException { + MkMapAggregationBuffer myagg = (MkMapAggregationBuffer) agg; + @SuppressWarnings("unchecked") + Map partialResult = (Map) internalMergeOI.getMap(partial); + for (Map.Entry entry: partialResult.entrySet()) { + putIntoMap(entry.getKey(), entry.getValue(), myagg); + } + } + + @Override + public Object terminate(AggregationBuffer agg) throws HiveException { + MkMapAggregationBuffer myagg = (MkMapAggregationBuffer) agg; + return myagg.container; + } + + /** + * Insert new elements into the map + */ + protected void putIntoMap(Object key, Object value, MkMapAggregationBuffer myagg) { + Object pKeyCopy = ObjectInspectorUtils.copyToStandardObject(key, this.inputKeyOI); + Object pValueCopy = ObjectInspectorUtils.copyToStandardObject(value, this.inputValueOI); + myagg.container.put(pKeyCopy, pValueCopy); + } + } + +} Property changes on: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToMap.java ___________________________________________________________________ Added: svn:executable + * Index: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToOrderedMap.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToOrderedMap.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToOrderedMap.java (revision 0) @@ -0,0 +1,64 @@ +/** + * 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 java.util.TreeMap; + +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.typeinfo.TypeInfo; + +/** + * Convert two aggregated columns into a sorted key-value map. + * + * The key must be a primitive type (int, boolean, float, string, ...) and the + * value may be a primitive or a complex type (structs, maps, arrays). + */ +@Description( + name = "implode_to_ordered_map", + value = "_FUNC_(key, value) - Convert two aggregated columns into an ordered key-value map", + extended = "Example:\n" + + "> SELECT implode_to_ordered_map(key, value) FROM src;\n" + + "{\"k1\":100,\"k2\":14.0,\"k3\":200}\n" + + "The return value is a map with keys sorted in ascendant order. The key " + + "must be a primitive type (int, boolean, float, string, ...) and the " + + "value may be a primitive or a complex type (structs, maps, arrays).") +public class GenericUDAFImplodeToOrderedMap extends GenericUDAFImplodeToMap { + + @Override + public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) + throws SemanticException { + + super.getEvaluator(parameters); + return new UDAFToOrderedMapEvaluator(); + } + + /** + * UDAFToOrderedMapEvaluator + */ + public static class UDAFToOrderedMapEvaluator extends UDAFToMapEvaluator { + + @Override + public void reset(AggregationBuffer agg) throws HiveException { + ((MkMapAggregationBuffer) agg).container = new TreeMap(); + } + + } + +} Property changes on: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFImplodeToOrderedMap.java ___________________________________________________________________ Added: svn:executable + *