Skip to main content
В ClickHouse версии 24.3 анализатор включен по умолчанию. Подробнее о принципах его работы можно прочитать здесь.

Известные несовместимости

Несмотря на исправление большого количества ошибок и внедрение новых оптимизаций, это также приводит к некоторым несовместимым изменениям в поведении ClickHouse. Ознакомьтесь со следующими изменениями, чтобы понять, как переписать ваши запросы для анализатора.

Некорректные запросы больше не оптимизируются

Прежняя инфраструктура планирования запросов применяла оптимизации на уровне AST до этапа проверки запроса. Оптимизации могли переписать исходный запрос так, чтобы он стал корректным и исполнимым. В анализаторе проверка запроса выполняется до этапа оптимизации. Это означает, что некорректные запросы, которые раньше можно было выполнить, теперь не поддерживаются. В таких случаях запрос необходимо исправить вручную.

Пример 1

Следующий запрос использует столбец number в списке проекций, хотя после агрегации доступно только toString(number). В старом анализаторе GROUP BY toString(number) оптимизировалось до GROUP BY number,, что делало запрос корректным.

Пример 2

Та же проблема возникает и в этом запросе. Столбец number используется после агрегации с другим ключом. Прежний анализатор запросов исправлял этот запрос, перемещая фильтр number > 5 из условия HAVING в условие WHERE.
Чтобы исправить запрос, перенесите все условия, относящиеся к неагрегированным столбцам, в раздел WHERE, чтобы привести его в соответствие со стандартным синтаксисом SQL:
Для упрощения миграции анализатор может воспроизводить прежнее преобразование HAVING в WHERE для неагрегатных AND-конъюнктов. Чтобы включить это поведение, задайте analyzer_compatibility_allow_non_aggregate_in_having = 1. Этот параметр доступен начиная с ClickHouse 26.7. Параметр игнорируется для WITH CUBE, WITH ROLLUP, WITH TOTALS и GROUPING SETS. Конъюнкты, содержащие агрегатные функции, grouping или недетерминированные функции, остаются в HAVING; если какой-либо конъюнкт содержит оконную функцию или функцию с сохранением состояния (например, rowNumberInBlock), преобразование отключается для всего HAVING, что соответствует прежнему поведению.

CREATE VIEW с некорректным запросом

Анализатор всегда выполняет проверку типов. Ранее можно было создать VIEW с некорректным запросом SELECT. В этом случае ошибка возникала при первом SELECT или INSERT (в случае MATERIALIZED VIEW). Теперь создать VIEW таким способом нельзя.

Пример

Известные несовместимости предложения JOIN

JOIN с использованием столбца из проекции

По умолчанию псевдоним из списка SELECT нельзя использовать в качестве ключа JOIN USING. Новая настройка analyzer_compatibility_join_using_top_level_identifier, если она включена, меняет поведение JOIN USING: при разрешении идентификаторов предпочтение отдается выражениям из списка проекций запроса SELECT, а не столбцам из левой таблицы напрямую. Например:
Если analyzer_compatibility_join_using_top_level_identifier установлено в true, условие JOIN интерпретируется как t1.a + 1 = t2.b, что соответствует поведению в более ранних версиях. Результат будет 2, 'two'. Если эта настройка имеет значение false, по умолчанию используется условие JOIN t1.b = t2.b, и запрос вернёт 2, 'one'. Если b отсутствует в t1, запрос завершится ошибкой.

Изменения в поведении JOIN USING со столбцами ALIAS/MATERIALIZED

В анализаторе использование * в запросе JOIN USING со столбцами ALIAS или MATERIALIZED по умолчанию включает эти столбцы в результирующий набор. Например:
В анализаторе результат этого запроса будет включать столбец payload вместе с id из обеих таблиц. В отличие от него, предыдущий анализатор включал эти столбцы ALIAS только при включении определённых настроек (asterisk_include_alias_columns или asterisk_include_materialized_columns), при этом столбцы могли отображаться в другом порядке. Чтобы результаты были предсказуемыми и согласованными, особенно при миграции старых запросов на анализатор, рекомендуется явно указывать столбцы в секции SELECT, а не использовать *.

