복붙노트

[SQL] ERROR : 인덱스 식의 기능은 포스트 그레스 불변 표시해야

SQL

ERROR : 인덱스 식의 기능은 포스트 그레스 불변 표시해야

나는 여러 열로 표현 인덱스를 만들려면,하지만 인덱스를 만들 때 다음과 같은 메시지가 출력됩니다 :

--detail message 
wapgrowth=> create index CONCURRENTLY idx_test on  tmp_table using btree (skyid, to_char(create_time, 'YYYY-MM-DD'), actiontype );
ERROR:  functions in index expression must be marked IMMUTABLE


--table ddl
wapgrowth=> \d tmp_table
               Table "wapgrowth.tmp_table"
   Column    |            Type             |   Modifiers   
-------------+-----------------------------+---------------
 id          | integer                     | not null
 actiontype  | character varying(20)       | 
 apptype     | character varying(20)       | 
 score       | integer                     | 
 create_time | timestamp without time zone | default now()
 skyid       | integer                     | 
Indexes:

해결법

  1. ==============================

    1.해커 메일 링리스트에서이 스레드에 따르면 :

    해커 메일 링리스트에서이 스레드에 따르면 :

    http://www.mail-archive.com/pgsql-hackers@postgresql.org/msg86725.html

    TO_CHAR로이 의도 동작은 LC_MESSAGES 설정에 따라 달라집니다

    귀하의 경우에는이 분명히 색인의 텍스트 표현을 사용할 필요 할 경우 그래서, 당신은 () 함수를 자신의 TO_CHAR를 만들 수 있습니다, 당신은 로케일에 의존하지 않습니다 사용하는 형식으로 이해하고로 표시하지 않습니다 불변 :

    CREATE OR REPLACE FUNCTION my_to_char(some_time timestamp) 
      RETURNS text
    AS
    $BODY$
        select to_char($1, 'yyyy-mm-dd');
    $BODY$
    LANGUAGE sql
    IMMUTABLE;
    

    당신은 색인의 텍스트로 사용 할 (와 샘이 제안 날짜로 캐스트를 사용할 수 없습니다) 당신은 당신이 불변으로 표시 할 수있는 자신 만의 포맷 함수를 작성해야됩니다. 그 다음 인덱스에 사용할 수 있습니다.

    그러나 포스트 그레스 당신뿐만 아니라 당신의 SQL 문에서 () my_to_char를 호출 할 필요가 인덱스를 사용하도록합니다. 당신이 내장 된 TO_CHAR를 사용할 때) (그것을 인식하지 않습니다

    하지만 인덱스에 직선 날짜를 사용하여 샘의 제안은 아마 더 나은 생각하십니까

  2. ==============================

    2.이것은 더 상세히 설명한다 :

    이것은 더 상세히 설명한다 :

    https://www.postgresql.org/message-id/CAKFQuwbcMfesmNkm19mXFLXP14sP5BiPsR1GSkY1suKiM1rukg%40mail.gmail.com

    기본적으로 시간대는 서버에 따라, 누군가가 그것을 변경하는 경우, 따라서 그 결과는 변경 될 수 있습니다. 하지만 당신은 시간대를 잠글 경우 :

    날짜 (시간대 ( 'UTC', CREATE_TIME)

    그것은 작동합니다.

  3. ==============================

    3.변환이 해당 지역의 시간대 설정에 의존하기 때문에 시간 소인없이-시간대의 TO_CHAR는, 불변의 함수가 아닙니다. 그 수단은 인덱스가 다른 시간대의 다른 휴대용 컴퓨터 않을 것이며, 포스트 그레스를 허용하지 않을 것이다. 난 당신이 시간대와 시간으로 CREATE_TIME을 선언하는 경우 문제가 사라질 것이라 생각합니다.

    변환이 해당 지역의 시간대 설정에 의존하기 때문에 시간 소인없이-시간대의 TO_CHAR는, 불변의 함수가 아닙니다. 그 수단은 인덱스가 다른 시간대의 다른 휴대용 컴퓨터 않을 것이며, 포스트 그레스를 허용하지 않을 것이다. 난 당신이 시간대와 시간으로 CREATE_TIME을 선언하는 경우 문제가 사라질 것이라 생각합니다.

  4. ==============================

    4.대신 YYYY-MM-DD로 타임 스탬프 형식을 TO_CHAR를 사용하는 같은 효과를 가질 것이다 날짜 유형에 타임 스탬프를 캐스팅하려고 :

    대신 YYYY-MM-DD로 타임 스탬프 형식을 TO_CHAR를 사용하는 같은 효과를 가질 것이다 날짜 유형에 타임 스탬프를 캐스팅하려고 :

    create index CONCURRENTLY idx_test on  tmp_table using btree (skyid, cast(create_time as date), actiontype );
    
  5. ==============================

    5.당신이 인덱스에 CREATE_TIME의 "YYYY-MM-DD"표현을 시도하고 같은 하루의 끝에서 그것은 본다. 왜 그냥 INDEX의 CREATE_TIME? 문제는 로케일 환경 변수가 변경 될 수 있기 때문에 (하기) TO_CHAR의 출력을 변경하는 변경 가능한 TO_CHAR ()이다.

    당신이 인덱스에 CREATE_TIME의 "YYYY-MM-DD"표현을 시도하고 같은 하루의 끝에서 그것은 본다. 왜 그냥 INDEX의 CREATE_TIME? 문제는 로케일 환경 변수가 변경 될 수 있기 때문에 (하기) TO_CHAR의 출력을 변경하는 변경 가능한 TO_CHAR ()이다.

    http://www.postgresql.org/docs/current/static/charset.html

    스키마를 제어 할 경우, 새 열 (예를 들어, create_date의 TEXT) 및 INDEX 그 다음 설정 트리거가 핸들 인서트를 추가 할 수 있습니다. 텍스트에 TIME ZONE없이 TIMESTAMP로 변환하는 방법을 만든 경우 사실, 당신은 INDEX 수 일정한 방식으로 그. a_horse_with_no_name의 제안은 당신이 로케일에 대해 신경 생각하지 않기 때문에 좋은 하나였다.

    당신이에 실행중인 문제는 그러므로 당신은 그 데이터 유형에 쉽게 INDEX 기능에 의존 할 수없는 불변없는 순종은 로케일 모든 날짜 및 시간 처리 코드입니다.

  6. from https://stackoverflow.com/questions/5973030/error-functions-in-index-expression-must-be-marked-immutable-in-postgres by cc-by-sa and MIT license