A documentação do PostgreSQL declara:
Qualquer função com efeitos colaterais deve ser rotulada como VOLÁTIL...
Considere a seguinte função:
CREATE OR REPLACE FUNCTION count_items()
RETURNS integer AS
$BODY$
DECLARE
v_result INTEGER DEFAULT 0;
BEGIN
SELECT
count( t.id )
INTO
v_result
FROM
some_table t;
RETURN v_result;
EXCEPTION
WHEN OTHERS THEN
PERFORM error_log_insert( SQLSTATE, SQLERRM, current_query() );
RETURN 0;
END;
$BODY$
LANGUAGE plpgsql STABLE
COST 10;
Como error_log_insert
altera o banco de dados (executa uma inserção em uma exceção), isso significa que a count_items
função tem um efeito colateral (embora indireto) e, portanto, não pode ser declarada STABLE
, mas deve ser VOLATILE
?
Em outras palavras, a estabilidade ou volatilidade de uma função também depende das funções que ela chama dentro de seu bloco de exceção ?
Se for esse o caso, como você criaria STABLE
funções no PostgreSQL que registram todas as exceções em uma tabela de banco de dados?
A leitura da documentação está em ordem. Isso vem de alguém que apenas se interessa e nunca usou Postgres e encontrou a resposta no primeiro link do google:
http://www.postgresql.org/docs/current/static/xfunc-volatility.html
Você pode querer colocar ênfase particular nessa parte do estábulo:
Portanto, o problema é - você deseja que as chamadas para o método sejam registradas. Mas as otimizações de uma função estável farão com que a função não seja executada todas as vezes (porque o valor de retorno para os mesmos parâmetros é conhecido e, portanto, é reutilizado), portanto, o log não será completo.
DITO ISSO:
Como você deseja apenas registrar exceções, pode estar tudo bem - isso também manterá seu log menor, pois você obtém apenas uma instância em uma consulta, mesmo quando a função SERIA chamada 100 milhões de vezes, desde que o otimizador a otimize. Portanto, no seu caso - de registro de exceção - pode estar tudo bem. Você terá que testar se os desenvolvedores postgres estão colocando proteção contra manipulações de banco de dados, mas minha aposta é não, e eu presumo que você se safa disso.
No caso de circunstâncias puramente matemáticas, entendo que a premissa de uma função
f
chamando umavolatile
funçãog
indicaria que isso tambémf
é inerentevolatile
. Isso ocorre porque funções em matemática são equivalências projetadas para reduzir o trabalho de explicar sistemas e uma (função ou expressão) pode ser substituída pela outra, geralmente como açúcar sintático mais do que qualquer outra coisa.No entanto, minha resposta não é especificamente do contexto do postgres, pois normalmente não trabalho no PG. Pode ser razoável em PG que a
f
função sejastable
par enquanto ag
função forvolatile
.Eu encorajaria todo desenvolvedor a examinar seu código como sendo basicamente apenas matemática exposta e, portanto, encorajaria você a considerar o código aqui como
volatile
.