Първо си помислих, че това може да е грешка в 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