Først tænkte jeg, at dette kunne være en fejl i CREATE INDEX
logik. Men pointen er, at castet fra text
til timestamptz
i sig selv er ikke IMMUTABLE
enten. Det afhænger af flygtige indstillinger såsom datestyle
.
I dit særlige tilfælde er der en løsning, der er endnu bedre end det, du prøvede. Flyt rollebesætningen ind i funktionen:
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;
Lige så effektivt, men nu CREATE INDEX
vil ikke barf:
CREATE INDEX bar ON foo(to_text(j->>'start_time'));
Du skal naturligvis justere dine funktionskald i overensstemmelse hermed:slip castet ::timestamptz
fra udtrykket. Sørg for, at du bruger de samme indstillinger overalt , ellers kan indekset føre til falske resultater.
Bedre endnu
Brug et faktisk uforanderligt udtryk med to_timestamp()
i stedet for castet (hvis dit inputmønster tillader det):
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;
Bemærk dog (der citerer en fejlmeddelelse fra min test):
"TZ"/"tz"/"OF" formatmønstre understøttes ikke i to_date