Capítulo 33. O sistema de regras

Sumário
33.1. A árvore de comando
33.2. As visões e o sistema de regras
33.2.1. Como as regras do SELECT funcionam
33.2.2. Regras de visão em instruções não-SELECT
33.2.3. O poder das visões no PostgreSQL
33.2.4. Atualização de visão
33.3. Regras para INSERT, UPDATE e DELETE
33.3.1. Como as regras de atualização funcionam
33.3.2. Cooperação com visões
33.4. Regras e privilégios
33.5. Regras e status dos comandos
33.6. Regras versus gatilhos

Este capítulo discute o sistema de regras do PostgreSQL. Os sistemas de regras de produção são conceitualmente simples, mas existem vários pontos delicados envolvidos na utilização destes sistemas.

Alguns outros sistemas de banco de dados definem regras de banco de dados ativas, que geralmente são procedimentos armazenados e gatilhos. No PostgreSQL estas regras podem ser implementadas utilizando funções e gatilhos também.

O sistema de regras (falando mais precisamente, o sistema de regras de reescrita de comandos) é totalmente diferente de procedimentos armazenados e gatilhos. O sistema de regras modifica o comando para levar as regras em consideração, e depois passa o comando modificado para o planejador de comandos para planejamento e execução. É muito poderoso, e pode ser utilizado para muitas finalidades como procedimentos de linguagem de comando, visões e versões. Os fundamentos teóricos e o poder deste sistema de regras estão discutidos também em On Rules, Procedures, Caching and Views in Database Systems e A Unified Framework for Version Modeling Using Production Rules in a Database System.

33.1. A árvore de comando

Para entender como o sistema de regras funciona, é necessário saber quando é chamado e quais são suas entradas e resultados.

O sistema de regras fica localizado entre o analisador e o planejador. Recebe a saída do analisador, uma árvore de comando, e as regras de reescrita definidas pelo usuário, que também são árvores de comando com algumas informações adicionais, e cria zero ou mais árvores de comando como resultado. Portanto, sua entrada e saída são sempre alguma coisa que poderia ter sido produzida pelo próprio analisador e, portanto, qualquer coisa que o sistema de regras enxerga é basicamente representável como uma instrução SQL.

Agora, o que é uma árvore de comando? É a representação interna da instrução SQL, onde as partes elementares com as quais a instrução é construída são armazenadas separadamente. As árvores de comando podem ser mostradas no log do servidor, se forem definidos os parâmetros de configuração debug_print_parse, debug_print_rewritten ou debug_print_plan. As ações da regra também são armazenadas como árvores de comando no catálogo do sistema pg_rewrite. Não são formatadas como a saída do log, mas contêm exatamente a mesma informação.

Ler a árvore de comando diretamente requer alguma experiência. Mas uma vez que as representações SQL das árvores do comando são suficientes para compreender o sistema de regras, este capítulo não ensina como ler estas árvores.

Para ler as representações SQL das árvores de comando presentes neste capitulo, é necessário ser capaz de identificar as partes em que a instrução fica dividida quando está na estrutura da árvore de comando. As partes da árvore de comando são:

o tipo do comando

Este é um valor simples, informando qual comando (SELECT, INSERT, UPDATE, DELETE) produziu a árvore de comando.

a tabela de abrangência

A tabela de abrangência é a lista de relações utilizadas no comando. Em uma instrução SELECT são as relações presentes após a palavra chave FROM.

Toda entrada na tabela de abrangência identifica uma tabela ou visão, e informa por qual nome esta é chamada nas outras partes do comando. Na árvore de comando as entradas na tabela de abrangência são referenciadas por número em vez de por nome, portanto não importa se há nomes duplicados, como seria o caso em uma instrução SQL. Isto pode acontecer após as tabelas de abrangência das regras serem mescladas. Nos exemplos deste capítulo esta situação não ocorre.

a relação do resultado

Este valor é um índice para a tabela de abrangência que identifica a relação para onde os resultados do comando vão.

Os comandos SELECT normalmente não possuem uma relação do resultado. O caso especial do SELECT INTO é praticamente idêntico ao comando CREATE TABLE seguido pelo comando INSERT ... SELECT, não sendo discutido separadamente aqui.

Para os comandos INSERT, UPDATE e DELETE, a relação do resultado é a tabela (ou visão!) onde as alterações vão ocorrer.

a lista de destino

a lista de destino é uma lista de expressões que definem o resultado do comando. No caso do SELECT, estas expressões são aquelas que constroem a saída final da consulta. Correspondem às expressões entre as palavras chave SELECT e FROM (* é apenas uma abreviatura de todos os nomes de coluna da relação. É expandido pelo analisador em colunas individuais e, portanto, o sistema de regras nunca o vê).

Os comandos DELETE não necessitam de uma lista de destino, porque não produzem nenhum resultado. Na verdade, o planejador adiciona a entrada especial CTID à lista de destino vazia, mas isto é após o sistema de regras e será discutido posteriormente; para o sistema de regras, a lista de destino é vazia.

Para os comandos INSERT, a lista de destino descreve as novas linhas que devem ir para a relação do resultado. Consiste das expressões na cláusula VALUES, ou das que vêm da cláusula SELECT em INSERT ... SELECT. O primeiro passo do processo de reescrita adiciona entradas na lista de destino para todas as colunas que não receberam atribuições pelo comando original, mas têm valor padrão. Todas as colunas restantes (sem valor atribuído nem valor padrão) são preenchidas pelo planejador com uma expressão nula constante.

Para os comandos UPDATE, a lista de destino descreve as novas linhas que substituirão as antigas. No sistema de regras, contém apenas as expressões da parte SET coluna = expressão do comando. O planejador trata as colunas que faltam inserindo expressões que copiam os valores da linha antiga para a linha nova. Também adiciona a entrada especial CTID, da mesma maneira que para o DELETE.

Toda entrada na lista de destino contém uma expressão que pode ser um valor constante, uma variável apontando para uma coluna de uma das relações da tabela de abrangência, um parâmetro ou uma árvore de expressão feita de chamadas a função, constantes, variáveis, operadores, etc.

a qualificação

A qualificação do comando é uma expressão muito parecida com as contidas nas entradas da lista de destino. O valor do resultado desta expressão é um valor booleano que informa se a operação (INSERT, UPDATE, DELETE ou SELECT) para a linha do resultado final deve ser executada ou não. Corresponde a cláusula WHERE de uma instrução SQL.

a árvore de junção

A árvore de junção do comando mostra a estrutura da cláusula FROM. Para uma consulta simples, como SELECT ... FROM a, b, c, a árvore de junção é apenas uma lista de itens do FROM, porque é permitido fazer a junção em qualquer ordem, mas quando são utilizadas expressões JOIN, em particular as junções externas, é necessário fazer a junção na ordem mostrada pelas expressões JOIN. Neste caso, a árvore de junção mostra a estrutura das expressões JOIN. As restrições associadas a uma determinadas cláusula JOIN (das expressões ON ou USING) são armazenadas como expressões de qualificação anexadas a estes nodos de árvore de junção. Também torna-se conveniente armazenar a expressão WHERE de nível mais alto como uma qualificação anexada ao item de nível mais alto da árvore de junção. Portanto, na realidade a árvore de junção representa as cláusulas FROM e WHERE do SELECT.

as outras

As outras partes da árvore de comando, como a cláusula ORDER BY, não são de interesse aqui. O sistema de regras substitui algumas entradas nestas partes ao aplicar as regras, mas isto não tem muito a ver com os fundamentos do sistema de regras.

SourceForge.net Logo CSS válido!