Trino UDF插件问题:map(varchar,varchar)对应哪种Java类型?
解决Trino UDF中map(varchar,varchar)对应的Java/Scala类型问题
问题重现
用Scala开发Trino UDF插件的http_get函数,接收http地址、查询参数和请求头参数,代码如下:
@ScalarFunction(value = "http_get", deterministic = true) @Description("Returns the result of an Http Get request") @SqlType(value = StandardTypes.VARCHAR) def httpGetFromArrayMap( @SqlType(StandardTypes.VARCHAR) httpAddress: Slice, @SqlType(constants.STRING_MAP) parameters: ImmutableMap[Slice, Slice], @SqlNullable @SqlType(constants.STRING_MAP) headers: ImmutableMap[Slice, Slice], ): String = { val stringHeaders = castSliceMap(headers) val stringParams = castSliceMap(parameters) val request = Http(httpAddress.toStringUtf8).headers(stringHeaders).params(stringParams) val stringResponse = request.asString.body stringResponse }
运行Trino时抛出异常:
io.trino.spi.TrinoException: Exact implementation of http_get do not match expected java types.
核心问题与解决方案
Trino中map(varchar, varchar)对应的正确Java/Scala类型不是Guava的ImmutableMap[Slice, Slice],而是**java.util.Map[Slice, Slice]**(JDK标准Map)。
修改后的参数类型定义示例:
@ScalarFunction(value = "http_get", deterministic = true) @Description("Returns the result of an Http Get request") @SqlType(value = StandardTypes.VARCHAR) def httpGetFromArrayMap( @SqlType(StandardTypes.VARCHAR) httpAddress: Slice, @SqlType(StandardTypes.MAP) @SqlTypeParameter("keyType", StandardTypes.VARCHAR) @SqlTypeParameter("valueType", StandardTypes.VARCHAR) parameters: java.util.Map[Slice, Slice], @SqlNullable @SqlType(StandardTypes.MAP) @SqlTypeParameter("keyType", StandardTypes.VARCHAR) @SqlTypeParameter("valueType", StandardTypes.VARCHAR) headers: java.util.Map[Slice, Slice], ): String = { // 转换为Scala Map方便处理(需引入scala.jdk.CollectionConverters._) val stringParams = parameters.asScala.map { case (k, v) => k.toStringUtf8 -> v.toStringUtf8 }.toMap val stringHeaders = headers.asScala.map { case (k, v) => k.toStringUtf8 -> v.toStringUtf8 }.toMap val request = Http(httpAddress.toStringUtf8).headers(stringHeaders).params(stringParams) request.asString.body }
关键说明
- Trino UDF接收
map类型参数时,必须使用java.util.Map作为参数类型,不可用Guava的不可变Map实现。 - 需通过
@SqlTypeParameter明确指定map的key和value类型为StandardTypes.VARCHAR;如果使用预定义的STRING_MAP常量(需确保常量定义为public static final TypeSignature STRING_MAP = TypeSignature.mapType(StandardTypes.VARCHAR, StandardTypes.VARCHAR);),参数类型依然是java.util.Map[Slice, Slice],示例如下:
@SqlType(constants.STRING_MAP) parameters: java.util.Map[Slice, Slice], @SqlNullable @SqlType(constants.STRING_MAP) headers: java.util.Map[Slice, Slice]
额外注意事项
- Scala 2.13+推荐用
scala.jdk.CollectionConverters._实现Java与Scala集合的互转,旧版本可使用scala.collection.JavaConverters._。 - 若Http客户端的
headers/params方法要求Java Map,可在转换后调用.asJava转回Java集合。
内容的提问来源于stack exchange,提问作者André Claudino
相关产品推荐
相关产品推荐

