PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Indeks na sygnaturze czasowej:funkcje w wyrażeniu indeksu muszą być oznaczone jako IMMUTABLE

Najpierw pomyślałem, że może to być błąd w CREATE INDEX logika. Ale chodzi o to, że rzut z text do timestamptz samo w sobie nie jest IMMUTABLE zarówno. To zależy od zmiennych ustawień, takich jak datestyle .

W twoim konkretnym przypadku istnieje obejście, które jest nawet lepsze niż to, które wypróbowałeś. Przenieś rzut do funkcji:

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;

Równie wydajny, ale teraz CREATE INDEX nie będzie rzygać:

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

Oczywiście, musisz odpowiednio dostosować wywołania funkcji:odrzuć rzut ::timestamptz z wyrażenia. Upewnij się, że używasz tych samych ustawień wszędzie lub indeks może prowadzić do fałszywych wyników.

Jeszcze lepiej

Użyj faktycznie niezmiennego wyrażenia z to_timestamp() zamiast rzutowania (jeśli pozwala na to Twój wzorzec wprowadzania):

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;

Uwaga jednak (cytując komunikat o błędzie z mojego testu):

Wzorce formatu "TZ"/"tz"/"OF" nie są obsługiwane w to_date




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Uruchom plik PostgreSQL .sql za pomocą argumentów wiersza poleceń

  2. WYBIERZ lub WSTAW wiersz w jednym poleceniu

  3. Skalowanie PostgreSQL za pomocą puli połączeń i równoważenia obciążenia

  4. uWSGI, Flask, sqlalchemy i postgres:błąd SSL:odszyfrowanie nie powiodło się lub zły rekord mac

  5. Wyświetlaj tabele w schemacie PostgreSQL