web-dev-qa-db-ja.com

to_charがIMMUTABLEにならないのはなぜですか、どうすれば回避できますか?

列のto_char()にインデックスを付けるにはどうすればよいですか?

私が試してみました:

_adam_db=> CREATE INDEX updates_hourly_idx 
          ON updates (to_char(update_time, 'YYYY-MM-DD HH24:00'));
_

しかし、エラーが発生しました:

エラー:インデックス式の関数はIMMUTABLEとマークする必要があります

タイムスタンプのto_char()は不変であるため、これは奇妙に思われます。

そのインデックスを生成する方法はありますか?

6
Adam Matan

to_char(timestamp, text)が受け入れる形式には、不変にしないローカライズされたパターンが含まれます。

同じ入力での異なる結果の例:

 test => BEGIN; 
 test => set lc_time = 'en_US.utf8'; 
 test => select to_char(now():: timestamp、 'TMDay'); 
 to_char 
 --------- 
月曜日
 
 test => set lc_time TO 'fr_FR.utf8'; 
 test => select to_char(now():: timestamp、 'TMDay'); 
 to_char 
 --------- 
ランディ
 
 test => END; 

この種類の形式を使用しない場合の解決策は、独自の不変のラッパー関数を作成することです。

CREATE FUNCTION custom_to_char(timestamp) RETURNS text AS
$$ select to_char($1, 'YYYY-MM-DD HH24:00'); $$
LANGUAGE sql immutable;

次に、その関数にインデックスを作成します。

6
Daniel Vérité

this forum post -EXTRACT(timestamp with time zone)は不変ではありませんが、EXTRACT(timestamp)is。したがって、CREATE INDEX ON table (EXTRACT(MONTH FROM timestamp AT TIME ZONE 'UTC'))を使用してテーブルを作成することができます。

2
Gaurav