PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Индекс на клеймото за време:Функциите в индексния израз трябва да бъдат маркирани като НЕИЗМЕНЯЕМИ

Първо си помислих, че това може да е грешка в CREATE INDEX логика. Но въпросът е, че предаването от text до timestamptz сам по себе си не е IMMUTABLE или. Зависи от нестабилни настройки като datestyle .

Във вашия конкретен случай има решение, което е дори по-добро от това, което сте опитали. Преместете cast във функцията:

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;

Също толкова ефективно, но сега CREATE INDEX няма да бухне:

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

Очевидно трябва да коригирате повикванията на функциите си съответно:пуснете cast ::timestamptz от израза. Уверете се, че навсякъде използвате едни и същи настройки , или индексът може да доведе до фалшиви резултати.

Още по-добре

Използвайте действително неизменяем израз с to_timestamp() вместо cast (ако вашият модел на въвеждане го позволява):

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;

Забележете обаче (цитирайки съобщение за грешка от моя тест):

Шаблоните на формат "TZ"/"tz"/"OF" не се поддържат в 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. Поправете „ГРЕШКА:всяка заявка INTERSECT трябва да има същия брой колони“ в PostgreSQL

  2. Как да променя стила на дата в PostgreSQL?

  3. Разбиране на JDBC пакетни операции

  4. Разлика между език sql и език plpgsql във функциите на PostgreSQL

  5. Многоредова вложка с pg-promise