为什么这个配置单元ql表达式失败了?

ryoqjall  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(529)

此查询失败,出现神秘的计算错误:

select printf("%08x", reflect('java.lang.Integer', 'reverseBytes', mhash3('123', 0)));

(以下是例外)

Failed with exception java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: Error evaluating printf('%08x', reflect('java.lang.Integer','reverseBytes',1))

我试图实现的是一致地再现一个使用hasher的murru3hash十六进制值的java实现 getBytes 方法,该方法以大端格式返回它们(十进制数字以小端格式写入),因此字节交换为整数。
分别执行查询的每一部分都能完美地工作,它混合了printf和reflect what fails。。。只有当格式是数字类型时,这才有效:

select printf("%s", reflect('java.lang.Integer', 'reverseBytes', mhash3('123', 0)));

但这也失败了

select printf("%d", reflect('java.lang.Integer', 'reverseBytes', mhash3('123', 0)));

我确保结果是数字类型而不是字符串,因为我可以对它进行算术运算,比如:

select printf("%s", 10 * reflect('java.lang.Integer', 'reverseBytes', mhash3('123', 0)));

到目前为止,我还没有需要添加任何自定义自定义自定义项的,所以如果有一个解决办法,这我想保持这种方式。

rekjcdws

rekjcdws1#

hive基本上是一个java程序,它将类似sql的数据类型和表达式转换为java数据类型和java/hadoop表达式/作业。
在大多数情况下都很复杂。但是如果你在混合中加入一个定制的java表达式——那就是 reflect() 都是关于——那么你很可能会陷入边缘案件。
在你的特定问题上,静态 java.lang.Integer.reverseBytes(int) 应该返回一个基元类型 int 价值观。但我不确定配置单元如何在内部处理通用整数值——可能是使用 long ? 可能是自定义对象类型??
不管怎样,返回值似乎不能直接输入到hive中 printf() 函数作为数字类型。也许是 int 被投给 String 默认情况下。。。也许它会和一个 long 相反。。。
我看到两种可能的解决方法:
结束通话 reflect() 在子查询中,使配置单元隐式转换为配置单元支持的类型(子查询在编译时合并,不需要额外的mr步骤),这样配置单元类型仍有可能
String select printf("%d", WTF) from (select reflect(.....) as WTF from ...) DUH 需要显式转换为您选择的配置单元数字类型 select printf("%d", cast(reflect(.......) as int)) from ...

相关问题