Per prima cosa ho pensato che questo potesse essere un bug in CREATE INDEX
logica. Ma il punto è che il cast di text
a timestamptz
di per sé non è IMMUTABLE
o. Dipende da impostazioni volatili come datestyle
.
Nel tuo caso particolare c'è una soluzione alternativa che è persino migliore di quella che hai provato. Sposta il cast nella funzione:
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;
Altrettanto efficiente, ma ora CREATE INDEX
non vomita:
CREATE INDEX bar ON foo(to_text(j->>'start_time'));
Ovviamente, devi regolare le tue chiamate di funzione di conseguenza:elimina il cast ::timestamptz
dall'espressione. Assicurati di utilizzare le stesse impostazioni ovunque o l'indice potrebbe portare a risultati falsi.
Meglio ancora
Usa un'espressione effettivamente immutabile con to_timestamp()
invece del cast (se il tuo modello di input lo consente):
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;
Nota tuttavia (citando un messaggio di errore dal mio test):
I modelli di formato "TZ"/"tz"/"OF" non sono supportati in to_date