提问人:fields1631 提问时间:3/24/2021 更新时间:4/10/2021 访问量:1540
Apache Drill UDF:未找到与函数签名匹配的函数签名
Apache Drill UDF: No match found for function signature
问:
嗨,我正在开发钻头用户定义的函数。我写了这个 UDF。
package somepackage.udfs;
import io.netty.buffer.DrillBuf;
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
import org.apache.drill.exec.expr.annotations.Output;
import org.apache.drill.exec.expr.annotations.Param;
import org.apache.drill.exec.expr.holders.Float8Holder;
import org.apache.drill.exec.expr.holders.NullableVarCharHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
import javax.inject.Inject;
@FunctionTemplate(
name = "split_sample",
scope = FunctionTemplate.FunctionScope.SIMPLE,
nulls = FunctionTemplate.NullHandling.NULL_IF_NULL
)
public class SplitTrainTestSample implements DrillSimpleFunc {
@Param
NullableVarCharHolder targetIn;
@Param(constant = true)
Float8Holder train_test_rate;
@Output
VarCharHolder label;
@Inject
DrillBuf buffer;
public SplitTrainTestSample() {
}
@Override
public void setup() {
}
@Override
public void eval() {
double r = Math.random();
String l;
assert 0 < train_test_rate.value && train_test_rate.value < 1;
if (r < train_test_rate.value) {
l = "train";
}
else {
l = "test";
}
byte[] bytes = l.getBytes();
label.buffer = buffer;
label.start = 0;
label.end = bytes.length;
label.buffer.setBytes(0, bytes);
}
}
但是当我运行此查询时
Apache Drill> select split_sample(cast(full_name as char), 0.5) from cp.`employee.json`;
Drill 返回错误消息。
Error: VALIDATION ERROR: From line 1, column 8 to line 1, column 49: No match found for function signature split_sample(<CHARACTER>, <NUMERIC>)
请帮我找出问题所在。我在同一个包下编写了另一个 UDF,它运行良好。因此,这不太可能是 UDF 注册表错误。
有没有一种方法可以探测 UDF 的函数签名?
答:
0赞
cgivre
4/9/2021
#1
Drill UDF 确实很难调试。
我怀疑在这种情况下的问题是:
double r = Math.random();
请尝试将其替换为:
double r = java.lang.Math.random();
如果这不起作用,您可能想尝试使用简单的语句而不是 .另外,我从未见过 UDF 参数。if
assert
(constant = true)
通常,除了 Drill 内部类之外,几乎所有外部类都必须写出其完整路径。除了钻取内部结构外,不能将任何内容导入到 UDF 中。UDF 实际上使用了 Java 的一个子集,结果是知道哪些是支持的,哪些是不支持的,可能有点棘手。
令人讨厌的是,Drill 没有为您提供任何有用的调试信息。它只是说它找不到 UDF。
当这种情况发生在我身上时,我要做的是注释掉整个 UDF 正文,在取消注释每行后运行该函数以查看哪一行导致了问题。
一个简单的解决方法是创建一个具有静态函数的帮助程序类。
public class functionHelpers {
public String getLabel(<params>) {
// Your code here...
}
}
// Then in your UDF exec() method
...
String label = com.my_package.functionHelpers.getLabel(<params>);
...
如果您有复杂的 UDF,这将使生活变得更加轻松。还可以更轻松地调试代码,因为您可以轻松地为帮助程序类编写单元测试,然后使用预制代码将输出映射到 Drill 向量。
上一个:如何替代通用匿名函数?
评论