Hi,

 

I have a PostgreSQL 8.0.3 running on an older debian server and have some 
problems with unicode databases and character conversions.

 

 

First up, some backgrund info about my server and installation:

 

test=# \set

VERSION = 'PostgreSQL 8.0.3 on i386-pc-linux-gnu, compiled by GCC cc (GCC) 
3.3.5 (Debian 1:3.3.5-13)'

AUTOCOMMIT = 'on'

VERBOSITY = 'default'

PROMPT1 = '%/%R%# '

PROMPT2 = '%/%R%# '

PROMPT3 = '>> '

HISTSIZE = '500'

LASTOID = '0'

DBNAME = 'test'

USER = 'postgres'

HOST = '/var/run/postgresql'

PORT = '5432'

ENCODING = 'UNICODE'

test=# \! uname -a

Linux xx 2.4.27-2-686-smp #1 SMP XX i686 GNU/Linux

test=# \! locale

LANG=POSIX

LC_CTYPE="POSIX"

LC_NUMERIC="POSIX"

LC_TIME="POSIX"

LC_COLLATE="POSIX"

LC_MONETARY="POSIX"

LC_MESSAGES="POSIX"

LC_PAPER="POSIX"

LC_NAME="POSIX"

LC_ADDRESS="POSIX"

LC_TELEPHONE="POSIX"

LC_MEASUREMENT="POSIX"

LC_IDENTIFICATION="POSIX"

LC_ALL=

 

 

My problem is, that the lowercase versions of non-ascii characters are broken. 
Specifically I found, that when lower() is invoked on a text with non-ascii 
characters, the operating system's locale is used for converting each octet in 
the string to lowercase in stead of using the locale of the database to convert 
each character in the string to lowercase. This caused the danish lower case o 
with slash "ø", which in unicode is represented as the latin1-readable octets 
"ø", to be converted to the latin1-readable octets "ã¸", which then in turn 
was (tried) to be interpreted as a unicode character - but the octects "ã¸" 
does not represent a unicode character in utf8. The lower case version of "ø" 
is of course just itself.

 

To get around this problem, I had to create a function ulower:

 

create or replace function ulower(text) returns text as 'begin 

 return convert(lower(convert($1,''utf8'',''latin1'')),''latin1'',''utf8'');

end;' language plpgsql immutable;

 

Not a very nice solution and it of course only works for latin1-compatible 
utf8-encoded strings.

 

First up, I would like to avoid this whole issue. How could this be 
circumvented, any settings I can flick around?

 

 

Then I tried to apply this immutable function as a functional index on a 
varchar:

 

test# create index mytable_mycolumn_lower_idx on mytable(ulower(mycolumn));

ERROR:  could not convert UTF-8 character 0x00e2 to ISO8859-1

 

I had a lot of data in the table before creating this index, and apparently one 
of the rows contained unicode character U+00E2 - which is latin small letter a 
with circumflex = â. This is a perfectly legal latin1-character (as any Unicode 
character below U+0100 is).

 

My second question is then, why did it fail to convert this character to latin1?

 

 

Thanks in advance for any help

 

 

Regards,

Morten Barklund

Head of Development

TBWA\

Reply via email to