如何在 AWS Athena/Presto 中实现 Hive 的按位左移?

How to do implement Hive's Bitwise Left Shift in AWS Athena/Presto?

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

更多上下文:

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

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

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

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

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

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

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

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

这是我要 "translate" 给 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 ,然后使用函数 from_base.
  2. 转换回它的 BIG INT 表示形式
  3. 如果数字不大于MAX BIGINT(9223372036854775807),那么乘以2,相当于左移1位。

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

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

我的解决方案是将 EMR 与 AWS 目录一起使用,并使用 Hive SQL 对相同表进行 运行 查询,它使用 shift_left 实现了按位左移。