Hive UDF:Hive 没有向 UDF 发送正确的参数

Posted

技术标签:

【中文标题】Hive UDF:Hive 没有向 UDF 发送正确的参数【英文标题】:Hive UDF : Hive does not send proper arguments to UDF 【发布时间】:2020-06-27 16:16:33 【问题描述】:

这是我的蜂巢桌

CREATE TABLE `dum`(`val` map<string,array<string>>);
insert into dum select map('A',array('1','2','3'),'B',array('4','5','6'));

这是它的外观

select * from dum;
"A":["1","2","3"],"B":["4","5","6"]

我正在尝试创建一个简单的 UDF,它可以将上述映射值中的所有项目组合成一个列表。这是我想看到的

select modudf(val) from dum;
["1","2","3","4","5","6"]

所以我创造了

package some.package;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.udf.UDFType;
import java.util.ArrayList;

import java.util.List;
import java.util.Map;

@UDFType(deterministic = true)
public class CustomUDF extends UDF 

public List<String> evaluate(Map<String, String[]> inMap) 

            ArrayList<String> res = new ArrayList<String>();
                for(Map.Entry<String, String[]> ent : inMap.entrySet())
                    for(String item : ent.getValue())
                        res.add(item);
            
        return res;
   

但是当我尝试调用它时

add jar /path/to/my/jar;
CREATE TEMPORARY FUNCTION modudf AS 'some.package.CustomUDF';
select modudf(val) from dum;

我明白了

FAILED: SemanticException [Error 10014]: Line 1:7 Wrong arguments 'val': No matching method for class some.package.CustomUDF with (map<string,array<string>>). Possible choices: _FUNC_(map<struct<>,struct<>>)

为什么 hive 认为我的 UDF 需要 map&lt;struct&lt;&gt;,struct&lt;&gt;&gt; 而不是 map&lt;string,array&lt;string&gt;&gt; ?我什至尝试用 Charsequence 替换 String 但我得到了同样的错误

请注意,根据文档

https://hive.apache.org/javadocs/r1.2.2/api/org/apache/hadoop/hive/ql/exec/UDF.html

我应该能够使用集合作为evaluate 方法的输入

我做错了什么?

更新

我也试过下面的定义

public List<CharSequence> evaluate(Map<CharSequence, List<CharSequence>> inMap) 

        modLogger.info(inMap);
            ArrayList<CharSequence> res = new ArrayList<CharSequence>();
                for(Map.Entry<CharSequence, List<CharSequence>> ent : inMap.entrySet())
                    for(CharSequence item : ent.getValue())
                        res.add(item);
            
        return res;
   

但我还是得到了

hive> add jar /path/to/my/jar;
Added [/path/to/my/jar] to class path
Added resources: [/path/to/my/jar]
hive> CREATE TEMPORARY FUNCTION modudf AS 'some.package.CustomUDF';
hive> desc dum;
OK
val                     map<string,array<string>>
Time taken: 0.094 seconds, Fetched: 1 row(s)
hive> select val from dum;
Query ID = root_20200629170147_80b5248f-4519-4dae-a070-3c5185f742ea
Total jobs = 1
Launching Job 1 out of 1
Status: Running (Executing on YARN cluster with App id application_1593449512239_0001)

----------------------------------------------------------------------------------------------
        VERTICES      MODE        STATUS  TOTAL  COMPLETED  RUNNING  PENDING  FAILED  KILLED
----------------------------------------------------------------------------------------------
Map 1 .......... container     SUCCEEDED      1          1        0        0       0       0
----------------------------------------------------------------------------------------------
VERTICES: 01/01  [==========================>>] 100%  ELAPSED TIME: 6.12 s
----------------------------------------------------------------------------------------------
OK
"A":["1","2","3"],"B":["4","5","6"]
Time taken: 10.631 seconds, Fetched: 1 row(s)
hive> select modudf(val) from dum;
FAILED: SemanticException [Error 10014]: Line 1:7 Wrong arguments 'val': No matching method for class com.walmart.labs.search.sib.gcp.ModularTransformUDF with (map<string,array<string>>). Possible choices: _FUNC_(map<struct<>,array<struct<>>>)

【问题讨论】:

【参考方案1】:

查看来自the link you've sent的引用:

请注意,Hive 数组在 Hive 中表示为列表。因此,ARRAY 列将作为 List 传入。

所以你应该有evaluate(Map&lt;String, List&lt;String&gt;&gt; inMap) 签名而不是evaluate(Map&lt;String, String[]&gt; inMap)

【讨论】:

感谢您的建议。请查看更新。我仍然得到同样的错误 您是否尝试过拥有这个签名:public List&lt;String&gt; evaluate(Map&lt;String, List&lt;String&gt;&gt; inMap)?因为将String 更改为CharSequence 对我来说毫无意义 嘿,成功了!由于其他一些代码依赖性,我使用了 Charsequence,但我不必这样做。非常感谢

以上是关于Hive UDF:Hive 没有向 UDF 发送正确的参数的主要内容,如果未能解决你的问题,请参考以下文章

Hive 自动增量 UDF 没有给出想要的结果

如何写hive的udf函数

在 hive 中注册 python 自定义 UDF

hive之udf函数的使用

Hive中如何添加自定义UDF函数以及oozie中使用hive的自定义函数

hive自定义UDF函数,步骤详解