hive使用udf函数时,insert select 和直接select出来结果不一致


//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.sm.hive;

import com.sm.util.Sm4Util;
import java.nio.charset.StandardCharsets;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
import org.apache.hadoop.io.Text;

public class Sm4EncryptUDF extends GenericUDF {
    private static final Log log = LogFactory.getLog(Sm4EncryptUDF.class.getName());
    private transient StringObjectInspector oi = null;

    public Sm4EncryptUDF() {
    }

    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        this.oi = (StringObjectInspector)arguments[0];
        if (arguments.length != 2) {
            throw new UDFArgumentLengthException("函数参数格式不正确!");
        } else {
            return PrimitiveObjectInspectorFactory.writableStringObjectInspector;
        }
    }

    public Object evaluate(GenericUDF.DeferredObject[] arguments) throws HiveException {
        log.info(String.format("入参1:%s,入参2:%s", arguments[0].get().toString(), arguments[1].get().toString()));
        Object dataArgument = arguments[0].get();
        if (dataArgument != null) {
            Text t = this.oi.getPrimitiveWritableObject(arguments[0].get());
            byte[] bytes = t.getBytes();
            String utfStr = new String(bytes, StandardCharsets.UTF_8);
            log.info(String.format("原始入参转UTF8后值:%s", utfStr));
            String sm4KeyArgument = arguments[1].get().toString();
            if (StringUtils.isBlank(sm4KeyArgument)) {
                throw new UDFArgumentTypeException(1, "函数参数二格式或长度不正确!");
            } else {
                String encrypt = Sm4Util.encrypt(utfStr, sm4KeyArgument);
                log.info(String.format("加密后密文数据:%s", encrypt));
                Text text = new Text(encrypt.getBytes(StandardCharsets.UTF_8));
                log.info(String.format("加密后密文数据:%s", new String(text.getBytes(), StandardCharsets.UTF_8)));
                return text;
            }
        } else {
            return "";
        }
    }

    public String getDisplayString(String[] strings) {
        return strings[0] + strings[1];
    }
}

使用上面代码进行udf函数注册,在hive实际使用过程中发现select出来的加密后的中文值,和直接insert select出来的值不一致,

根据您提供的代码和描述,出现结果不一致的原因可能是以下几个方面:

字符集编码问题:在您的UDF函数中,涉及到字符串的编码和解码操作。确保在不同步骤中使用相同的字符集编码,以免引起数据丢失或乱码。请检查以下代码段:
java
byte[] bytes = t.getBytes();
String utfStr = new String(bytes, StandardCharsets.UTF_8);
确认该代码与插入语句或查询语句中的字符集编码一致。

数据处理一致性:在UDF函数中,可能对输入数据进行了某些处理(如加密)。确保在插入和选择数据时,使用相同的方法和参数来处理数据。检查以下代码段:
java
String encrypt = Sm4Util.encrypt(utfStr, sm4KeyArgument);
确认加密方法Sm4Util.encrypt()在插入和选择数据时的调用方式和参数是一致的。

字段类型转换:如果输入数据的字段类型有变化,例如从字符串到二进制,或者从二进制到字符串,那么在插入和选择数据时需要正确处理类型转换。确保在插入和选择数据时,将数据转换为正确的类型。

数据源问题:如果使用不同的数据源进行插入和选择数据操作,例如在插入数据时使用了不同的库或表,可能会导致结果不一致。请确保在相同的数据源中进行插入和选择操作。

同时,请确保在使用UDF函数时,注册和加载该函数的过程正确无误,以及在查询或插入语句中正确引用了UDF函数。

如果您排除了上述问题仍然存在结果不一致的情况,可能需要进一步检查代码逻辑、调试日志、输入数据和输出结果,以确定具体原因。