No PostgreSQL o suporte a conjuntos de caracteres permite armazenar textos usando vários conjuntos de caracteres, incluindo conjuntos de caracteres de um único byte, como a série ISO 8859, e conjuntos de caracteres de vários bytes, como o EUC (Extended Unix Code), Unicode (The universal character encoding) e o código interno Mule (Multilingual Emacs). Todos os conjuntos de caracteres podem ser utilizados de forma transparente no servidor (Se forem utilizadas funções de extensão de terceiros, vai depender do código destas funções utilizadas ter sido escrito corretamente). O conjunto de caracteres padrão é selecionado durante a inicialização do agrupamento de bancos de dados do PostgreSQL, feito pelo utilitário initdb. Ao se criar um banco de dados através do utilitário createdb, ou através do comando CREATE DATABASE da linguagem SQL, pode ser escolhido um conjunto de caracteres diferente do padrão do agrupamento. Portanto, podem haver vários bancos de dados, cada um com um conjunto de caracteres diferentes.
A Tabela 20-1 mostra os conjuntos de caracteres disponíveis para uso no servidor.
Tabela 20-1. Conjuntos de caracteres do servidor
Nome | Descrição |
---|---|
SQL_ASCII | ASCII |
EUC_JP | EUC Japonês |
EUC_CN | EUC Chinês |
EUC_KR | EUC Coreano |
JOHAB | EUC Coreano (baseado em Hangle) |
EUC_TW | EUC Tailandês |
UNICODE | Unicode (UTF-8) [a] |
MULE_INTERNAL | Código interno Mule |
LATIN1 | ISO 8859-1/ECMA 94 (Alfabeto latino nº 1) |
LATIN2 | ISO 8859-2/ECMA 94 (Alfabeto latino nº 2) |
LATIN3 | ISO 8859-3/ECMA 94 (Alfabeto latino nº 3) |
LATIN4 | ISO 8859-4/ECMA 94 (Alfabeto latino nº 4) |
LATIN5 | ISO 8859-9/ECMA 128 (Alfabeto latino nº 5) |
LATIN6 | ISO 8859-10/ECMA 144 (Alfabeto latino nº 6) |
LATIN7 | ISO 8859-13 (Alfabeto latino nº 7) |
LATIN8 | ISO 8859-14 (Alfabeto latino nº 8) |
LATIN9 | ISO 8859-15 (Alfabeto latino nº 9) |
LATIN10 | ISO 8859-16/ASRO SR 14111 (Alfabeto latino nº 10) |
ISO_8859_5 | ISO 8859-5/ECMA 113 (Latino/Cirílico) |
ISO_8859_6 | ISO 8859-6/ECMA 114 (Latino/Arábico) |
ISO_8859_7 | ISO 8859-7/ECMA 118 (Latino/Grego) |
ISO_8859_8 | ISO 8859-8/ECMA 121 (Latino/Hebreu) |
KOI8 | KOI8-R(U) |
ALT | Windows CP866 |
WIN874 | Windows CP874 (Thai) |
WIN1250 | Windows CP1250 |
WIN | Windows CP1251 |
WIN1256 | Windows CP1256 (Arábico) |
TCVN | TCVN-5712/Windows CP1258 (Vietnamês) |
Notas: a. UTF8 é a forma de codificação de caracteres especificada na ISO/IEC 10646-1, Anexo D (normativa), "UCS Transformation Format 8 (UTF-8)", na qual cada caractere é codificado de um a quatro octetos. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.) |
Importante: Por engano, antes do PostgreSQL 7.2 LATIN5 significava ISO 8859-5. A partir da versão 7.2 LATIN5 passou a significar ISO 8859-9. Caso exista um banco de dados LATIN5 criado pela versão 7.1 ou anterior, e for desejado migrar para a versão 7.2 ou posterior, deve haver cuidado com relação a esta modificação.
Nem todas as APIs suportam todos os conjuntos de caracteres listados. Por exemplo, o driver de JDBC do PostgreSQL não aceita MULE_INTERNAL, LATIN6, LATIN8 e LATIN10.
O utilitário initdb define o conjunto de caracteres padrão para o agrupamento de bancos de dados do PostgreSQL. Por exemplo,
initdb -E EUC_JP
define o conjunto de caracteres padrão (codificação) como EUC_JP (Código Unix Estendido para Japonês). Pode ser utilizado --encoding em vez de -E, se for preferido digitar a forma mais longa das opções. Se não for fornecida nem a opção -E nem a opção --encoding, é utilizado SQL_ASCII.
Pode ser criado um banco de dados com um conjunto de caracteres diferente:
createdb -E EUC_KR coreano
Este comando cria um banco de dados chamado coreano que utiliza o conjunto de caracteres EUC_KR. Outra forma de se fazer é através do comando SQL:
CREATE DATABASE coreano WITH ENCODING 'EUC_KR';
A codificação usada no banco de dados é armazenada no catálogo do sistema pg_database. Pode ser vista utilizando a opção -l ou o comando \l do psql.
$ psql -l Lista de bancos de dados Banco de Dados | Dono | Codificação ---------------+---------+--------------- euc_cn | t-ishii | EUC_CN euc_jp | t-ishii | EUC_JP euc_kr | t-ishii | EUC_KR euc_tw | t-ishii | EUC_TW mule_internal | t-ishii | MULE_INTERNAL regression | t-ishii | SQL_ASCII template1 | t-ishii | EUC_JP test | t-ishii | EUC_JP unicode | t-ishii | UNICODE (9 linhas)
Importante: Embora possa ser especificado para o banco de dados qualquer codificação desejada, não é recomendável escolher uma codificação que não é a esperada para o idioma escolhido. As definições de LC_COLLATE e LC_CTYPE implicam em uma determinada codificação e, por isso, é possível que as operações dependentes do idioma (como a classificação) interpretem de forma errada os dados que estiverem em uma codificação incompatível.
Uma vez que as definições de idioma são congeladas pelo utilitário initdb, a flexibilidade aparente de utilizar codificações diferentes em bancos de dados diferentes é mais teórica do que real. É provável que estes mecanismos sejam revistos em uma versão futura do PostgreSQL.
Uma maneira de utilizar várias configurações com segurança é definir o idioma como C ou POSIX ao executar o initdb acabando, assim, com qualquer preocupação real com relação a idioma.
O PostgreSQL suporta a conversão automática de conjuntos de caracteres entre o cliente e o servidor, para determinados conjuntos de caracteres. A informação de conversão é armazenada no catálogo do sistema pg_conversion. Podem ser criadas novas conversões utilizando o comando CREATE CONVERSION. O PostgreSQL possui algumas conversões pré-definidas, conforme mostrado na Tabela 20-2.
Tabela 20-2. Conversões de conjuntos de caracteres cliente/servidor
Conjunto de caracteres do servidor | Conjuntos de caracteres do cliente aceitos |
---|---|
SQL_ASCII | SQL_ASCII, UNICODE, MULE_INTERNAL |
EUC_JP | EUC_JP, SJIS, UNICODE, MULE_INTERNAL |
EUC_CN | EUC_CN, UNICODE, MULE_INTERNAL |
EUC_KR | EUC_KR, UNICODE, MULE_INTERNAL |
JOHAB | JOHAB, UNICODE |
EUC_TW | EUC_TW, BIG5, UNICODE, MULE_INTERNAL |
LATIN1 | LATIN1, UNICODE MULE_INTERNAL |
LATIN2 | LATIN2, WIN1250, UNICODE, MULE_INTERNAL |
LATIN3 | LATIN3, UNICODE, MULE_INTERNAL |
LATIN4 | LATIN4, UNICODE, MULE_INTERNAL |
LATIN5 | LATIN5, UNICODE |
LATIN6 | LATIN6, UNICODE, MULE_INTERNAL |
LATIN7 | LATIN7, UNICODE, MULE_INTERNAL |
LATIN8 | LATIN8, UNICODE, MULE_INTERNAL |
LATIN9 | LATIN9, UNICODE, MULE_INTERNAL |
LATIN10 | LATIN10, UNICODE, MULE_INTERNAL |
ISO_8859_5 | ISO_8859_5, UNICODE, MULE_INTERNAL, WIN, ALT, KOI8 |
ISO_8859_6 | ISO_8859_6, UNICODE |
ISO_8859_7 | ISO_8859_7, UNICODE |
ISO_8859_8 | ISO_8859_8, UNICODE |
UNICODE | EUC_JP, SJIS, EUC_KR, UHC, JOHAB, EUC_CN, GBK, EUC_TW, BIG5, LATIN1 até LATIN10, ISO_8859_5, ISO_8859_6, ISO_8859_7, ISO_8859_8, WIN, ALT, KOI8, WIN1256, TCVN, WIN874, GB18030, WIN1250 |
MULE_INTERNAL | EUC_JP, SJIS, EUC_KR, EUC_CN, EUC_TW, BIG5, LATIN1 até LATIN5, WIN, ALT, WIN1250, BIG5, ISO_8859_5, KOI8 |
KOI8 | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
ALT | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
WIN874 | WIN874, UNICODE |
WIN1250 | LATIN2, WIN1250, UNICODE, MULE_INTERNAL |
WIN | ISO_8859_5, WIN, ALT, KOI8, UNICODE, MULE_INTERNAL |
WIN1256 | WIN1256, UNICODE |
TCVN | TCVN, UNICODE |
Para ativar a conversão automática entre os conjuntos de caracteres, deve ser informado ao PostgreSQL o conjunto de caracteres (codificação) que se deseja utilizar no cliente. Existem diversas maneiras de fazer:
Utilizando o comando \encoding no psql. O \encoding permite mudar a codificação do cliente dinamicamente. Por exemplo, para mudar a codificação para SJIS deve ser executado:
\encoding SJIS
Utilizando as funções da biblioteca libpq. O comando \encoding na verdade chama PQsetClientEncoding() para esta finalidade:
int PQsetClientEncoding(PGconn *conexão, const char *codificação);
Onde conexão é a conexão com o servidor, e codificação é a codificação que se deseja utilizar. Se for bem-sucedida a definição da codificação pela função, esta retorna 0, senão retorna -1. A codificação corrente para a conexão pode ser obtida utilizando:
int PQclientEncoding(const PGconn *conexão);
Deve ser observado que é retornado o ID da codificação, e não uma cadeia de caracteres simbólica como EUC_JP. Para converter o ID da codificação no nome da codificação deve ser utilizado:
char *pg_encoding_to_char(int id_codificação);
Utilizando o comando SET client_encoding TO. A definição da codificação do cliente pode ser feita através do comando SQL:
SET CLIENT_ENCODING TO 'valor';
Também pode ser utilizada a sintaxe SET NAMES do padrão SQL para esta finalidade:
SET NAMES 'valor';
Para consultar a codificação corrente do cliente:
SHOW client_encoding;
Para voltar à codificação padrão:
RESET client_encoding;
Utilizando a variável de ambiente PGCLIENTENCODING. Se a variável de ambiente PGCLIENTENCODING estiver definida no ambiente do cliente, esta codificação de cliente é selecionada automaticamente quando é feita a conexão com o servidor (Pode ser mudada depois utilizando um dos métodos mencionados acima).
Utilizando a variável de configuração client_encoding. Se a variável client_encoding estiver definida, esta codificação do cliente é selecionada automaticamente quando é feita a conexão com o servidor (Pode ser mudada depois utilizando um dos métodos mencionados acima).
Se não for possível converter um determinado caractere — suponha que seja escolhido EUC_JP para o servidor e LATIN1 para o cliente, então alguns caracteres Japoneses não poderão ser convertidos em LATIN1 — este caractere será transformado nos valores hexadecimais de seus bytes entre parênteses como, por exemplo, (826C).
Abaixo estão mostrados bons lugares para começar a aprender os vários tipos de sistema de codificação.
Estão mostradas na seção 3.2 explicações detalhadas sobre EUC_JP, EUC_CN, EUC_KR e EUC_TW.
O sítio na Web do Consórcio Unicode
Onde o UTF-8 é definido.