23.1. Suporte a localidade #

23.1.1. Visão geral
23.1.2. Comportamento
23.1.3. Seleção de localidades
23.1.4. Provedores de localidade
23.1.5. Localidades ICU
23.1.6. Problemas

O suporte a localidade refere-se a uma aplicação que respeita as preferências culturais em relação a alfabetos, ordem de classificação, formatação de números, etc. O PostgreSQL usa os recursos de localidade do padrão ISO C e POSIX fornecidos pelo sistema operacional do servidor. Para obter mais informações, veja a documentação do sistema.

23.1.1. Visão geral #

O suporte a localidade é configurado automaticamente quando uma instância de banco de dados é criada usando o utilitário initdb. Por padrão, o initdb irá inicializar a instância usando a configuração de localidade de seu ambiente de execução, portanto se o sistema já estiver configurado para usar a localidade que se deseja na instância, não há mais nada a se fazer. Se for desejado usar uma localidade diferente (ou não se tiver certeza sobre qual localidade o sistema está configurado), pode-se informar ao initdb exatamente qual localidade usar, especificando a opção --locale. Por exemplo:

initdb --locale=pt_BR

Este exemplo para sistemas Unix define a localidade como português (pt) falado no Brasil (BR). Outras possibilidades podem incluir en_US (inglês dos EUA) e fr_CA (francês canadense). Se puder ser usado mais de um conjunto de caracteres para a localidade, as especificações podem assumir a forma: linguagem_território.​conjunto_de_caracteres. Por exemplo, fr_BE.UTF-8 representa a linguagem francês (fr) falado na Bélgica (BE), com a codificação de conjunto de caracteres UTF-8.

Quais localidades estão disponíveis no sistema, e sob quais nomes, depende do que é disponibilizado pelo fornecedor do sistema operacional, e do que foi instalado. Na maioria dos sistemas Unix, o comando locale -a fornece uma lista das localidades disponíveis. O Windows usa nomes de localidade mais detalhados, como German_Germany ou Swedish_Sweden.1252, mas os princípios são os mesmos.

Ocasionalmente, é útil misturar regras de várias localidades como, por exemplo, usar as regras de ordenação do inglês, mas mensagens em espanhol. Para oferecer suporte a isto, existe um conjunto de subcategorias de localidade que controlam apenas alguns aspectos das regras de localização:

LC_COLLATE [a] Ordem de classificação de cadeia de caracteres
LC_CTYPE [b] Classes de conjunto de caracteres (O que é uma letra? E a letra maiúscula equivalente?)
LC_MESSAGESLinguagem das mensagens
LC_MONETARYFormatação de valores monetários
LC_NUMERICFormatação de números
LC_TIMEFormatação de datas e horas

[a] collation: comparação de texto usando regras convenientes à linguagem, em oposição à comparação bit a bit de códigos de caracteres numéricos. Isto é geralmente feito para classificar uma lista de cadeias de caracteres. ICU Documentation – Glossário (N. T.)

[b] A categoria LC_CTYPE determina as regras de tratamento de caracteres que regem a interpretação de sequências de bytes de caracteres de dados de texto (ou seja, caracteres de byte único versus caracteres multibyte), a classificação de caracteres (por exemplo, alfa, dígito, e assim por diante), e o comportamento de classes de caracteres. IBM – Understanding locale environment variables (N. T.)

Os nomes das categorias se traduzem em nomes de opções do utilitário initdb para substituir a escolha de localidade para uma determinada categoria. Por exemplo, para definir a localidade como francês canadense, mas usar as regras dos EUA para a formatação de valores monetários, deve ser usado initdb --locale=fr_CA --lc-monetary=en_US.

Se for desejado que o sistema se comporte como se não tivesse suporte a localidade, deve ser usado o nome de localidade especial C ou, de forma equivalente, POSIX.

Algumas categorias de localidade devem ter seus valores fixados quando o banco de dados é criado. Pode-se usar diferentes configurações para diferentes bancos de dados, mas uma vez que o banco de dados esteja criado, não se pode mais as alterar para este banco de dados. Estas categorias são LC_COLLATE e LC_CTYPE. Elas afetam a ordem de classificação dos índices, portanto devem ser mantidas fixas, ou os índices das colunas de texto serão corrompidos. (Mas pode-se aliviar esta restrição usando ordenações, conforme discutido em Suporte a ordenação.) Os valores padrão para estas categorias são determinados quando o utilitário initdb é executado, e estes valores são usados ​​quando novos bancos de dados são criados, a menos que seja especificado de outra forma no comando CREATE DATABASE.

