Uive UDF - Generi c UDF для всех типов примитивов - PullRequest
2 голосов
/ 13 апреля 2020

Я пытаюсь реализовать UDF Hive с параметром , поэтому я расширяю класс 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 .had oop .hive.serde2.objectinspector. primitive.JavaIntObjectInspector нельзя преобразовать в org. apache .had oop .hive.serde2.objectinspector.primitive.StringObjectInspector

1 Ответ

0 голосов
/ 27 апреля 2020

Я бы предложил вам заменить 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);

Это просто псевдокод, как примеры. Надеюсь, это поможет.

...