Skip to main content
Na versão 24.3 do ClickHouse, o analisador de consultas foi ativado por padrão. Você pode ler mais detalhes sobre como ele funciona aqui.

Incompatibilidades conhecidas

Apesar de corrigir um grande número de bugs e introduzir novas otimizações, isso também traz algumas mudanças incompatíveis no comportamento do ClickHouse. Leia as alterações a seguir para entender como reescrever suas consultas para o analisador.

Consultas inválidas não são mais otimizadas

A infraestrutura anterior de planejamento de consultas aplicava otimizações no nível da AST antes da etapa de validação da consulta. Essas otimizações podiam reescrever a consulta original para torná-la válida e executável. No analisador, a validação da consulta ocorre antes da etapa de otimização. Isso significa que consultas inválidas que antes podiam ser executadas agora não são mais suportadas. Nesses casos, a consulta precisa ser corrigida manualmente.

Exemplo 1

A consulta a seguir usa a coluna number na lista de projeção quando apenas toString(number) fica disponível após a agregação. No analisador antigo, GROUP BY toString(number) era otimizado para GROUP BY number,, o que tornava a consulta válida.

Exemplo 2

O mesmo problema ocorre nesta consulta. A coluna number é usada após a agregação junto com outra chave. O analisador de consultas anterior corrigiu essa consulta movendo o filtro number > 5 da cláusula HAVING para a cláusula WHERE.
Para corrigir a consulta, mova todas as condições que se aplicam a colunas não agregadas para a seção WHERE, para seguir a sintaxe SQL padrão:
Como auxílio à migração, o analisador pode replicar a antiga reescrita de HAVING para WHERE para conjunções AND não agregadas. Ative analyzer_compatibility_allow_non_aggregate_in_having = 1 para habilitar esse comportamento. A configuração está disponível desde o ClickHouse 26.7. A configuração é ignorada para WITH CUBE, WITH ROLLUP, WITH TOTALS e GROUPING SETS. Conjunções que contêm funções de agregação, grouping ou funções não determinísticas permanecem em HAVING; se alguma conjunção contiver uma função de janela ou uma função com estado (por exemplo, rowNumberInBlock), a reescrita será desabilitada para todo o HAVING, em conformidade com o comportamento legacy.

CREATE VIEW com uma consulta inválida

O analisador sempre realiza a verificação de tipos. Anteriormente, era possível criar uma VIEW com uma consulta SELECT inválida. A falha só ocorria no primeiro SELECT ou INSERT (no caso de MATERIALIZED VIEW). Não é mais possível criar uma VIEW dessa maneira.

Exemplo

Incompatibilidades conhecidas da cláusula JOIN

JOIN usando uma coluna de uma projeção

Por padrão, um alias da lista SELECT não pode ser usado como chave em JOIN USING. Uma nova configuração, analyzer_compatibility_join_using_top_level_identifier, quando habilitada, altera o comportamento de JOIN USING para priorizar a resolução de identificadores com base em expressões da lista de projeção da consulta SELECT, em vez de usar diretamente as colunas da tabela da esquerda. Por exemplo:
Com analyzer_compatibility_join_using_top_level_identifier definido como true, a condição de join é interpretada como t1.a + 1 = t2.b, em conformidade com o comportamento das versões anteriores. O resultado será 2, 'two'. Quando a configuração estiver definida como false, a condição de join será, por padrão, t1.b = t2.b, e a consulta retornará 2, 'one'. Se b não estiver presente em t1, a consulta falhará com um erro.

Mudanças no comportamento com JOIN USING e colunas ALIAS/MATERIALIZED

No analisador, o uso de * em uma consulta com JOIN USING que envolve colunas ALIAS ou MATERIALIZED incluirá essas colunas no conjunto de resultados por padrão. Por exemplo:
No analisador, o resultado desta consulta incluirá a coluna payload juntamente com id de ambas as tabelas. Em contrapartida, o analisador anterior só incluiria essas colunas ALIAS se configurações específicas (asterisk_include_alias_columns ou asterisk_include_materialized_columns) estivessem habilitadas, e as colunas poderiam aparecer em uma ordem diferente. Para garantir resultados consistentes e previsíveis, especialmente ao migrar consultas antigas para o analisador, é recomendável especificar explicitamente as colunas na cláusula SELECT, em vez de usar *.

