sql >> Database teknologi >  >> RDS >> PostgreSQL

Indeks på tidsstempel:Funktioner i indeksudtryk skal være markeret som IMUTABLE

Først tænkte jeg, at dette kunne være en fejl i CREATE INDEX logik. Men pointen er, at castet fra text til timestamptz i sig selv er ikke IMMUTABLE enten. Det afhænger af flygtige indstillinger såsom datestyle .

I dit særlige tilfælde er der en løsning, der er endnu bedre end det, du prøvede. Flyt rollebesætningen ind i funktionen:

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;

Lige så effektivt, men nu CREATE INDEX vil ikke barf:

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

Du skal naturligvis justere dine funktionskald i overensstemmelse hermed:slip castet ::timestamptz fra udtrykket. Sørg for, at du bruger de samme indstillinger overalt , ellers kan indekset føre til falske resultater.

Bedre endnu

Brug et faktisk uforanderligt udtryk med to_timestamp() i stedet for castet (hvis dit inputmønster tillader det):

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;

Bemærk dog (der citerer en fejlmeddelelse fra min test):

"TZ"/"tz"/"OF" formatmønstre understøttes ikke i to_date




  1. Sådan vælger du Top N rækker pr. gruppe i MySQL

  2. Sådan gemmer du UTF8-tegn i MySQL

  3. Oracle .Net ManagedDataAccess Fejl:Kunne ikke indlæse typen 'OracleInternal.Common.ConfigBaseClass' fra assembly

  4. Rækkemål, del 3:Anti Joins