CREATE CAST — D�finir un transtypage
CREATE CAST (type_source AS type_cible) WITH FUNCTION nom_fonction (type_argument [, ...]) [ AS ASSIGNMENT | AS IMPLICIT ] CREATE CAST (type_source AS type_cible) WITHOUT FUNCTION [ AS ASSIGNMENT | AS IMPLICIT ] CREATE CAST (type_source AS type_cible) WITH INOUT [ 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 float8);
convertit la constante enti�re 42 en float8 en appelant une fonction pr�c�demment d�finie, float8(int4) dans le cas pr�sent (si aucun transtypage convenable n'a �t� d�fini, la conversion �choue).
Deux types peuvent �tre coercibles binairement, ce qui signifie que le transtypage peut �tre fait � gratuitement � sans invoquer aucune fonction. Ceci impose que les valeurs correspondantes aient la m�me repr�sentation interne. Par exemple, les types text et varchar sont coercibles binairement dans les deux sens. La coercibilit� binaire n'est pas forc�ment une relation sym�trique. Par exemple, le transtypage du type xml au type text peut �tre fait gratuitement dans l'impl�mentation actuelle, mais l'op�ration inverse n�cessite une fonction qui fasse au moins une validation syntaxique. (Deux types qui sont coercibles binairement dans les deux sens sont aussi appel�s binairement compatibles.)
Vous pouvez d�finir un transtypage comme transtypage I/O en utilisant la syntaxe WITH INOUT. Un transtype I/O est effectu� en appelant la fonction de sortie du type de donn�es source, et en passant la cha�ne r�sultante � la fonction d'entr�e du type de donn�es cible. Dans la plupart des cas, cette fonctionnalit� �vite d'avoir � �crire une fonction de transtypage s�par�e pour la conversion. Un transtypage I/O agit de la m�me fa�on qu'un transtypage standard bas� sur une fonction. Seule l'impl�mentation diff�re.
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 la conversion est marqu�e AS IMPLICIT, alors elle peut �tre appel�e implicitement dans tout contexte, soit par une affectation soit en interne dans une expression (nous utilisons g�n�ralement le terme conversion implicite pour d�crire ce type de conversion.) Par exemple, voici une requ�te :
SELECT 2 + 4.0;
L'analyseur marque au d�but les constantes comme �tant de type integer et numeric respectivement. Il n'existe pas d'op�rateur integer + numeric dans les catalogues syst�mes mais il existe un op�rateur numeric + numeric. La requ�te sera un succ�s si une conversion de integer vers numeric est disponible et marqu�e AS IMPLICIT -- ce qui est le cas. L'analyseur appliquera la conversion implicite et r�soudra la requ�te comme si elle avait �t� �crite de cette fa�on :
SELECT CAST ( 2 AS numeric ) + 4.0;
Maintenant, les catalogues fournissent aussi une conversion de numeric vers integer. Si cette conversion �tait marqu�e AS IMPLICIT -- mais ce n'est pas le cas -- alors l'analyseur devra choisir entre l'interpr�tation ci-dessus et son alternative (la conversion de la constante numeric en un integer) et appliquer l'op�rateur integer + integer. Comme il n'a aucune information qui lui permettrait de choisir le meilleur moyen, il abandonne et d�clare la requ�te comme �tant ambig�e. Le fait qu'une seule des conversions est indiqu�e comme implicite est le moyen par lequel nous apprenons � l'analyseur de pr�f�rer la premi�re solution (c'est-�-dire de transformer une expression numeric-and-integer en numeric) ; il n'y a pas d'autre moyen.
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.
Il est parfois n�cessaire, pour des raisons de convivialit� ou de respect des standards, de fournir plusieurs transtypages implicites sur un ensemble de types de donn�es. Ceux-ci peuvent alors entra�ner des ambiguit�s qui ne peuvent �tre �vit�es, comme ci-dessus. L'analyseur poss�de pour ces cas une heuristique de secours s'appuyant sur les cat�gories de types et les types pr�f�r�s, qui peut aider � fournir le comportement attendu dans ce genre de cas. Voir CREATE TYPE(7) pour plus de d�tails.
Pour cr�er un transtypage, il faut �tre propri�taire du type source ou destination et avoir le droit USAGE sur l'autre type. 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 entre le type source et le type cible pour qu'aucune fonction ne soit requise pour effectuer la conversion.
Inique que le transtypage est un transtypage I/O, effectu� en appelant la fonction de sortie du type de donn�es source, et en passant la cha�ne r�sultante � la fonction d'entr�e du type de donn�es cible.
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 ou doit �tre compatible avec ce type. 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, le standard SQL appelle 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.
Le type de retour d'une fonction de transtypage doit �tre identique ou coercible binairement avec le type cible du transtypage.
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.
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.
Le transtypage du ou vers le type d'un domaine n'a actuellement pas d'effet. Transtyper d'un ou vers un domaine utilise le transtypage associ� avec son type sous-jacent.
DROP CAST(7) 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.
Il est n'est pas n�cessaire habituellement de cr�er des conversions entre des types d�finis par l'utilisateur et des types de cha�ne standards (text, varchar etchar(n), pas plus que pour des types d�finis par l'utilisateur d�finis comme entrant dans la cat�gorie des cha�nes). PostgreSQL™ fournit un transtypage I/O automatique pour cela. Ce transtypage automatique vers des types cha�nes est trait� comme des transtypages d'affectation, alors que les transtypages automatiques � partir de types cha�ne sont de type explicite seulement. Vous pouvez changer ce comportement en d�clarant votre propre conversion pour remplacer une conversion automatique. La seule raison usuelle de le faire est de vouloir rendre l'appel de la conversion plus simple que le param�trage standard (affectation seulement ou explicite seulement). Une autre raison envisageable est de vouloir que la conversion se comporte diff�rement de la fonction I/O du type ; mais c'est suffisamment d�routant pour que vous y pensiez � deux fois avant de le faire. (Un petit nombre de types internes ont en fait des comportements diff�rents pour les conversions, principalement � cause des besoins du standard SQL.)
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.
En fait, le paragraphe pr�c�dent est une sur-simplification : il existe deux cas pour lesquels une construction d'appel de fonction sera trait�e comme une demande de conversion sans qu'il y ait correspondance avec une fonction r�elle. Si un appel de fonction nom(x) ne correspond pas exactement � une fonction existante, mais que nom est le nom d'un type de donn�es et que pg_cast fournit une conversion compatible binairement vers ce type � partir du type x, alors l'appel sera construit � partir de la conversion compatible binairement. Cette exception est faite pour que les conversions compatibles binairement puissent �tre appel�es en utilisant la syntaxe fonctionnelle, m�me si la fonction manque. De ce fait, s'il n'y pas d'entr�e dans pg_cast mais que la conversion serait � partir de ou vers un type chap�ne, l'appel sera r�alis� avec une conversion I/O. Cette exception autorise l'appel de conversion I/O en utilisant la syntaxe fonctionnelle.
Il existe aussi une exception � l'exception : le transtypage I/O convertissant des types composites en types cha�ne de caract�res ne peut pas �tre appel� en utilisant la syntaxe fonctionnelle, mais doit �tre �crite avec la syntaxe de transtypage explicite (soit CAST soit ::). Cette exception a �t� ajout�e car, apr�s l'introduction du transtypage I/O automatique, il �tait trop facile de provoquer par erreur une telle conversion alors que l'intention �tait de r�f�rencer une fonction ou une colonne.
Cr�ation d'un transtypage d'affectation du type bigint vers le type int4 � l'aide de la fonction int4(bigint) :
CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
(Ce transtypage est d�j� pr�d�fini dans le syst�me.)