CREATE RULE

CREATE RULE — define uma nova regra de reescrita

Sinopse

CREATE [ OR REPLACE ] RULE nome AS ON evento
    TO nome_da_tabela [ WHERE condição ]
    DO [ ALSO | INSTEAD ] { NOTHING | comando | ( comando ; comando ... ) }

onde evento pode ser um entre:

    SELECT | INSERT | UPDATE | DELETE

Descrição

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.)

Nota

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.

Parâmetros

nome

O 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_tabela

O 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.

Notas

É 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.

Conformidade

O comando CREATE RULE é uma extensão do PostgreSQL à linguagem SQL, assim como todo o sistema de reescrita de consultas também é.

Veja também

ALTER RULE, DROP RULE, pg_rules