此查询失败并出现神秘的评估错误:
Failed with exception java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: Error evaluating printf('%08x', reflect('java.lang.Integer','reverseBytes',1))
(这是例外)
getBytes
我想要完成的是一致地重现murmur3哈希十六进制值的Java实现,该值使用hasher select printf("%s", reflect('java.lang.Integer', 'reverseBytes', mhash3('123', 0)));
方法,以大端格式返回它们(并且十进制数字写得很少) endian),因此字节交换整数。
分别完成查询的每个部分,它会混合printf并反映出失败的内容......只有当格式化为数字类型时,才有效:
select printf("%d", reflect('java.lang.Integer', 'reverseBytes', mhash3('123', 0)));
但这也失败了
select printf("%s", 10 * reflect('java.lang.Integer', 'reverseBytes', mhash3('123', 0)));
并且我确保结果是数字类型而不是字符串,因为我可以对它进行算术运算,例如:
{{1}}
到目前为止,我还没有添加任何自定义UDF,所以如果有解决方法,我希望保持这种方式。
答案 0 :(得分:1)
Hive基本上是一个Java程序,它将类似SQL的数据类型和表达式转换为Java数据类型和Java / Hadoop表达式/作业。
在大多数情况下,它足够复杂。但是如果你在混合中抛出一个自定义Java表达式 - 那就是reflect()
的全部内容 - 那么你可能会陷入边缘情况。
在您的特定问题中,静态java.lang.Integer.reverseBytes(int)
应返回原始类型int
值。但我不确定Hive如何在内部处理通用整数值 - 可能是long
?也许用自定义对象类型??
无论如何,看起来返回值不能直接直接作为数字类型提供给Hive printf()
函数。也许int
默认会投放到String
...也许它会与long
合作...
我看到两种可能的解决方法:
reflect()
的调用,以便Hive隐式转换为Hive支持的类型(在编译时合并的子查询,不需要额外的MR步骤) - 使用Hive类型仍然是String
select printf("%d", WTF) from (select reflect(.....) as WTF from ...) DUH
select printf("%d", cast(reflect(.......) as int)) from ...