Postgresql ERROR: operator does not exist: bigint << bigint

Postgresql ERROR: operator does not exist: bigint << bigint

我的算法运行良好,但是对于一个新的大数据库,我的整数变量超过了最大限制大小。 (我使用幂集算法:https://www.postgresql.org/message-id/20060924054759.GA71934%40winnie.fuhr.org

所以我决定将所有整数更改为 bigint,但现在我在比较运算符上遇到了问题...我不知道如何处理它:

CREATE OR REPLACE FUNCTION powerset(a anyarray)
  RETURNS SETOF anyarray AS
$BODY$
DECLARE
    retval  a%TYPE;
    alower  bigint := array_lower(a, 1);
    aupper  bigint := array_upper(a, 1);
    j       bigint;
    k       bigint;
BEGIN
    FOR i IN 1 .. COALESCE((CAST(1 AS BIGINT) << (aupper - alower + 1)) - 1, 0) LOOP
        retval := '{}';
        j := alower;
        k := i;

        WHILE k > CAST(0 AS BIGINT) LOOP
            IF k & CAST(1 AS BIGINT) = CAST(1 AS BIGINT) THEN
                retval := array_append(retval, a[j]);
            END IF;

            j := j + CAST(1 AS BIGINT);
            k := k >> CAST(1 AS BIGINT);
        END LOOP;

        RETURN NEXT retval;
    END LOOP;

    RETURN;
END;
$BODY$
  LANGUAGE plpgsql IMMUTABLE STRICT
  COST 100
  ROWS 1000;
ALTER FUNCTION powerset(anyarray)
  OWNER TO postgres;

我收到在线错误:

FOR i IN 1 .. COALESCE((CAST(1 AS BIGINT) << (aupper - alower + 1)) - 1, 0) LOOP

错误 42883 Postgresql 错误:运算符不存在:bigint << bigint

位移运算符右操作数的类型是integer. 遗憾的是the documentation.

中没有提到

您应该将移位运算符的右操作数转换为 integer:

-- instead of 
-- COALESCE((CAST(1 AS BIGINT) << (aupper - alower + 1)) - 1, 0)
-- use
select COALESCE(1 << (aupper - alower + 1)::int- 1, 0)::bigint

-- instead of
-- k := k >> CAST(1 AS BIGINT);
--- use
k := k >> 1;
-- etc

您可以通过查询系统目录来检查可能的操作数类型pg_operator,例如:

select oprname, oprleft::regtype, oprright::regtype
from pg_operator
where oprname = '<<'
and oprcode::text like '%shl%' -- shift left functions

 oprname | oprleft  | oprright 
---------+----------+----------
 <<      | smallint | integer
 <<      | integer  | integer
 <<      | bigint   | integer
(3 rows)    

以上结果表明运算符<<(按位左移)的左操作数可以是smallint,integerbigint,右操作数必须是integer.