Мы написали функцию get_timestamp()
, определенную как
CREATE OR REPLACE FUNCTION get_timestamp()
RETURNS integer AS
$$
SELECT (FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 10) - 13885344000)::int;
$$
LANGUAGE SQL;
Это использовалось для INSERT и UPDATE для ввода или редактирования значения в созданном и измененном поле в записи базы данных. Однако при добавлении или обновлении записей мы обнаружили, что оно возвращало одно и то же значение.
При проверке функции в pgAdmin III мы отметили, что при запуске SQL для построения функции ключевое слово IMMUTABLE было введено после оператора SQL ЯЗЫК. В документации указано, что значением по умолчанию является VOLATILE (Если ни одно из них не появляется, VOLATILE является предположением по умолчанию), поэтому я не уверен, почему IMTUTABLE был введен, однако изменение этого параметра на STABLE решило проблему повторяющихся значений.
ПРИМЕЧАНИЕ. Как указано в принятом ответе, IMMUTABLE никогда не добавляется к функции через pgAdmin или Postgres и должен быть добавлен во время разработки.
Я предполагаю, что происходит то, что эта функция была оценена, и результат был кэширован для оптимизации, поскольку он был помечен IMMUTABLE, указывающий движку Postgres, что возвращаемое значение не должно изменяться с учетом того же (пустого) списка параметров, Однако, когда он не используется в триггере, когда он используется непосредственно в инструкции INSERT, функция возвращает четное значение FIVE раз, а затем возвращает то же самое значение с этого момента. Это связано с некоторым алгоритмом оптимизации, который говорит что-то вроде "Если функция IMMUTABLE используется более 5 раз в сеансе, кешируйте результат для будущих вызовов"?
Любые разъяснения относительно того, как эти ключевые слова должны использоваться в функциях Postgres, будут оценены. Является ли STABLE правильным вариантом для нас, учитывая, что мы используем эту функцию в триггерах, или есть что-то большее, чтобы рассмотреть, например, документы говорят:
(Неправильно для триггеров AFTER, которые хотят запрашивать строки измененный текущей командой.)
Но я не совсем понимаю, почему.