【问题标题】:Hive UDF - Generic UDF for all Primitive TypeHive UDF - 所有原始类型的通用 UDF
【发布时间】:2020-07-26 10:14:29
【问题描述】:

我正在尝试使用参数实现 Hive UDF,因此我正在扩展 GenericUDF 类。

问题是我的 UDF 在字符串数据类型上找到,但是如果我在其他数据类型上运行它会引发错误。无论数据类型如何,我都希望 UDF 运行。

请有人告诉我以下代码有什么问题。

@Description(name = "Encrypt", value = "Encrypt the Given Column", extended = "SELECT Encrypt('Hello World!', 'Key');")
public class Encrypt extends GenericUDF {
    StringObjectInspector key;
    StringObjectInspector col;

    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        if (arguments.length != 2) {
            throw new UDFArgumentLengthException("Encrypt only takes 2 arguments: T, String");
        }

        ObjectInspector keyObject = arguments[1];
        ObjectInspector colObject = arguments[0];

        if (!(keyObject instanceof StringObjectInspector)) {
            throw new UDFArgumentException("Error: Key Type is Not String");
        }

        this.key = (StringObjectInspector) keyObject;
        this.col = (StringObjectInspector) colObject;

        return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
    }

    @Override
    public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
        String keyString = key.getPrimitiveJavaObject(deferredObjects[1].get());
        String colString = col.getPrimitiveJavaObject(deferredObjects[0].get());
        return AES.encrypt(colString, keyString);
    }

    @Override
    public String getDisplayString(String[] strings) {
        return null;
    }

}


错误

java.lang.ClassCastException:org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaIntObjectInspector 无法转换为 org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector

【问题讨论】:

    标签: hadoop hive hiveql user-defined-functions hive-udf


    【解决方案1】:

    我建议您将StringObjectInspector col 替换为PrimitiveObjectInspector col 和相应的演员this.col = (PrimitiveObjectInspector) colObject。那么有两种方式:

    首先是处理所有可能的 Primitive 类型,像这样

        switch (((PrimitiveTypeInfo) colObject.getTypeInfo()).getPrimitiveCategory()) {
            case BYTE:
            case SHORT:
            case INT:
            case LONG:
            case TIMESTAMP:
                cast_long_type;
            case FLOAT:
            case DOUBLE:
                cast_double_type;
            case STRING:
                 everyting_is_fine;
            case DECIMAL:
            case BOOLEAN:
                throw new UDFArgumentTypeException(0, "Unsupported yet");
            default:
                throw new UDFArgumentTypeException(0,
                        "Unsupported type");
        }
    }
    

    另一种方式,是使用PrimitiveObjectInspectorUtils.getString方法:

    Object colObject = col.getPrimitiveJavaObject(deferredObjects[0].get());
    String colString = PrimitiveObjectInspectorUtils.getString(colObject, key);
    

    它只是类似示例的伪代码。希望对您有所帮助。

    【讨论】:

    • 我使用PrimitiveObjectInspector col;col.getPrimitiveJavaObject(deferredObjects[0].get()).toString(); 解决了这个问题,那会不会造成问题。
    猜你喜欢
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    相关资源
    最近更新 更多