sql >> Base de Datos >  >> RDS >> PostgreSQL

La función superior de Postgres en el carácter turco no devuelve el resultado esperado

Tu problema es 100% Windows. (O más bien, Microsoft Visual Studio, con el que se creó PostgreSQL, para ser más precisos).

Para el registro, SQL UPPER termina llamando a LCMapStringW de Windows (a través de towupper vía str_toupper ) con casi todos los parámetros correctos (locale 1055 Turco para un UTF-8 -codificado, Turkish_Turkey base de datos),

pero

el tiempo de ejecución de Visual Studio (towupper ) no establece el LCMAP_LINGUISTIC_CASING bit en LCMapStringW 's dwMapFlags . (Puedo confirmar que configurarlo funciona). Esto no se considera un error en Microsoft; es por diseño, y probablemente nunca será "arreglado" (Oh, las alegrías del legado.)

Tienes tres formas de salir de esto:

  • implemente la solución contenedora de @Sorrow (o escriba su propio reemplazo de función nativa (DLL).)
  • ejecuta tu instancia de PostgreSQL, p. Ubuntu que exhibe el comportamiento correcto para los lugares de Turkic (@Sorrow confirmó que funciona para él); esta es probablemente la salida más simple y limpia.
  • coloque un parche MSVCR100.DLL de 32 bits en su bin de PostgreSQL directorio (pero aunque UPPER y LOWER funcionaría, otras cosas, como la intercalación, podrían seguir fallando, de nuevo, a nivel de Windows. YMMV.)

Para completar (y diversión nostálgica) SOLO , este es el procedimiento para parchear un sistema Windows (pero recuerde, a menos que esté administrando esta instancia de PostgreSQL desde la cuna hasta la tumba, puede causar mucho dolor a su(s) sucesor(es); cada vez que implemente un nuevo sistema de prueba o respaldo desde scratch, usted o su(s) sucesor(es) tendrían que recordar aplicar el parche nuevamente, y si, digamos, algún día actualiza a PostgreSQL 10, que dice que usa MSVCR120.DLL en lugar de MSVCR100.DLL , entonces tendrá que probar suerte parcheando la nueva DLL también). En un sistema de prueba

  • usa HxD para abrir C:\WINDOWS\SYSTEM32\MSVCR100.DLL
  • guarde la DLL de inmediato con el mismo nombre debajo de PostgreSQL bin directorio (no intente copiar el archivo usando Explorer o la línea de comandos, podrían copiar la versión de 64 bits)
  • con el archivo aún abierto en HxD, vaya a Buscar> Reemplazar , elija Tipo de datos:valores hexadecimales , entonces
    • buscar...... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 00
    • reemplazar con... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 01
    • ...luego una vez más...
    • buscar...... FC 51 6A 01 8D 4D 08 51 68 00 02 00 00 50 E8 E2
    • reemplazar con... FC 51 6A 01 8D 4D 08 51 68 00 02 00 01 50 E8 E2
  • ... y volver a guardar en el bin de PostgreSQL directorio, luego reinicie PostgreSQL y vuelva a ejecutar su consulta.
    • si su consulta aún no funciona (asegúrese de que su base de datos esté codificada en UTF-8 con Turkish_Turkey para ambos LC_CTYPE y LC_COLLATE ) abra postgres.exe en Caminante de dependencias de 32 bits y asegúrese de que indica que carga MSVCR100.DLL desde el bin de PostgreSQL directorio.
    • si todas las funciones están bien, copie la DLL parcheada en el bin de PostgreSQL de producción directorio y reiniciar.

PERO RECUERDE, en el momento en que traslade los datos del sistema Ubuntu o del sistema Windows parcheado a un sistema Windows sin parches, volverá a tener el problema y es posible que no pueda volver a importar estos datos en Ubuntu si la instancia de Windows introdujo duplicados en un citext campo o en un UPPER /LOWER índice de función basado.