As outras categorias de localidade podem ser alteradas sempre que desejado, definindo os parâmetros de configuração do servidor que têm o mesmo nome das categorias de localidade (veja Localidade e formatação para obter detalhes). Os valores escolhidos pelo utilitário initdb são, na verdade, apenas escritos no arquivo de configuração postgresql.conf para servir de padrão quando o servidor é ativado. Se forem removidas estas atribuições do arquivo postgresql.conf, então o servidor herdará as configurações de seu ambiente de execução.

Note-se que o comportamento de localidade do servidor é determinado pelas variáveis ​​de ambiente vistas pelo servidor, e não pelo ambiente de qualquer cliente. Portanto, deve-se ter o cuidado de definir as configurações de localidade corretas antes de iniciar o servidor. Uma consequência disso é que, se cliente e servidor forem configurados usando localidades diferentes, as mensagens poderão aparecer em linguagens diferentes, dependendo de onde foram originadas.

Nota

Quando falamos em herdar a localidade do ambiente de execução, isto significa o seguinte na maioria dos sistemas operacionais: para uma determinada categoria de localidade, digamos a ordenação, as seguintes variáveis ​​de ambiente são consultadas nesta ordem, até que uma esteja definida: LC_ALL, LC_COLLATE (ou a variável correspondente à respectiva categoria), e LANG. Se nenhuma dessas variáveis ​​de ambiente estiver definida, o padrão de localidade será C.

Algumas bibliotecas de localização de mensagens também examinam a variável de ambiente LANGUAGE, que substitui todas as outras configurações de localidade cujo objetivo é definir a linguagem das mensagens. Em caso de dúvida, veja a documentação do sistema operacional, em particular a documentação sobre o pacote gettext.

Para permitir que as mensagens sejam traduzidas para a linguagem preferida do usuário, deve ter sido selecionado NLS (suporte à linguagem nativa) no momento da construção (configure --enable-nls). Os demais suportes a localidade são incorporados automaticamente.

23.1.2. Comportamento #

As configurações de localidade influenciam os seguintes recursos do SQL:

  • A ordem de classificação nas consultas que usam ORDER BY, ou os operadores de comparação padrão nos dados textuais

  • As funções upper, lower e initcap

  • Os operadores de correspondência de padrão (LIKE, SIMILAR TO e expressões regulares no estilo POSIX); as localidades afetam tanto a correspondência que não diferencia letras maiúsculas de minúsculas, quanto a classificação dos caracteres por expressões regulares com classes de caracteres

  • A família de funções to_char

  • A capacidade de usar índices com cláusulas LIKE

A desvantagem de usar localidades diferentes de C ou POSIX no PostgreSQL é seu impacto no desempenho. Elas tornam lento o tratamento de caracteres, e impedem que índices comuns sejam usados ​​pela cláusula LIKE. Por este motivo, as localidades devem ser usadas somente se realmente forem necessárias.

Como solução alternativa para permitir que o PostgreSQL use índices com cláusulas LIKE em uma localidade diferente de C, existem várias classes de operador personalizadas. Elas permitem a criação de um índice que executa uma comparação estrita, caractere por caractere, ignorando as regras de comparação de localidade. Veja Classes e famílias de operador para obter mais informações. Outra abordagem é criar índices usando a ordenação C, conforme discutido em Suporte a ordenação.

23.1.3. Seleção de localidades #

As localidades podem ser selecionadas em diferentes âmbitos, dependendo dos requisitos. A visão geral acima mostrou como as configurações regionais são especificadas usando o comando initdb para definir os padrões para toda a instância. A lista a seguir mostra onde as linguagens podem ser selecionados. Cada item fornece os valores padrão para os itens subsequentes, e cada item inferior permite a substituição dos valores padrão com maior precisão.

  1. Conforme explicado acima, o ambiente do sistema operacional fornece os valores padrão para as configurações regionais de uma instância recém-inicializada. Em muitos casos isto será suficiente se o sistema operacional estiver configurado para a linguagem/território desejada. Por padrão, o PostgreSQL também se comportará de acordo com esta localidade.

  2. Conforme mostrado acima, as opções de linha de comando do initdb especificam as configurações de localidade para uma instância recém-inicializada. Deve ser usada esta opção se o sistema operacional não tiver a configuração de localidade desejada para o sistema de banco de dados.

  3. É possível selecionar uma localidade em separado para cada banco de dados. O comando SQL CREATE DATABASE e seu equivalente de linha de comando createdb possuem opções para isto. Isto deve ser usado, por exemplo, se a instância hospedar bancos de dados para vários usuários com requisitos diferentes.

  4. É possível definir configurações de localidade para colunas da tabela individualmente. Isto usa um objeto SQL chamado ordenação e é explicado em Suporte a ordenação. Isto deve ser usado, por exemplo, para classificar dados em diferentes linguagens ou personalizar a ordem de classificação de uma tabela específica.

  5. Por fim, é possível selecionar localidades para uma consulta individual. Novamente, isto usa objetos de ordenação SQL. Isto pode ser usado para alterar a ordem de classificação com base em escolhas feitas em tempo de execução ou para experimentação específica (ad hoc).

