Presto/Trino自定义UDF调用报do not match expected java types错误如何解决
报错原因
- 返回值类型不匹配:Trino中
@SqlType(StandardTypes.VARCHAR)注解对应的Java返回类型必须是io.airlift.slice.Slice,你当前方法返回Java原生String类型,Trino无法自动完成类型映射,是触发类型不匹配报错的核心原因。 - 受检异常声明不合法:Trino自定义UDF的实现方法不允许抛出非Trino内置的受检异常,你声明的
throws PrivaceraException属于自定义受检异常,会被Trino的类型校验逻辑判定为方法签名不匹配。 - 缺失返回语句:当前方法定义了返回值类型但代码中没有
return逻辑,也会导致后续运行报错。
修复方案
- 将方法返回值类型从
String改为Slice,返回结果时调用Slices.utf8Slice()将字符串转为Slice类型 - 捕获方法内部的
PrivaceraException,转换为TrinoException抛出 - 补充返回逻辑,建议用
toStringUtf8()替代Slice的toString()方法避免编码问题
修改后的代码示例:
import io.airlift.slice.Slice; import io.airlift.slice.Slices; import io.trino.spi.TrinoException; import io.trino.spi.StandardErrorCode; @ScalarFunction("do_protect") @Description("Return encrypted string") @SqlType(StandardTypes.VARCHAR) public Slice protectUDF(@SqlType(StandardTypes.VARCHAR) Slice slice1, @SqlType(StandardTypes.VARCHAR) Slice slice2) { logger.info("protectUDF get called..."); String valueForEncrypt = slice1.toStringUtf8(); logger.info("AS :: valueForEncrypt :: "+valueForEncrypt); String schemeForEncrypt = slice2.toStringUtf8(); logger.info("AS :: schemeForEncrypt :: "+schemeForEncrypt); try { // 此处补充你原本的加密逻辑,得到加密后的字符串encryptedStr String encryptedStr = "实际加密结果"; // 替换为自身业务逻辑输出 return Slices.utf8Slice(encryptedStr); } catch (PrivaceraException e) { throw new TrinoException(StandardErrorCode.USER_ERROR, "加密执行失败: " + e.getMessage(), e); } }
修改完成后重新打包注册UDF,再执行select do_protect('abc@test.com','Test_EMAIL');即可正常调用。
内容的提问来源于stack exchange,提问作者Anand Suryavanshi
相关产品推荐
相关产品推荐

