sql >> Base de Datos >  >> RDS >> PostgreSQL

Índice en la marca de tiempo:las funciones en la expresión de índice deben marcarse como INMUTABLE

Primero pensé que esto podría ser un error en CREATE INDEX lógica. Pero el punto es que el elenco de text a timestamptz en sí mismo no es IMMUTABLE o. Depende de configuraciones volátiles como datestyle .

En su caso particular, hay una solución que es incluso mejor que la que intentó. Mueve el elenco a la función:

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;

Igual de eficiente, pero ahora CREATE INDEX no vomitará:

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

Obviamente, debe ajustar sus llamadas de función en consecuencia:suelte el cast ::timestamptz de la expresión. Asegúrese de utilizar la misma configuración en todas partes , o el índice podría conducir a resultados falsos.

Mejor aún

Use una expresión realmente inmutable con to_timestamp() en lugar del molde (si su patrón de entrada lo permite):

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;

Sin embargo, tenga en cuenta (citando un mensaje de error de mi prueba):

Los patrones de formato "TZ"/"tz"/"OF" no se admiten en to_date