Najpierw pomyślałem, że może to być błąd w CREATE INDEX
logika. Ale chodzi o to, że rzut z text
do timestamptz
samo w sobie nie jest IMMUTABLE
zarówno. To zależy od zmiennych ustawień, takich jak datestyle
.
W twoim konkretnym przypadku istnieje obejście, które jest nawet lepsze niż to, które wypróbowałeś. Przenieś rzut do funkcji:
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;
Równie wydajny, ale teraz CREATE INDEX
nie będzie rzygać:
CREATE INDEX bar ON foo(to_text(j->>'start_time'));
Oczywiście, musisz odpowiednio dostosować wywołania funkcji:odrzuć rzut ::timestamptz
z wyrażenia. Upewnij się, że używasz tych samych ustawień wszędzie lub indeks może prowadzić do fałszywych wyników.
Jeszcze lepiej
Użyj faktycznie niezmiennego wyrażenia z to_timestamp()
zamiast rzutowania (jeśli pozwala na to Twój wzorzec wprowadzania):
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;
Uwaga jednak (cytując komunikat o błędzie z mojego testu):
Wzorce formatu "TZ"/"tz"/"OF" nie są obsługiwane w to_date