Синтаксис
В этом разделе мы рассмотрим SQL-синтаксис ClickHouse. ClickHouse использует синтаксис на основе SQL, но предлагает ряд расширений и оптимизаций.
Парсинг запросов
В ClickHouse есть два типа парсеров:
- Полный SQL парсер (рекурсивный парсинг).
- Парсер формата данных (быстрый потоковый парсер).
Полный SQL парсер используется во всех случаях, кроме запроса INSERT
, который использует оба парсера.
Рассмотрим следующий запрос:
Как уже упоминалось, запрос INSERT
использует оба парсера.
Фрагмент INSERT INTO t VALUES
обрабатывается полным парсером,
а данные (1, 'Hello, world'), (2, 'abc'), (3, 'def')
обрабатываются парсером формата данных или быстрым потоковым парсером.
Включение полного парсера
Вы также можете включить полный парсер для данных
с помощью настройки input_format_values_interpret_expressions
.
Когда указанная настройка установлена в 1
,
ClickHouse сначала пытается разобрать значения с помощью быстрого потокового парсера.
Если это не удаётся, ClickHouse пытается использовать полный парсер для данных, рассматривая их как SQL выражение.
Данные могут иметь любой формат.
Когда запрос поступает, сервер вычисляет не более чем max_query_size байт запроса в ОЗУ
(по умолчанию 1 МБ), а остальная часть обрабатывается потоковым парсером.
Это делается для предотвращения проблем с большими запросами INSERT
, что является рекомендуемым способом вставки данных в ClickHouse.
При использовании формата Values
в запросе INSERT
может показаться, что данные обрабатываются так же, как и для выражений в запросе SELECT
, однако это не так.
Формат Values
гораздо более ограниченный.
Остальная часть этого раздела охватывает полный парсер.
Для получения дополнительной информации о парсерах формата обратитесь к разделу Форматы.
Пробелы
- Между синтаксическими конструкциями может быть любое количество пробелов (включая начало и конец запроса).
- Пробелы включают пробел, табуляцию, перевод строки, возврат каретки и новую страницу.
Комментарии
ClickHouse поддерживает как SQL-стиль, так и C-стиль комментарии:
- SQL-стиль комментарии начинаются с
--
,#!
или#
и продолжаются до конца строки. Пробел после--
и#!
может быть опущен. - C-стиль комментарии охватывают от
/*
до*/
и могут быть многострочными. Пробелы также не обязательны.
Ключевые слова
Ключевые слова в ClickHouse могут быть либо чувствительными к регистру, либо _ insensitive_, в зависимости от контекста.
Ключевые слова являются insensitive к регистру когда они соответствуют:
- Стандарту SQL. Например,
SELECT
,select
иSeLeCt
все действительны. - Реализациям в некоторых популярных СУБД (MySQL или Postgres). Например,
DateTime
равноdatetime
.
Вы можете проверить, является ли имя типа данных чувствительным к регистру в таблице system.data_type_families.
В отличие от стандартного SQL, все другие ключевые слова (включая названия функций) являются чувствительными к регистру.
Кроме того, ключевые слова не являются зарезервированными. Они рассматриваются как таковые только в соответствующем контексте. Если вы используете идентификаторы с тем же именем, что и ключевые слова, заключите их в двойные кавычки или обратные кавычки.
Например, следующий запрос является действительным, если таблица table_name
имеет столбец с именем "FROM"
:
Идентификаторы
Идентификаторы это:
- Имена кластера, базы данных, таблицы, раздела и столбца.
- Функции.
- Типы данных.
- Псевдонимы выражений.
Идентификаторы могут быть заключены в кавычки или не заключены, хотя последние предпочтительнее.
Не заключенные в кавычки идентификаторы должны совпадать с регулярным выражением ^[a-zA-Z_][0-9a-zA-Z_]*$
и не могут совпадать с ключевыми словами.
Смотрите таблицу ниже для примеров действительных и недействительных идентификаторов:
Действительные идентификаторы | Недействительные идентификаторы |
---|---|
xyz , _internal , Id_with_underscores_123_ | 1x , tom@gmail.com , äußerst_schön |
Если вы хотите использовать идентификаторы, такие как ключевые слова или вы хотите использовать другие символы в идентификаторах, заключите их в двойные кавычки или обратные кавычки, например, "id"
, `id`
.
Тем же правилам, которые применяются для экранирования в заключенных в кавычки идентификаторах, также подвергаются строковые литералы. См. Строка для получения более подробной информации.
Литералы
В ClickHouse литерал — это значение, которое непосредственно представлено в запросе. Другими словами, это фиксированное значение, которое не изменяется во время выполнения запроса.
Литералы могут быть:
Мы подробнее рассмотрим каждую из этих категорий в следующих разделах.
Строка
Строковые литералы должны быть заключены в одинарные кавычки. Двойные кавычки не поддерживаются.
Экранирование осуществляется следующим образом:
- используя предшествующую одинарную кавычку, где символ одинарной кавычки
'
(и только этот символ) можно экранировать как''
, или - используя предшествующий обратный слэш с поддерживаемыми последовательностями экранирования, перечисленными в таблице ниже.
Обратный слэш теряет своё специальное значение, то есть он интерпретируется буквально, если он предшествует символам, отличным от перечисленных ниже.
Поддерживаемое экранирование | Описание |
---|---|
\xHH | Спецификация 8-битного символа, за которым следует любое количество шестнадцатеричных цифр (H). |
\N | зарезервированный, ничего не делает (например, SELECT 'a\Nb' возвращает ab ) |
\a | сигнал |
\b | возврат каретки |
\e | символ экранирования |
\f | новая страница |
\n | перевод строки |
\r | возврат каретки |
\t | горизонтальная табуляция |
\v | вертикальная табуляция |
\0 | нулевой символ |
\\ | обратный слэш |
\' (или '' ) | одинарная кавычка |
\" | двойная кавычка |
` | обратная кавычка |
\/ | прямой слэш |
\= | знак равенства |
ASCII контрольные символы (c <= 31). |
В строковых литералах вы должны экранировать как минимум символы '
и \
с помощью escape-кодов \'
(или: ''
) и \\
.
Числовой
Числовые литералы анализируются следующим образом:
- Сначала как 64-битное знаковое число с использованием функции strtoull.
- Если это не удастся, как 64-битное без знака число с использованием функции strtoll.
- Если это не удастся, как число с плавающей запятой с использованием функции strtod.
- В противном случае возвращается ошибка.
Литералы преобразуются в наименьший тип, в который вмещается значение. Например:
1
интерпретируется какUInt8
256
интерпретируется какUInt16
.
Для получения дополнительной информации смотрите Типы данных.
Подчеркивание _
внутри числовых литералов игнорируется и может использоваться для улучшения читаемости.
Следующие числовые литералы поддерживаются:
Числовой литерал | Примеры |
---|---|
Целые числа | 1 , 10_000_000 , 18446744073709551615 , 01 |
Десятичные числа | 0.1 |
Экспоненциальная нотация | 1e100 , -1e-100 |
Числа с плавающей точкой | 123.456 , inf , nan |
Шестнадцатеричные | 0xc0fe |
Строка шестнадцатеричного формата, совместимая со стандартом SQL | x'c0fe' |
Двоичные числа | 0b1101 |
Строка двоичного формата, совместимая со стандартом SQL | b'1101' |
Октальные литералы не поддерживаются для избежания случайных ошибок интерпретации.
Составной
Массивы создаются с использованием квадратных скобок [1, 2, 3]
. Кортежи создаются с использованием круглых скобок (1, 'Hello, world!', 2)
.
Технически это не литералы, а выражения с оператором создания массива и оператором создания кортежа соответственно.
Массив должен содержать как минимум один элемент, а кортеж — как минимум два элемента.
Существует отдельный случай, когда кортежи встречаются в условии IN
запроса SELECT
.
Результаты запросов могут включать кортежи, но кортежи не могут быть сохранены в базе данных (исключая таблицы с использованием движка Memory).
NULL
NULL
используется для указания на то, что значение отсутствует.
Чтобы сохранить NULL
в поле таблицы, оно должно быть типа Nullable.
Следует отметить следующее относительно NULL
:
- В зависимости от формата данных (входного или выходного)
NULL
может иметь разное представление. Для получения дополнительной информации смотрите форматы данных. - Обработка
NULL
имеет свои нюансы. Например, если хотя бы один из аргументов операции сравнения равенNULL
, результат этой операции также будет равенNULL
. То же самое относится к умножению, сложению и другим операциям. Мы рекомендуем ознакомиться с документацией по каждой операции. - В запросах вы можете проверять
NULL
с помощью операторовIS NULL
иIS NOT NULL
и связанных функцийisNull
иisNotNull
.
Heredoc
Heredoc — это способ определения строки (часто многострочной), сохраняя оригинальное форматирование.
Heredoc определяется как пользовательский строковой литерал, размещаемый между двумя символами $
.
Например:
- Значение между двумя heredoc обрабатывается "как есть".
- Вы можете использовать heredoc для встраивания фрагментов SQL, кода HTML или XML и т.д.
Определение и использование параметров запроса
Параметры запросов позволяют вам писать универсальные запросы, содержащие абстрактные заполнители вместо конкретных идентификаторов. Когда запрос с параметрами выполняется, все заполнители разрешаются и заменяются фактическими значениями параметров запроса.
Существует два способа определения параметра запроса:
SET param_<name>=<value>
--param_<name>='<value>'
При использовании второго варианта он передаётся как аргумент к clickhouse-client
в командной строке, где:
<name>
— это имя параметра запроса.<value>
— его значение.
Параметр запроса может быть ссылается в запросе, используя {<name>: <datatype>}
, где <name>
— это имя параметра запроса, а <datatype>
— это тип данных, в который он преобразуется.
Пример с командой SET
Например, следующий SQL определяет параметры с именами a
, b
, c
и d
, каждый с разным типом данных:
Пример с clickhouse-client
Если вы используете clickhouse-client
, параметры задаются как --param_name=value
. Например, следующий параметр имеет имя message
, и он извлекается как String
:
Если параметр запроса представляет собой имя базы данных, таблицы, функции или другого идентификатора, используйте Identifier
для его типа. Например, следующий запрос возвращает строки из таблицы с названием uk_price_paid
:
Параметры запросов не являются общими текстовыми заменами, которые могут использоваться в произвольных местах в произвольных SQL-запросах.
Они в первую очередь предназначены для работы в операторах SELECT
на месте идентификаторов или литералов.
Функции
Вызовы функций записываются как идентификатор с перечнем аргументов (возможно, пустых) в круглых скобках. В отличие от стандартного SQL, скобки обязательны, даже для пустого списка аргументов. Например:
Существуют также:
Некоторые агрегатные функции могут содержать два списка аргументов в скобках. Например:
Эти агрегатные функции называются "параметрическими" функциями, а аргументы в первом списке называются "параметрами".
Синтаксис агрегатных функций без параметров такой же, как и для обычных функций.
Операторы
Операторы преобразуются в соответствующие функции во время парсинга запросов, принимая во внимание их приоритет и ассоциативность.
Например, выражение
преобразуется в
Типы данных и движки таблиц базы данных
Типы данных и движки таблиц в запросе CREATE
записываются так же, как идентификаторы или функции.
Другими словами, они могут содержать аргументы в скобках или не содержать.
Для получения дополнительной информации смотрите разделы:
Выражения
Выражение может быть следующим:
- функцией
- идентификатором
- литералом
- применением оператора
- выражением в скобках
- подзапросом
- или звездочкой.
Оно также может содержать псевдоним.
Список выражений представляет собой одно или несколько выражений, разделённых запятыми. Функции и операторы, в свою очередь, могут принимать выражения в качестве аргументов.
Псевдонимы выражений
Псевдоним — это имя, заданное пользователем для выражения в запросе.
Части синтаксиса выше объясняются ниже.
Часть синтаксиса | Описание | Пример | Примечания |
---|---|---|---|
AS | Ключевое слово для определения псевдонимов. Вы можете определить псевдоним для имени таблицы или имени столбца в операторе SELECT , не используя ключевое слово AS . | SELECT table_name_alias.column_name FROM table_name table_name_alias . | В функции CAST ключевое слово AS имеет другое значение. См. описание функции. |
expr | Любое выражение, поддерживаемое ClickHouse. | SELECT column_name * 2 AS double FROM some_table | |
alias | Имя для expr . Псевдонимы должны соответствовать синтаксису идентификаторов. | SELECT "table t".column_name FROM table_name AS "table t" . |
Примечания по использованию
- Псевдонимы действительны глобально для запроса или подзапроса, и вы можете определить псевдоним в любой части запроса для любого выражения. Например:
- Псевдонимы не видны в подзапросах и между подзапросами. Например, при выполнении следующего запроса ClickHouse генерирует исключение
Неизвестный идентификатор: num
:
- Если псевдоним определяется для результирующих столбцов в операторе
SELECT
подзапроса, эти столбцы видны в внешнем запросе. Например:
- Будьте осторожны с псевдонимами, которые совпадают с именами столбцов или таблиц. Рассмотрим следующий пример:
В предыдущем примере мы объявили таблицу t
с колонкой b
.
Затем, когда мы отбирали данные, мы определили псевдоним sum(b) AS b
.
Так как псевдонимы действительны глобально,
ClickHouse заменил литерал b
в выражении argMax(a, b)
на выражение sum(b)
.
Эта замена вызвала исключение.
Вы можете изменить это стандартное поведение, установив prefer_column_name_to_alias в 1
.
Звездочка
В операторе SELECT
звездочка может заменить выражение.
Для получения дополнительной информации смотрите раздел SELECT.