CREATE RULE — define uma nova regra de reescrita
CREATE [ OR REPLACE ] RULEnomeAS ONeventoTOnome_da_tabela[ WHEREcondição] DO [ ALSO | INSTEAD ] { NOTHING |comando| (comando;comando... ) } ondeeventopode ser um entre: SELECT | INSERT | UPDATE | DELETE
O comando CREATE RULE define uma nova regra
a ser aplicada à tabela ou visão especificada.
O comando CREATE OR REPLACE RULE irá criar uma
nova regra, ou substituir uma regra existente com o mesmo nome para
a mesma tabela.
O sistema de regras do PostgreSQL permite
definir uma ação alternativa a ser executada nas inserções,
atualizações ou exclusões nas tabelas do banco de dados.
Grosso modo, uma regra faz com que comandos adicionais sejam
executados quando um determinado comando em uma determinada tabela
é executado.
Como alternativa, uma regra INSTEAD pode
substituir um dado comando por outro, ou fazer com que um comando
não seja executado.
As regras também são usadas para implementar visões
SQL.
É importante perceber que uma regra é realmente um mecanismo de
transformação de comando, ou macro de comando.
A transformação acontece antes do início da execução do comando.
Se for realmente desejado que uma operação seja disparada de forma
independente para cada linha física, provavelmente se desejará
usar um gatilho, e não uma regra.
Mais informações sobre o sistema de regras são encontradas no
O Sistema de regras.
No momento, as regras ON SELECT só podem ser
anexadas a visões.
Esta regra deve se chamar
"_RETURN", deve ser uma
regra incondicional INSTEAD, e deve ter uma ação
que consiste em um único comando SELECT.
Este comando define o conteúdo visível da visão.
(A própria visão é basicamente uma tabela fictícia sem nenhum
espaço de armazenamento.)
É melhor considerar esta regra como um detalhe de implementação.
Embora uma visão possa ser redefinida por meio de
CREATE OR REPLACE RULE "_RETURN" AS ...,
é um estilo melhor usar CREATE OR REPLACE VIEW.
Pode-se criar a ilusão de uma visão atualizável definindo regras
ON INSERT, ON UPDATE, e
ON DELETE (ou qualquer subconjunto destas que
seja suficiente para atingir os objetivos desejados) para substituir
ações de atualização na visão por atualizações apropriadas em
outras tabelas.
Se for desejado dar suporte a INSERT RETURNING,
e assim por diante, então será necessário colocar uma cláusula
RETURNING adequada em cada uma dessas regras.
Há uma pegadinha se for tentado usar regras condicionais para
atualizações de visões complexas: deverá haver
uma regra INSTEAD incondicional para cada ação
que se deseja permitir na visão.
Se a regra for condicional, ou não for INSTEAD,
então o sistema ainda irá rejeitar as tentativas de executar a ação
de atualização, porque acha que poderá acabar tentando executar a
ação na tabela fictícia da visão em alguns casos.
Se for desejado lidar com todos os casos úteis usando regras
condicionais, deverá ser adicionada uma regra
DO INSTEAD NOTHING incondicional, para garantir
que o sistema entenda que nunca será chamado para atualizar a tabela
fictícia.
Em seguida, as regras condicionais devem ser tornadas
não-INSTEAD; nos casos em que são aplicadas,
elas adicionam ação ao padrão INSTEAD NOTHING.
(Entretanto, no momento este método não funciona para dar suporte
a consultas com RETURNING.)
Uma visão que é simples o suficiente para ser automaticamente atualizável (veja CREATE VIEW) não requer uma regra criada pelo usuário para ser atualizável. Embora se possa criar uma regra explícita de qualquer maneira, a transformação de atualização automática geralmente supera uma regra explícita.
Outra alternativa que vale a pena considerar é o uso de gatilhos
INSTEAD OF
(veja CREATE TRIGGER) no lugar de regras.
nomeO nome da regra a ser criada. Deve ser diferente do nome de qualquer outra regra para a mesma tabela. Quando existem várias regras na mesma tabela e no mesmo tipo de evento, estas são aplicadas em ordem alfabética de nomes.
evento
O evento é um entre SELECT,
INSERT, UPDATE, ou
DELETE.
Note que não pode ser usado um comando INSERT
contendo a cláusula ON CONFLICT em tabelas que
possuem regras para INSERT ou
UPDATE.
Deve-se considerar o uso de uma visão atualizável.
nome_da_tabelaO nome (opcionalmente qualificado pelo esquema) da tabela ou visão à qual a regra se aplica.
condição
Qualquer expressão condicional SQL
(retornando boolean).
A expressão de condição não pode se referir a nenhuma tabela,
exceto NEW e OLD, e não
pode conter funções de agregação.
INSTEAD
INSTEAD indica que os comandos devem ser
executados ao invés do comando original.
ALSO
ALSO indica que os comandos devem ser
executados em adição ao comando original.
Se não for especificado nem ALSO, nem
INSTEAD, ALSO será o padrão.
comando
O comando ou comandos que compõem a ação da regra.
Os comandos válidos são SELECT,
INSERT, UPDATE,
DELETE, ou NOTIFY.
Dentro da condição e do
comando, podem ser
usados os nomes de tabelas especiais NEW e
OLD para se referir a valores na tabela
referenciada.
NEW é válido nas regras ON INSERT
e ON UPDATE para se referir à nova linha que está
sendo inserida ou atualizada.
OLD é válido nas regras ON UPDATE
e ON DELETE para se referir à linha existente que
está sendo atualizada ou excluída.
É necessário ser o dono da tabela para criar ou alterar regras para ela.
Em uma regra para INSERT, UPDATE,
ou DELETE em uma visão, pode-se adicionar a
cláusula RETURNING para retornar as colunas da visão.
Esta cláusula será usada para computar as saídas se a regra for
acionada por um comando INSERT RETURNING,
UPDATE RETURNING, ou
DELETE RETURNING, respectivamente.
Quando a regra é acionada por um comando sem
RETURNING, a cláusula RETURNING
da regra será ignorada.
A implementação corrente permite que apenas as regras
INSTEAD incondicionais contenham
RETURNING; além disso, pode haver no máximo uma
cláusula RETURNING entre todas as regras para
o mesmo evento.
(Isto garante que haja apenas uma cláusula RETURNING
candidata a ser usada para computar os resultados.)
As consultas à visão com a cláusula RETURNING
serão rejeitadas se não houver uma cláusula RETURNING
disponível em nenhuma regra.
É muito importante tomar cuidado para evitar regras circulares.
Por exemplo, embora cada uma das duas definições de regra a seguir
sejam aceitas pelo PostgreSQL, o comando
SELECT faria com que o
PostgreSQL relatasse um erro devido à
expansão recursiva da regra:
CREATE RULE "_RETURN" AS
ON SELECT TO t1
DO INSTEAD
SELECT * FROM t2;
CREATE RULE "_RETURN" AS
ON SELECT TO t2
DO INSTEAD
SELECT * FROM t1;
SELECT * FROM t1;
No momento, se uma ação de regra contiver o comando
NOTIFY, o comando NOTIFY será
executado incondicionalmente, ou seja, o NOTIFY
será emitido mesmo se não houver linhas às quais a regra deva ser
aplicada.
Por exemplo, em
CREATE RULE me_notifique
AS ON UPDATE TO minha_tabela
DO ALSO NOTIFY minha_tabela;
UPDATE minha_tabela SET name = 'foo' WHERE id = 42;
um evento NOTIFY será emitido durante o
UPDATE, haja ou não alguma linha que corresponda
à condição id = 42.
Esta é uma restrição de implementação que poderá ser corrigida em
versões futuras.
O comando CREATE RULE é uma extensão do
PostgreSQL à linguagem
SQL, assim como todo o sistema de reescrita de
consultas também é.