varchar(N)
によって課せられる長さの制限 タイプとlength
によって計算されます 関数はバイトではなく文字で表されます。したがって、'abcdef'::char(3)
'abc'
に切り捨てられます ただし、'a€cdef'::char(3)
'a€c'
に切り捨てられます 、UTF-8としてエンコードされたデータベースのコンテキストでも、'a€c'
5バイトを使用してエンコードされます。
ダンプファイルを復元すると、'Mér'
varchar(3)
には入りません 列。これは、UTF-8でエンコードされたダンプファイルをSQL_ASCIIデータベースに復元していたことを示しています。
たとえば、UTF-8データベースでこれを行いました:
create schema so4249745;
create table so4249745.t(key varchar(3) primary key);
insert into so4249745.t values('Mér');
そして、これをダンプして、SQL_ASCIIデータベースにロードしようとしました:
pg_dump -f dump.sql --schema=so4249745 --table=t
createdb -E SQL_ASCII -T template0 enctest
psql -f dump.sql enctest
そして確かに:
psql:dump.sql:34: ERROR: value too long for type character varying(3)
CONTEXT: COPY t, line 1, column key: "Mér"
対照的に、LATIN1またはUTF8をエンコードするようにデータベースenctestを作成すると、正常に読み込まれます。
この問題は、データベースをマルチバイト文字エンコードでダンプすることと、それをSQL_ASCIIデータベースに復元しようとすることの組み合わせが原因で発生します。 SQL_ASCIIを使用すると、基本的にクライアントデータからサーバーデータへのトランスコーディングが無効になり、文字ごとに1バイトが想定され、クライアントが適切な文字マップを使用する責任を負います。ダンプファイルにはUTF-8、つまり4バイトとして格納された文字列が含まれているため、SQL_ASCIIデータベースはそれを4文字と見なし、制約に違反していると見なします。そして、それは値を出力し、それを私の端末は3文字として再構成します。