Първо си помислих, че това може да е грешка в CREATE INDEX логика. Но въпросът е, че предаването от text до timestamptz сам по себе си не е IMMUTABLE или. Зависи от нестабилни настройки като datestyle .
Във вашия конкретен случай има решение, което е дори по-добро от това, което сте опитали. Преместете cast във функцията:
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;
Също толкова ефективно, но сега CREATE INDEX няма да бухне:
CREATE INDEX bar ON foo(to_text(j->>'start_time'));
Очевидно трябва да коригирате повикванията на функциите си съответно:пуснете cast ::timestamptz от израза. Уверете се, че навсякъде използвате едни и същи настройки , или индексът може да доведе до фалшиви резултати.
Още по-добре
Използвайте действително неизменяем израз с to_timestamp() вместо cast (ако вашият модел на въвеждане го позволява):
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; Забележете обаче (цитирайки съобщение за грешка от моя тест):
Шаблоните на формат "TZ"/"tz"/"OF" не се поддържат в to_date