2017-11-21 25 views
0

내 알고리즘은 정상적으로 작동하지만 새로운 큰 데이터베이스를 사용하면 내 정수 변수가 최대 제한 크기를 초과합니다. (나는 powerset 알고리즘을 사용한다 : https://www.postgresql.org/message-id/20060924054759.GA71934%40winnie.fuhr.org)Postgresql ERROR : 연산자가 존재하지 않습니다. bigint << bigint

그래서 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

,536,913 63,210

답변

1

비트 시프트 연산자의 오른쪽 피연산자의 유형은 불행하게도, 이것은 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 

the documentation.

당신은 시프트 연산자의 오른쪽 피연산자를 캐스팅해야 언급되지 integer. 당신은 가능한 유형을 확인할 수있다 시스템 카탈로그를 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,integer 또는 bigint을 할 수 있습니다 오른쪽 피연산자는 integer.

+0

감사해야합니다! int2shl, int4shl, int8shl의 차이점은 무엇입니까? 그래서 모든 알고리즘을 수행해야합니까? 각 비교 연산자는 함수에서 변경해야합니까? –

+0

업데이트 된 답변보기 – klin