I want to create an index on my table for start_time, a timestamptz (timestamp with time zone) field in my json column called match.
Following this
First I thought this might be bug in the CREATE INDEX
logic. But the point is that the cast from text
to timestamptz
itself isn't IMMUTABLE
either. It depends on volatile settings like datestyle.
In your particular case there is a workaround that's even better than what you tried. Move the cast into the function:
CREATE OR REPLACE FUNCTION to_text(text)
RETURNS text AS
$func$
SELECT to_char($1::timestamptz AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US')
$func$ LANGUAGE sql IMMUTABLE;
Just as efficient, but now CREATE INDEX
won't barf:
CREATE INDEX bar ON foo(to_text(j->>'start_time'));
Obviously, you have to adjust your function calls accordingly: drop the cast ::timestamptz
from the expression. Make sure that you use the same settings everywhere, or the index might lead to false results.
Use an actually immutable expression with to_timestamp() instead of the cast (if your input pattern allows it):
CREATE OR REPLACE FUNCTION to_text(text)
RETURNS text AS
$func$
SELECT to_char(to_timestamp($1, 'YYYY-MM-DD"T"HH24:MI:SS.US') -- adapt to your pattern
AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US')
$func$ LANGUAGE sql IMMUTABLE;
Note however (quoting an error message from my test):
"TZ"/"tz"/"OF" format patterns are not supported in to_date