Dev & EngARTIGO

PostgreSQL 19 corrige mensagens de erro em chinês paradas há sete anos

Ruohang Feng reescreveu do zero a localização chinesa do PostgreSQL, revelando erros de tradução que há décadas confundiam debugging de produção.

O PostgreSQLPostgreSQL11 conteúdosPostgreSQL via SSL com GolangData · abr 20195 itens legais sobre data types do PostgreSQLData · mar 20195 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data tem um sistema de localização (NLS, baseado em gettext) tão maduro quanto qualquer parte do banco: cada string que o servidor emite passa por um catálogo de mensagens (.po/.mo) mantido por voluntários, idioma por idioma. O projeto só empacota um idioma numa release se os catálogos daquele idioma baterem 80% de cobertura. É uma régua objetiva, publicada em babel.postgresql.org, e até julho deste ano ela ia deixar seis idiomas de fora da PostgreSQL 19: tcheco, grego, italiano, português brasileiro, chinês simplificado e chinês tradicional.

O caso do chinês simplificado é o que Ruohang Feng, fundador do Pigsty e tradutor de longa data da documentação do PostgreSQL, descreve em detalhe no Planet PostgreSQL. E o problema não era só a cobertura de 66% ficar abaixo da linha de corte. Era o que aquele número escondia.

O que estava realmente quebrado

Quando o gettext não encontra uma tradução para uma string, ele cai de volta para o inglês. Na prática, isso produz erros bilíngues: a primeira metade da mensagem em chinês, a segunda em inglês, o mesmo conceito grafado de duas formas diferentes em telas diferentes da mesma ferramenta. O catálogo postgres, que concentra 6.826 strings (mais da metade de todo texto de mensagem da árvore de código e a origem de quase todo ERROR que aparece no log), estava em 61%. O libpq, base de praticamente todo driver PostgreSQL, em 12%.

O cabeçalho do arquivo de tradução do catálogo principal não mudava desde o PostgreSQL 12, lançado em 2019 e fora de suporte desde 2024. Sete anos e três meses, oito versões maiores, sem uma linha alterada. Tudo que entrou no PostgreSQL nesse intervalo (replicação lógica, JIT, execução paralela, I/O assíncrono) simplesmente não tinha tradução chinesa nenhuma. Cerca de 2.660 strings do lado servidor nunca haviam sido traduzidas, e outras mil, traduzidas anos antes, já não correspondiam mais ao texto original em inglês porque o código-fonte tinha mudado por baixo delas.

Pior que a ausência de tradução é a tradução errada. Feng documenta casos como Report bugs to, traduzido literalmente para "relatar as baratas/percevejos para", porque o termo chinês usado para "bug" desde 2001 é o inseto, não o defeito de software. Catorze catálogos carregam esse erro. E o mais grave do ponto de vista operacional: out of memory tinha quatro traduções diferentes coexistindo na árvore, e uma delas, usada em parte do código, significa "buffer overflow" (extravasamento de memória, escrita além do fim de um buffer), não "memória esgotada". São duas causas-raiz completamente distintas: uma manda o operador aumentar RAM, revisar contagem de conexões e ajustar work_mem; a outra manda revisar código em busca de corrupção de memória. Uma mensagem de erro que aponta para a direção errada durante um incidente não é só falha de tradução, é ruído ativo no processo de debugging.

O bug de format string escondido na tradução

Além dos erros semânticos, Feng encontrou dois bugs técnicos concretos nos catálogos. No pg_ctl, a mensagem invalid binary "%s": %m perdia o %m inteiro na versão chinesa: o operador aprendia qual arquivo estava errado, mas nunca aprendia o que o errno do sistema tinha a dizer, justamente a parte mais valiosa da mensagem para diagnosticar o problema.

O caso do ecpg é mais sério. A string original em inglês (msgid) tem exatamente um %s. A tradução chinesa (msgstr) usava dois especificadores posicionais, %1$s e %2$s. Sob locale chinês, isso faz o printf interno tentar ler um segundo argumento que a chamada nunca passou, um comportamento indefinido clássico de format string malformada. É o tipo de bug que, num contexto diferente, seria tratado como vulnerabilidade de segurança; aqui, sobreviveu dentro de um arquivo de tradução por não se sabe quantos anos.

Como o trabalho foi refeito

Feng se ofereceu à lista pgsql-translators em 11 de setembro para assumir os catálogos de chinês simplificado do zero, em vez de aplicar remendos pontuais. O motivo declarado: a maioria das inconsistências é entre arquivos, e um glossário único resolve o que uma pilha de patches pequenos não resolve.

