Ce chapitre discute du système de règles dans PostgreSQL™. les systèmes de règles de production sont simples conceptuellement mais il existe de nombreux points subtils impliqués dans leur utilisation.
Certains autres systèmes de bases de données définissent des règles actives pour la base de données, conservées habituellement en tant que procédures stockées et déclencheurs. Avec PostgreSQL™, elles peuvent aussi être implémentées en utilisant des fonctions et des déclencheurs.
Le système de règles (plus précisément, le système de règles de réécriture de requêtes) est totalement différent des procédures stockées et des déclencheurs. Il modifie les requêtes pour prendre en considération les règles puis passe la requête modifiée au planificateur de requêtes pour planification et exécution. Il est très puissant et peut être utilisé pour beaucoup de choses comme des procédures en langage de requêtes, des vues et des versions. Les fondations théoriques et la puissance de ce système de règles sont aussi discutées dans On Rules, Procedures, Caching and Views in Database Systems et A Unified Framework for Version Modeling Using Production Rules in a Database System.
Pour comprendre comment fonctionne le système de règles, il est nécessaire de comprendre quand il est appelé et quelles sont ses entrées et sorties.
Le système de règles est situé entre l'analyseur et le planificateur. Il prend la sortie de l'analyseur, un arbre de requête et les règles de réécriture définies par l'utilisateur qui sont aussi des arbres de requêtes avec quelques informations supplémentaires, et crée zéro ou plusieurs arbres de requêtes comme résultat. Donc, son entrée et sortie sont toujours des éléments que l'analyseur lui-même pourrait avoir produit et, du coup, tout ce qu'il voit est représentable basiquement comme une instruction SQL.
Maintenant, qu'est-ce qu'un arbre de requêtes ? C'est une représentation interne d'une instruction SQL où les parties qui le forment sont stockées séparément. Ces arbres de requêtes sont affichables dans le journal de traces du serveur si vous avez configuré les paramètres debug_print_parse, debug_print_rewritten, ou debug_print_plan. les actions de règles sont aussi enregistrées comme arbres de requêtes dans le catalogue système pg_rewrite. elles ne sont pas formatées comme la sortie de traces mais elles contiennent exactement la même information.
Lire un arbre de requête brut requiert un peu d'expérience. Mais comme les représentations SQL des arbres de requêtes sont suffisantes pour comprendre le système de règles, ce chapitre ne vous apprendra pas à les lire.
Lors de la lecture des représentations SQL des arbres de requêtes dans ce chapitre, il est nécessaire d'être capable d'identifier les morceaux cassés de l'instruction lorsqu'ils sont dans la structure de l'arbre de requête. Les parties d'un arbre de requêtes sont
C'est une simple valeur indiquant quelle commande (select, insert, update, delete) l'arbre de requêtes produira.
La table d'échelle est une liste des relations utilisées dans la requête. Dans une instruction select, ce sont les relations données après le mot clé from.
Chaque entrée de la table d'échelle identifie une table ou une vue et indique par quel nom elle est désignée dans les autres parties de la requête. Dans l'arbre de requêtes, les entrées de la table d'échelle sont référencées par des numéros plutôt que par des noms. Il importe donc peu, ici, de savoir s'il y a des noms dupliqués comme cela peut être le cas avec une instruction SQL. Cela peut arriver après l'assemblage des tables d'échelle des règles. Les exemples de ce chapitre ne sont pas confrontés à cette situation.
C'est un index dans la table d'échelle qui identifie la relation où iront les résultats de la requête.
Les requêtes select n'ont pas de relation résultat. Le cas spécial d'un select into est pratiquement identique à un create table suivi par un insert ... select et n'est pas discuté séparément ici.
Pour les commandes insert, update et delete, la relation de résultat est la table (ou vue !) où les changements prennent effet.
La liste cible est une liste d'expressions définissant le résultat d'une requête. Dans le cas d'un select, ces expressions sont celles qui construisent la sortie finale de la requête. Ils correspondent aux expressions entre les mots clés select et from (* est seulement une abréviation pour tous les noms de colonnes d'une relation. Il est étendu par l'analyseur en colonnes individuelles, pour que le système de règles ne le voit jamais).
Les commandes delete n'ont pas besoin d'une liste normale de colonnes car elles ne produisent aucun résultat. En fait, le système de règles ajoutera une entrée spéciale ctid pour aller jusqu'à la liste de cibles vide pour permettre à l'exécuteur de trouver la ligne à supprimer. (CTID est ajouté quand la relation résultante est une table ordinaire. S'il s'agit d'une vue, une variable de type ligne est ajoutée à la place, comme décrit dans Section 40.2.4, « Mise à jour d'une vue ».)
Pour les commandes insert, la liste cible décrit les nouvelles lignes devant aller dans la relation résultat. Elle consiste en des expressions de la clause values ou en celles de la clause select dans insert ... SELECT. la première étape du processus de réécriture ajoute les entrées de la liste cible pour les colonnes n'ont affectées par la commande originale mais ayant des valeurs par défaut. Toute colonne restante (avec soit une valeur donnée soit une valeur par défaut) sera remplie par le planificateur avec une expression NULL constante.
Pour les commandes update, la liste cible décrit les nouvelles lignes remplaçant les anciennes. Dans le système des règles, elle contient seulement les expressions de la partie set colonne = expression de la commande. le planificateur gèrera les colonnes manquantes en insérant des expressions qui copient les valeurs provenant de l'ancienne ligne dans la nouvelle. Comme pour DELETE, le système de règles ajoute un CTID ou une variable de type ligne pour que l'exécuteur puisse identifier l'ancienne ligne à mettre à jour.
Chaque entrée de la liste cible contient une expression qui peut être une valeur constante, une variable pointant vers une colonne d'une des relations de la table d'échelle, un paramètre ou un arbre d'expressions réalisé à partir d'appels de fonctions, de constantes, de variables, d'opérateurs, etc.
La qualification de la requête est une expression ressemblant à une de celles contenues dans les entrées de la liste cible. La valeur résultant de cette expression est un booléen indiquant si l'opération (insert, update, delete ou select) pour la ligne de résultat final devrait être exécutée ou non. Elle correspond à la clause where d'une instruction SQL.
L'arbre de jointure de la requête affiche la structure de la clause from. pour une simple requête comme select ... from a, b, c, l'arbre de jointure est une simple liste d'éléments de from parce que nous sommes autorisés à les joindre dans tout ordre. Mais quand des expressions join, et plus particulièrement les jointures externes, sont utilisées, nous devons les joindre dans l'ordre affiché par les jointures. Dans ce cas, l'arbre de jointure affiche la structure des expressions join. les restrictions associées avec ces clauses join particulières (à partir d'expressions on ou using) sont enregistrées comme des expressions de qualification attachées aux nœuds de l'arbre de jointure. Il s'avère agréable d'enregistrer l'expression de haut niveau where comme une qualification attachée à l'élément de l'arbre de jointure de haut niveau. Donc, réellement, l'arbre de jointure représente à la fois les clauses from et where d'un select.
Les autres parties de l'arbre de requête comme la clause order BY n'ont pas d'intérêt ici. le système de règles substitue quelques entrées lors de l'application des règles mais ceci n'a pas grand chose à voir avec les fondamentaux du système de règles.