sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgres övre funktion på turkisk karaktär ger inte förväntat resultat

Ditt problem är 100 % Windows. (Eller snarare Microsoft Visual Studio, som PostgreSQL byggdes med, för att vara mer exakt.)

För att ta reda på, SQL UPPER slutar anropa Windows LCMapStringW (via towupper via str_toupper ) med nästan alla rätt parametrar (locale 1055 turkiska för en UTF-8 -kodad, Turkish_Turkey databas),

men

Visual Studio Runtime (towupper ) ställer inte in LCMAP_LINGUISTIC_CASING bit i LCMapStringW s dwMapFlags . (Jag kan bekräfta att inställningen gör susen.) Detta anses inte vara ett fel hos Microsoft; det är designat och kommer förmodligen aldrig att "fixas" (åh, arvets glädje.)

Du har tre vägar ut ur detta:

  • implementera @Sorrows omslagslösning (eller skriv din egen inbyggda funktionsersättning (DLL).)
  • kör din PostgreSQL-instans på t.ex. Ubuntu som uppvisar rätt beteende för turkiska lokaler (@Sorrow bekräftade att det fungerar för honom); detta är förmodligen den enklaste och renaste vägen ut.
  • släpp in en korrigerad 32-bitars MSVCR100.DLL i din PostgreSQL bin katalog (men även om UPPER och LOWER skulle fungera, andra saker som sortering kan fortsätta att misslyckas -- igen, på Windows-nivå. YMMV.)

För fullständighetens skull (och nostalgisk kul) ENDAST , här är proceduren för att patcha ett Windows-system (men kom ihåg, om du inte kommer att hantera den här PostgreSQL-instansen från vagga till grav kan du orsaka mycket sorg för dina efterträdare; närhelst du distribuerar ett nytt test- eller backupsystem från repa du eller dina efterträdare måste komma ihåg att applicera patchen igen -- och om låt oss säga att du en dag uppgraderar till PostgreSQL 10, som säger använder MSVCR120.DLL istället för MSVCR100.DLL , då måste du prova lyckan med att patcha den nya DLL-filen också.) På ett testsystem

  • använd HxD för att öppna C:\WINDOWS\SYSTEM32\MSVCR100.DLL
  • spara DLL direkt med samma namn under PostgreSQL bin katalog (försök inte kopiera filen med Explorer eller kommandoraden, de kan kopiera 64-bitarsversionen)
  • med filen fortfarande öppen i HxD, gå till Sök> Ersätt , välj Datatyp:Hexvärden , sedan
    • sök efter...... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 00
    • ersätt med... 4E 14 33 DB 3B CB 0F 84 41 12 00 00 B8 00 01 00 01
    • ...sen en gång till...
    • sök efter...... FC 51 6A 01 8D 4D 08 51 68 00 02 00 00 50 E8 E2
    • ersätt med... FC 51 6A 01 8D 4D 08 51 68 00 02 00 01 50 E8 E2
  • ...och spara igen under PostgreSQL bin katalog, starta sedan om PostgreSQL och kör din fråga igen.
    • om din fråga fortfarande inte fungerar (se till att din databas är UTF-8-kodad med Turkish_Turkey för båda LC_CTYPE och LC_COLLATE ) öppna postgres.exe i 32-bitars Dependency Walker och se till att det indikerar att den laddar MSVCR100.DLL från PostgreSQL bin katalog.
    • om alla funktioner bra kopierar den korrigerade DLL-filen till produktionen PostgreSQL bin katalogen och starta om.

MEN KOM IHÅG, i det ögonblick du flyttar data från Ubuntu-systemet eller från det korrigerade Windows-systemet till ett oparpat Windows-system kommer du att få problemet igen, och du kanske inte kan importera dessa data tillbaka till Ubuntu om Windows-instansen introducerade dubbletter i en citext fältet eller i en UPPER /LOWER -baserat funktionsindex.



  1. MySQL:Ignorera en vald kolumn när du använder DISTINCT

  2. MySQL beräkna procentandelen av två andra beräknade summor inklusive en grupp per månad

  3. Oracle PL/SQL UTL_FILE.PUT buffring

  4. Sök efter en post - i en databas (utan att ange ett kolumnnamn/tabellnamn)