Não entendo por que o agrupamento padrão na minha instância do psqlserver 11 retorna um resultado diferente do uso com agrupamento explícito.
Detalhes:
show LC_CTYPE; -- de-AT
show LC_COLLATE; -- de-AT
Quando uso o agrupamento padrão, recebo uma saída inesperada:
demo=# SELECT unnest(array['a','B', 'A']) order by 1;
unnest
--------
A
B
a
(3 rows)
Quando adiciono o agrupamento padrão explicitamente, recebo a saída esperada:
demo=# SELECT unnest(array['a','B', 'A']) collate "de-AT-x-icu" ORDER BY 1;
unnest
--------
a
A
B
(3 rows)
A ordenação de-AT-x-icu
usa exatamente os valores padrão para LC_COLLATE
e LC_COLTYPE
mostrados acima:
SELECT collname, collcollate, collctype
FROM pg_collation
where collname like '%de-AT%';
collname | collcollate | collctype
-------------+-------------+-----------
de-AT-x-icu | de-AT | de-AT
Então acho que ambas as consultas devem retornar o mesmo resultado: O que estou perdendo?
Mais informações:
- versão do postgresql
11.5
- SO dentro do contêiner do Docker:
Linux 8660fb4cef84 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64 Linux
Deixe-me adivinhar: você está usando o Alpine Linux, que usa
musl
como biblioteca C, que usa agrupamentos ICU por padrão.Sabe-se que os agrupamentos no Alpine Linux não funcionam como deveriam, o que é a causa do problema. Não tenho certeza se isso é culpa do PostgreSQL ou não.
De qualquer forma, você deve usar uma distribuição Linux diferente que use
glibc
.Depois de ler muitos posts, documentos e os ótimos comentários e respostas aqui, vou tentar resumir o caso (por favor, deixe um comentário se algo estiver errado).
Acontece que @Laurenz Albe está certo: eu estava usando a imagem do docker
timescale/timescaledb:1.5.0-pg11
( link Docker-Hub ).Eu não pensei que isso pudesse ser baseado em alpino, porque essas imagens geralmente terminam em
-alpine
. Mas como isso é apenas uma convenção, eu deveria ter verificado o Dockerfile deles ...Parece que atualmente existe apenas a imagem db de escala de tempo baseada em alpino disponível no dockerhub: veja timescaledb-docker#78
Os documentos no postgres do docker-hub mencionam que:
Portanto, a imagem do docker usa musl que tem algumas diferenças para glibc . Uma diferença importante é que o comando os
locale
não está disponível.Ao iniciar o docker-container com os parâmetros init-db : por exemplo
POSTGRES_INITDB_ARGS=--lc-collate=de-AT --lc-ctype=de-AT
, há avisos no console:Portanto, o banco de dados realmente nos disse corretamente que a localidade/collation fornecida é ignorada.
O que é bastante confuso é que as instruções a seguir ainda mostram os valores definidos pelos parâmetros initdb:
Mas estes não são usados por padrão, como @Daniel Vérité apontou em um comentário.
Observando o Dockerfile postgres-alpine , podemos ver que a imagem é construída com o suporte icu ativado (
--with-icu
).Portanto, quando usamos um agrupamento icu diretamente em uma consulta (por exemplo
collate "de-AT-x-icu"
, ) ele funcionará, porque isso usa a icu lib vinculada estaticamente e não precisa perguntar ao os dependente glib-c.