Documentation PostgreSQL 8.1.23 > Référence > Commandes SQL > CREATE CAST | |
CREATE AGGREGATE | CREATE CONSTRAINT TRIGGER |
CREATE CAST (typesource AS typecible) WITH FUNCTION nomfonction (argtype) [ AS ASSIGNMENT | AS IMPLICIT ] CREATE CAST (typesource AS typecible) WITHOUT FUNCTION [ AS ASSIGNMENT | AS IMPLICIT ]
CREATE CAST définit un transtypage. Un transtypage spécifie l'opération de conversion entre deux types de données. Par exemple,
SELECT CAST(42 AS text);
convertit la constante entière 42 en text en appelant une fonction précédemment définie, text(int4) dans le cas présent (si aucun transtypage convenable n'a été défini, la conversion échoue).
Deux types peuvent être binairement compatibles, ce qui signifie que la conversion d'un type en l'autre est « gratuite » et ne nécessite pas d'appel de fonction. Les valeurs correspondantes doivent pour cela utiliser la même représentation interne. Les types text et varchar, par exemple, sont binairement compatibles.
Un transtypage peut être appelé explicitement. Par exemple : CAST(x AS nomtype) ou x::nomtype.
Si le transtypage est marqué AS ASSIGNMENT (NDT : à l'affectation), alors son appel peut être implicite lors de l'affectation d'une valeur à une colonne du type de donnée cible. Par exemple, en supposant que foo.f1 soit une colonne de type text,
INSERT INTO foo (f1) VALUES (42);
est autorisé si la conversion du type integer vers le type text est indiquée AS ASSIGNMENT. Dans le cas contraire, c'est interdit. Le terme de transtypage d'affectation est utilisé pour décrire ce type de conversion.
Si le transtypage est marqué AS IMPLICIT, alors son appel peut être implicite, indépendemment du contexte, lors d'une affectation ou dans une expression. Par exemple, comme || prend deux opérandes text,
SELECT 'L\'heure est ' || now();
n'est autorisé que si la conversion du type timestamp vers le type text est marquée AS IMPLICIT. Dans le cas contraire, il est nécessaire d'écrire explicitement la conversion, par exemple
SELECT 'L\'heure est ' || CAST(now() AS text);
Le terme de transtypage implicite est habituellement utilisé pour décrire ce type de conversion.
Il est conseillé d'être conservateur sur le marquage du caractère implicite des transtypages. Une surabondance de transtypages implicites peut conduire PostgreSQL™ à interpréter étrangement des commandes, voire à se retrouver dans l'incapacité totale de les résoudre parce que plusieurs interprétations s'avèrent envisageables. Une bonne règle est de ne réaliser des transtypages implicites que pour les transformations entre types de la même catégorie générale et qui préservent l'information. Par exemple, la conversion entre int2 et int4 peut être raisonnablement implicite mais celle entre float8 et int4 est probablement réservée à l'affectation. Les transtypages inter-catégories, tels que de text vers int4, sont préférablement exécutés dans le seul mode explicite.
Pour créer un transtypage, il faut être propriétaire du type source ou destination. Seul le superutilisateur peut créer un transtypage binairement compatible (une erreur sur un tel transtypage peut aisément engendrer un arrêt brutal du serveur).
Le nom du type de donnée source du transtypage.
Le nom du type de donnée cible du transtypage.
La fonction utilisée pour effectuer la conversion. Le nom de la fonction peut être qualifié du nom du schéma. Si ce n'est pas le cas, la fonction est recherchée dans le chemin des schémas. Le type de données résultant de la fonction doit correspondre au type cible du transtypage. Ses arguments sont explicités ci-dessous.
Indication d'une compatibilité binaire des types source et cible. Aucune fonction n'est ainsi requise pour effectuer la conversion.
Lors d'une affectation, l'invocation du transtypage peut être implicite.
L'invocation du transtypage peut être implicite dans tout contexte.
Les fonctions de transtypage ont un à trois arguments. Le premier argument est du même type que le type source. Le deuxième argument, si fourni, doit être de type integer. Il stocke le modificateur de type associé au type de destination, ou -1 en l'absence de modificateur. Le troisième argument, si fourni, doit être de type boolean. Il vaut true si la conversion est explicite, false dans le cas contraire. Bizarrement, les spécifications SQL appellent des comportements différents pour les transtypages explicites et implicites dans certains cas. Ce paramètre est fourni pour les fonctions qui implémentent de tel transtypages. Il n'est pas recommandé de concevoir des types de données utilisateur entrant dans ce cas de figure.
En général, un transtypage correspond à des type source et destination différents. Cependant, il est permis de déclarer un transtypage entre types source et destination identiques si la fonction de transtypage a plus d'un argument. Cette possibilité est utilisée pour représenter dans le catalogue système des fonctions de transtypage agissant sur la longueur d'un type. La fonction nommée est utilisée pour convertir la valeur d'un type à la valeur du modificateur de type fournie par le second argument (puisque la grammaire n'autorise qu'un nombre restreint de types internes à avoir des modificateurs de type, cette fonctionnalité n'est d'aucun intérêt pour les types cibles utilisateur ; elle n'est signalée que dans un souci de complétude).
Quand un transtypage concerne des types source et destination différents et que la fonction a plus d'un argument, le transtypage et la conversion de longeur du type destination sont faites en une seule etape. Quand une telle entrée n'est pas disponible, le transtypage vers un type qui utilise un modificateur de type implique deux étapes, une pour convertir les types de données et la seconde pour appliquer le modificateur.
DROP CAST est utilisé pour supprimer les transtypages utilisateur.
Pour convertir les types dans les deux sens, il est obligatoire de déclarer explicitement les deux sens.
Avant PostgreSQL™ 7.3, toute fonction qui portait le même nom qu'un type de données, retournait ce type de données et prenait un argument d'un autre type était automatiquement détectée comme une fonction de conversion. Cette convention a été abandonnée du fait de l'introduction des schémas et pour pouvoir représenter des conversions binairement compatibles dans les catalogues système. Les fonctions de conversion intégrées suivent toujours le même schéma de nommage mais elle doivent également être présentées comme fonctions de transtypage dans le catalogue système pg_cast.
Bien que cela ne soit pas requis, il est recommandé de suivre l'ancienne convention de nommage des fonctions de transtypage en fonction du type de données de destination. Beaucoup d'utilisateurs sont habitués à convertir des types de données à l'aide d'une notation de style fonction, c'est-à-dire nom_type(x). En fait, cette notation n'est ni plus ni moins qu'un appel à la fonction d'implantation du transtypage ; sa gestion n'est pas spécifique à un transtypage. Le non-respect de cette convention peut surprendre certains utilisateurs. Puisque PostgreSQL™ permet de surcharger un même nom de fonction avec différents types d'argument, il n'y a aucune difficulté à avoir plusieurs fonctions de conversion vers des types différents qui utilisent toutes le même nom de type destination.
Le paragraphe précédent présente une légère imprécision : il existe un cas dans lequel pg_cast sera utilisé pour résoudre le sens d'un appel de fonction. Si un appel de fonction nom(x) ne coïncide avec aucune fonction existante, mais que nom(x) est le nom d'un type de données et que pg_cast indique une conversion binairement compatible du type de x, alors l'appel sera interprété comme un transtypage explicite. Cette exception autorise les conversions binairement compatibles à être invoquées à l'aide d'une syntaxe fonctionnelle, même en l'absence de fonction les décrivant.
Création d'un transtypage du type text vers le type int4 à l'aide de la fonction int4(text) :
CREATE CAST (text AS int4) WITH FUNCTION int4(text);
(Ce transtypage est déjà prédéfini dans le système.)