Re: [BUGS] BUG #1931: ILIKE and LIKE fails on Turkish locale (fwd)

From: Volkan YAZICI <volkan(dot)yazici(at)gmail(dot)com>
To: Devrim GUNDUZ <devrim(at)gunduz(dot)org>
Cc: pgsql-tr-genel(at)postgresql(dot)org
Subject: Re: [BUGS] BUG #1931: ILIKE and LIKE fails on Turkish locale (fwd)
Date: 2005-10-14 08:06:59
Message-ID: 7104a7370510140106w28552cf4wf62a91cec3156e19@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-tr-genel

Merhaba,

On 10/2/05, Devrim GUNDUZ <devrim(at)gunduz(dot)org> wrote:
> Geçenlerde UTF-8'de bir çalışma yaparken ILIKE üzerinde bir hata
> farkettik. Sorun İ ile i'nin (ya da diğer özel harflerin( ILIKE
> sorgusunda ortaya çıkıyordu. Sorunu önce glibc'de sandım ve ilk hata
> raporunu oraya gönderdim:
>
> http://sourceware.org/bugzilla/long_list.cgi?buglist=1354
>
> Ancak yanıtı anında alınca ( :-D ) gecikmeli de olsa PostgreSQL'e hata
> bildirdim:
>
> http://archives.postgresql.org/pgsql-bugs/2005-10/msg00001.php

Gecenin bu saatinde (biliyorum artık sabah oldu) yaklaşık 10 saattir
çalışıyorum ve açıkcası bu sorunun şuan için ideal bir çözümü olmadığı
görüşündeyim. Yani bir yama ile bu sorun hallolsa dahi, çözüm "Quick &
Dirty" olmaktan öteye geçemez. İzah etmek gerekirse:

ASCII dışındaki karakterler, PostgreSQL'de char olarak ele
alındığından her bir UTF8 karakteri N tane char tipine denk geliyor.
(Burada N, stdlib.h'de tanımlanan MAX_MB_LEN'den küçük, 1'den büyük.)
Bu nedenle şu sorun ortaya çıkıyor:

ASCII Ö: [X]
UTF Ö: [Y][Z]
[X] ?= [Y][Z]

Bu sorun bir nebze aşılabilir nitelikte: ASCII Ö karakterini UTF8'e
çevirirsiniz olur biter. Ama iş harf boyutları ile oynamaya geldiğinde
su bulanıklaşıyor. (Bkz. PostgreSQL kaynak kodunun içine girip şunu
deneyin: bogus ve locale kelimelerinin arattırımı.) Şöyle ki, istemci
locale'si ile 2 byte'lık char haline getirilmiş wchar (yani multi-byte
char), sunucu tarafından, sunucu locale'si ile ilk önce tekrar wchar
haline getirilip towlower/towupper çağrıları gerçekleştiriliyor, sonra
tekrar dön geri 2 byte'lık char helinde saklanıyor. Yani epey bir
amelelik gerektiriyor. Aslında sorun bu da değil, genelde sunucu ve
istemci locale'si uyuşmadığı için towlower/towupper çağrıları hatalı
sonuç döndürüyor. (Bkz. Bizim durum.) setlocale() ile durum
kurtarılabilir gözüküyor, ama ya sunucu işletim sisteminde ilgili
locale yoksa?

MySQL'in kaynak kodunu (ANLADIĞIM KADARI İLE) incelediğimde, onların
yöntemleri bana çok daha sağlıklı geldi. Eğer veritabanını Multi-Byte
desteği aktif olarak derlenirse, amcam char yerine wchar kullanıyor ve
yukarıda saydığım tüm sorunların üstesinden gelmiş oluyor. Aksi halde,
normal ASCII char ile yoluna paşa paşa devam ediyor. (Bunun bir
performans artısı sağlayacağını da görebildiniz umarım. Eğer
veritabanı sadece ASCII kullanırsa birden fazla char tipi gerektiren
MB karakterler için uğraşmayacak. Her karakter tek bir char içine
sığacak.) Biz PostgreSQL'de biraz daha pimpirikli davranıp, işleri
epey bir komplike hala getirmişiz. Bunu kısaca özetleyecek olursam:

MySQL: "Bir karakter katarı ya MB'dir ya da değildir."
PostgreSQL: "Bir karakter katarı MB de olabilir, ASCII de."

Bence benzer bir yöntem bizim için de daha meşru olacak. Şu an
fikirlerim çok net değil. Kafamdaki beyin fırtınasını stdout'a pipe
ettim o kadar. Üzerinde biraz daha düşünüp pgsql-hackers'a
danışacağım.

Bilgilerinize.

Responses

Browse pgsql-tr-genel by date

  From Date Subject
Next Message Volkan YAZICI 2005-10-16 09:19:59 Fwd: PotgreSQL and SQL standards commentary WWW page
Previous Message Bruce Momjian 2005-10-13 20:33:49 Re: BUG #1931: ILIKE and LIKE fails on Turkish locale