42.3. Étape d'analyse
L'étape d'analyse est constituée de deux
parties :
-
L'analyseur défini dans gram.y et scan.l est
construit en utilisant les outils Unix yacc et lex.
-
Le processus de transformation fait
des modifications et des ajouts aux structures de données
renvoyées par l'analyseur.
42.3.1. Analyseur
L'analyseur doit vérifier que la syntaxe de la chaîne de la requête
(arrivant comme un texte ASCII) est valide. Si la syntaxe est
correcte, un arbre d'analyse est
construit et renvoyé, sinon une erreur est retournée. Les analyseur
et vérificateur syntaxiques sont développés à l'aide des outils
Unix bien connus lex et
yacc.
L'analyseur lexical, défini dans le
fichier scan.l, est responsable de la
reconnaissance des identificateurs, des
mots clés SQL, etc. Pour chaque mot clé
ou identificateur trouvé, un jeton est
engendré et renvoyé à l'analyseur.
L'analyseur est défini dans le fichier gram.y et consiste en un ensemble de règles de grammaire et en des actions à exécuter lorsqu'une règle est
découverte. Le code des actions (qui est en langage C) est utilisé
pour construire l'arbre d'analyse.
Le fichier scan.l est transformé en
fichier source C scan.c en utilisant le
programme lex et gram.y est transformé en gram.c en utilisant yacc. Après avoir réalisé ces transformations,
un compilateur C normal peut être utilisé pour créer l'analyseur.
Il est inutile de modifier les fichiers C engendrés car ils seront
écrasés au prochaine appel de lex
ou yacc.
Note
Les transformations et compilations mentionnées sont
normalement réalisées automatiquement en utilisant les
makefile distribués avec les sources
de PostgreSQL™.
La description détaillée de yacc
ou des règles de grammaire données dans gram.y dépasse le cadre de ce document. Il existe
de nombreux livres et documentations en relation avec lex et yacc.
Il est préférable d'être familier avec yacc avant de commencer à étudier la grammaire
donnée dans gram.y, au risque de ne rien
y comprendre.
42.3.2. Processus de transformation
L'étape d'analyse crée un arbre d'analyse qui n'utilise que les
règles fixes de la structure syntaxique de SQL. Il ne fait aucune
recherche dans les catalogues système. Il n'y a donc aucune
possibilité de comprendre la sémantique détaillée des opérations
demandées. Après que l'analyseur ait fini, le processus de transformation prend en entrée
l'arbre résultant de l'analyseur et réalise l'interprétation
sémantique nécessaire pour connaître les tables, fonctions et
opérateurs référencés par la requête. La structure de données
construite pour représenter cette information est appelée
l'arbre de requête.
La séparation de l'analyse brute et de l'analyse sémantique résulte
du fait que les recherches des catalogues système ne peuvent se
dérouler qu'à l'intérieur d'une transaction. Or, il n'est pas
nécessaire de commencer une transaction dès la réception d'une
requête. L'analyse brute est suffisante pour identifier les
commandes de contrôle des transactions (
BEGIN
,
ROLLBACK
, etc.). Elles peuvent de
plus être correctement exécutées sans analyse complémentaire.
Lorsqu'il est établi qu'une vraie requête doit être gérée (telle
que
SELECT
ou
UPDATE
), une nouvelle
transaction est démarrée si aucune n'est déjà en cours. Ce n'est
qu'à ce moment-là que le processus de transformation peut être
invoqué.
La plupart du temps, l'arbre d'une requête créé par le processus de
transformation a une structure similaire à l'arbre d'analyse brute
mais, dans le détail, de nombreuses différences existent. Par
exemple, un noeud FuncCall dans
l'arbre d'analyse représente quelque chose qui ressemble
syntaxiquement à l'appel d'une fonction. Il peut être transformé
soit en noeud FuncExpr soit en
noeud Aggref selon que le nom
référencé est une fonction ordinaire ou une fonction d'agrégat. De
même, des informations sur les types de données réels des colonnes
et des résultats sont ajoutées à l'arbre de la requête.