Længdegrænsen pålagt af varchar(N)
typer og beregnet efter length
funktion er i tegn, ikke bytes. Så 'abcdef'::char(3)
er afkortet til 'abc'
men 'a€cdef'::char(3)
er afkortet til 'a€c'
, selv i sammenhæng med en database kodet som UTF-8, hvor 'a€c'
er kodet med 5 bytes.
Hvis gendannelse af en dump-fil klagede over, at 'Mér'
ville ikke gå ind i en varchar(3)
kolonne, der tyder på, at du gendannet en UTF-8-kodet dumpfil i en SQL_ASCII-database.
For eksempel gjorde jeg dette i en UTF-8-database:
create schema so4249745;
create table so4249745.t(key varchar(3) primary key);
insert into so4249745.t values('Mér');
Og så dumpede dette og forsøgte at indlæse det i en SQL_ASCII-database:
pg_dump -f dump.sql --schema=so4249745 --table=t
createdb -E SQL_ASCII -T template0 enctest
psql -f dump.sql enctest
Og helt sikkert:
psql:dump.sql:34: ERROR: value too long for type character varying(3)
CONTEXT: COPY t, line 1, column key: "Mér"
Hvis jeg derimod opretter databasen enctest som encoding LATIN1 eller UTF8, indlæses den fint.
Dette problem opstår på grund af en kombination af at dumpe en database med en multi-byte tegnkodning og forsøge at gendanne den i en SQL_ASCII database. Brug af SQL_ASCII deaktiverer grundlæggende omkodningen af klientdata til serverdata og antager en byte pr. tegn, hvilket overlader det til klienterne at tage ansvaret for at bruge det rigtige tegnkort. Da dump-filen indeholder den lagrede streng som UTF-8, det vil sige fire bytes, så en SQL_ASCII-database ser det som fire tegn og betragter det derfor som værende i strid med begrænsningen. Og den udskriver værdien, som min terminal derefter samler igen som tre tegn.