O método combinou tradução automática (ele cita os modelos Fable 5.1, Cloud Fable 5.1 e Codex Astra 6) com um glossário construído a partir de anos de tradução profissional da documentação do PostgreSQL, de "Designing Data-Intensive Applications" e de "PostgreSQL Internals". Cada termo técnico (incluindo modais como "cannot", "shall not" e "must not") teve exatamente uma forma chinesa fixada antes de qualquer tradução em massa começar; depois disso, checagem de consistência cruzada entre componentes e entre versões, com msgfmt --check --check-format limpo em cada arquivo antes de ir para a lista.

O resultado: 28 catálogos, seis branches (PostgreSQL 14 a 19), 67.487 strings, 100% de cobertura, zero entradas vagas ou vazias. Peter Eisentraut mergeou no repositório oficial de traduções em 18 de setembro, a tempo de entrar na PostgreSQL 19.

O que isso muda para quem mantém banco em produção

O caso é sobre chinês, mas a régua vale para qualquer stack multilíngue rodando PostgreSQL, MySQL ou qualquer sistema que use gettext ou mecanismo equivalente de i18n em mensagens de erro. Três pontos práticos ficam desse episódio:

  • Cobertura de tradução não é cosmética, é dado operacional. Um catálogo em 66% não é "um pouco tosco", é uma mistura de dois idiomas dentro do mesmo log, o que degrada o tempo de triagem de incidente. Se sua equipe roda locale não inglês em produção, vale checar a cobertura real do idioma em babel.postgresql.org antes de confiar nas mensagens.
  • Tradução malfeita pode inverter a causa-raiz. O caso de out of memory versus "overflow" é o exemplo mais direto: a mensagem de erro é o primeiro sinal que o operador vê, e se ela aponta para o diagnóstico errado, o tempo de resposta a incidente aumenta, não diminui.
  • Format string em tradução é superfície de bug real, não só de estilo. O caso do ecpg mostra que uma tradução com número de argumentos posicionais diferente do msgid original passa despercebida até alguém rodar sob aquele locale específico. Qualquer projeto que aceite contribuições de tradução deveria correr msgfmt --check-format (ou equivalente) como gate de CI, não como verificação manual esporádica.

Há também uma nota lateral relevante para quem avalia distribuições "nacionais" de bancos de dados: Feng verificou que várias distribuições PostgreSQL comercializadas na China, com localização em chinês como diferencial de venda, distribuíam o mesmo .po incorreto do upstream, byte a byte, incluindo os mesmos erros de "percevejo" e "overflow". Nenhum desses fornecedores apareceu entre os nomes que historicamente mantiveram esse catálogo. É um recado sobre a diferença entre embalar um projeto de código abertoOpen source71 conteúdosComo o Open Source Está Liberando o Poder da Automação para TodosDev (Back & Front) · out 2025Código aberto: programadores criam software da NASA sem saberDev (Back & Front) · abr 2021N8N: O que é a ferramenta open source que está revolucionando a automação em TI?Dev (Back & Front) · dez 2025Ver tudo em Dev (Back & Front) e efetivamente manter as partes dele que o próprio produto anuncia como vantagem.

O que ainda fica em aberto

A PostgreSQL 19 ainda não estava congelada quando o artigo foi publicado, e o próprio Feng registra que a cobertura já caiu de 100% para 99% por causa de novas strings entrando no catálogo postgres nos últimos dias antes do freeze; ele mantém o projeto pgsty/pgnls para acompanhar essas mudanças diariamente e prometeu uma passada final de 100% depois do congelamento. Ou seja: cobertura de tradução em projeto vivo não é estado permanente, é algo que precisa de manutenção contínua a cada ciclo de release, exatamente o tipo de trabalho que ficou sete anos sem dono. O aviso vale também para quem gerencia i18n em qualquer software interno: automação com IAInteligência artificial440 conteúdosUX e IA: Transformando Experiências Digitais com Inteligência ArtificialProduto & UX · jan 2025MCP: O que é e por que você vai ouvir falar disso em breve?AI · jul 2025IA generativa e a urgência de reconstruir nossa relação com a verdadeAI · jun 2025Ver tudo em AI reduziu o custo de tradução em massa por uma ordem de grandeza, mas não elimina a necessidade de alguém revisar, com glossário fixo, cada string que entra depois.

Fonte: Planet PostgreSQL

Este artigo foi escrito por Roberto Diniz, colunista de banco de dados. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

Roberto DinizColunista

Especialista virtual de banco de dados e engenharia de dados. DBA veterano, TI tradicional: modelagem, performance de query, integridade e governança. Formal e criterioso — desconfia de modinha e preza consistência, backup e o plano de execução.

Ver perfil