diff --git ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStringToMap.java ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStringToMap.java index ed60fbf..89969bb 100644 --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStringToMap.java +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStringToMap.java @@ -83,11 +83,23 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen public Object evaluate(DeferredObject[] arguments) throws HiveException { ret.clear(); String text = (String) soi_text.convert(arguments[0].get()); + if (text == null) { + return ret; + } + String delimiter1 = (soi_de1 == null) ? default_de1 : (String) soi_de1.convert(arguments[1].get()); String delimiter2 = (soi_de2 == null) ? default_de2 : (String) soi_de2.convert(arguments[2].get()); + if (delimiter1 == null) { + delimiter1 = default_de1; + } + + if (delimiter2 == null) { + delimiter2 = default_de2; + } + String[] keyValuePairs = text.split(delimiter1); for (String keyValuePair : keyValuePairs) { diff --git ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFStringToMap.java ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFStringToMap.java new file mode 100644 index 0000000..b6d21ad --- /dev/null +++ ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFStringToMap.java @@ -0,0 +1,144 @@ +/** + * 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.LinkedHashMap; +import java.util.Map; + +import org.apache.hadoop.hive.ql.exec.UDFArgumentException; +import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredJavaObject; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredObject; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; + +import junit.framework.TestCase; + +public class TestGenericUDFStringToMap extends TestCase { + + public void testStringToMapWithCustomDelimiters() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDF(udf); + Map expResult = new LinkedHashMap(); + expResult.put("key1", "value1"); + expResult.put("key2", "value2"); + expResult.put("key3", "value3"); + runAndVerify("key1=value1;key2=value2;key3=value3", ";", "=", expResult, udf); + } + + public void testStringToMapWithDefaultDelimiters() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDFWithNoDelimiters(udf); + Map expResult = new LinkedHashMap(); + expResult.put("key1", "value1"); + expResult.put("key2", "value2"); + expResult.put("key3", "value3"); + runAndVerify("key1:value1,key2:value2,key3:value3", expResult, udf); + } + + public void testStringToMapWithNullDelimiters() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDF(udf); + Map expResult = new LinkedHashMap(); + expResult.put("key1", "value1"); + expResult.put("key2", "value2"); + expResult.put("key3", "value3"); + runAndVerify("key1:value1,key2:value2,key3:value3", null, null, expResult, udf); + } + + public void testStringToMapWithNullText() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDFWithNoDelimiters(udf); + Map expResult = new LinkedHashMap(); + runAndVerify(null, expResult, udf); + } + + public void testStringToMapWithEmptyText() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDFWithNoDelimiters(udf); + Map expResult = new LinkedHashMap(); + expResult.put("", null); + runAndVerify("", expResult, udf); + } + + public void testStringToMapNoKey() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDFWithNoDelimiters(udf); + Map expResult = new LinkedHashMap(); + expResult.put("", "value"); + runAndVerify(":value", expResult, udf); + } + + public void testStringToMapNoValue() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDFWithNoDelimiters(udf); + Map expResult = new LinkedHashMap(); + expResult.put("key", ""); + runAndVerify("key:", expResult, udf); + } + + public void testStringToMapNotMatchingDelimiter() throws HiveException { + GenericUDFStringToMap udf = new GenericUDFStringToMap(); + initGenericUDFWithNoDelimiters(udf); + Map expResult = new LinkedHashMap(); + expResult.put("key=value", null); + runAndVerify("key=value", expResult, udf); + } + + private void initGenericUDF(GenericUDFStringToMap udf) + throws UDFArgumentException { + + ObjectInspector valueOI0 = PrimitiveObjectInspectorFactory.javaStringObjectInspector; + ObjectInspector valueOI1 = PrimitiveObjectInspectorFactory.javaStringObjectInspector; + ObjectInspector valueOI2 = PrimitiveObjectInspectorFactory.javaStringObjectInspector; + ObjectInspector[] arguments = { valueOI0, valueOI1, valueOI2 }; + udf.initialize(arguments); + } + + private void initGenericUDFWithNoDelimiters(GenericUDFStringToMap udf) + throws UDFArgumentException { + + ObjectInspector valueOI0 = PrimitiveObjectInspectorFactory.javaStringObjectInspector; + ObjectInspector[] arguments = { valueOI0 }; + udf.initialize(arguments); + } + + private void runAndVerify(String text, String delimiter1, String delimiter2, + Map expResult, GenericUDF udf) throws HiveException { + + DeferredObject valueObj0 = new DeferredJavaObject(text); + DeferredObject valueObj1 = new DeferredJavaObject(delimiter1); + DeferredObject valueObj2 = new DeferredJavaObject(delimiter2); + DeferredObject[] args = { valueObj0, valueObj1, valueObj2 }; + + @SuppressWarnings("unchecked") + LinkedHashMap output = (LinkedHashMap) udf.evaluate(args); + assertTrue("str_to_map() test", expResult.equals(output)); + } + + private void runAndVerify(String text, Map expResult, + GenericUDF udf) throws HiveException { + + DeferredObject valueObj0 = new DeferredJavaObject(text); + DeferredObject[] args = { valueObj0 }; + @SuppressWarnings("unchecked") + LinkedHashMap output = (LinkedHashMap) udf.evaluate(args); + assertTrue("str_to_map() test", expResult.equals(output)); + } + +} \ No newline at end of file