IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

23.2. Support des collations

Cette fonctionnalité permet de définir pour colonne, ou pour chaque requête, la collation utilisée pour déterminer l'ordre de tri et le classement des caractères. Cette fonctionnalité permet de lever la restriction sur les paramètres LC_COLLATE et LC_CTYPE d'une base de données et qui ne pouvaient pas être modifiés après sa création.

23.2.1. Concepts

Conceptuellement, toute expression d'un type de donnée qui est collatable a une collation. (Les types de données intégrés qui supportent une collation sont text, varchar, et char. Les types de données définies par l'utilisateur peuvent aussi être marquées comme supportant la collation, et bien entendu un domaine qui est défini sur un type de données supportant la collation est, lui aussi, collationnable.) Si l'expression est une colonne, la collation de l'expression est déterminée par la collation de la colonne. Si l'expression est une constante, la collation utilisée sera la collation par défaut du type de données de la constante. La collation d'une expression plus complexe est déterminée à partir des différentes collations de ses entrées, comme cela est décrit ci-dessous.

Une expression peut prendre la collation par défaut, « default », c'est à dire la collation définie au niveau de la base de données. Il est possible que la collation d'une expression soit indéterminée. Dans un tel cas, les opérations de tri et les autres opérations qui ont besoin de connaître la collation vont échouer.

Lorsque la base de données doit réaliser un tri ou classement de caractères, alors elle utilisera la collation de l'expression en entrée. Ce cas se présentera, par exemple, si vous employez la clause ORDER BY et des appels à des fonctions ou des opérateurs tels que <. La collation qui s'applique à une clause ORDER BY est simplement la collation de la clé de tri. La collation qui s'applique pour l'appel à une fonction ou à un opérateur est dérivé des arguments, comme décrit plus bas. En plus de s'appliquer aux opérateurs de comparaison, les collations sont également prises en compte par les fonctions qui réalisent les conversions entre minuscules et majuscules, comme lower, upper et initcap; par les opérateurs de correspondance de motifs et par to_char et les fonctions affiliées.

Pour un appel à une fonction ou un opérateur, la collation est déterminée à partir de la collation des arguments qui sont passés à l'exécution de l'opération. Si une expression voisine nécessite de connaître la collation de la fonction ou de l'opérateur, et si le type de données du résultat de l'appel possède une collation alors cette collation est interprétée comme la collation de l'expression au moment de l'analyse.

Le calcul de la collation d'une expression est réalisé implicitement ou explicitement. Cette distinction affecte la façon dont les collations sont combinées entre elles lorsque plusieurs collations différentes sont utilisées dans une expression. La collation d'une expression peut être déterminée explicitement par l'emploi de la clause COLLATE; dans les autres cas, la collation est déterminée de manière implicite. Les règles suivantes s'appliquent lorsque plusieurs collations doivent être utilisée en même temps, par exemple dans un appel à une fonction, les règles suivantes s'appliquent:

  1. Si la collation d'une expression d'entrée est déclarée explicitement alors les collations déclarée explicitement pour les autres expressions d'entrées doivent être les mêmes, sinon une erreur est levée. Si une expression en entrée contient une collation explicite, toutes les collations explicitement dérivées parmi les expressions en entrée doivent être identiques. Dans le cas contraire, une erreur est renvoyée. Si une collation dérivée explicitement est présente, elle est le résultat de la combinaison des collations.

  2. Dans les autres cas, toutes les expressions en entrée doivent avoir la même collation, qu'elle soit implicite ou déterminée à partir de la collation par défaut. Si une collation est présente, autre que celle par défaut, elle est le résultat de la combinaison des collations. Sinon, le résultat correspond à la collation par défaut.

  3. S'il existe des collations implicites mais non par défaut qui entrent en conflit avec les expressions en entrée, alors la combinaison ne peut aboutir qu'à une collation indéterminée. Ce n'est pas une erreur sauf si la fonction appelée requiert une application de la collation. Dans ce cas, une erreur est renvoyée lors de l'exécution.

