Documentação do PostgreSQL 8.0.0 | ||||
---|---|---|---|---|
Anterior | Início | Capítulo 31. Estendendo a linguagem SQL | Fim | Próxima |
Toda função é classificada quanto à sua volatilidade, sendo que as possibilidades são VOLATILE (volátil), STABLE (estável) e IMMUTABLE (imutável). Quando o comando CREATE FUNCTION não especifica a categoria, o padrão é VOLATILE. A categorização quanto à volatilidade é uma promessa feita ao otimizador sobre o comportamento da função: [1]
Uma função VOLATILE pode fazer qualquer coisa, inclusive modificar o banco de dados. Pode retornar resultados diferentes em chamadas sucessivas usando os mesmos argumentos. O otimizador não assume nada com relação ao comportamento destas funções. Um comando que utiliza uma função volátil reavalia a função em todas as linhas onde seu valor seja necessário.
Uma função STABLE não pode modificar o banco de dados, e há garantia do retorno dos mesmos resultados quando a função recebe os mesmos parâmetros em todas as chamadas dentro de um mesmo comando envolvente. Esta categoria permite que o otimizador otimize o caso de várias chamadas à função dentro de um mesmo comando. Em particular, é seguro utilizar uma expressão contendo uma função deste tipo em uma condição de varredura de índice (Como a varredura de índice determina o valor a ser comparado somente uma vez, e não uma vez para cada linha, não é válido utilizar uma função VOLATILE em uma condição de varredura de índice).
Uma função IMMUTABLE não pode modificar o banco de dados, e há garantia do retorno dos mesmos resultados quando esta recebe os mesmos argumentos. Esta categoria de função permite ao otimizador pré-avaliar a função quando o comando chama a função com argumentos constantes. Por exemplo, uma consulta do tipo SELECT ... WHERE x = 2 + 2 pode ser transformada imediatamente em SELECT ... WHERE x = 4, porque a função subjacente ao operador de adição inteira está marcada como IMMUTABLE.
Para obter os melhores resultados de otimização, deve-se classificar a função na categoria de volatilidade que for mais rigorosa para a mesma.
Toda função com efeitos colaterais deve ser categorizada como VOLATILE, para que as chamadas às mesmas não sejam otimizadas. Mesmo as funções sem efeitos colaterais precisam ser classificadas como VOLATILE, se o valor retornado puder mudar dentro de um mesmo comando; alguns exemplos são random(), currval() e timeofday().
Existe pouca diferença entre as categorias STABLE e IMMUTABLE, quando se considera comandos interativos simples que são planejados e executados imediatamente: não faz muita diferença se a função é executada durante o planejamento ou durante o início da execução do comando, mas existe muita diferença quando o plano é salvo para reutilização posterior. Classificar a função como IMMUTABLE, quando na verdade esta não é, pode fazer com que a mesma seja transformada prematuramente em uma constante durante o planejamento, resultando na utilização de um valor desatualizado durante as próximas utilizações do plano. Isto é um risco associado ao uso de declarações preparadas e ao uso de funções escritas em linguagens que colocam planos no cache (como o PL/pgSQL).
Devido ao comportamento de instantâneo do MVCC (consulte o Capítulo 12), uma função contendo apenas comandos SELECT pode ser classificada como STABLE com segurança, mesmo que faça seleção em tabelas que podem estar sendo modificadas por comandos simultâneos. O PostgreSQL executa a função STABLE utilizando o instantâneo estabelecido para o comando que faz a chamada e, portanto, será enxergada uma visão fixa do banco de dados durante o comando. Deve ser observado, também, que a família de funções current_timestamp é classificada como estável, uma vez que seus resultados não mudam dentro de uma transação.
O mesmo comportamento de instantâneo é utilizado nos comandos SELECT dentro das funções IMMUTABLE. Geralmente não se aconselha fazer seleções em tabelas do banco de dados dentro de uma função IMMUTABLE, uma vez que a imutabilidade será quebrada se o conteúdo da tabela mudar. Entretanto, o PostgreSQL não exige que seja assim.
Um erro comum é classificar a função como IMMUTABLE quando seu resultado depende de parâmetros de configuração. Por exemplo, uma função que manipula carimbos do tempo pode ter resultados dependentes da definição de timezone. Por motivo de segurança, estas funções devem ser classificadas como STABLE.
Nota: Antes da versão 8.0 do PostgreSQL, o requisito que as funções STABLE e IMMUTABLE não podem modificar o banco de dados não era requerido pelo sistema. A versão 8.0 obriga obedecer este requisito, requerendo que as funções SQL, e as funções escritas em linguagem procedural, destas categorias, não contenham nenhum comando SQL além do SELECT (Isto não é um teste totalmente seguro, uma vez que estas funções podem chamar funções VOLATILE que modificam o banco de dados. Se isto for feito, vai ser descoberto que as funções STABLE e IMMUTABLE não percebem as mudanças feitas no banco de dados aplicadas pela função chamada).
[1] |
SQL Server 2005 — As funções determinísticas sempre retornam o mesmo resultado quando são chamadas com um conjunto específico de valores de entrada, e mantido o mesmo estado do banco de dados. As funções não determinísticas podem retornar resultados diferentes cada vez que são chamadas com um conjunto específico de valores de entrada, mesmo que o estado do banco de dados acessado permaneça o mesmo. Existem várias propriedades das funções definidas pelo usuário que determinam a capacidade do Mecanismo de Banco de Dados do SQL Server indexar os resultados da função, seja através de índices nas colunas computadas que chamam a função, ou através de visões indexadas que fazem referência à função. O determinismo da função é uma destas propriedades. Server 2005 Books Online — Deterministic and Nondeterministic Functions (N. do T.) |