CREATE TYPE — Définir un nouveau type de données
CREATE TYPEnomAS (nom_attributtype_donnée[ COLLATEcollation] [, ... ] ) CREATE TYPEnomAS ENUM ( [ 'label' [, ... ] ] ) CREATE TYPEnameAS RANGE ( SUBTYPE =sous_type[ , SUBTYPE_OPCLASS =classe_operateur_sous_type] [ , COLLATION =collationnement] [ , CANONICAL =fonction_canonique] [ , SUBTYPE_DIFF =fonction_diff_sous_type] [ , MULTIRANGE_TYPE_NAME =nom_type_multirange] ) CREATE TYPEnom( INPUT =fonction_entrée, OUTPUT =fonction_sortie[ , RECEIVE =fonction_réception] [ , SEND =fonction_envoi] [ , TYPMOD_IN =type_modifier_input_function] [ , TYPMOD_OUT =type_modifier_output_function] [ , ANALYZE =fonction_analyse] [ , SUBSCRIPT =fonction_indice] [ , INTERNALLENGTH = {longueurinterne| VARIABLE } ] [ , PASSEDBYVALUE ] [ , ALIGNMENT =alignement] [ , STORAGE =stockage] [ , LIKE =type_like] [ , CATEGORY =catégorie] [ , PREFERRED =préféré] [ , DEFAULT =défaut] [ , ELEMENT =élément] [ , DELIMITER =délimiteur] [ , COLLATABLE =collatable] ) CREATE TYPEnom
   CREATE TYPE enregistre un nouveau type de données
   utilisable dans la base courante. L'utilisateur qui définit un type
   en devient le propriétaire.
  