Par exemple, considérez la table définie de la façon suivante:

CREATE TABLE test1 (
    a text COLLATE "de_DE",
    b text COLLATE "es_ES",
    ...
);
    

Ensuite, dans la requête

SELECT a < 'foo' FROM test1;
    

la comparaison < est réalisée en tenant compte des règles de la locale de_DE, parce que l'expression combine la collation calculée implicitement avec la collation par défaut. Mais, dans la requête

        SELECT a < ('foo' COLLATE "fr_FR") FROM test1;
        

la comparaison est effectuée en utilisant les règles de la locale fr_FR, parce que l'utilisation explicite de cette locale prévaut sur la locale déterminée de manière implicite. De plus, avec la requête

        SELECT a < b FROM test1;
        

l'analyseur ne dispose pas des éléments pour déterminer quelle collation employer, car les collations des colonnes a et b sont différentes. Comme l'opérateur < a besoin de connaître quelle locale utiliser, une erreur sera générée. Cette erreur peut être résolue en attachant une déclaration de collation explicite à l'une ou l'autre des expressions d'entrées, soit:

        SELECT a < b COLLATE "de_DE" FROM test1;
    

ou de manière équivalente

        SELECT a COLLATE "de_DE" < b FROM test1;
    

Toutefois, pour cas structurellement similaire comme

SELECT a || b FROM test1;
    

ne retournera pas d'erreur car l'opérateur || ne tient pas compte des collations: son résultat sera le même quel que soit la collation.

La collation qui est assignée à une fonction ou à une combinaisons d'un opérateur avec ses expressions d'entrées s'appliquent également au résultat de la fonction ou de l'opérateur. Bien évidemment, cela s'applique que si la fonction de l'opérateur délivre un résultat dans un type de données auquel la collation peut s'appliquer. Ainsi, dans la requête

        SELECT * FROM test1 ORDER BY a || 'foo';
        

le tri sera réalisé en fonction de règles de la locale de_DE. Mais cette requête:

SELECT * FROM test1 ORDER BY a || b;
    

retournera une erreur car bien que l'opérateur || ne tienne pas compte des collations de ses expressions, la clause ORDER BY en tient compte. Comme précédemment, ce conflit peut être résolue par l'emploi d'une déclaration explicite de collation:

SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
    

23.2.2. Gestion des collations

Une collation est un objet du catalogue dont le nom au niveau SQL correspond à une locale fournie par les bibliothèques installées sur le système. Une définition de la collation a un fournisseur spécifiant quelle bibliothèque fournit les données locales. L'un des fournisseurs standards est libc, qui utilise les locales fournies par la bibliothèque C du système. Ce sont les locales les plus utilisées par des outils du système. Un autre fournisseur est icu, qui utilise la bibliothèque externe ICU. Les locales ICU peuvent seulement être utilisées si le support d'ICU a été configuré lors de la construction de PostgreSQL.

Un objet de type collation fourni par libc pointe sur une combinaison de paramètres LC_COLLATE et LC_CTYPE. (Comme le nom le suggère, le principal objectif d'une collation est de positionner LC_COLLATE qui contrôle l'ordre de tri. Dans la pratique, il est très rarement nécessaire de définir un paramètre LC_CTYPE différent de LC_COLLATE. De cette façon, il est plus facile de regrouper ces deux paramètres dans un même concept plutôt que de créer une infrastructure différente simplement pour pouvoir positionner LC_CTYPE pour chaque requête.) De la même façon, une collation libc est liée à un jeu de caractère (voir Section 23.3, « Support des jeux de caractères »). Ainsi, plusieurs jeux de caractères peuvent utiliser une collation portant le même nom.

Un objet de type collation fourni par icu pointe sur un collateur nommé fourni par la bibliothèque ICU. ICU ne permet pas de paramétrages « collate » et « ctype » séparés, ils sont donc toujours les mêmes. De même, les collations ICU sont indépendantes de l'encodage, donc il n'y a toujours qu'une seule collation ICU pour un nom donné dans une base de données.

