42704: collation “tr_TR” for encoding “UTF8” does not exist

Bu yazı, PostgreSQL 13 bir veritabanı için uygulama ekiplerinden gelen aşağıdaki hata üzerine yapılan çalışmaları içermektedir.

Hata

 42704: collation "tr_TR" for encoding "UTF8" does not exist

Bu hata üzerine ilgili veritabanı kontrol edildi ve Collate kısmının en_US.UTF-8 olduğu görüldü

Name        |  Owner   | Encoding |   Collate   | Ctype
uys         | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8

Bu hata alınması üzerine tr_TR.UTF-8 bir database oluşturalım ve mevcut veritabanını bu veritabanına taşıyalım, sonra isim değişikliği yapıp bu problemi ortadan kaldıralım diye düşündüm, teoride harika ancak aşağıda görüldüğü üzere pratikte öyle olmadı :=)

postgres=# Create Database uys_collate with ENCODING = 'UTF8'  LC_COLLATE = 'tr_TR.UTF-8' LC_CTYPE = 'tr_TR.UTF-8';
ERROR:  invalid locale name: "tr_TR.UTF-8"

locale name bulamıyorum diyor. Mevcut locale durumuna OS seviyesinde bir bakalım;

# locale -a
C.utf8
en_AG
en_AU
en_AU.utf8
en_BW
en_BW.utf8
en_CA
en_CA.utf8
en_DK
en_DK.utf8
en_GB
en_GB.iso885915
en_GB.utf8
en_HK
en_HK.utf8
en_IE
[email protected]
en_IE.utf8
en_IL
en_IN
en_NG
en_NZ
en_NZ.utf8
en_PH
en_PH.utf8
en_SC.utf8
en_SG
en_SG.utf8
en_US
en_US.iso885915
en_US.utf8
en_ZA
en_ZA.utf8
en_ZM
en_ZW
en_ZW.utf8

Tr ile ilgili bir locale bulunmuyor, sadece bu liste var peki tüm locale listesinin olması için ne yapmalıyız; glibc-all-langpacks paketini yüklemeliyiz. Bu örnekteki makine Centos8 ve offline durumda, o yüzden
glibc-all-langpacks-2.28-164.el8.x86_64.rpm paketini internetten bulup sunucu üzerine kopyaladım ve;

# rpm -ivh glibc-all-langpacks-2.28-164.el8.x86_64.rpm
Verifying...                          ################################# [100%]
Preparing...                          ################################# [100%]
Updating / installing...
   1:glibc-all-langpacks-2.28-164.el8 ################################# [100%]
   
   
# rpm -qa|grep  glibc-all-langpacks
glibc-all-langpacks-2.28-164.el8.x86_64

# locale -a
 
--zilyon tane locale geldiğini görmeliyiz :)

Veritabanı kapatılıp açılır

$ pg_ctl stop
$ pg_ctl start

Tekrar deniyoruz;

postgres=# Create Database uys_collate with ENCODING = 'UTF8'  LC_COLLATE = 'tr_TR.UTF-8' TEMPLATE template0;
CREATE DATABASE

postgres-# \l
                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-------------+----------+----------+-------------+-------------+-----------------------
 cbs         | kcacbs   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 postgres    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
 template1   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
 uys         | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres         +
             |          |          |             |             | postgres=CTc/postgres+
             |          |          |             |             | uys=CTc/postgres     +
             |          |          |             |             | uys_app=CTc/postgres +
             |          |          |             |             | pms=CTc/postgres
 uys_collate | postgres | UTF8     | tr_TR.UTF-8 | en_US.UTF-8 |
(6 rows)

Mevcut Collation için bir test yapalım sonrasında olmadı ise Collation create işlemi yapacağız

uys_collate=# select lower('ISPARTA' COLLATE "tr_TR.UTF-8");
ERROR:  collation "tr_TR.UTF-8" for encoding "UTF8" does not exist

postgres=# create collation "tr_TR.UTF-8" (LOCALE="tr_TR.UTF-8");
CREATE COLLATION
postgres=#
postgres=# select lower('ISPARTA' COLLATE "tr_TR.UTF-8");
  lower
---------
 ısparta
(1 row)

--uys_collate içinde yapmalıyız bu işlemi

uys_collate=# select lower('ISPARTA' COLLATE "tr_TR.UTF-8");
ERROR:  collation "tr_TR.UTF-8" for encoding "UTF8" does not exist
LINE 1: select lower('ISPARTA' COLLATE "tr_TR.UTF-8");
                               ^
uys_collate=# create collation "tr_TR.UTF-8" (LOCALE="tr_TR.UTF-8");
CREATE COLLATION
uys_collate=# select lower('ISPARTA' COLLATE "tr_TR.UTF-8");
  lower
---------
 ısparta
(1 row)