Ce document décrit la version 3.0 de ce protocole, telle qu'implantée
dans postgresql™ depuis la
version 7.4. pour obtenir la description des versions précédentes du
protocole, il faudra se reporter aux versions antérieures de la
documentation de postgresql™.
un même serveur peut supporter plusieurs versions du protocole. Lors
de l'établissement de la communication le client indique au serveur
la version du protocole qu'il souhaite utiliser. Le serveur suivra ce
protocole s'il en est capable.
Les fonctionnalités de haut niveau construites sur ce protocole (par
exemple, la façon dont libpq passe
certaines variables d'environnement à l'établissement de la
connexion) ne sont pas couvertes par ce chapitre.
Pour répondre efficacement à de multiples clients, le serveur lance
un nouveau serveur (« backend »)
pour chaque client. dans l'implémentation actuelle, un nouveau
processus fils est créé immédiatement après la détection d'une
connexion entrante. Et cela de façon transparente pour le protocole.
Pour le protocole, les termes « backend » et « serveur » sont interchangeables ; comme
« frontend »,
« interface » et
« client ».
44.1. Aperçu
Le protocole utilise des phases distinctes pour le lancement et le
fonctionnement habituel. Dans la phase de lancement, le client
ouvre une connexion au serveur et s'authentifie (ce qui peut
impliquer un message simple, ou plusieurs messages, en fonction de
la méthode d'authentification utilisée). En cas de réussite, le
serveur envoie une information de statut au client et entre dans le
mode normal de fonctionnement. Exception faite du message initial
de demande de lancement, cette partie du protocole est conduite par
le serveur.
En mode de fonctionnement normal, le client envoie requêtes et
commandes au serveur et celui-ci retourne les résultats de requêtes
et autres réponses. Il existe quelques cas (comme
notify
) pour lesquels le serveur
enverra des messages non sollicités. Mais dans l'ensemble, cette
partie de la session est conduite par les requêtes du client.
En général, c'est le client qui décide de la clôture de la session.
Il arrive, cependant, qu'elle soit forcée par le moteur. Dans tous
les cas, lors de la fermeture de la connexion par le serveur, toute
transaction ouverte (non terminée) sera annulée.
En mode opérationnel normal, les commandes SQL peuvent être
exécutées via deux sous-protocoles. Dans le protocole des
« requêtes simples », le
client envoie juste une chaîne, la requête, qui est analysée et
exécutée immédiatement par le serveur. Dans le protocole des
« requêtes étendues », le
traitement des requêtes est découpé en de nombreuses étapes :
l'analyse, le lien avec les valeurs de paramètres et l'exécution.
Ceci offre flexibilité et gains en performances au prix d'une
complexité supplémentaire.
Le mode opérationnel normal offre des sous-protocoles
supplémentaires pour certaines opérations comme
copy
.
44.1.1. Aperçu des messages
Toute la communication s'effectue au travers d'un flux de
messages. Le premier octet d'un message identifie le type de
message et les quatre octets suivants spécifient la longueur du
reste du message (cette longueur inclut les 4 octets de longueur,
mais pas l'octet du type de message). Le reste du contenu du
message est déterminé par le type de message. Pour des raisons
historiques, le tout premier message envoyé par le client (le
message de lancement) n'a pas l'octet initial de type du message.
Pour éviter de perdre la synchronisation avec le flux de
messages, le serveur et le client stocke le message complet dans
un tampon (en utilisant le nombre d'octets) avant de tenter de
traiter son contenu. Cela permet une récupération simple si une
erreur est détectée lors du traitement du contenu. Dans les
situations extrêmes (telles que de ne pas avoir assez de mémoire
pour placer le message dans le tampon), le récepteur peut
utiliser le nombre d'octets pour déterminer le nombre d'entrées à
ignorer avant de continuer la lecture des messages.
En revanche, serveurs et clients doivent être attentifs à ne pas
envoyer de message incomplet. Ceci est habituellement obtenu en
plaçant le message complet dans un tampon avant de commencer
l'envoi. Si un échec de communications survient pendant l'envoi
ou la réception d'un message, la seule réponse plausible est
l'abandon de la connexion. Il y a, en effet, peu d'espoir de
resynchronisation des messages.
44.1.2. Aperçu des requêtes étendues
Dans le protocole des requêtes étendues, l'exécution de commandes
SQL est scindée en plusieurs étapes. L'état retenu entre les
étapes est représenté par deux types d'objets : les instructions préparées et les portails. une instruction préparée représente le
résultat de l'analyse syntaxique, de l'analyse sémantique et de
la planification d'une chaîne de requête textuelle. Une
instruction préparée n'est pas nécessairement prête à être
exécutée parce qu'il peut lui manquer certaines valeurs de
paramètres. un portail représente une
instruction prête à être exécutée ou déjà partiellement exécutée,
dont toutes les valeurs de paramètres manquant sont données (pour
les instructions
select
, un portail est
équivalent à un curseur ouvert. il est choisi d'utiliser un terme
différent car les curseurs ne gèrent pas les instructions autres
que
select
)
Le cycle d'exécution complet consiste en une étape d'analyse syntaxique, qui crée une instruction
préparée à partir d'une chaîne de requête textuelle ; une étape
de liaison, qui crée un portail à
partir d'une instruction préparée et des valeurs pour les
paramètres nécessaires ; et une étape d'exécution qui exécute une requête du portail.
Dans le cas d'une requête qui renvoie des lignes (
select
,
show
, etc), il peut être
signalé à l'étape d'exécution que seul un certain nombre de
lignes doivent être retournées, de sorte que de multiples étapes
d'exécution seront nécessaires pour terminer l'opération.
Le serveur peut garder la trace de multiples instructions
préparées et portails (qui n'existent qu'à l'intérieur d'une
session, et ne sont jamais partagés entre les sessions). Les
instructions préparées et les portails sont référencés par les
noms qui leur sont affectés à la création. De plus, il existe une
instruction préparée et un portail « non
nommés ». bien qu'ils se comportent comme des objets
nommés, les opérations y sont optimisées en vue d'une exécution
unique de la requête avant son annulation puis est annulée. En
revanche, les opérations sur les objets nommés sont optimisées
pour des utilisations multiples.
44.1.3. Formats et codes de format
Les données d'un type particulier pouvaient être transmises sous
différents formats. depuis
postgresql™ 7.4, les seuls
formats supportés sont le « texte » et le « binaire » mais le protocole prévoit des
extensions futures. Le format désiré pour toute valeur est
spécifié par un code de format. les
clients peuvent spécifier un code de format pour chaque valeur de
paramètre transmise et pour chaque colonne du résultat d'une
requête. Le texte a zéro pour code de format zéro, le binaire un.
Tous les autres codes de format sont réservés pour des
définitions futures.
La représentation au format texte des valeurs est toute chaîne
produite et acceptée par les fonctions de conversion en
entrée/sortie pour le type de données particulier. Dans la
représentation transmise, il n'y a pas de caractère nul de
terminaison de chaîne ; le client doit en ajouter un s'il
souhaite traiter les valeurs comme des chaînes C (le format texte
n'autorise pas les valeurs nulles intégrées).
Les représentations binaires des entiers utilisent l'ordre
d'octet réseau (octet le plus significatif en premier). Pour les
autres types de données, il faudra consulter la documentation ou
le code source pour connaître la représentation binaire. Les
représentations binaires des types de données complexes changent
parfois entre les versions du serveur ; le format texte reste le
choix le plus portable.