23.2.2.1. Standard de collations

Les collations nommées default, C, et POSIX sont disponibles sur toutes les plateformes. Les collations complémentaires seront ou non disponibles en fonction de leur support au niveau du système d'exploitation. La collation default permet d'utiliser les valeurs de LC_COLLATE et LC_CTYPE telles qu'elles ont été définies à la création de la base de données. Les collations C et POSIX spécifie toute deux le comportement « traditionnel C », dans lequel seules les caractères ASCII de « A » à « Z » sont considérées comme des lettres, et les tris sont ordonnés strictement par valeur de l'octet du code caractère.

En complément, la collation du standard SQL, nommée ucs_basic, est disponible avec l'encodage UTF8. Elle est équivalente à C et trie les données par le point de code Unicode.

23.2.2.2. Collations prédéfinies

Si le système d'exploitation permet à un programme de supporter plusieurs locales (fonction newlocale et fonctions conjointes) ou si le support d'ICU est configuré, alors initdb peuplera le catalogue système pg_collation en se basant sur toutes les locales qu'il trouve sur le système d'exploitation au moment de l'initialisation du cluster de bases de données.

Pour inspecter les locales actuellement disponibles, utilisez la requête SELECT * FROM pg_collation, ou la commande \dOS+ dans psql.

23.2.2.2.1. Collations LibC

Par exemple, le système d'exploitation peut offrir une locale appelée de_DE.utf8. initdb créera alors une collation nommée de_DE.utf8 pour le jeu de caractère UTF8 pour lequel LC_COLLATE et LC_CTYPE sont positionnés à de_DE.utf8. Il créera aussi une collation dont le nom sera amputé du tag .utf8. Ainsi, vous pouvez utiliser cette collation sous le nom de_DE, dont l'écriture est beaucoup plus facile et qui le rend moins dépendant du jeu de caractères. Néanmoins, notez que le nommage de chaque collation collectée par initdb est dépendant de la plateforme utilisée.

Le jeu de collation par défaut fourni par libc pointe directement vers les locales installées sur le système, qui peuvent être listées en utilisant la commande locale -a. Dans le cas où une collation libc avec différentes valeurs pour LC_COLLATE et LC_CTYPE est nécessaire, ou si des nouvelles locales sont installées sur le système après que la base de données soit initialisée, alors une nouvelle collation pourrait être créée en utilisant la commande CREATE COLLATION(7). De nouvelles locales du système d'exploitation peuvent aussi être importées en masse en utilisant la fonction pg_import_system_collations().

Dans une même base de données, seules les collations qui utilisent le jeu de caractères de la base de données sont pris en compte. Les autres entrées de pg_collation sont ignorées. De cette façon, une collation dont le nom est tronqué, comme de_DE, sera considéré de manière unique au sein d'une même base de données, même si elle ne peut être considérée comme unique à un niveau plus global. L'utilisation de collations dont le nom est tronqué est d'ailleurs recommandé car vous n'aurez pas besoin de le modifier si vous décidez de changer le jeu de caractères de la base de données. Notez toutefois que les collations default, C, et POSIX peuvent être utilisé sans se soucier de l'encodage de la base de données.

PostgreSQL™ considère les collations comme des objets distincts et incompatibles entre eux, même si elles possèdent des propriétés identiques. Ainsi, par exemle,

SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1;
    

va afficher une erreur alors que les collations C et POSIX possèdent des propriétés strictement identiques. Il n'est donc pas recommandé de mélanger des collations dont le nom est complet avec des collations dont le nom l'est.

23.2.2.2.2. Collations ICU

Les collations fournies par ICU sont créées avec des noms correspondant au format de balises de langage BCP 47, avec l'ajout d'une extension -x-icu à « usage privé », pour les distinguer des locales libc. Donc de-x-icu serait un exemple.

