42.6. Exécuteur
L'exécuteur prend le plan envoyé par le
planificateur/optimiseur et l'exécute récursivement pour extraire
l'ensemble requis de lignes. Il s'agit principalement d'un mécanisme
de pipeline en demande-envoi. Chaque fois qu'un noeud du plan est
appelé, il doit apporter une ligne supplémentaire ou indiquer qu'il a
fini d'envoyer des lignes.
Pour donner un exemple concret, on peut supposer que le noeud
supérieur est un noeud MergeJoin. Avant de
pouvoir faire une fusion, deux lignes doivent être récupérées (une
pour chaque sous-plan). L'exécuteur s'appelle donc récursivement pour
exécuter les sous-plans (en commençant par le sous-plan attaché à
l'arbre gauche). Le nouveau noeud supérieur
(le noeud supérieur du sous-plan gauche) est, par exemple, un noeud
Sort (NdT : Tri) et un appel récursif est
une nouvelle fois nécessaire pour obtenir une ligne en entrée. Le
noeud fils de Sort pourrait être un noeud
SeqScan, représentant la lecture réelle
d'une table. L'exécution de ce noeud impose à l'exécuteur de
récupérer une ligne à partir de la table et de la retourner au noeud
appelant. Le noeud Sort appelle de façon
répétée son fils pour obtenir toutes les lignes à trier. Quand
l'entrée est épuisée (indiqué par le noeud fils renvoyant un NULL au
lieu d'une ligne), le code de Sort est enfin
capable de renvoyer sa première ligne en sortie, c'est-à-dire le
premier suivant l'ordre de tri. Il conserve les lignes restantes en
mémoire de façon à les renvoyer dans le bon ordre en réponse à des
demandes ultérieures.
Le noeud MergeJoin demande de la même façon
la première ligne à partir du sous-plan droit. Ensuite, il compare
les deux lignes pour savoir si elles peuvent être jointes ; si c'est
le cas, il renvoie la ligne de jointure à son appelant. Au prochain
appel, ou immédiatement, s'il ne peut pas joindre la paire actuelle
d'entrées, il avance sur la prochaine ligne d'une des deux tables
(suivant le résultat de la comparaison), et vérifie à nouveau la
correspondance. Éventuellement, l'un des sous-plans est épuisé et le
noeud MergeJoin renvoie NULL pour indiquer
qu'il n'y a plus de lignes jointes à former.
Les requêtes complexes peuvent nécessiter un grand nombre de niveaux
de noeuds pour les plans, mais l'approche générale est la même :
chaque noeud est exécuté et renvoie sa prochaine ligne en sortie à
chaque fois qu'il est appelé. Chaque noeud est responsable aussi de
l'application de toute expression de sélection ou de projection qui
lui a été confiée par le planificateur.
Le mécanisme de l'exécuteur est utilisé pour évaluer les quatre types
de requêtes de base en SQL :
SELECT
,
INSERT
,
UPDATE
et
DELETE
. Pour
SELECT
, le code de l'exécuteur de
plus haut niveau a uniquement besoin d'envoyer chaque ligne retournée
par l'arbre plan de la requête vers le client. Pour
INSERT
, chaque ligne renvoyée est
insérée dans la table cible indiquée par
INSERT
. (Une simple commande
INSERT ... VALUES
crée
un arbre plan trivial constitué d'un seul noeud, Result, calculant une seule ligne de résultat. Mais
INSERT ... SELECT
peut
demander la pleine puissance du mécanisme de l'exécuteur.) Pour
UPDATE
, le
planificateur s'arrange pour que chaque ligne calculée inclue toutes
les valeurs mises à jour des colonnes, plus le TID (tuple ID ou l'identifiant de la ligne) de la
ligne de la cible originale ; l'exécuteur de plus haut niveau utilise
cette information pour créer une nouvelle ligne mise à jour et pour
marquer la suppression de l'ancienne ligne. Pour
DELETE
, la seule colonne renvoyée
par le plan est le TID, et l'exécuteur de plus haut niveau utilise
simplement le TID pour visiter chaque ligne cible et la marquer comme
supprimée.