Синтаксис
В этом разделе мы рассмотрим синтаксис 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
намного более ограничен.
Остальная часть этого раздела охватывает полный парсер.
Для получения дополнительной информации о парсерах формата, смотрите раздел Форматы.
Пробелы
- Между синтаксическими конструкциями (включая начало и конец запроса) может быть любое количество символов пробела.
- Символы пробела включают пробел, табуляцию, перевод строки, CR и слипающую ленту.
Комментарии
ClickHouse поддерживает как SQL-стиль, так и C-стиль комментарии:
- SQL-стиль комментарии начинаются с
--
,#!
или#
и продолжаются до конца строки. Пробел после--
и#!
можно опустить. - C-стиль комментарии охватывают от
/*
до*/
и могут быть многострочными. Пробелы также не требуются.
Ключевые слова
Ключевые слова в ClickHouse могут быть либо чувствительными к регистру, либо не чувствительными к регистру, в зависимости от контекста.
Ключевые слова являются не чувствительными к регистру, когда они соответствуют:
- Стандарту 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`
.
Те же правила, которые применяются для экранирования вquoted идентификаторах, также применяются для строковых литералов. Смотрите раздел Строка для получения дополнительных деталей.
Литералы
В ClickHouse литерал – это значение, которое представлено непосредственно в запросе. Другими словами, это фиксированное значение, которое не изменяется в процессе выполнения запроса.
Литералы могут быть:
- Строковыми
- Числовыми
- Составными
NULL
- Heredocs (пользовательские строковые литералы)
Мы рассмотрим каждую из этих категорий более подробно в следующих разделах.
Строка
Строковые литералы должны быть заключены в одиночные кавычки. Двойные кавычки не поддерживаются.
Экранирование работает либо путем:
- использования предшествующей одиночной кавычки, где символ одиночной кавычки
'
(и только этот символ) может быть экранирован как''
, или - использования предшествующей обратной косой черты с перечислением поддерживаемых escape-последовательностей, приведенных в таблице ниже.
Обратная косая черта теряет свое специальное значение, т.е. она интерпретируется буквально, если она предшествует символам, отличным от тех, что перечислены ниже.
Поддерживаемое экранирование | Описание |
---|---|
\xHH | Спецификация 8-битного символа, сопровождаемая любым количеством шестнадцатеричных цифр (H). |
\N | зарезервировано, ничего не делает (например, SELECT 'a\Nb' возвращает ab ) |
\a | сигнал |
\b | возврат на одну позицию назад |
\e | символ экранирования |
\f | перевод страницы |
\n | перевод строки |
\r | возврат каретки |
\t | горизонтальная табуляция |
\v | вертикальная табуляция |
\0 | нулевой символ |
\\ | обратная косая черта |
\' (или '' ) | одиночная кавычка |
\" | двойная кавычка |
` | обратная кавычка |
\/ | косая черта |
\= | знак равенства |
ASCII управляющие символы (c <= 31). |
В строковых литералах вы должны экранировать по крайней мере '
и \
, используя коды экранирования \'
(или: ''
) и \\
.
Числовой
Числовые литералы разбираются следующим образом:
- Сначала как 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 определяется как пользовательский строковый литерал, помещенный между двумя символами $
.
Например:
- Значение между двумя heredocs обрабатывается "как есть".
- Вы можете использовать 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 генерирует исключение
Unknown identifier: num
:
- Если псевдоним определен для результирующих колонок в предложении
SELECT
подзапроса, эти колонки видны в внешнем запросе. Например:
- Будьте осторожны с псевдонимами, которые совпадают с именами колонок или таблиц. Рассмотрим следующий пример:
В приведенном выше примере мы объявили таблицу t
с колонкой b
.
Затем, при выборе данных, мы определили псевдоним sum(b) AS b
.
Поскольку псевдонимы глобальны,
ClickHouse заменил литерал b
в выражении argMax(a, b)
на выражение sum(b)
.
Эта замена и вызвала исключение.
Вы можете изменить это поведение по умолчанию, установив prefer_column_name_to_alias в 1
.
Звездочка
В запросе SELECT
звездочка может заменить выражение.
Для получения дополнительной информации смотрите раздел SELECT.