Обработка модификаторов типов столбцов в предложении USING

В анализаторе правила определения общего супертипа для столбцов, указанных в предложении USING, были унифицированы, чтобы результаты стали более предсказуемыми, особенно при работе с такими модификаторами типов, как LowCardinality и Nullable.
  • LowCardinality(T) и T: если столбец типа LowCardinality(T) участвует в JOIN со столбцом типа T, результирующим общим супертипом будет T, то есть модификатор LowCardinality фактически отбрасывается.
  • Nullable(T) и T: если столбец типа Nullable(T) участвует в JOIN со столбцом типа T, результирующим общим супертипом будет Nullable(T), что гарантирует сохранение свойства nullable.
Например:
В этом запросе общий супертип для id определяется как String, а модификатор LowCardinality из t1 отбрасывается.

Изменения в именах столбцов проекции

При вычислении имён проекции псевдонимы не подставляются.

Несовместимые типы аргументов функции

В анализатор вывод типов происходит на этапе начального анализа запроса. Это означает, что проверка типов выполняется до укороченного вычисления, поэтому аргументы функции if всегда должны иметь общий супертип. Например, следующий запрос завершается ошибкой There is no supertype for types Array(UInt8), String because some of them are Array and some of them are not:

Неоднородные кластеры

Анализатор существенно меняет протокол обмена данными между серверами в кластере. Поэтому выполнять распределённые запросы на серверах с разными значениями настройки enable_analyzer невозможно.

Мутации обрабатываются предыдущим анализатором

Мутации по-прежнему используют старый анализатор. Это означает, что некоторые новые возможности ClickHouse SQL нельзя использовать в мутациях. Например, оператор QUALIFY. Текущий статус можно проверить здесь.

Неподдерживаемые возможности

Ниже приведен список возможностей, которые анализатор пока не поддерживает:
  • Индекс Annoy.
  • Индекс Hypothesis. Работа над ним ведется здесь.
  • Оконное представление не поддерживается. Его поддержка в будущем не планируется.

Миграция в Cloud

Мы включаем анализатор на всех экземплярах, где он сейчас отключен, чтобы обеспечить новые функциональные возможности и оптимизации производительности. Это изменение ужесточает правила области видимости в SQL, поэтому клиентам потребуется вручную обновить запросы, которые им не соответствуют.

Процесс миграции

  1. Определите запрос, отфильтровав записи в system.query_log по normalized_query_hash:
  1. Выполните запрос при включенном анализаторе, добавив следующие настройки.
  1. Доработайте запрос и проверьте, что его результаты совпадают с выводом при отключённом анализаторе.
Ознакомьтесь с наиболее частыми несовместимостями, обнаруженными в ходе внутреннего тестирования.

Неизвестный идентификатор выражения

Ошибка: Unknown expression identifier ... in scope ... (UNKNOWN_IDENTIFIER). Код исключения: 47 Причина: запросы, зависящие от нестандартного устаревшего поведения, допускающего неоднозначности, — например, обращения к вычисляемым псевдонимам в фильтрах, неоднозначных проекций подзапросов или «динамической» области видимости CTE, — теперь корректно определяются как недопустимые и сразу отклоняются. Решение: обновите SQL-шаблоны следующим образом:
  • Логика фильтрации: перенесите условие из WHERE в HAVING, если фильтрация идёт по результатам, или продублируйте выражение в WHERE, если фильтрация идёт по исходным данным.
  • Область видимости подзапроса: явно выберите все столбцы, необходимые внешнему запросу.
  • Ключи JOIN: используйте ON с полными выражениями вместо USING, если ключ — это псевдоним.
  • Во внешних запросах обращайтесь к псевдониму самого подзапроса/CTE, а не к таблицам внутри него.

