El límite de longitud impuesto por los tipos varchar(N)
y calculado por la función length
está en caracteres, no en bytes. Por lo tanto, 'abcdef'::char(3)
se trunca en 'abc'
, pero 'a€cdef'::char(3)
se trunca en 'a€c'
, incluso en el contexto de una base de datos codificada como UTF-8, donde 'a€c'
se codifica utilizando 5 bytes.
Si la restauración de un archivo de volcado se quejaron de que 'Mér'
no entraría en una columna varchar(3)
, que sugiere que estaban restaurando un archivo de volcado codificado UTF-8 en una base de datos SQL_ASCII.
Por ejemplo, hice esto en una base de datos UTF-8:
create schema so4249745;
create table so4249745.t(key varchar(3) primary key);
insert into so4249745.t values('Mér');
Y luego arrojar esto y trataron de cargarlo en una base de datos SQL_ASCII:
pg_dump -f dump.sql --schema=so4249745 --table=t
createdb -E SQL_ASCII -T template0 enctest
psql -f dump.sql enctest
y bastante seguro:
psql:dump.sql:34: ERROR: value too long for type character varying(3)
CONTEXT: COPY t, line 1, column key: "Mér"
Por el contrario, si creo la base de datos enctest como codificación LATIN1 o UTF8, se carga bien.
Este problema se produce debido a una combinación de dumping una base de datos con una codificación de caracteres de varios bytes, y tratando de restaurar en una base de datos SQL_ASCII. El uso de SQL_ASCII básicamente deshabilita la transcodificación de los datos del cliente a los datos del servidor y asume un byte por carácter, dejando que los clientes asuman la responsabilidad de utilizar el mapa de caracteres correcto. Dado que el archivo de volcado contiene la cadena almacenada como UTF-8, es decir, cuatro bytes, por lo que una base de datos SQL_ASCII ve que como cuatro caracteres, y por lo tanto la considera como una violación de la restricción. E imprime el valor, que mi terminal vuelve a ensamblar como tres caracteres.
La codificación de caracteres es una cuestión por base de datos. PostgreSQL admite todo tipo de codificaciones, pero solo una puede tener efecto para una base de datos determinada.Quizás su base de datos de origen fue configurada para una codificación diferente a la del objetivo. – Pointy
Busque este texto (centro de la página) en el manual. Parece sugerir que la codificación determina el número de caracteres requeridos: el requisito de almacenamiento para los datos de estos tipos es de 4 bytes más la cadena real ... [con codificaciones de caracteres multibyte] (http://www.postgresql.org/docs). /8.0/interactive/datatype-character.html) el número de caracteres y bytes puede ser bastante diferente ... – frayser
Comentario de Upotted Pointy: lo seleccionaría si fuera la respuesta. – bennylope