sql >> Databáze >  >> RDS >> PostgreSQL

Index on Timestamp:Funkce ve výrazu indexu musí být označeny jako IMMUTABLE

Nejprve jsem si myslel, že by to mohla být chyba v CREATE INDEX logika. Jde ale o to, že obsazení z text na timestamptz sám o sobě není IMMUTABLE buď. Závisí to na nestálých nastaveních, jako je datestyle .

Ve vašem konkrétním případě existuje řešení, které je ještě lepší než to, co jste zkoušeli. Přesuňte obsazení do funkce:

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;

Stejně efektivní, ale nyní CREATE INDEX nebude vykřikovat:

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

Je zřejmé, že musíte odpovídajícím způsobem upravit volání funkcí:zahoďte obsazení ::timestamptz z výrazu. Ujistěte se, že všude používáte stejná nastavení nebo index může vést k falešným výsledkům.

Ještě lépe

Pomocí to_timestamp() použijte skutečně neměnný výraz místo přetypování (pokud to váš vstupní vzor umožňuje):

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;

Všimněte si však (cituji chybovou zprávu z mého testu):

Vzory formátu "TZ"/"tz"/"OF" nejsou v to_date

podporovány



  1. ListAGG v SQLSERVER

  2. Jak používat SUBSTRING() v MySQL

  3. Jak používat Coalesce v MySQL

  4. jak nahradit písmeno s diakritikou ve sloupci varchar2 v oracle