Avec ICU, il n'est pas nécessaire d'énumérer tous les noms de locales possibles. ICU utilise un système de nommage particulier pour les locales, mais il y a plus de façons de nommer une locale qu'il y a actuellement de locales distinctes. (En fait, n'importe quelle chaine de caractères sera acceptée en tant que nom de locale.) Consultez http://userguide.icu-project.org/locale pour des informations sur le nommage des locales ICU. initdb utilise l'API ICU pour extraire un jeu de locales distinctes afin de peupler le jeu initial de collations. Voici quelques exemples de collations pouvant être créées :

de-x-icu

Collation allemande, variante par défaut

de-AT-x-icu

Collation allemande pour l'Autriche, variante par défaut

(Il y a aussi, par exemple, de-DE-x-icu ou de-CH-x-icu mais, lorsque cette partie fut rédigée, elles étaient équivalentes à de-x-icu.)

und-x-icu (pour « undefined »)

Collation « root » ICU. Utilisez ceci pour avoir un ordre de tri linguistique agnostique raisonnable.

Certains encodages parmi les moins fréquemment utilisés ne sont pas supportés par ICU. Si c'est le cas pour l'encodage de la base de données, les enregistrements de collations ICU dans pg_collation sont ignorés. Tenter d'en utiliser un renverra une erreur du type « collation "de-x-icu" for encoding "WIN874" does not exist ».

ICU permet la personnalisation des collations en dehors de l'ensemble pré- enregistré langue/pays, préchargé par initdb. Les utilisateurs sont encouragés à définir leur propres objets de collation utilisant ces fonctionnalités pour rendre le comportement de tri compatible avec leurs besoins. Voici quelques exemples :

CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk')

Collationnement allemand avec le type de collationnement d'un carnet d'adresses

CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji')

Collationnement racine avec un type de collationnement Emoji, d'après l'Unicode Technical Standard #51

CREATE COLLATION digitslast (provider = icu, locale = 'en-u-kr-latn-digit')

Trie les chiffres après les lettres latines. (Par défaut, les chiffres sont avant les lettres.)

CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper')

Trie les lettres majuscules avant les lettres minuscules. (La valeur par défaut est les mniscules avant).

CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-latn-digit')

Combine ces deux options.

CREATE COLLATION numeric (provider = icu, locale = 'en-u-kn-true')

Ordre numérique, trie les séquences de chiffres par leur valeur numérique. Par exemple : A-21 < A-123 (aussi connu sous le nom de tri naturel).

Voir Unicode Technical Standard #35 et BCP 47 pour les détails. La liste des types de collationnement possibles (sous-ensemble co) peut être trouvée dans le dépôt CLDR. Le ICU Locale Explorer peut être utilisé pour vérifier les détails de la définition d'une locale particulière.

Notez qu'alors que ce système permet la création de collationnements qui « ignorent la casse » ou « ignorent les accents » ou quelque chose de similaire (en utilisant la clé ks), PostgreSQL ne permet pas pour le moment que ces collationnements n'agissent d'une façon réellement insensible à la casse ou aux accents. Toute chaîne qui se compare raisonnablement suivant le collationnement mais qui n'est pas identique octet à octet, sera trié suivant la valeurs des octets.

23.2.2.3. Copier les collations

La commande CREATE COLLATION(7) peut également être utilisée pour créer une nouvelle collation depuis une collation existante, ce qui peut être utile afin d'être capable d'utiliser une collation indépendante du système dans les applications, de créer des noms compatibles, ou d'utiliser une collation fournie par ICU avec un nom plus lisible. Par exemple :

CREATE COLLATION german FROM "de_DE";
CREATE COLLATION french FROM "fr-x-icu";

Les collations standards et prédéfinies se trouvent dans le schéma pg_catalog, comme tout objet prédéfini. Les collations définies par l'utilisateur devraient être créées dans les schémas utilisateur. Ceci permet également de s'assurer qu'ils sont sauvegardés par pg_dump.