23.1.4. Provedores de localidade #

Um provedor de localidade especifica qual biblioteca define o comportamento da localidade para ordenações e classificações de caracteres.

Os comandos e ferramentas que selecionam as configurações de localidade, conforme descrito acima, possuem uma opção para selecionar o provedor de localidade. Segue um exemplo de como inicializar uma instância usando o provedor ICU:

initdb --locale-provider=icu --icu-locale=pt-BR

Veja a descrição dos respectivos comandos e programas para obter detalhes. Note-se que se pode misturar provedores de localização em diferentes granularidades; por exemplo, usar libc por padrão para a instância, mas ter um banco de dados que usa o provedor icu e, em seguida, ter objetos de ordenação usando qualquer um dos provedores nesses bancos de dados.

Independentemente do provedor de localização, o sistema operacional ainda é usado para fornecer alguns comportamentos que levam em consideração a localidade, como mensagens (veja lc_messages).

Os provedores de localidade disponíveis estão listados abaixo:

builtin

O provedor builtin utiliza operações internas. Somente as localidades C, C.UTF-8 e PG_UNICODE_FAST têm suporte neste provedor.

O comportamento da localidade C é idêntico ao da localidade C no provedor libc. Ao usar esta localidade, o comportamento pode depender da codificação do banco de dados.

A localidade C.UTF-8 está disponível apenas quando a codificação do banco de dados é UTF-8, e o comportamento é baseado no Unicode. A ordenação usa apenas os valores dos pontos de código. As classes de caracteres de expressões regulares são baseadas na semântica Compatível com POSIX, e o mapeamento de maiúsculas e minúsculas é a variante simple.

A localidade PG_UNICODE_FAST está disponível apenas quando a codificação do banco de dados é UTF-8, e o comportamento é baseado no Unicode. A ordenação utiliza apenas os valores dos pontos de código. As classes de caracteres de expressões regulares são baseadas na semântica Standard, e o mapeamento de maiúsculas e minúsculas é a variante full.

icu

O provedor icu usa a biblioteca externa ICU. O PostgreSQL deve ter sido configurado com suporte a ICU.

O ICU oferece comportamento de ordenação e classificação de caracteres independente do sistema operacional e da codificação do banco de dados, o que é preferível se for esperado migrar para outras plataformas sem qualquer alteração nos resultados. LC_COLLATE e LC_CTYPE podem ser configurados independentemente da localidade do ICU [143].

Nota

Para o provedor ICU, os resultados podem depender da versão da biblioteca ICU usada, visto que ela é atualizada ao longo do tempo para refletir as mudanças na linguagem natural.

libc

O provedor libc utiliza a biblioteca C do sistema operacional. O comportamento de ordenação e classificação de caracteres é controlado pelas configurações LC_COLLATE e LC_CTYPE, portanto elas não podem ser definidas independentemente.

Nota

O mesmo nome de localidade pode ter comportamentos diferentes em plataformas diferentes ao usar o provedor libc.

23.1.5. Localidades ICU #

23.1.5.1. Nomes das localidades ICU #

O formato ICU para o nome da localidade é uma Etiqueta de linguagem.

CREATE COLLATION mycollation1 (provider = icu,
                               locale = 'ja-JP');
CREATE COLLATION mycollation2 (provider = icu,
                               locale = 'fr');

23.1.5.2. Padronização e validação de localidades #

Ao definir um novo objeto de ordenação ICU ou banco de dados com ICU como provedor, o nome da localidade fornecido é transformado ("padronizado") em uma etiqueta de linguagem, caso não esteja neste formato. Por exemplo,

CREATE COLLATION mycollation3 (provider = icu,
                               locale = 'en-US-u-kn-true');
NOTA:  usando a forma padrão "en-US-u-kn" ↵
       para a localidade ICU "en-US-u-kn-true"
CREATE COLLATION mycollation4 (provider = icu,
                               locale = 'de_DE.utf8');
NOTA:  usando a forma padrão "de-DE" ↵
       para a localidade ICU "de_DE.utf8"

Se for vista esta nota, deve-se verificar se provider e locale correspondem ao resultado esperado. Para obter resultados consistentes ao usar o provedor ICU, deve-se especificar a etiqueta de linguagem padrão (canônica) em vez de depender da transformação.

Uma localidade sem nome de linguagem, ou com o nome de linguagem especial root, é transformada para ter a linguagem und ("indefinida").

O ICU pode transformar a maioria dos nomes de localidades da libc, bem como alguns outros formatos, em etiquetas de linguagem para facilitar a transição para o ICU. Se for usado no ICU um nome de localidade da libc, ele poderá não ter o mesmo comportamento que na libc.

