PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Index sur l'horodatage :les fonctions dans l'expression d'index doivent être marquées comme IMMUTABLE

J'ai d'abord pensé que cela pourrait être un bogue dans le CREATE INDEX logique. Mais le fait est que le casting de text à timestamptz lui-même n'est pas IMMUTABLE Soit. Cela dépend de paramètres volatils comme datestyle .

Dans votre cas particulier, il existe une solution de contournement encore meilleure que celle que vous avez essayée. Déplacez le cast dans la fonction :

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;

Tout aussi efficace, mais maintenant CREATE INDEX ne vomira pas :

CREATE INDEX bar ON foo(to_text(j->>'start_time'));

Évidemment, vous devez ajuster vos appels de fonction en conséquence :supprimez le cast ::timestamptz de l'expression. Assurez-vous d'utiliser les mêmes paramètres partout , ou l'index peut conduire à de faux résultats.

Mieux encore

Utilisez une expression réellement immuable avec to_timestamp() au lieu de la distribution (si votre modèle d'entrée le permet) :

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;

Notez cependant (citant un message d'erreur de mon test) :

Les modèles de format "TZ"/"tz"/"OF" ne sont pas pris en charge dans to_date