

Les types de données de PostgreSQL sont répartis en types de base, types conteneurs, domaines et pseudo-types.
    Les types de base sont ceux qui, comme integer, sont implantés
    sous le niveau du langage SQL (typiquement dans un
    langage de bas niveau comme le C). Ils correspondent généralement à ce que
    l'on appelle les types de données abstraits.
    PostgreSQL ne peut opérer sur de tels types
    qu'au moyen de fonctions utilisateur et n'en comprend le fonctionnement que
    dans la limite de la description qu'en a fait l'utilisateur. Les types de
    base internes sont décrits dans Chapitre 8.
   
Les types énumérés (enum) peuvent être considérés comme une sous-catégorie des types de base. La différence principale est qu'ils peuvent être créés en utilisant juste les commandes SQL, sans programmation de bas niveau. Référez-vous à Section 8.7 pour plus d'informations.
PostgreSQL a trois genres de types « conteneurs », qui sont des types contenant plusieurs valeurs d'autres types. Ce sont des tableaux, des valeurs composites et des intervalles.
Les tableaux peuvent contenir plusieurs valeurs qui sont toutes du même type. Un type tableau est automatiquement créé pour chaque type de base, type composite, type intervalle et type domaine. Par contre, il n'y a pas de tableaux de tableaux. Pour ce qui concerne le système de typage, les tableaux multi-dimensionnels sont identiques aux tableaux uni-dimensionnels. Référez-vous à Section 8.15 pour plus d'informations.
Les types composites, ou types lignes, sont créés chaque fois qu'un utilisateur crée une table. Il est également possible de définir un type composite autonome sans table associée. Un type composite n'est qu'une simple liste de types de base avec des noms de champs associés. Une valeur de type composite est une ligne ou un enregistrement de valeurs de champ. La Section 8.16 fournit de plus amples informations sur ces types.
Un type intervalle (range) peut contenir deux valeurs de même type, qui sont les bornes inférieure et supérieure de l'intervalle. Les types intervalle sont créés par les utilisateurs, bien que quelques-uns soient intégrés. Référez-vous à Section 8.17 pour plus d'informations.
Un domaine est basé sur un type sous-jacent donné particulier, et est interchangeable avec ce type dans beaucoup d'utilisations. Cependant, un domaine peut avoir des contraintes restreignant ses valeurs à un sous-ensemble de ce que permet le type sous-jacent. Les domaines sont créés avec la fonction SQL CREATE DOMAIN. Référez-vous à Section 8.18 pour plus d'informations.
Il existe quelques « pseudo-types » pour des besoins particuliers. Les pseudo-types ne peuvent pas apparaître comme champs de table ou comme composants de types conteneurs, mais ils peuvent être utilisés pour déclarer les types des arguments et des résultats de fonctions. Dans le système de typage, ils fournissent un mécanisme d'identification des classes spéciales de fonctions. La Tableau 8.27 donne la liste des pseudo-types qui existent.
Les pseudo-types ayant un intérêt particulier sont les types polymorphiques, utilisés pour déclarer des fonctions polymorphiques. Cette puissante fonctionnalité permet à une définition unique de fonction d'opérer sur différents types de données, le type de données étant déterminé par le type passé lors d'un appel donné. Les types polymorphiques sont indiqués dans Tableau 38.1. Quelques exemples de leurs usages apparaissent dans Section 38.5.11.
Tableau 38.1. Types polymorphiques
| Nom | Famille | Description | 
|---|---|---|
| anyelement | Simple | Indique qu'une fonction accepte n'importe quel type de données | 
| anyarray | Simple | Indique qu'une fonction accepte n'importe quel type de données tableau. | 
| anynonarray | Simple | Indique qu'une fonction accepte n'importe quel type de données qui n'est pas un tableau | 
| anyenum | Simple | Indique que cette fonction accepte n'importe quel type de données enum (voir Section 8.7) | 
| anyrange | Simple | Indique que cette fonction accepte n'importe quel type interval (voir Section 8.17) | 
| anymultirange | Simple | Indique qu'une fonction accepte tout type de données multirange (voir Section 8.17) | 
| anycompatible | Common | Indique que la fonction accepte n'importe quel type de données, avec promotion automatique d'arguments multiples en un type de données commun. | 
| anycompatiblearray | Common | Indique que la fonction accepte n'importe quel type de données tableau, avec promotion automatique d'arguments multiples en un type de données commun. | 
| anycompatiblenonarray | Common | Indique que la fonction accepte n'importe quel type de données qui n'est pas un tableau, avec promotion automatique d'arguments multiples en un type de données commun. | 
| anycompatiblerange | Common | Indique que la fonction accepte n'importe quel type de données interval, avec promotion automatique d'arguments multiples en un type de données commun. | 
| anycompatiblemultirange | Common | Indique qu'une fonction accepte tout type de données multirange, avec une promotion automatique de plusieurs arguments vers un type de données commun | 
Les arguments et résultats polymorphes sont liés entre eux et sont résolus dans un type de données spécifique quand une requête faisant appel à une fonction polymorphe est analysée. Quand il y a plus d'un argument polymorphique, les types de données courants doivent correspondre comme décrit ci-dessous. Si le type de résultat de la fonction est polymorphique, or que ses arguments de sortie sont de types polymorphiques, alors les types de ces résultats sont déduits par les types polymorphiques en entrée présents comme décrit ci-dessous.
Pour les types polymorphiques de famille « simple », la correspondance et les règles de déduction fonctionnent ainsi :
    Chaque occurrence (argument
    ou valeur de retour) déclarée comme anyelement
    peut prendre n'importe quel type réel de données mais, lors d'un
    appel de fonction donné, elles doivent toutes avoir le
    même type réel. Chaque occurrence déclarée comme
    anyarray peut prendre n'importe quel type de données tableau.
    De façon similaire, les occurrences déclarées en tant que
    anyrange doivent toutes être du même type.
    anymultirange.
   
    De la même façon, si des occurrences sont déclarées comme
    anyarray et d'autres comme anyelement ou
    anyarray, le type réel de tableau des occurrences
    anyarray doit être un tableau dont les éléments sont du même
    type que ceux apparaissant dans les occurrences de type
    anyelement. anynonarray est traité de la même
    façon que anyelement mais ajoute une contrainte
    supplémentaire. Le type réel ne doit pas être un tableau.
    anyenum est traité de la même façon que
    anyelement mais ajoute une contrainte supplémentaire. Le
    type doit être un type enuméré.
   
    De façon similaire, S'il existe des positions déclarées
    anyrange et d'autres déclarées anyelement ou
    anyarray, le type intervalle réel dans les positions
    anyrange doit être un intervalle dont le sous-type est le
    même type apparaissant dans les positions anyelement et le
    même que le type élément des positions anyarray. S'il existe
    des positions déclarées anymultirange, leur type multirange
    réel doit contenir des intervalles correspondant aux paramètres déclarés
    anyrange et des éléments de base correspondant aux
    paramètres déclarés anyelement et anyarray.
   
    Ainsi, quand plusieurs occurrences d'argument sont déclarées avec un type
    polymorphe, seules certaines combinaisons de
    types réels d'argument sont autorisées. Par exemple, une fonction déclarée
    comme foo(anyelement, anyelement) peut prendre comme
    arguments n'importe quelles valeurs à condition qu'elles soient du même
    type de données.
   
    Quand la valeur renvoyée par une fonction est déclarée de type polymorphe,
    il doit exister au moins une occurrence d'argument également polymorphe, et
    le type réel de donnée passé comme argument détermine le(s) type(s) réel(s)
    du résultat renvoyé lors de cet appel à la fonction. Par exemple, s'il
    n'existe pas déjà un mécanisme d'indexation d'éléments de
    tableau, on peut définir une fonction qui code ce mécanisme :
    indice(anyarray, integer) returns anyelement. La
    déclaration de fonction contraint le premier argument réel à être de type
    tableau et permet à l'analyseur d'inférer le type correct de résultat à
    partir du type réel du premier argument. Une fonction déclarée de cette
    façon f(anyarray) returns anyenum n'accepte que des
    tableaux contenant des valeurs de type enum.
   
    Dans la plupart des cas, l'analyseur peut inférer que le type de données
    réel pour un type résultat polymorphique pour des arguments qui sont d'un
    type polymorphique différent dans la même famille  par exemple
    anyarray peut
    être déduit à partir de anyelement et vice versa. Une exception
    est qu'un résultat polymorphique de type anyrange nécessite
    un argument de type anyrange ; il ne peut pas être
    déduit d'arguments anyarray ou anyelement. Ceci
    est dû au fait qu'il pourrait y avoir plusieurs types d'intervalles avec
    le même sous-type.
   
    anynonarray et anyenum ne représentent
    pas des variables de type séparé ; elles sont du même type que
    anyelement, mais avec une contrainte supplémentaire. Par
    exemple, déclarer une fonction f(anyelement, anyenum)
    est équivalent à la déclarer f(anyenum, anyenum) :
    les deux arguments réels doivent être du même type enum.
   
    Pour la famille de types polymorphiques « common », la
    correspondance et les règles de déduction fonctionnent presque pareilles
    que pour la famille « simple », avec une différence majeure :
    les types courants des arguments n'ont pas besoin d'être identiques,
    aussi longtemps qu'ils peuvent être implicitement convertis en un type commun simple.
    Le type commun est sélectionné en suivant la même règle que pour UNION
    et les constructions liées (voir Section 10.5).
    La sélection du type commun considère les types présents
    anycompatible et anycompatiblenonarray en entrée,
    les éléments de type tableau anycompatiblearray en entrée, et
    les sous-types anycompatiblerange et
    anycompatiblemultirange en entrée.
    Si anycompatiblenonarray est présent, alors le type commun doit
    être un type qui n'est pas un tableau. Une fois le type commun identifié, les arguments
    en position anycompatible et anycompatiblenonarray
    sont automatiquement convertis en ce type, et les arguments en position
    anycompatiblearray sont automatiquement convertis en type tableau
    pour ce type.
   
    Du fait qu'il n'y a pas de moyen de sélectionner le type interval à partir
    uniquement de son sous-type, l'usage de anycompatiblerange
    et/ou anycompatiblemultirange requiert que tous les
    arguments déclarés avec ce type aient le même type range et/ou
    multirange, et que le type du sous-type est en accord avec le type commun
    sélectionné, pour qu'il n'y ait pas de conversion nécessaire de la valeur
    de l'intervalle. Comme avec anyrange et
    anymultirange, l'usage de anycompatiblerange et
    anymultirange en tant que type de résultat de fonction
    demande qu'il y ait un argument anycompatiblerange ou
    anycompatiblemultirange.
   
    Notez qu'il n'y a aucun type anycompatibleenum. Un tel
    type ne serait pas très utile, du fait qu'il n'y a normalement aucune
    conversion implicite de types enum, signifiant ainsi qu'il n'y aura aucune
    façon de résoudre un type commun pour des entrées enum différentes.
   
Les familles polymorphiques « simple » et « common » représentent deux ensembles de types de variable indépendants. Considérez par exemple :
CREATE FUNCTION myfunc(a anyelement, b anyelement,
                       c anycompatible, d anycompatible)
RETURNS anycompatible AS ...
    Dans un appel de cette fonction, les deux premières entrées doivent avoir le même type exact. Les deux dernières entrées doivent être convertibles en un type commun, mais ce type nécessite d'être complétement différent du type des deux premières entrées. Le résultat aura le type commun des deux dernières entrées.
    Une fonction variadic (c'est-à-dire une fonction acceptant un nombre
    variable d'arguments, comme dans Section 38.5.6) peut être polymorphique :
    cela se fait en déclarant son dernier paramètre VARIADIC
    anyarray ou VARIADIC
    anycompatiblearray. Pour s'assurer de la correspondance des
    arguments et déterminer le type de la valeur en retour, ce type de
    fonction se comporte de la même façon que si vous aviez écrit le nombre
    approprié de paramètres anynonarray ou
    anycompatiblenonarray.