Tratamento de modificadores de tipo para colunas na cláusula USING

No analisador, as regras para determinar o supertipo comum de colunas especificadas na cláusula USING foram padronizadas para produzir resultados mais previsíveis, especialmente ao lidar com modificadores de tipo como LowCardinality e Nullable.
  • LowCardinality(T) e T: Quando uma coluna do tipo LowCardinality(T) é combinada com uma coluna do tipo T em um join, o supertipo comum resultante será T, descartando efetivamente o modificador LowCardinality.
  • Nullable(T) e T: Quando uma coluna do tipo Nullable(T) é combinada com uma coluna do tipo T em um join, o supertipo comum resultante será Nullable(T), garantindo que a anulabilidade seja preservada.
Por exemplo:
Nesta consulta, o supertipo comum de id é definido como String, descartando o modificador LowCardinality de t1.

Alterações nos nomes das colunas da projeção

Ao calcular os nomes da projeção, os aliases não são substituídos.

Tipos incompatíveis de argumentos de função

No analisador, a inferência de tipos ocorre durante a análise inicial da consulta. Essa mudança significa que as verificações de tipo são feitas antes da avaliação de curto-circuito; portanto, os argumentos da função if devem sempre ter um supertipo comum. Por exemplo, a consulta a seguir falha com There is no supertype for types Array(UInt8), String because some of them are Array and some of them are not:

Clusters heterogêneos

O analisador altera significativamente o protocolo de comunicação entre os servidores do cluster. Portanto, é impossível executar consultas distribuídas em servidores com valores diferentes para a configuração enable_analyzer.

As mutações são interpretadas pelo analisador anterior

As mutações ainda usam o analisador antigo. Isso significa que alguns recursos novos do ClickHouse SQL não podem ser usados em mutações. Por exemplo, a cláusula QUALIFY. O status pode ser consultado aqui.

Recursos sem suporte

A lista de recursos aos quais o analisador atualmente não dá suporte é apresentada abaixo:
  • Índice Annoy.
  • Índice Hypothesis. Trabalho em andamento aqui.
  • Window view não tem suporte. Não há planos de oferecer suporte a esse recurso no futuro.

Migração para Cloud

Estamos habilitando o analisador em todas as instâncias nas quais ele ainda está desativado, para oferecer suporte a novas otimizações funcionais e de desempenho. Essa mudança impõe regras mais rigorosas de escopo em SQL, exigindo que os clientes atualizem manualmente as consultas que não estiverem em conformidade.

Fluxo de migração

  1. Identifique a consulta filtrando system.query_log pelo normalized_query_hash:
  1. Execute a consulta com o analisador ativado, adicionando estas configurações.
  1. Refatore e verifique os resultados da consulta para garantir que correspondam à saída gerada quando o analisador estiver desativado.
Consulte as incompatibilidades mais frequentes encontradas durante os testes internos.

Identificador de expressão desconhecido

Erro: Unknown expression identifier ... in scope ... (UNKNOWN_IDENTIFIER). Código da exceção: 47 Causa: Consultas que dependem de comportamentos legados não padronizados e permissivos, como referenciar aliases calculados em filtros, projeções ambíguas de subconsultas ou escopo “dinâmico” de CTEs, agora são corretamente identificadas como inválidas e rejeitadas de imediato. Solução: Atualize seus padrões SQL da seguinte forma:
  • Lógica de filtro: Mova a lógica de WHERE para HAVING se estiver filtrando resultados, ou duplique a expressão em WHERE se estiver filtrando dados de origem.
  • Escopo da subconsulta: Selecione explicitamente todas as colunas necessárias para a consulta externa.
  • Chaves de JOIN: Use ON com expressões completas em vez de USING se a chave for um alias.
  • Em consultas externas, use o alias da própria subconsulta/CTE, não o das tabelas dentro dela.

