Index: ql/src/test/results/clientpositive/udf_array.q.out =================================================================== --- ql/src/test/results/clientpositive/udf_array.q.out (revision 0) +++ ql/src/test/results/clientpositive/udf_array.q.out (revision 0) @@ -0,0 +1,61 @@ +PREHOOK: query: EXPLAIN SELECT array(), array()[1], array(1, 2, 3), array(1, 2, 3)[2], array(1,"a", 2, 3), array(1,"a", 2, 3)[2], +array(array(1), array(2), array(3), array(4))[1][0] FROM src LIMIT 1 +PREHOOK: type: QUERY +POSTHOOK: query: EXPLAIN SELECT array(), array()[1], array(1, 2, 3), array(1, 2, 3)[2], array(1,"a", 2, 3), array(1,"a", 2, 3)[2], +array(array(1), array(2), array(3), array(4))[1][0] FROM src LIMIT 1 +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 array)) (TOK_SELEXPR ([ (TOK_FUNCTION array) 1)) (TOK_SELEXPR (TOK_FUNCTION array 1 2 3)) (TOK_SELEXPR ([ (TOK_FUNCTION array 1 2 3) 2)) (TOK_SELEXPR (TOK_FUNCTION array 1 "a" 2 3)) (TOK_SELEXPR ([ (TOK_FUNCTION array 1 "a" 2 3) 2)) (TOK_SELEXPR ([ ([ (TOK_FUNCTION array (TOK_FUNCTION array 1) (TOK_FUNCTION array 2) (TOK_FUNCTION array 3) (TOK_FUNCTION array 4)) 1) 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: array() + type: array + expr: array()[1] + type: string + expr: array(1,2,3) + type: array + expr: array(1,2,3)[2] + type: int + expr: array(1,'a',2,3) + type: array + expr: array(1,'a',2,3)[2] + type: string + expr: array(array(1),array(2),array(3),array(4))[1][0] + type: int + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6 + 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 array(), array()[1], array(1, 2, 3), array(1, 2, 3)[2], array(1,"a", 2, 3), array(1,"a", 2, 3)[2], +array(array(1), array(2), array(3), array(4))[1][0] FROM src LIMIT 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/pyang/trunk-HIVE-554/VENDOR.hive/trunk/build/ql/tmp/1854297096/10000 +POSTHOOK: query: SELECT array(), array()[1], array(1, 2, 3), array(1, 2, 3)[2], array(1,"a", 2, 3), array(1,"a", 2, 3)[2], +array(array(1), array(2), array(3), array(4))[1][0] FROM src LIMIT 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/pyang/trunk-HIVE-554/VENDOR.hive/trunk/build/ql/tmp/1854297096/10000 +[] NULL [1,2,3] 3 ["1","a","2","3"] 2 2 Index: ql/src/test/results/clientpositive/udf_map.q.out =================================================================== --- ql/src/test/results/clientpositive/udf_map.q.out (revision 0) +++ ql/src/test/results/clientpositive/udf_map.q.out (revision 0) @@ -0,0 +1,59 @@ +PREHOOK: query: EXPLAIN SELECT map(), map(1, "a", 2, "b", 3, "c"), map(1, 2, "a", "b"), +map(1, "a", 2, "b", 3, "c")[2], map(1, 2, "a", "b")["a"], map(1, array("a"))[1][0] FROM src LIMIT 1 +PREHOOK: type: QUERY +POSTHOOK: query: EXPLAIN SELECT map(), map(1, "a", 2, "b", 3, "c"), map(1, 2, "a", "b"), +map(1, "a", 2, "b", 3, "c")[2], map(1, 2, "a", "b")["a"], map(1, array("a"))[1][0] FROM src LIMIT 1 +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 map)) (TOK_SELEXPR (TOK_FUNCTION map 1 "a" 2 "b" 3 "c")) (TOK_SELEXPR (TOK_FUNCTION map 1 2 "a" "b")) (TOK_SELEXPR ([ (TOK_FUNCTION map 1 "a" 2 "b" 3 "c") 2)) (TOK_SELEXPR ([ (TOK_FUNCTION map 1 2 "a" "b") "a")) (TOK_SELEXPR ([ ([ (TOK_FUNCTION map 1 (TOK_FUNCTION array "a")) 1) 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: map() + type: map + expr: map(1:'a',2:'b',3:'c') + type: map + expr: map(1:2,'a':'b') + type: map + expr: map(1:'a',2:'b',3:'c')[2] + type: string + expr: map(1:2,'a':'b')['a'] + type: string + expr: map(1:array('a'))[1][0] + type: string + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5 + 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 map(), map(1, "a", 2, "b", 3, "c"), map(1, 2, "a", "b"), +map(1, "a", 2, "b", 3, "c")[2], map(1, 2, "a", "b")["a"], map(1, array("a"))[1][0] FROM src LIMIT 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: file:/data/users/pyang/trunk-HIVE-554/VENDOR.hive/trunk/build/ql/tmp/802535376/10000 +POSTHOOK: query: SELECT map(), map(1, "a", 2, "b", 3, "c"), map(1, 2, "a", "b"), +map(1, "a", 2, "b", 3, "c")[2], map(1, 2, "a", "b")["a"], map(1, array("a"))[1][0] FROM src LIMIT 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: file:/data/users/pyang/trunk-HIVE-554/VENDOR.hive/trunk/build/ql/tmp/802535376/10000 +{} {1:"a",2:"b",3:"c"} {"1":"2","a":"b"} b b a Index: ql/src/test/queries/clientpositive/udf_map.q =================================================================== --- ql/src/test/queries/clientpositive/udf_map.q (revision 0) +++ ql/src/test/queries/clientpositive/udf_map.q (revision 0) @@ -0,0 +1,5 @@ +EXPLAIN SELECT map(), map(1, "a", 2, "b", 3, "c"), map(1, 2, "a", "b"), +map(1, "a", 2, "b", 3, "c")[2], map(1, 2, "a", "b")["a"], map(1, array("a"))[1][0] FROM src LIMIT 1; + +SELECT map(), map(1, "a", 2, "b", 3, "c"), map(1, 2, "a", "b"), +map(1, "a", 2, "b", 3, "c")[2], map(1, 2, "a", "b")["a"], map(1, array("a"))[1][0] FROM src LIMIT 1; Index: ql/src/test/queries/clientpositive/udf_array.q =================================================================== --- ql/src/test/queries/clientpositive/udf_array.q (revision 0) +++ ql/src/test/queries/clientpositive/udf_array.q (revision 0) @@ -0,0 +1,5 @@ +EXPLAIN SELECT array(), array()[1], array(1, 2, 3), array(1, 2, 3)[2], array(1,"a", 2, 3), array(1,"a", 2, 3)[2], +array(array(1), array(2), array(3), array(4))[1][0] FROM src LIMIT 1; + +SELECT array(), array()[1], array(1, 2, 3), array(1, 2, 3)[2], array(1,"a", 2, 3), array(1,"a", 2, 3)[2], +array(array(1), array(2), array(3), array(4))[1][0] FROM src LIMIT 1; Index: ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (revision 1888) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (working copy) @@ -165,7 +165,7 @@ registerGenericUDF("isnotnull", GenericUDFOPNotNull.class); registerGenericUDF("if", GenericUDFIf.class); - + // Aliases for Java Class Names // These are used in getImplicitConvertUDFMethod registerUDF(Constants.BOOLEAN_TYPE_NAME, UDFToBoolean.class, false, @@ -210,6 +210,8 @@ registerGenericUDF("instr", GenericUDFInstr.class); registerGenericUDF("locate", GenericUDFLocate.class); registerGenericUDF("elt", GenericUDFElt.class); + registerGenericUDF("array", GenericUDFArray.class); + registerGenericUDF("map", GenericUDFMap.class); } public static void registerTemporaryUDF(String functionName, Class UDFClass, Index: ql/src/java/org/apache/hadoop/hive/ql/parse/Hive.g =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/parse/Hive.g (revision 1888) +++ ql/src/java/org/apache/hadoop/hive/ql/parse/Hive.g (working copy) @@ -1015,7 +1015,7 @@ @init { msgs.push("function name"); } @after { msgs.pop(); } : // Keyword IF is also a function name - Identifier | KW_IF + Identifier | KW_IF | KW_ARRAY | KW_MAP ; castExpression Index: ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFMap.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFMap.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFMap.java (revision 0) @@ -0,0 +1,129 @@ +/** + * 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 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.exec.description; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; +import org.apache.hadoop.io.Text; + +@description( + name = "map", + value = "_FUNC_(key0, value0, key1, value1...) - Creates a map with the given key/value pairs " +) + +public class GenericUDFMap extends GenericUDF { + Converter[] converters; + HashMap ret = new HashMap(); + + @Override + public ObjectInspector initialize(ObjectInspector[] arguments) + throws UDFArgumentException { + + if (arguments.length % 2 != 0) { + throw new UDFArgumentLengthException( + "Arguments must be in key/value pairs"); + } + + GenericUDFUtils.ReturnObjectInspectorResolver keyOIResolver = + new GenericUDFUtils.ReturnObjectInspectorResolver(true); + GenericUDFUtils.ReturnObjectInspectorResolver valueOIResolver = + new GenericUDFUtils.ReturnObjectInspectorResolver(true); + + for(int i=0; i ret = new ArrayList(); + @Override + public ObjectInspector initialize(ObjectInspector[] arguments) + throws UDFArgumentException { + + GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver; + + returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true); + + for(int i=0; i