sql >> Databasteknik >  >> RDS >> PostgreSQL

Index på tidsstämpel:Funktioner i indexuttryck måste vara märkta som IMUTABLE

Först tänkte jag att det här kan vara en bugg i CREATE INDEX logik. Men poängen är att casten från text till timestamptz i sig är inte IMMUTABLE antingen. Det beror på flyktiga inställningar som datestyle .

I just ditt fall finns det en lösning som är ännu bättre än vad du försökte. Flytta rollbesättningen till 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;

Lika effektivt, men nu CREATE INDEX kommer inte barf:

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

Självklart måste du justera dina funktionsanrop därefter:släpp casten ::timestamptz från uttrycket. Se till att du använder samma inställningar överallt , eller så kan indexet leda till falska resultat.

Ännu bättre

Använd ett faktiskt oföränderligt uttryck med to_timestamp() istället för casten (om ditt inmatningsmönster tillåter 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;

Notera dock (citerar ett felmeddelande från mitt test):

"TZ"/"tz"/"OF" formatmönster stöds inte i to_date




  1. Gruppera WHERE-satser i Codeigniter

  2. Skrivoptimeringar för Qualcomm Centriq 2400 i MariaDB 10.3.5 Release Candidate

  3. Hur man ändrar en användare till Superuser i PostgreSQL

  4. SQL Server SHOWPLAN_ALL