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, l'optimiseur
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, par le système de
règles, comme décrit dans
Section 40.2.4.)
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
, un CTID ou une variable
de type ligne est ajouté 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.