Синтаксис
В этом разделе мы рассмотрим синтаксис 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 , [email protected] , ä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) |
В строковых литералах необходимо экранировать как минимум '
и \
с использованием кодов экранирования \'
(или: ''
) и \\
.
Числовой
Числовые литералы обрабатываются следующим образом:
- Сначала как 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
nuanced. Например, если хотя бы один из аргументов операции сравнения равен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 генерирует исключение
Неизвестный идентификатор: num
:
- Если псевдоним определен для столбцов результата в операторе
SELECT
подзапроса, эти столбцы видны во внешнем запросе. Например:
- Будьте осторожны с псевдонимами, которые совпадают с именами колонок или таблиц. Рассмотрим следующий пример:
В приведенном примере мы объявили таблицу t
с колонкой b
.
Затем, при выборке данных, мы определили псевдоним sum(b) AS b
.
Поскольку псевдонимы глобальны,
ClickHouse подменил литерал b
в выражении argMax(a, b)
на выражение sum(b)
.
Эта подстановка вызвала исключение.
Вы можете изменить это поведение по умолчанию, установив prefer_column_name_to_alias в 1
.
Звездочка
В запросе SELECT
звездочка может заменить выражение.
Для получения дополнительной информации смотрите раздел SELECT.