Se houver algum problema na interpretação do nome da localidade, ou se o nome da localidade representar uma linguagem ou região que o ICU não reconhece, deverá aparecer o seguinte aviso:

CREATE COLLATION nonsense (provider = icu,
                           locale = 'nonsense');
AVISO:  ICU locale "nonsense" has unknown language "nonsense"
DICA:  To disable ICU locale validation, ↵
       set the parameter "icu_validation_level" to "disabled".
CREATE COLLATION

icu_validation_level controla como a mensagem é relatada. A menos que esteja definido como ERROR, a ordenação ainda será criada, mas o comportamento pode não ser o pretendido pelo usuário.

23.1.5.3. Etiqueta de linguagem #

Uma etiqueta de linguagem, definida no BCP 47, é um identificador padronizado usado para identificar linguagens, regiões e outras informações sobre uma localidade.

Etiquetas básicas de linguagem são simplesmente linguagem-região; ou até mesmo apenas linguagem. A linguagem é um código de linguagem (por exemplo, fr para francês), e região é um código de região (por exemplo, CA para Canada). Exemplos: ja-JP, de, fr-CA ou pt-BR:

CREATE COLLATION ptbr (provider = icu, locale = 'pt-BR');
CREATE COLLATION

As configurações de ordenação podem ser incluídas na etiqueta de linguagem para personalizar o comportamento de ordenação. O ICU permite ampla personalização, como sensibilidade (ou insensibilidade) a acentos, maiúsculas e minúsculas e pontuação; tratamento de dígitos dentro do texto; e muitas outras opções para atender a uma variedade de usos.

Para incluir estas informações adicionais de ordenação em uma etiqueta de linguagem, deve ser adicionado -u, indicando que existem configurações de ordenação adicionais, seguido por um ou mais pares -chave-valor. A chave é a chave para uma configuração de ordenação e valor é um valor válido para esta configuração. Para configurações booleanas, a chave -chave pode ser especificada sem o -valor correspondente, que implica no valor true.

Por exemplo, a etiqueta de linguagem en-US-u-kn-ks-level2 significa localidade de língua inglesa na região dos EUA, com configurações de ordenação kn definida como true e ks definida como level2. Estas configurações significam que a ordenação não diferenciará maiúsculas de minúsculas e tratará uma sequência de dígitos como um único número:

CREATE COLLATION mycollation5 (provider = icu,
                               deterministic = false,
                               locale = 'en-US-u-kn-ks-level2');
SELECT 'aB' = 'Ab' COLLATE mycollation5 as resultado;

 resultado
-----------
 t
(1 linha)

SELECT 'N-45' < 'N-123' COLLATE mycollation5 as resultado;

 resultado
-----------
 t
(1 linha)

Veja Ordenações ICU personalizadas para obter detalhes e exemplos adicionais de uso de etiquetas de linguagem com informações de ordenação personalizadas para a localidade.

23.1.6. Problemas #

Se o suporte a localidade não funcionar conforme explicado acima, deve-se verificar se o suporte a localidade no sistema operacional está configurado corretamente. Para verificar quais localidades estão instaladas no sistema, pode ser usado o comando locale -a, se estiver disponível no sistema operacional.

Deve-se verificar se o PostgreSQL está realmente usando a localidade pensada que está sendo usada. As configurações de LC_COLLATE e LC_CTYPE são determinadas quando um banco de dados é criado, não podendo ser alteradas, exceto pela criação de um novo banco de dados. Outras configurações de localidade, incluindo LC_MESSAGES e LC_MONETARY, são inicialmente determinadas pelo ambiente em que o servidor é ativado, mas podem ser alteradas em tempo real. Pode-se verificar as configurações de localidade ativas usando o comando SHOW.

O diretório src/test/locale da distribuição do código-fonte contém um conjunto de testes para o suporte de localidade do PostgreSQL.

Aplicações cliente que lidam com erros do lado do servidor, analisando o texto da mensagem de erro, obviamente terão problemas quando as mensagens do servidor estiverem em uma linguagem diferente. Os autores dessas aplicações são aconselhados a usar o esquema de código de erro.

A manutenção dos catálogos de traduções de mensagens requer o esforço contínuo de muitos voluntários, que desejam ver o PostgreSQL falar bem sua linguagem preferida. Se as mensagens na sua linguagem não estiverem disponíveis no momento, ou não estiverem inteiramente traduzidas, sua ajuda será apreciada. Se desejar ajudar, veja Suporte ao idioma nativo, ou escreva para a lista de discussão dos desenvolvedores.



[143] O ICU proporciona estabilidade ao banco de dados, evitando a corrupção de índices causada por alterações de ordenação do sistema operacional. IBM Cloud — Suporte do PostgreSQL ICU (N. T.)