37.5. Expressions
Toutes les expressions utilisées dans les instructions PL/pgSQL sont traitées par l'exécuteur
SQL classique du serveur. En
effet, une requête comme
SELECT expression
est exécutée en utilisant le gestionnaire SPI. Avant l'évaluation, les occurrences des
identifiants de variables PL/pgSQL
sont remplacées par des paramètres, et les valeurs réelles des
variables sont passées à l'exécuteur dans le tableau des paramètres.
Ceci permet au plan de requêtes pour le
SELECT
de n'être élaboré qu'une
fois et réutilisé pour les évaluations postérieures.
L'évaluation faite par l'analyseur syntaxique principal de
PostgreSQL™ a quelques effets
de bord sur l'interprétation des valeurs constantes. Plus
précisément, il y a une différence entre ce que font ces deux
fonctions :
CREATE FUNCTION trace1(texte_trace text) RETURNS timestamp AS $$
BEGIN
INSERT INTO table_trace VALUES (texte_trace, 'now');
RETURN 'now';
END;
$$ LANGUAGE plpgsql;
et
CREATE FUNCTION trace2(texte_trace text) RETURNS timestamp AS $$
DECLARE
heure timestamp;
BEGIN
heure := 'now';
INSERT INTO table_trace VALUES (texte_trace, heure);
RETURN heure;
END;
$$ LANGUAGE plpgsql;
Dans le cas de trace1, l'analyseur
syntaxique principal de PostgreSQL™ sait, quand il élabore le plan
pour l'
INSERT
, que la
chaîne 'now' doit être interprétée comme un
timestamp parce que la colonne cible de
table_trace est de ce type. Ainsi,
'now' sera converti en une constante lors de
l'instruction
INSERT
,
puis utilisé dans tous les appels à trace1
pendant le temps que durera la session. Il va sans dire que ce n'est
pas ce que le programmeur voulait.
Dans le cas de trace2, l'analyseur
principal de PostgreSQL™ ne
sait pas quel type 'now' doit devenir, et
par conséquent, il renvoie une valeur de type text contenant la chaîne now.
Durant l'assignation consécutive de la variable locale heure, l'interpréteur PL/pgSQL transtype cette chaîne en type
timestamp en appelant les fonctions
text_out et timestamp_in pour la conversion. Ainsi, l'horodateur
est mis à jour à chaque exécution comme l'attend le programmeur.
La nature modifiable des variables record présente un problème lors
de cette connexion. Quand les champs d'une variable record sont
utilisés dans les expressions ou les instructions, les types de
données des champs ne doivent pas changer entre les appels de deux
expressions identiques, puisque l'expression sera planifiée en
utilisant le type de données présent quand l'expression est atteinte
pour la première fois. Gardez ceci à l'esprit quand vous écrivez des
procédures déclencheurs qui gèrent des évènements pour plus d'une
table (
EXECUTE
peut
être utilisé pour contourner le problème si nécessaire).