Index: data/files/posexplode_data.txt =================================================================== --- data/files/posexplode_data.txt (revision 0) +++ data/files/posexplode_data.txt (revision 0) @@ -0,0 +1,4 @@ +John Doe100000.0Mary SmithTodd JonesFederal Taxes.2State Taxes.05Insurance.11 Michigan Ave.ChicagoIL60600 +Mary Smith80000.0Jeremy KingFederal Taxes.2State Taxes. 05Insurance.1100 Ontario St.ChicagoIL60601 +Todd Jones70000.0Federal Taxes.15State Taxes.03Insurance. 1200 Chicago Ave.Oak ParkIL60700 +Jeremy King60000.0Federal Taxes.15State Taxes.03Insurance. 1300 Obscure Dr.ObscuriaIL60100 Index: ql/src/test/results/clientpositive/show_functions.q.out =================================================================== --- ql/src/test/results/clientpositive/show_functions.q.out (revision 1511567) +++ ql/src/test/results/clientpositive/show_functions.q.out (working copy) @@ -124,6 +124,7 @@ percentile_approx pi pmod +posexplode positive pow power @@ -234,6 +235,7 @@ ntile parse_url_tuple percentile +posexplode positive regexp_replace reverse Index: ql/src/test/queries/clientpositive/udtf_posexplode.q =================================================================== --- ql/src/test/queries/clientpositive/udtf_posexplode.q (revision 0) +++ ql/src/test/queries/clientpositive/udtf_posexplode.q (revision 0) @@ -0,0 +1,15 @@ +CREATE TABLE employees ( +name STRING, +salary FLOAT, +subordinates ARRAY, +deductions MAP, +address STRUCT); + +LOAD DATA LOCAL INPATH '../data/files/posexplode_data.txt' INTO TABLE employees; + +SELECT + name, pos, sub +FROM + employees +LATERAL VIEW + posexplode(subordinates) subView AS pos, sub; Index: ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (revision 1511567) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (working copy) @@ -420,6 +420,7 @@ registerGenericUDTF("inline", GenericUDTFInline.class); registerGenericUDTF("json_tuple", GenericUDTFJSONTuple.class); registerGenericUDTF("parse_url_tuple", GenericUDTFParseUrlTuple.class); + registerGenericUDTF("posexplode", GenericUDTFPosExplode.class); registerGenericUDTF("stack", GenericUDTFStack.class); //PTF declarations Index: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDTFPosExplode.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDTFPosExplode.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDTFPosExplode.java (revision 0) @@ -0,0 +1,69 @@ +package org.apache.hadoop.hive.ql.udf.generic; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.hive.ql.exec.Description; +import org.apache.hadoop.hive.ql.exec.UDFArgumentException; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory; +import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; + +/** + * PosExplode. + * + */ +@Description( + name = "posexplode", + value = "_FUNC_(a) - behaves like explode for arrays, " + + "but includes the position of items in the original array") +public class GenericUDTFPosExplode extends GenericUDTF { + private ListObjectInspector listOI = null; + private final Object[] forwardObj = new Object[2]; + + @Override + public void close() throws HiveException { + } + + @Override + public StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException { + + if (args.length != 1) { + throw new UDFArgumentException("posexplode() takes only one argument"); + } + + if (args[0].getCategory() != ObjectInspector.Category.LIST) { + throw new UDFArgumentException("posexplode() takes an array as a parameter"); + } + listOI = (ListObjectInspector) args[0]; + + ArrayList fieldNames = new ArrayList(); + ArrayList fieldOIs = new ArrayList(); + fieldNames.add("pos"); + fieldNames.add("val"); + fieldOIs.add(PrimitiveObjectInspectorFactory + .getPrimitiveJavaObjectInspector(PrimitiveCategory.INT)); + fieldOIs.add(listOI.getListElementObjectInspector()); + return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs); + } + + @Override + public void process(Object[] o) throws HiveException { + List list = listOI.getList(o[0]); + for (int i = 0; i < list.size(); i++) { + Object r = list.get(i); + forwardObj[0] = new Integer(i); + forwardObj[1] = r; + forward(forwardObj); + } + } + + @Override + public String toString() { + return "posexplode"; + } +}