Colunas não agregadas em GROUP BY

Erro: Column ... is not under aggregate function and not in GROUP BY keys (NOT_AN_AGGREGATE). Código da exceção: 215 Causa: O analisador antigo permitia selecionar colunas que não estavam presentes na cláusula GROUP BY (muitas vezes escolhendo um valor arbitrário). O analisador segue o padrão SQL: toda coluna selecionada deve ser uma agregação ou uma chave de agrupamento. Solução: Envolva a coluna em any(), argMax() ou adicione-a ao GROUP BY.

Colunas não agregadas em HAVING

Erro: Column ... is not under aggregate function and not in GROUP BY keys (NOT_AN_AGGREGATE). Código da exceção: 215 Causa: O analisador antigo movia silenciosamente os conjuntos não agregados unidos por AND de HAVING para WHERE, tratando-os como filtros de pré-agregação. O analisador segue o SQL padrão: HAVING só pode referenciar chaves de agregação e funções de agregação. Solução: Mova manualmente o predicado de HAVING para WHERE ou habilite analyzer_compatibility_allow_non_aggregate_in_having = 1 (disponível desde o ClickHouse 26.7) para restaurar a reescrita legada como auxílio à migração. A configuração de compatibilidade é ignorada para WITH CUBE, WITH ROLLUP, WITH TOTALS e GROUPING SETS. Os conjuntos que contêm funções de agregação, grouping ou funções não determinísticas permanecem em HAVING; se algum conjunto contiver uma função de janela ou uma função com estado (por exemplo, rowNumberInBlock), a reescrita será desabilitada para todo o HAVING, em linha com o comportamento legado.

Nomes de CTE duplicados

Erro: CTE with name ... already exists (MULTIPLE_EXPRESSIONS_FOR_ALIAS). Código da exceção: 179 Causa: O analisador antigo permitia definir várias expressões de tabela comuns (WITH …) com o mesmo nome, ocultando a anterior. O analisador proíbe essa ambiguidade. Solução: Renomeie as CTEs duplicadas para que tenham nomes únicos.

Identificadores de coluna ambíguos

Erro: JOIN [JOIN TYPE] ambiguous identifier ... (AMBIGUOUS_IDENTIFIER) Código da exceção: 207 Causa: A consulta faz referência a um nome de coluna presente em várias tabelas em um JOIN sem especificar a tabela de origem. O analisador antigo frequentemente deduzia a coluna com base na lógica interna; o analisador exige um nome explícito. Solução: Qualifique totalmente a coluna com table_alias.column_name.

Uso inválido de FINAL

Erro: Table expression modifiers FINAL are not supported for subquery... ou Storage ... doesn't support FINAL (UNSUPPORTED_METHOD). Códigos de exceção: 1, 181 Causa: FINAL é um modificador de armazenamento de tabela (especificamente [Shared]ReplacingMergeTree). O analisador rejeita FINAL quando é aplicado a:
  • Subconsultas ou tabelas derivadas (por exemplo, FROM (SELECT …) FINAL).
  • Motores de tabela que não oferecem suporte a ele (por exemplo, SharedMergeTree).
Solução: Aplique FINAL apenas à tabela de origem dentro da subconsulta ou remova-o se o motor não oferecer suporte a ele.

Sensibilidade a maiúsculas e minúsculas na função countDistinct()

Erro: Function with name countdistinct does not exist (UNKNOWN_FUNCTION). Código da exceção: 46 Causa: Os nomes de funções diferenciam maiúsculas de minúsculas ou são mapeados estritamente pelo analisador. countdistinct (tudo em minúsculas) não é mais resolvida automaticamente. Solução: Use a countDistinct padrão (camelCase) ou a uniq, específica do ClickHouse.
Última modificação em 23 de julho de 2026