【问题标题】:How to do implement Hive's Bitwise Left Shift in AWS Athena/Presto?如何在 AWS Athena/Presto 中实现 Hive 的按位左移?
【发布时间】:2019-09-24 00:29:11
【问题描述】:

我正在使用 AWS Athena 查询我的数据,我需要执行按位左移操作。如何在 Athena 中实现这一点?

更多上下文:

我正在尝试使用按位运算来跟踪事件(向左移动位,其中 1 表示我的事件发生了,0 表示它没有发生)。

所以链 11101 将从右到左读取,指示事件是否发生如下:“是,否,是,是,是',我可以构建的最大链等于BIGINT,所以我最多可以跟踪 63 天

我尝试像在 Hadoop/Hive 架构中一样使用运算符 <<,但它在 Athena 中不可用。

我看到有人要求更改,但没有实施。

https://github.com/prestodb/presto/issues/4028

我在这里阅读了有关此主题的更多信息:

What are bitwise shift (bit-shift) operators and how do they work?

所以我尝试实现我自己的非循环按位左移版本,但我不知道它是否涵盖所有边缘情况。

这是我想“翻译”给 Athena 的 Hive 代码:

SELECT my_num<<1 as bit_shifted_num 
FROM my_table

这是我的代码:

SELECT if(CAST(my_num AS BIGINT) = 9223372036854775807 OR CAST(my_num AS BIGINT)*pow(2,1) > 9223372036854775807,from_base(rpad(substr(to_base(CAST(my_num AS BIGINT),2),2,length(to_base(CAST(my_num AS BIGINT),2))-1), length(to_base(CAST(my_num AS BIGINT),2)), '1'),2),CAST(CAST(my_num AS BIGINT)*pow(2,1) AS BIGINT)) AS bit_shifted_num 
FROM my_table

我的逻辑分解是:

  1. 如果我的数字等于 9223372036854775807 或者我的数字乘以 2(左移 1 位)大于 9223372036854775807(因为 MAX BIGINT * 2 导致 NUMBER 数据类型大于 MAX BIGINT),转换之前的数字使用函数 to_base 将其转换为 STRING BIT 表示,将此 STRING 子串化,删除第一个数字(从左到右读取)并在字符串末尾插入 1,然后转换回它的 BIG INT 表示使用函数 from_base
  2. 如果数字不大于 MAX BIGINT (9223372036854775807),则只需将其乘以 2,这相当于左移 1 位。

我是否遗漏了 HIVE 的 &lt;&lt; 处理的任何案例,或者我需要什么实现以便我的函数在所有情况下都能正确处理左移?

【问题讨论】:

标签: hive bit-manipulation bit-shift amazon-athena presto


【解决方案1】:

通过 SQL 实现这个函数比我建议的要复杂得多,因为一旦达到 MAX BIG INT 值,Hive 就会为负值添加一点(加上 Presto 中的一些强制转换行为使值小于 MAX BIG INT 等于 MAX BIG INT)。

我的解决方案是使用带有 AWS 目录的 EMR,并使用 Hive SQL 在相同的表上运行查询,它使用shift_left 实现了按位左移。

【讨论】:

    猜你喜欢
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 2018-09-06
    • 2019-10-19
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多