Nejprve jsem si myslel, že by to mohla být chyba v CREATE INDEX
logika. Jde ale o to, že obsazení z text
na timestamptz
sám o sobě není IMMUTABLE
buď. Závisí to na nestálých nastaveních, jako je datestyle
.
Ve vašem konkrétním případě existuje řešení, které je ještě lepší než to, co jste zkoušeli. Přesuňte obsazení do funkce:
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;
Stejně efektivní, ale nyní CREATE INDEX
nebude vykřikovat:
CREATE INDEX bar ON foo(to_text(j->>'start_time'));
Je zřejmé, že musíte odpovídajícím způsobem upravit volání funkcí:zahoďte obsazení ::timestamptz
z výrazu. Ujistěte se, že všude používáte stejná nastavení nebo index může vést k falešným výsledkům.
Ještě lépe
Pomocí to_timestamp()
použijte skutečně neměnný výraz místo přetypování (pokud to váš vstupní vzor umožňuje):
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;
Všimněte si však (cituji chybovou zprávu z mého testu):
Vzory formátu "TZ"/"tz"/"OF" nejsou v to_date
podporovány