此查询失败,出现神秘的计算错误:
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)));
到目前为止,我还没有需要添加任何自定义自定义自定义项的,所以如果有一个解决办法,这我想保持这种方式。
1条答案
按热度按时间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 ...