Si un nom de schéma est précisé, le type est créé dans ce schéma. Sinon, il est créé dans le schéma courant. Le nom du type doit être distinct du nom de tout type ou domaine existant dans le même schéma. Les tables possèdent des types de données associés. Il est donc nécessaire que le nom du type soit également distinct du nom de toute table existant dans le même schéma.
   Il existe cinq formes de CREATE TYPE, comme indiqué dans
   la syntaxe ci-dessus. Elles créent respectivement un type
    composite, un type enum, un type
    range (intervalle), un type de base ou un
   type shell. Les autre premiers sont discutés dans
   l'ordre ci-dessous. Un type shell est un simple conteneur de type qui sera
   défini ultérieurement. Il est créé en lançant CREATE
    TYPE sans paramètre en dehors de son nom. Les types shell sont
   nécessaires comme référence lors de la création de types intervalles et de types
   de base, comme indiqué dans ces sections.
  
    La première forme de CREATE TYPE crée un type composite. Le
    type composite est défini par une liste de noms d'attributs et de types de
    données. Un collationnement d'attribute peut aussi être spécifié si son
    type de données est collationnable. Un type composite est essentiellement
    le même que le type ligne (NDT : row
     type en anglais) d'une table, mais l'utilisation de
    CREATE TYPE permet d'éviter la création d'une table
    réelle quand seule la définition d'un type est voulue. Un type composite
    autonome est utile, par exemple, comme type d'argument ou de retour d'une
    fonction.
   
    Pour pouvoir créer un type composite, vous devez avoir le droit
    USAGE sur les types de tous les attributs.
   
    La seconde forme de CREATE TYPE crée un type énuméré
    (enum), comme décrit dans Section 8.7. Les types enum
    prennent une liste de plusieurs labels entre guillemets, chacun devant
    faire moins de NAMEDATALEN octets (64 octets dans une
    installation PostgreSQL standard). (Il est
    possible de créer un type énuméré avec zéro label, mais un tel type ne
    peut pas être utilisé pour contenir des valeurs avant qu'au moins un label
    soit ajouté en utilisant ALTER TYPE.)
   
    La troisième forme de CREATE TYPE crée un type intervalle,
    comme décrit dans Section 8.17.
   
    Le sous-type du type intervalle
    peut être de tout type qui soit associé avec une classe d'opérateurs B-tree
    (pour déterminer l'ordre des valeurs pour le type intervalle). Habituellement,
    la classe d'opérateurs par défaut du sous-type est utilisée pour déterminer
    l'ordre. Pour utiliser un opérateur de classe autre que celle par défaut,
    indiquez son nom avec classe_operateur_sous_type. Si le sous-type
    est collationnable et que vous voulez utiliser un collationnement autre que
    celui par défaut dans l'ordre de l'intervalle, indiquez le collationnement
    souhaité avec l'option collationnement.
   
    La fonction optionnelle canonique
    prend un argument du type intervalle défini, et renvoie une valeur du même
    type. C'est utilisé pour convertir les valeurs intervalles en leur forme
    canonique, lorsque c'est applicable. Voir Section 8.17.8 pour plus d'informations. Créer une fonction
    canonique peut être un peu
    compliqué car il doit être défini avant que le type intervalle ne soit défini.
    Pour cela, vous devez tout d'abord créer un type shell, qui est un coquille
    vide qui n'a aucune propriété en dehors de son nom et propriétaire. Cela
    se crée en exécutant la commande CREATE TYPE
     , sans paramètre supplémentaire.
    Ensuite, la fonction peut être déclarée en utilisant le type shell comme
    argument et résultat. Enfin, le type intervalle peut être déclaré en utilisant
    le même nom. Ceci remplace automatiquement l'entrée du type shell avec
    un type intervalle valide.
   nom
    La fonction optionnelle diff_sous_type
    doit prendre deux valeurs du type sous-type comme arguments, et renvoie une
    valeur de type double precision représentant la différence
    entre les deux valeurs données. Bien que cela soit optionnel, la fournir
    autorise une plus grande efficacité des index GiST sur les colonnes du type
    intervalle. Voir Section 8.17.8 pour plus
    d'informations.
   
    Le paramètre optionnel nom_type_multirange
    indique le nom du type multirange correspondant. Si non specifié, ce nom
    est choisi automatiquement comme suit. Si le type de type range contient
    la sous-chaîne range, alors le nom du type multirange
    est formé par le remplacement de la sous-chaîne avec
    multirange dans le nom du type range. Sinon le nom du
    type multirange est formé en ajoutant le suffixe
    _multirange au nom du type range.
   
    La quatrième forme de CREATE TYPE crée un nouveau type de base
    (type scalaire). Pour créer un nouveau type de base, il faut être super-utilisateur.
    (Cette restriction est imposée parce qu'une définition de type erronée pourrait
    embrouiller voire arrêter brutalement le serveur.)
   
    L'ordre des paramètres, dont la plupart sont optionnels, n'a aucune
    d'importance. Avant de définir le type, il est nécessaire de définir au moins
    deux fonctions (à l'aide de la commande CREATE FUNCTION).
    Les fonctions de support fonction_entrée
    et fonction_sortie sont obligatoires. Les
    fonctions fonction_réception,
    fonction_envoi,
    type_modifier_input_function,
    type_modifier_output_function,
    fonction_analyse et
    fonction_indice sont
    optionnelles. Généralement, ces fonctions sont codées en C ou dans un
    autre langage de bas niveau.
   
    La fonction_entrée convertit la
    représentation textuelle externe du type en représentation interne
    utilisée par les opérateurs et fonctions définis pour le type.
    La fonction_sortie réalise la transformation
    inverse. La fonction entrée peut être déclarée avec un
    argument de type cstring ou trois arguments de
    types cstring, oid, integer. Le
    premier argument est le texte en entrée sous la forme d'une chaîne C, le second
    argument est l'OID du type (sauf dans le cas des types tableau où il
    s'agit de l'OID du type de l'élément) et le troisième est le typmod
    de la colonne destination, s'il est connu (-1 sinon). La fonction entrée
    doit renvoyer une valeur du nouveau type de données.
    Habituellement, une fonction d'entrée devrait être déclarée comme STRICT 
    si ce n'est pas le cas, elle sera appelée avec un premier paramètre NULL à
    la lecture d'une valeur NULL en entrée. La fonction doit toujours envoyer
    NULL dans ce cas, sauf si une erreur est rapportée.
    (Ce cas a pour but de supporter les fonctions d'entrée des domaines qui ont
    besoin de rejeter les entrées NULL.)
    La fonction sortie doit prendre un argument du nouveau type de données, et
    retourner le type cstring. Les fonctions sortie ne sont pas
    appelées pour des valeurs NULL.
   
    La fonction_réception,
    optionnelle, convertit la représentation binaire externe du type en
    représentation interne.
    
    Si cette fonction n'est pas fournie, le type n'accepte pas
    d'entrée binaire. La représentation binaire est choisie de telle sorte
    que sa conversion en forme interne soit peu coûteuse, tout en restant
    portable. (Par exemple, les types de données
    standard entiers utilisent l'ordre réseau des octets comme représentation
    binaire externe alors que la représentation interne est dans l'ordre natif
    des octets de la machine.) La fonction de réception réalise les
    vérifications adéquates pour s'assurer que la valeur est valide. Elle
    peut être déclarée avec un argument de type
    internal ou trois arguments de types
    internal, integer et oid. Le premier
    argument est un pointeur vers un tampon StringInfo
    qui contient la chaîne d'octets reçue ; les arguments optionnels sont les
    mêmes que pour la fonction entrée de type texte. La fonction de réception
    retourne une valeur du type de données.
    Habituellement, une fonction de réception devrait être déclarée comme STRICT 
    si ce n'est pas le cas, elle sera appelée avec un premier paramètre NULL à
    la lecture d'une valeur NULL en entrée. La fonction doit toujours envoyer
    NULL dans ce cas, sauf si une erreur est rapportée.
    (Ce cas a pour but de supporter les fonctions de réception des domaines qui ont
    besoin de rejeter les entrées NULL.)
    De façon similaire, la
    fonction_envoi, optionnelle,
    convertit la représentation interne en représentation
    binaire externe. Si cette fonction n'est pas fournie, le type
    
    n'accepte pas de sortie binaire. La fonction d'envoi doit être déclarée
    avec un argument du nouveau type de données et retourner le type bytea.
    Les fonctions réception ne sont pas appelées pour des valeurs NULL.
   
    À ce moment-là, vous pouvez vous demander comment les fonctions d'entrée et
    de sortie peuvent être déclarées avoir un résultat ou un argument du nouveau
    type alors qu'elles sont à créer avant que le nouveau type ne soit créé. La
    réponse est que le type sera tout d'abord défini en tant que
    type squelette (shell type),
    une ébauche de type sans propriété à part un nom et un propriétaire. Ceci se
    fait en exécutant la commande CREATE TYPE 
    sans paramètres supplémentaires. Ensuite, les fonctions d'entrée/sortie C
    peuvent être définies en référençant le squelette. Enfin, le
    nomCREATE TYPE avec une définition complète remplace le
    squelette avec une définition complète et valide du type, après quoi le
    nouveau type peut être utilisé normalement.
   
    Les fonctions optionnelles
    type_modifier_input_function
    et type_modifier_output_function
    sont nécessaires si le type supporte des modificateurs, c'est-à-dire des
    contraintes optionnelles attachées à une déclaration de type comme
    char(5) ou numeric(30,2).
    PostgreSQL autorise les types définis par
    l'utilisateur à prendre une ou plusieurs constantes ou identifiants comme
    modifieurs ; néanmoins, cette information doit être capable d'être
    englobée dans une seule valeur entière positive pour son stockage dans les
    catalogues système.
    type_modifier_input_function
    se voit fournir le modifieur déclaré de la forme d'un tableau de
    cstring. Il doit vérifier la validité des valeurs et renvoyer une
    erreur si elles sont invalides. Dans le cas contraire, il renvoie une valeur
    entière positive qui sera stockée dans la colonne « typmod ». Les
    modifieurs de type seront rejetés si le type n'a pas de
    type_modifier_input_function.
    type_modifier_output_function
    convertit la valeur typmod integer en une forme correcte pour l'affichage.
    Il doit renvoyer une valeur de type cstring qui est la chaîne
    exacte à ajouter au nom du type ; par exemple la fonction de
    numeric pourrait renvoyer (30,2). Il est
    permis d'omettre le
    type_modifier_output_function,
    auquel cas le format d'affichage par défaut est simplement la valeur typmod
    stockée entre parenthèses.
   
    La fonction_analyse, optionnelle,
    calcule des statistiques spécifiques au type de données pour les
    colonnes de ce type. Par défaut, ANALYZE tente de
    récupérer des statistiques à l'aide des opérateurs d'« égalité » et
    d'« infériorité » du type, s'il existe une classe d'opérateurs B-tree
    par défaut pour le type. Ce comportement est inadapté aux types non-scalaires ;
    il peut être surchargé à l'aide d'une fonction
    d'analyse personnalisée. La fonction d'analyse doit être déclarée avec
    un seul argument de type internal et un résultat de type
    boolean. L'API détaillée des fonctions d'analyses est présentée dans
    src/include/commands/vacuum.h.
   
    La fonction optionnelle fonction_indice autorise l'utilisation
    d'indice pour le type de données dans les commandes SQL. Indiquer cette
    fonction ne fait pas en sorte que le type soit considéré comme un
    « vrai » type tableau ; par exemple, il ne sera pas un
    candidat pour le type résultat de constructions ARRAY
    []. Mais si indicer une valeur du type est une notation
    naturelle pour en extraire des données, alors une fonction_indice peut être écrite pour
    définir la signification. La fonction d'indice doit être déclarée comme
    prenant un seul argument de type internal, et renvoyer un
    résultat de type internal, qui est un pointeur vers une
    structure de méthodes (fonctions) qui implémentent l'indiçage. L'API
    détaillée pour les fonctions d'indice apparaît dans in
    src/include/nodes/subscripting.h. Il pourrait aussi
    être utile de lire l'implémentation des tableaux dans
    src/backend/utils/adt/arraysubs.c, ou le code simple
    de contrib/hstore/hstore_subs.c. Des informations
    supplémentaires apparaissent dans Types tableau,
    ci-dessous.
   
    Alors que les détails de la représentation interne du nouveau type ne sont
    connus que des fonctions d'entrées/sorties et des fonctions utilisateurs
    d'interaction avec le type, plusieurs propriétés de
    la représentation interne doivent être déclarées à
    PostgreSQL. La première est
    longueurinterne. Les types de
    données basiques peuvent être de longueur fixe (dans ce cas,
    longueurinterne est un entier positif)
    ou de longueur variable (indiquée par le positionnement de
    longueurinterne à
    VARIABLE ; en interne, cela est représenté en initialisant
    typlen à -1). La représentation interne de tous les types de
    longueur variable doit commencer par un entier de quatre octets indiquant la
    longueur totale de cette valeur. (Notez que le champ length est souvent
    encodé, comme décrit dans Section 70.2 ; il n'est
    pas conseillé d'y accéder directement.)
   
    Le drapeau optionnel PASSEDBYVALUE indique que les
    valeurs de ce type de données sont passées par valeur plutôt que par
    référence. Les types dont la représentation interne est plus grande que la
    taille du type Datum (quatre octets sur la plupart des
    machines, huit sur quelques-unes) ne doivent pas être passés par valeur.
    Les types passés par valeur doivent avoir une longueur fixe et leur
    représentation interne ne peut pas être plus large que la taille du type
    Datum (4 octets sur certaines machines, 8 octets sur
    d'autres).
   
    Le paramètre alignement
    spécifie l'alignement de stockage requis pour le type de données. Les
    valeurs permises sont des alignements sur 1, 2, 4 ou 8 octets.
    Les types de longueurs variables ont un alignement d'au
    moins quatre octets car leur premier composant est nécessairement un int4.
   
    Le paramètre stockage permet de
    choisir une stratégie de stockage pour les types de données de longueur
    variable. (Seul plain est autorisé pour les types de
    longueur fixe.) plain indique des données
    stockées en ligne et non compressées.
    Dans le cas d'extended le système essaie tout d'abord de
    compresser une valeur longue et déplace la valeur hors de
    la ligne de la table principale si elle est toujours trop longue.
    external permet à la valeur d'être déplacée hors de la
    table principale mais le système ne tente pas de la compresser.
    main autorise la compression mais ne déplace
    la valeur hors de la table principale qu'en dernier recours.
    (Ils seront déplacés s'il n'est pas possible de placer la ligne
    dans la table principale, mais
    sont préférentiellement conservés dans la table principale, contrairement aux éléments
    extended et external.)
   
    Toutes les valeurs storage
    autres que plain impliquent que les fonctions du type
    de données peuvent gérer les valeurs placées en
    TOAST, comme décrit dans Section 70.2 et Section 38.13.1. L'aure valeur
    spécifique détermine la stratégie de stockage par défaut pour les colonnes
    d'un type de données externalisable ; les utilisateurs peuvent
    sélectionner les autres stratégies pour les colonnes individuelles en
    utilisant ALTER TABLE SET STORAGE.
   
    Le paramètre type_like fournit
    une méthode alternative pour spécifier les propriétés de représentation de
    base d'un type de données : les copier depuis un type existant. Les valeurs
    de longueurinterne,
    passedbyvalue,
    alignement et
    stockage sont copiées du type
    indiqué. (C'est possible, mais habituellement non souhaité, d'écraser
    certaines de ces valeurs en les spécifiant en même temps que la clause
    LIKE.)  Spécifier la représentation de cette façon est
    particulièrement pratique quand l'implémentation de bas niveau du nouveau type
    emprunte celle d'un type existant d'une façon ou d'une autre.
   
    Les paramètres catégorie et
    préféré peuvent être utilisés pour
    aider à contrôler la conversion implicite appliquée en cas d'ambiguïté.
    Chaque type de données appartient à une catégorie identifiée par un seul
    caractère ASCII, et chaque type est « préféré » ou pas de sa
    catégorie. L'analyseur préfèrera convertir vers des types préférés (mais
    seulement à partir d'autres types dans la même catégorie) quand cette règle
    peut servir à résoudre des fonctions ou opérateurs surchargés. Pour plus de
    détails, voir Chapitre 10. Pour les types qui n'ont pas de
    conversion implicite de ou vers d'autres types, on peut se contenter de laisser
    ces paramètres aux valeurs par défaut. Par contre, pour un groupe de types
    liés entre eux qui ont des conversions implicites, il est souvent pratique
    de les marquer tous comme faisant partie d'une même catégorie, et de choisir
    un ou deux des types les « plus généraux » comme étant les types
    préférés de la catégorie.
    Le paramètre catégorie est
    particulièrement utile quand on ajoute un type défini par l'utilisateur à un
    type interne, comme un type numérique ou chaîne. Toutefois, c'est aussi tout
    à fait possible de créer des catégories de types entièrement nouvelles.
    Choisissez un caractère ASCII autre qu'une lettre en majuscule pour donner
    un nom à une catégorie de ce genre.
   
    Une valeur par défaut peut être spécifiée dans le cas où l'utilisateur
    souhaite que cette valeur soit différente de NULL pour les colonnes de ce type.
    La valeur par défaut est précisée à l'aide du mot clé
    DEFAULT. (Une telle valeur par défaut peut être surchargée
    par une clause DEFAULT explicite attachée à une colonne
    particulière.)
   
    Pour indiquer qu'un type est un tableau de taille fixe, le type des éléments du
    tableau est précisé par le mot clé ELEMENT. Par exemple, pour
    définir un tableau d'entiers de quatre octets (int4),
    ELEMENT = int4 est utilisé. Pour plus de détails,
    voir Types tableau ci-dessous.
   
    Pour préciser le délimiteur de valeurs utilisé dans la
    représentation externe des tableaux de ce type,
    délimiteur peut être positionné à un
    caractère particulier. Le délimiteur par défaut est la virgule
    (,). Le délimiteur est associé avec le type
    élément de tableau, pas avec le type tableau.
   
    Si le paramètre booléen optionnel collatable vaut true, les définitions et
    expressions de colonnes du type peuvent embarquer une information de
    collationnement via la clause COLLATE. C'est aux
    implémentations des fonctions du type de faire bon usage de cette
    information. Cela n'arrive pas automatiquement en marquant le type
    collationnable.
   
    À chaque fois qu'un type défini par un utilisateur est créé,
    PostgreSQL crée automatiquement un type tableau
    associé dont le nom est composé à partir du type de base préfixé d'un tiret
    bas et tronqué si nécessaire pour que le nom généré fasse moins de
    NAMEDATALEN octets. (Si le nom généré est en conflit avec
    un autre nom, le traitement est répété jusqu'à ce qu'un nom sans conflit
    soit trouvé.) Ce type tableau créé implicitement est de longueur variable
    et utilise les fonctions d'entrée et sortie array_in et
    array_out. De plus, ce type est ce que le système
    utilise pour les constructions telles que ARRAY[] sur
    le type défini par l'utilisateur. Le type tableau trace tout changement
    dans du type de base pour le propriétaire et le schéma. Il est aussi
    supprimé quand le type de base l'est.
   
    Pourquoi existe-t-il une option
    ELEMENT si le système fabrique automatiquement le bon type
    tableau ?
    L'utilité principale d'ELEMENT est la création d'un type de longueur
    fixe représenté en interne par un tableau d'éléments identiques auxquels on souhaite
    accéder directement par leurs indices (en plus de toute autre opération
    effectuée sur le type dans sa globalité). Par exemple, le type
    point est représenté par deux nombres à virgule flottante,
    qui sont accessibles par point[0] et
    point[1]. Cette
    fonctionnalité n'est possible qu'avec les types de longueur fixe dont la
    forme interne est strictement une séquence de champs de longueur fixée.
    Pour des raisons historiques (c'est-à-dire pour de mauvaises raisons, mais
    il est trop tard pour changer) les indices des tableaux de types de longueur
    fixe commencent à zéro et non à un comme c'est le cas pour les tableaux de
    longueur variable.
   
    Ajouter l'option SUBSCRIPT permet au type de données
    d'utiliser des indices, même si le système ne le gère pas comme un type
    tableau. Le comportement tout juste décrit pour les tableaux à longueur
    fixe est en fait implémenté par la fonction gestionnaire
    SUBSCRIPT appelée
    raw_array_subscript_handler, qui est utilisée
    automatiquement si vous indiquez ELEMENT pour un type de
    longueur fixe sans écrire aussi SUBSCRIPT.
   
    Lors de l'indication explicite d'une fonction SUBSCRIPT,
    il n'est pas nécessaire d'indiquer ELEMENT sauf si la
    fonction gestionnaire SUBSCRIPT a besoin de consulter
    typelem pour savoir ce qu'elle renvoie. Faites
    attentent qu'indiquer ELEMENT cause le système à assumer
    que le nouveau type contient ou est quelque part physiquement dépendant,
    du type élément ; de ce fait, changer par exemple les propriétés du
    type élément n'est pas autorisé s'il y a des colonnes du type dépendant.
   
nomLe nom (éventuellement qualifié du nom du schéma) du type à créer.
nom_attributLe nom d'un attribut (colonne) du type composite.
type_donnéesLe nom d'un type de données existant utilisé comme colonne du type composite.
collationnementLe nom d'un collationnement existant à associer avec une colonne d'un type composite ou avec un type intervalle.
labelUne chaîne représentant le label associé à une valeur du type enum.
sous_typeLe nom du type élément dont le type intervalle va représenter des intervalles.
classe_operateur_sous_typeLe nom d'une classe d'opérateurs B-tree pour le sous-type.
fonction_canoniqueLe nom de la fonction canonique pour le type intervalle.
fonction_diff_sous_typeLe nom de la fonction de différence pour le sous-type.
multirange_type_nameLe nom du type multirange correspondant.
fonction_entréeLe nom d'une fonction de conversion des données de la forme textuelle externe du type en forme interne.
fonction_sortieLe nom d'une fonction de conversion des données de la forme interne du type en forme textuelle externe.
fonction_réceptionLe nom d'une fonction de conversion des données de la forme binaire externe du type en forme interne.
fonction_envoiLe nom d'une fonction de conversion des données de la forme interne du type en forme binaire externe.
type_modifier_input_functionLe nom d'une fonction qui convertit un tableau de modifieurs pour le type vers sa forme interne.
type_modifier_output_functionLe nom d'une fonction qui convertit la forme interne des modifieurs du type vers leur forme textuelle externe.
fonction_analyzeLe nom d'une fonction d'analyses statistiques pour le type de données.
fonction_indiceLe nom d'une fonction qui définit ce qu'indicer une valeur de ce type de données signifie.
longueur_interneUne constante numérique qui précise la longueur en octets de la représentation interne du nouveau type. Supposée variable par défaut.
alignement
      La spécification d'alignement du stockage du type de données. Peut être
      char, int2,
      int4 ou double ;
      int4 par défaut.
     
stockage
      La stratégie de stockage du type de données. Peut être plain,
      external,
      extended ou main ;
      plain par défaut.
     
type_like
      Le nom d'un type de données existant dont le nouveau type partagera la
      représentation. Les valeurs de
      longueurinterne,
      passedbyvalue,
      alignement et
      stockage sont recopiées à
      partir de ce type, sauf si elles sont écrasées explicitement ailleurs
      dans la même commande CREATE TYPE.
     
catégorie
      Le code de catégorie (un unique caractère ASCII) pour ce type.
      La valeur par défaut est U pour
      « user-defined type » (type défini par l'utilisateur).
      Les autres codes standard de catégorie peuvent être trouvés dans
      Tableau 52.63. Vous pouvez aussi choisir
      d'autres caractères ASCII pour créer vos propres catégories personnalisées.
     
préféréTrue si ce type est un type préféré dans sa catégorie de types, sinon false. La valeur par défaut est false. Faites très attention en créant un nouveau type préféré à l'intérieur d'une catégorie existante car cela pourrait créer des modifications surprenantes de comportement.
défautLa valeur par défaut du type de données. Omise, elle est NULL.
élémentType des éléments du type tableau créé.
délimiteurLe caractère délimiteur des valeurs des tableaux de ce type.
collatableVrai si les opérations de ce type peuvent utiliser les informations de collationnement. Par défaut, à faux.
Comme il n'y a pas de restrictions à l'utilisation d'un type de données une fois qu'il a été créé, créer un type de base ou un type range est équivalent à donner les droits d'exécution sur les fonctions mentionnées dans la définition du type. Ce n'est pas un problème habituellement pour le genre de fonctions utiles dans la définition d'un type mais réfléchissez bien avant de concevoir un type d'une façon qui nécessiterait que des informations « secrètes » soient utilisées lors de sa convertion vers ou à partir d'une forme externe.
   Avant PostgreSQL version 8.3, le nom d'un type
   tableau généré était toujours exactement le nom du type élément avec un
   caractère tiret bas (_) en préfixe. (Les noms des types
   étaient du coup limités en longueur à un caractère de moins que les autres
   noms.) Bien que cela soit toujours le cas, le nom d'un type tableau peut
   varier entre ceci dans le cas des noms de taille maximum et les collisions
   avec des noms de type utilisateur qui commencent avec un tiret bas. Écrire
   du code qui dépend de cette convention est du coup obsolète. À la place,
   utilisez pg_type.typarray
   pour situer le type tableau associé avec un type donné.
  
Il est conseillé d'éviter d'utiliser des noms de table et de type qui commencent avec un tiret bas. Alors que le serveur changera les noms des types tableau générés pour éviter les collisions avec les noms donnés par un utilisateur, il reste toujours un risque de confusion, particulièrement avec les anciens logiciels clients qui pourraient supposer que les noms de type commençant avec un tiret bas représentent toujours des tableaux.
   Avant PostgreSQL version 8.2, la syntaxe de
   création d'un type shell
   CREATE TYPE  n'existait pas.
   La façon de créer un nouveau type de base était de créer en premier les
   fonctions paramètres. Dans cette optique,
   PostgreSQL verra tout d'abord le nom d'un nouveau
   type de données comme type de retour de la fonction en entrée. Le type shell
   est créé implicitement dans ce cas et il est ensuite référencé dans le reste
   des fonctions d'entrée/sortie. Cette approche fonctionne toujours mais
   est obsolète et pourrait être interdite dans une version future. De plus,
   pour éviter de faire grossir les catalogues de façon accidentelle avec des
   squelettes de type erronés, un squelette sera seulement créé quand la fonction
   en entrée est écrit en C.
  nom
Créer un type composite utilisé dans la définition d'une fonction :
CREATE TYPE compfoo AS (f1 int, f2 text); CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$ SELECT fooid, fooname FROM foo $$ LANGUAGE SQL;
Cet exemple crée un type énuméré et l'utilise dans la création d'une table :
CREATE TYPE statut_bogue AS ENUM ('nouveau', 'ouvert', 'fermé');
CREATE TABLE bogue (
    id serial,
    description text,
    status statut_bogue
);
   
Cet exemple crée un type intervalle :
CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
   Créer le type de données basique box utilisé dans
   la définition d'une table :
   
CREATE TYPE box;
CREATE FUNCTION ma_fonction_entree_box(cstring) RETURNS box AS ... ;
CREATE FUNCTION ma_fonction_sortie_box(box) RETURNS cstring AS ... ;
CREATE TYPE box (
    INTERNALLENGTH = 16,
    INPUT = ma_fonction_entree_box,
    OUTPUT = ma_fonction_sortie_box
);
CREATE TABLE myboxes (
    id integer,
    description box
);
   
   Si la structure interne de box est un tableau de quatre
   éléments float4, on peut écrire :
   
CREATE TYPE box (
    INTERNALLENGTH = 16,
    INPUT = ma_fonction_entree_box,
    OUTPUT = ma_fonction_sortie_box,
    ELEMENT = float4
);
   ce qui permet d'accéder aux nombres composant la valeur d'une boîte par les indices. Le comportement du type n'est pas modifié.
Créer un objet large utilisé dans la définition d'une table :
CREATE TYPE bigobj (
    INPUT = lo_filein, OUTPUT = lo_fileout,
    INTERNALLENGTH = VARIABLE
);
CREATE TABLE big_objs (
    id integer,
    obj bigobj
);
   
D'autres exemples, intégrant des fonctions utiles d'entrée et de sortie, peuvent être consultés dans Section 38.13.
   La première forme de la commande CREATE TYPE, qui crée
   un type composite, est conforme au standard SQL. Les
   autres formes sont des extensions de PostgreSQL.
   L'instruction CREATE TYPE du standard
   SQL définit aussi d'autres formes qui ne sont pas
   implémentées dans PostgreSQL.
  
   La possibilité de créer un type composite sans attributs est une différence
   spécifique de PostgreSQL que le standard ne
   propose pas (de façon analogue au CREATE TABLE).