PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Índice no carimbo de data/hora:as funções na expressão de índice devem ser marcadas como IMMUTABLE


Primeiro eu pensei que isso poderia ser um bug no CREATE INDEX lógica. Mas o ponto é que o elenco de text para timestamptz em si não é IMMUTABLE ou. Depende de configurações voláteis como datestyle .

No seu caso particular, existe uma solução alternativa que é ainda melhor do que a que você tentou. Mova o cast para a função:
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;

Tão eficiente, mas agora CREATE INDEX não vai vomitar:
CREATE INDEX bar ON foo(to_text(j->>'start_time'));

Obviamente, você precisa ajustar suas chamadas de função de acordo:solte o cast ::timestamptz da expressão. Certifique-se de usar as mesmas configurações em todos os lugares , ou o índice pode levar a resultados falsos.

Melhor ainda


Use uma expressão realmente imutável com to_timestamp() em vez do cast (se o seu padrão de entrada permitir):
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;

Observe no entanto (citando uma mensagem de erro do meu teste):

Os padrões de formato "TZ"/"tz"/"OF" não são suportados em to_date