/** * 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 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.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils; import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils.PrimitiveGrouping; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils; /** * GenericUDFStringToMap. * */ @Description(name = "str_to_map", value = "_FUNC_(text, delimiter1, delimiter2) - " + "Creates a map by parsing text ", extended = "Split text into key-value pairs" + " using two delimiters. The first delimiter separates pairs, and the" + " second delimiter sperates key and value. If only one parameter is given, default" + " delimiters are used: ',' as delimiter1 and ':' as delimiter2.") public class GenericUDFStringToMap extends GenericUDF { // Must be deterministic order map for consistent q-test output across Java versions - see HIVE-9161 private final LinkedHashMap<Object, Object> ret = new LinkedHashMap<Object, Object>(); private transient Converter soi_text, soi_de1 = null, soi_de2 = null; final static String default_de1 = ","; final static String default_de2 = ":"; @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { for (int idx = 0; idx < Math.min(arguments.length, 3); ++idx) { if (arguments[idx].getCategory() != Category.PRIMITIVE || PrimitiveObjectInspectorUtils.getPrimitiveGrouping( ((PrimitiveObjectInspector) arguments[idx]).getPrimitiveCategory()) != PrimitiveGrouping.STRING_GROUP) { throw new UDFArgumentException("All argument should be string/character type"); } } soi_text = ObjectInspectorConverters.getConverter(arguments[0], PrimitiveObjectInspectorFactory.javaStringObjectInspector); if (arguments.length > 1) { soi_de1 = ObjectInspectorConverters.getConverter(arguments[1], PrimitiveObjectInspectorFactory.javaStringObjectInspector); } if (arguments.length > 2) { soi_de2 = ObjectInspectorConverters.getConverter(arguments[2], PrimitiveObjectInspectorFactory.javaStringObjectInspector); } return ObjectInspectorFactory.getStandardMapObjectInspector( PrimitiveObjectInspectorFactory.javaStringObjectInspector, PrimitiveObjectInspectorFactory.javaStringObjectInspector); } @Override 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) { String[] keyValue = keyValuePair.split(delimiter2, 2); if (keyValue.length < 2) { ret.put(keyValuePair, null); } else { ret.put(keyValue[0], keyValue[1]); } } return ret; } @Override public String getDisplayString(String[] children) { assert (children.length <= 3); return getStandardDisplayString("str_to_map", children, ","); } }