Неагрегированные столбцы в GROUP BY

Ошибка: Column ... is not under aggregate function and not in GROUP BY keys (NOT_AN_AGGREGATE). Код исключения: 215 Причина: Старый анализатор позволял выбирать столбцы, которых нет в GROUP BY (часто подставляя произвольное значение). Анализатор следует стандарту SQL: каждый выбранный столбец должен быть либо агрегатом, либо ключом группировки. Решение: Оберните столбец в any(), argMax() или добавьте его в GROUP BY.

Неагрегированные столбцы в HAVING

Ошибка: Column ... is not under aggregate function and not in GROUP BY keys (NOT_AN_AGGREGATE). Код исключения: 215 Причина: Старый анализатор без предупреждения переносил неагрегирующие AND-конъюнкты из HAVING в WHERE, рассматривая их как фильтры предварительной агрегации. Анализатор соответствует standard SQL: HAVING может ссылаться только на ключи агрегации и агрегатные функции. Решение: Вручную перенесите предикат из HAVING в WHERE или включите analyzer_compatibility_allow_non_aggregate_in_having = 1 (доступно начиная с ClickHouse 26.7), чтобы вернуть прежнее преобразование как вспомогательное средство при миграции. Настройка совместимости не применяется к WITH CUBE, WITH ROLLUP, WITH TOTALS и GROUPING SETS. Конъюнкты, содержащие агрегатные, grouping или недетерминированные функции, остаются в HAVING; если хотя бы один конъюнкт содержит оконную функцию или функцию с сохранением состояния (например, rowNumberInBlock), преобразование отключается для всего HAVING, как и в прежнем поведении.

Дублирующиеся имена CTE

Ошибка: CTE with name ... already exists (MULTIPLE_EXPRESSIONS_FOR_ALIAS). Код исключения: 179 Причина: Старый анализатор допускал определение нескольких общих табличных выражений (WITH …) с одним и тем же именем, когда более позднее выражение перекрывало предыдущее. Анализатор не допускает такой неоднозначности. Решение: Переименуйте повторяющиеся CTE, чтобы их имена были уникальными.

Неоднозначные идентификаторы столбцов

Ошибка: JOIN [JOIN TYPE] ambiguous identifier ... (AMBIGUOUS_IDENTIFIER) Код исключения: 207 Причина: В запросе используется имя столбца, которое присутствует в нескольких таблицах в JOIN, без указания исходной таблицы. Старый анализатор часто определял нужный столбец на основе внутренней логики, тогда как анализатор требует явного указания имени. Решение: Полностью указывайте столбец в виде table_alias.column_name.

Недопустимое использование FINAL

Ошибка: Table expression modifiers FINAL are not supported for subquery... или Storage ... doesn't support FINAL (UNSUPPORTED_METHOD). Коды исключений: 1, 181 Причина: FINAL — это модификатор хранения таблицы (в частности, для [Shared]ReplacingMergeTree). Анализатор отклоняет FINAL, если он применяется к:
  • Подзапросам или производным таблицам (например, FROM (SELECT …) FINAL).
  • Движкам таблиц, которые его не поддерживают (например, SharedMergeTree).
Решение: Применяйте FINAL только к исходной таблице внутри подзапроса или уберите его, если движок его не поддерживает.

Чувствительность функции countDistinct() к регистру

Ошибка: Function with name countdistinct does not exist (UNKNOWN_FUNCTION). Код исключения: 46 Причина: имена функций чувствительны к регистру, либо в анализаторе для них используется строгое сопоставление. countdistinct (полностью в нижнем регистре) больше не распознаётся автоматически. Решение: используйте стандартную countDistinct (camelCase) или специфичную для ClickHouse функцию uniq.
Последнее изменение 23 июля 2026 г.