Синтаксис
В этом разделе мы рассмотрим синтаксис 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 могут восприниматься как чувствительные к регистру, так и нечувствительные к регистру в зависимости от контекста.
Ключевые слова нечувствительны к регистру когда они соответствуют:
- Стандарту 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). |
В строковых литералах вам необходимо экранировать как минимум '
и \
используя экранированные коды \'
(или: ''
) и \\
.
Числовой
Числовые литералы разбираются следующим образом:
- Сначала как 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 выдает исключение
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.