PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 12.18 » Programmation serveur » Étendre SQL » Le système des types de PostgreSQL

37.2. Le système des types de PostgreSQL

Les types de données de PostgreSQL sont répartis en types de base, types conteneurs, domaines et pseudo-types.

37.2.1. Les types de base

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.

37.2.2. Les types conteneurs

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.

37.2.3. Les domaines

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.

37.2.4. Pseudo-types

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.

37.2.5. Types et fonctions polymorphes

Cinq pseudo-types sont particulièrement intéressants : anyelement, anyarray, anynonarray, anyenum et anyrange, collectivement appelés types polymorphes. Toute fonction déclarée utiliser ces types est dite fonction polymorphe. Une fonction polymorphe peut opérer sur de nombreux types de données différents, les types de données spécifiques étant déterminés par les types des données réellement passés lors d'un appel particulier de la fonction.

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. 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 occurences déclarées en tant que anyrange doivent toutes être du même type. De la même façon, elles doivent toutes être du même type. 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 ou du même type que ceux apparaissant dans les occurrences de type anyarray. De la même façon, si des occurences sont déclarées de type anyrange et d'autres de type anyelement, le type range réel dans les occurences de anyrange doit être un type dont le sous-type est du même type que celui apparaissant dans les occurences de 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é.

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 type réel de 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  par exemple anyarray peut être déduit à partir de anyelement et vice versa. L'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.

Une fonction variadic (c'est-à-dire une fonction acceptant un nombre variable d'arguments, comme dans Section 37.5.5) peut être polymorphique : cela se fait en déclarant son dernier paramètre VARIADIC anyarray. 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.