Votre problème est 100 % Windows. (Ou plutôt Microsoft Visual Studio, avec lequel PostgreSQL a été construit, pour être plus précis.)
Pour mémoire, SQL UPPER finit par appeler LCMapStringW de Windows
(via towupper
via str_toupper
) avec presque tous les bons paramètres (locale 1055 turc pour un UTF-8 -encodé, Turkish_Turkey base de données),
mais
le Runtime de Visual Studio (towupper ) ne définit pas le LCMAP_LINGUISTIC_CASING
bit dans LCMapStringW dwMapFlags de . (Je peux confirmer que le réglage fait l'affaire.) Ceci n'est pas considéré comme un bogue chez Microsoft ; c'est voulu et ne sera probablement jamais "réparé" (oh les joies de l'héritage.)
Vous avez trois façons de vous en sortir :
- implémentez la solution wrapper de @Sorrow (ou écrivez votre propre remplacement de fonction native (DLL).)
- exécutez votre instance PostgreSQL, par ex. Ubuntu qui présente le bon comportement pour les paramètres régionaux turcs (@Sorrow a confirmé que cela fonctionnait pour lui); c'est probablement la solution la plus simple et la plus propre.
- ajoutez un fichier
MSVCR100.DLL32 bits corrigé dans votrebinPostgreSQL répertoire (mais bien queUPPERetLOWERfonctionnerait, d'autres choses telles que le classement peuvent continuer à échouer - encore une fois, au niveau de Windows. YMMV.)
Pour être complet (et plaisir nostalgique) SEULEMENT , voici la procédure pour corriger un système Windows (mais rappelez-vous, à moins que vous ne gériez cette instance PostgreSQL du berceau à la tombe, vous risquez de causer beaucoup de problèmes à votre ou vos successeurs ); chaque fois que vous déployez un nouveau système de test ou de sauvegarde à partir de vous ou vos successeurs devrez vous rappeler d'appliquer à nouveau le correctif - et si disons qu'un jour vous mettez à niveau vers PostgreSQL 10, qui dit utilise MSVCR120.DLL au lieu de MSVCR100.DLL , vous devrez également tenter votre chance en corrigeant la nouvelle DLL.) Sur un système de test
- utiliser HxD
pour ouvrir
C:\WINDOWS\SYSTEM32\MSVCR100.DLL - enregistrez immédiatement la DLL avec le même nom sous votre PostgreSQL
binrépertoire (n'essayez pas de copier le fichier à l'aide de l'Explorateur ou de la ligne de commande, ils pourraient copier la version 64 bits) - avec le fichier toujours ouvert dans HxD, allez dans Rechercher> Remplacer , sélectionnez Type de données :valeurs hexadécimales , alors
- chercher......
4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 00 - remplacer par...
4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 01 - ...puis encore une fois...
- rechercher......
FC 51 6A 01 8D 4D 08 51 68 00 02 00 00 50 E8 E2 - remplacer par...
FC 51 6A 01 8D 4D 08 51 68 00 02 00 01 50 E8 E2
- chercher......
- ...et ré-enregistrer sous le
binPostgreSQL répertoire, puis redémarrez PostgreSQL et relancez votre requête.- si votre requête ne fonctionne toujours pas (assurez-vous que votre base de données est encodée en UTF-8 avec
Turkish_Turkeypour les deuxLC_CTYPEetLC_COLLATE) ouvrezpostgres.exedans Explorateur de dépendances 32 bits et assurez-vous qu'il indique qu'il chargeMSVCR100.DLLdepuis lebinde PostgreSQL répertoire. - si tout fonctionne bien, copiez la DLL corrigée dans le
binPostgreSQL de production répertoire et redémarrez.
- si votre requête ne fonctionne toujours pas (assurez-vous que votre base de données est encodée en UTF-8 avec
MAIS N'OUBLIEZ PAS, au moment où vous déplacez les données du système Ubuntu ou du système Windows corrigé vers un système Windows non corrigé, vous aurez à nouveau le problème, et vous ne pourrez peut-être pas réimporter ces données sur Ubuntu si l'instance Windows introduit des doublons dans un citext champ ou dans un UPPER /LOWER index de fonction basé sur.