En la versión 24.3 de ClickHouse, el analizador de consultas estaba habilitado de forma predeterminada.
Puede obtener más información sobre su funcionamiento aquí.
Incompatibilidades conocidas
A pesar de corregir una gran cantidad de errores e introducir nuevas optimizaciones, también se introducen algunos cambios incompatibles en el comportamiento de ClickHouse. Lea los siguientes cambios para determinar cómo reescribir sus consultas para el analizador.
Las consultas no válidas ya no se optimizan
La infraestructura anterior de planificación de consultas aplicaba optimizaciones a nivel de AST antes del paso de validación de la consulta.
Las optimizaciones podían reescribir la consulta inicial para que fuera válida y ejecutable.
En el analizador, la validación de la consulta se realiza antes del paso de optimización.
Esto significa que las consultas no válidas que antes podían ejecutarse ahora ya no se admiten.
En esos casos, la consulta debe corregirse manualmente.
La siguiente consulta usa la columna number en la lista de proyección cuando, tras la agregación, solo está disponible toString(number).
En el analizador anterior, GROUP BY toString(number) se optimizaba a GROUP BY number,, lo que hacía que la consulta fuera válida.
El mismo problema se produce en esta consulta. La columna number se usa después de la agregación con otra clave.
El analizador de consultas anterior corrigió esta consulta al mover el filtro number > 5 de la cláusula HAVING a la cláusula WHERE.
Para corregir la consulta, debes mover a la sección WHERE todas las condiciones que se apliquen a columnas no agregadas, para ajustarte a la sintaxis SQL estándar:
Como ayuda para la migración, el analizador puede replicar la antigua reescritura de HAVING a WHERE para conjunciones AND no agregadas. Habilita analyzer_compatibility_allow_non_aggregate_in_having = 1 para activar este comportamiento. Esta configuración está disponible desde ClickHouse 26.7. La configuración se ignora para WITH CUBE, WITH ROLLUP, WITH TOTALS y GROUPING SETS. Las conjunciones que contienen funciones de agregación, grouping o no deterministas permanecen en HAVING; si alguna conjunción contiene una función de ventana o una función con estado (por ejemplo, rowNumberInBlock), la reescritura se desactiva para toda la cláusula HAVING, en consonancia con el comportamiento heredado.
CREATE VIEW con una consulta no válida
El analizador siempre realiza la verificación de tipos.
Anteriormente, era posible crear una VIEW con una consulta SELECT no válida.
El error aparecía durante el primer SELECT o INSERT (en el caso de MATERIALIZED VIEW).
Ya no es posible crear una VIEW de esta forma.
Incompatibilidades conocidas de la cláusula JOIN
JOIN usando una columna de una proyección
De forma predeterminada, no se puede usar un alias de la lista SELECT como clave de JOIN USING.
Una nueva configuración, analyzer_compatibility_join_using_top_level_identifier, cuando está habilitada, cambia el comportamiento de JOIN USING para que dé prioridad a la resolución de identificadores a partir de las expresiones de la lista de proyección de la consulta SELECT, en lugar de usar directamente las columnas de la tabla de la izquierda.
Por ejemplo:
Con analyzer_compatibility_join_using_top_level_identifier establecido en true, la condición de join se interpreta como t1.a + 1 = t2.b, en consonancia con el comportamiento de las versiones anteriores.
El resultado será 2, 'two'.
Cuando la configuración está en false, la condición de join pasa a ser t1.b = t2.b de forma predeterminada, y la consulta devolverá 2, 'one'.
Si b no está presente en t1, la consulta fallará con un error.
Cambios de comportamiento con JOIN USING y columnas ALIAS/MATERIALIZED
En el analizador, usar * en una consulta JOIN USING que involucre columnas ALIAS o MATERIALIZED hará que esas columnas se incluyan en el conjunto de resultados de forma predeterminada.
Por ejemplo:
En el analizador, el resultado de esta consulta incluirá la columna payload junto con id de ambas tablas.
En cambio, el analizador anterior solo incluía estas columnas ALIAS si se habían habilitado opciones específicas (asterisk_include_alias_columns o asterisk_include_materialized_columns),
y las columnas podían aparecer en un orden diferente.
Para garantizar resultados coherentes y previsibles, especialmente al migrar consultas antiguas al analizador, es aconsejable especificar las columnas explícitamente en la cláusula SELECT en lugar de usar *.
Manejo de los modificadores de tipo de las columnas en la cláusula USING
En el analizador, se han estandarizado las reglas para determinar el supertipo común de las columnas especificadas en la cláusula USING, con el fin de producir resultados más predecibles,
especialmente al trabajar con modificadores de tipo como LowCardinality y Nullable.
LowCardinality(T) y T: Cuando una columna de tipo LowCardinality(T) se combina con una columna de tipo T, el supertipo común resultante será T, lo que en la práctica descarta el modificador LowCardinality.
Nullable(T) y T: Cuando una columna de tipo Nullable(T) se combina con una columna de tipo T, el supertipo común resultante será Nullable(T), lo que garantiza que se conserve la propiedad Nullable.
Por ejemplo:
En esta consulta, el supertipo común de id se establece como String, descartando el modificador LowCardinality de t1.
Cambios en los nombres de las columnas de la proyección
Durante el cálculo de los nombres de la proyección, no se sustituyen los alias.
Tipos incompatibles en los argumentos de función
En el analizador, la inferencia de tipos se produce durante el análisis inicial de la consulta.
Este cambio significa que las comprobaciones de tipos se realizan antes de la evaluación de cortocircuito; por lo tanto, los argumentos de la función if siempre deben tener un supertipo común.
Por ejemplo, la siguiente consulta falla con There is no supertype for types Array(UInt8), String because some of them are Array and some of them are not:
El analizador cambia de forma significativa el protocolo de comunicación entre los servidores del clúster. Por lo tanto, es imposible ejecutar consultas distribuidas en servidores con valores distintos de la configuración enable_analyzer.
Las mutaciones se interpretan con el analizador anterior
Las mutaciones siguen usando el analizador anterior.
Esto significa que algunas funciones nuevas de ClickHouse SQL no se pueden usar en las mutaciones. Por ejemplo, la cláusula QUALIFY.
Se puede consultar el estado aquí.
Funcionalidades no compatibles
A continuación se muestra la lista de funcionalidades que el analizador no admite actualmente:
- Índice Annoy.
- Índice Hypothesis. Trabajo en curso aquí.
- window view no es compatible. No hay planes de admitirla en el futuro.
Estamos habilitando el analizador en todas las instancias donde actualmente está deshabilitado para permitir nuevas optimizaciones funcionales y de rendimiento. Este cambio impone reglas de ámbito de SQL más estrictas, por lo que los clientes deberán actualizar manualmente las consultas que no las cumplan.
- Identifique la consulta filtrando
system.query_log con normalized_query_hash:
- Ejecute la consulta con el analizador habilitado agregando esta configuración.
- Refactoriza y verifica los resultados de la consulta para asegurarte de que coincidan con la salida generada cuando el analizador está desactivado.
Consulta las incompatibilidades más frecuentes detectadas durante las pruebas internas.
Identificador de expresión desconocido
Error: Unknown expression identifier ... in scope ... (UNKNOWN_IDENTIFIER). Código de excepción: 47
Causa: Las consultas que dependen de comportamientos heredados permisivos y no estándar, como hacer referencia a alias calculados en filtros, proyecciones ambiguas de subconsultas o un alcance “dinámico” de CTE, ahora se identifican correctamente como no válidas y se rechazan de inmediato.
Solución: Actualice sus patrones SQL de la siguiente manera:
- Lógica de filtro: Mueva la lógica de WHERE a HAVING si filtra por resultados, o duplique la expresión en WHERE si filtra por datos de origen.
- Alcance de la subconsulta: Seleccione explícitamente todas las columnas necesarias para la consulta externa.
- Claves de JOIN: Use ON con expresiones completas en lugar de USING si la clave es un alias.
- En las consultas externas, haga referencia al alias de la propia subconsulta/CTE, no a las tablas que contiene.
Columnas no agregadas en GROUP BY
Error: Column ... is not under aggregate function and not in GROUP BY keys (NOT_AN_AGGREGATE). Código de excepción: 215
Causa: El analizador anterior permitía seleccionar columnas que no estaban presentes en la cláusula GROUP BY (a menudo tomando un valor arbitrario). El analizador sigue el estándar SQL: cada columna seleccionada debe ser un agregado o una clave de agrupación.
Solución: Envuelva la columna en any(), argMax() o añádala a GROUP BY.
Columnas no agregadas en HAVING
Error: Column ... is not under aggregate function and not in GROUP BY keys (NOT_AN_AGGREGATE). código de excepción: 215
Causa: El analizador anterior movía silenciosamente a WHERE las conjunciones con AND de HAVING que no eran de agregación, tratándolas como filtros de preagregación. El analizador se ajusta al SQL estándar: HAVING solo puede hacer referencia a claves de agregación y funciones de agregación.
Solución: Mueva manualmente el predicado de HAVING a WHERE, o habilite analyzer_compatibility_allow_non_aggregate_in_having = 1 (disponible desde ClickHouse 26.7) para restaurar la reescritura heredada como ayuda para la migración. La configuración compatibility se ignora para WITH CUBE, WITH ROLLUP, WITH TOTALS y GROUPING SETS. Las conjunciones que contienen funciones de agregación, grouping o funciones no deterministas permanecen en HAVING; si alguna conjunción contiene una función de ventana o una función con estado (por ejemplo, rowNumberInBlock), la reescritura se desactiva para todo el HAVING, en consonancia con el comportamiento heredado.
Nombres de CTE duplicados
Error: CTE with name ... already exists (MULTIPLE_EXPRESSIONS_FOR_ALIAS). Código de excepción: 179
Causa: El analizador anterior permitía definir varias Common Table Expressions (WITH …) con el mismo nombre, de modo que una ocultaba a la anterior. El analizador prohíbe esta ambigüedad.
Solución: Renombre los CTE duplicados para que tengan nombres únicos.
Identificadores de columna ambiguos
Error: JOIN [JOIN TYPE] ambiguous identifier ... (AMBIGUOUS_IDENTIFIER) Código de excepción: 207
Causa: La consulta hace referencia a un nombre de columna presente en varias tablas dentro de un JOIN sin especificar la tabla de origen. El analizador antiguo a menudo deducía la columna según su lógica interna; el analizador requiere un nombre explícito.
Solución: Especifique el nombre completo de la columna con table_alias.column_name.
Error: Table expression modifiers FINAL are not supported for subquery... o Storage ... doesn't support FINAL (UNSUPPORTED_METHOD). Códigos de excepción: 1, 181
Causa: FINAL es un modificador del almacenamiento de tablas (en concreto, [Shared]ReplacingMergeTree). El analizador rechaza FINAL cuando se aplica a:
- Subconsultas o tablas derivadas (p. ej., FROM (SELECT …) FINAL).
- Motores de tabla que no lo admiten (p. ej., SharedMergeTree).
Solución: Aplique FINAL solo a la tabla de origen dentro de la subconsulta, o elimínelo si el motor no lo admite.
Insensibilidad a mayúsculas y minúsculas en la función countDistinct()
Error: Function with name countdistinct does not exist (UNKNOWN_FUNCTION). Código de excepción: 46
Causa: Los nombres de las funciones son sensibles a mayúsculas y minúsculas o están asociados de forma estricta en el analizador. countdistinct (todo en minúsculas) ya no se resuelve automáticamente.
Solución: Use countDistinct estándar (camelCase) o uniq, específico de ClickHouse. Última modificación el 23 de julio de 2026