hadoop - Hive UDF-适用于所有基本类型的通用UDF

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

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

问题是我的UDF可以在String数据类型上找到,但是如果我在其他数据类型上运行则会抛出错误。我希望无论数据类型如何均可运行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 cannot be cast to org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector

最佳答案

我建议您将StringObjectInspector col替换为PrimitiveObjectInspector col和相应的强制转换this.col = (PrimitiveObjectInspector) colObject。然后有两种方法:

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

    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);

它只是伪代码,例如示例。希望能帮助到你。

关于hadoop - Hive UDF-适用于所有基本类型的通用UDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61194914/

相关文章:

performance - Spark 最近 30 天过滤器,提高性能的最佳方法

apache-spark - 将关系数据存储在hadoop中以进行分析

sql - Hive - Concat 字符串与行数据

java - 尽管使用 "ADD JAR"添加 jar 文件,Hive shell 在执行查询时仍会抛出 Filenotfound 异常

hadoop - 使用 sqoop 在 HIVE 表中进行增量更新

hadoop - Hive 从带分区的文件创建表

hadoop - 关于通过 Kerberos 的 Hadoop 安全性

hadoop - Hadoop环境不佳

json - 无法使用JSON Serde在Hive上上传JSON文件

mysql - Hive Metastore 的 JDBC URL 设置与 mysql