Why isn't to_char IMMUTABLE, and how can I work around it?
The formats accepted by to_char(timestamp, text)
include localized patterns that make it not immutable.
Example of different results with the same input:
test=> BEGIN; test=> set lc_time='en_US.utf8'; test=> select to_char(now()::timestamp, 'TMDay'); to_char --------- Monday test=> set lc_time TO 'fr_FR.utf8'; test=> select to_char(now()::timestamp, 'TMDay'); to_char --------- Lundi test=> END;
If not using this kind of format, the solution is to create your own immutable wrapper function,
CREATE FUNCTION custom_to_char(timestamp) RETURNS text AS
$$ select to_char($1, 'YYYY-MM-DD HH24:00'); $$
LANGUAGE sql immutable;
and then create the index on that function.
I just found another solution to this problem based on this forum post -- EXTRACT(timestamp with time zone)
isn't immutable, but EXTRACT(timestamp)
is. So it is possible to create a table with CREATE INDEX ON table (EXTRACT(MONTH FROM timestamp AT TIME ZONE 'UTC'))
.