Migration vers 9.0 et supérieures¶
Contrôle des noms de variables¶
Dans les versions précédentes de PostgreSQL, dans une fonction PL/pgSQL, si une variable portait
le même nom qu’un objet de la base, la variable était utilisée systématiquement.
À partir de la version 9.0, une erreur à propos de cette ambiguïté est levée.
Dans l’exemple ci-après, la table test
contient une colonne nommée a
:
DO LANGUAGE plpgsql
$$
DECLARE
a INT;
BEGIN
SELECT a FROM test;
END
$$
ERROR: COLUMN reference "a" IS ambiguous
LINE 1: SELECT a FROM test
DETAIL: It could refer TO either a PL/pgSQL variable OR a TABLE COLUMN.
QUERY: SELECT a FROM test
CONTEXT: PL/pgSQL FUNCTION "inline_code_block" line 4 at SQL statement
Si vous voulez modifier ce comportement, vous pouvez le faire globalement, mais il est préférable de le faire par fonction, en exécutant une de ces commandes au début de votre fonction :
#variable_conflict error -- mode par défaut
#variable_conflict use_variable -- choisir le nom de variable
#variable_conflict use_column -- choisir le nom de colonne
Protection des mots réservés en PL/pgSQL¶
L’utilisation de mot clé SQL dans le code PL/pgSQL est désormais protégée. Il faudra donc explicitement entourer le nom de ces variables de double guillemets afin de lever l’ambiguïté. de maintenant explicitement entourer le nom de ces variables de double guillemet afin de lever l’ambiguïté. Par exemple avec le code suivant :
=> DO LANGUAGE plpgsql
$$
DECLARE
TABLE INT;
BEGIN
TABLE :=TABLE+1;
END
$$;
ERROR: syntax error at OR near "table"
LINE 6: TABLE :=TABLE+1;
^
La solution sera :
Echaper des bytea
¶
En 8.4 et antérieures, les caractères non-ascii des bytea
(tableaux d’octets) étaient échappés (protégés).
Le format par défaut a été modifié en 9.0 :
En 8.4 :
En 9.0
:
En 8.4, seules les valeurs d’octet ne correspondant pas à des caractères ASCII sont protégées. En 9.0, tout est codé directement en hexadécimal.
La chaîne été
saisie est en Unicode (UTF-8
). Elle est donc composée de la séquence
d’octets suivante (en hexadécimal): c3 a9 74 c3 a9
.
c3 a9
est le caractère é
(encodé sur 2 octets en UTF8
). t
, quant à lui, fait partie
des caractères ASCII, et est donc encodé sur un seul caractère, le même qu’en ASCII (74
).
Le nouveau format 9.0 est donc \xXXXXXXXXXXXX
, chaque paire de XX
correspondant à la valeur
d’un octet, en valeur hexadécimale.
L’ancien format ne protège que les valeurs d’octet non transposable en ASCII (ici, le é
), sous
la forme \DDD
(valeur décimale de l’octet). Ce format est souvent moins compact, et beaucoup plus
lent à coder et décoder, puisque nécessitant des tests sur la présence d’un \
ou non, ou des
comportements différents suivant la valeur ASCII d’un caractère.
Le nouveau format est donc à privilégier, si vous pouvez modifier votre application (si vous traitez
vous-mêmes les bytea
dans le code), ou si vous pouvez modifier votre driver (le driver JDBC 9.0,
par exemple, autodétecte le type d’encodage et fait de lui-même ce qui est nécessaire).
Si vous ne pouvez pas modifier l’application, il est possible de revenir à l’ancien fonctionnement,
en modifiant le paramètre bytea_output
à escape
au lieu de sa valeur par défaut hex
. Mais vous
ne bénéficierez pas du gain de performance apporté par le nouveau format. `