sql >> Database >  >> RDS >> PostgreSQL

Index op tijdstempel:functies in indexexpressie moeten worden gemarkeerd als IMMUTABLE

Eerst dacht ik dat dit een fout zou kunnen zijn in de CREATE INDEX logica. Maar het punt is dat de cast van text naar timestamptz zelf is niet IMMUTABLE een van beide. Het hangt af van vluchtige instellingen zoals datestyle .

In jouw specifieke geval is er een oplossing die zelfs beter is dan wat je hebt geprobeerd. Verplaats de cast naar de functie:

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;

Net zo efficiënt, maar nu CREATE INDEX zal niet barfen:

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

Uiteraard moet je je functie-aanroepen dienovereenkomstig aanpassen:drop de cast ::timestamptz uit de uitdrukking. Zorg ervoor dat u overal dezelfde instellingen gebruikt , of de index kan leiden tot verkeerde resultaten.

Beter nog

Gebruik een feitelijk onveranderlijke uitdrukking met to_timestamp() in plaats van de cast (als uw invoerpatroon dit toelaat):

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;

Merk echter op (een foutmelding uit mijn test citerend):

"TZ"/"tz"/"OF" formaatpatronen worden niet ondersteund in to_date




  1. Android Room - Hoe de automatisch gegenereerde primaire sleutel van de tabel opnieuw in te stellen bij elke app-run

  2. 4 functies om het jaar terug te geven vanaf een datum in MariaDB

  3. Wat zijn de beperkingen van MS Access?

  4. SQLite - Gegevens bijwerken