ClickHouse/docs/ru/sql-reference/syntax.md

205 lines
17 KiB
Markdown
Raw Normal View History

---
sidebar_position: 31
sidebar_label: "Синтаксис"
---
2021-09-21 02:18:13 +00:00
# Синтаксис {#syntax}
В системе есть два вида парсеров: полноценный парсер SQL (recursive descent parser) и парсер форматов данных (быстрый потоковый парсер).
Во всех случаях кроме запроса INSERT, используется только полноценный парсер SQL.
В запросе INSERT используется оба парсера:
``` sql
INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')
```
Фрагмент `INSERT INTO t VALUES` парсится полноценным парсером, а данные `(1, 'Hello, world'), (2, 'abc'), (3, 'def')` - быстрым потоковым парсером.
Данные могут иметь любой формат. При получении запроса, сервер заранее считывает в оперативку не более `max_query_size` байт запроса (по умолчанию, 1МБ), а всё остальное обрабатывается потоково.
Таким образом, в системе нет проблем с большими INSERT запросами, как в MySQL.
При использовании формата Values в INSERT запросе может сложиться иллюзия, что данные парсятся также, как выражения в запросе SELECT, но это не так. Формат Values гораздо более ограничен.
Далее пойдёт речь о полноценном парсере. О парсерах форматов, смотри раздел «Форматы».
2021-09-21 02:18:13 +00:00
## Пробелы {#spaces}
Между синтаксическими конструкциями (в том числе, в начале и конце запроса) может быть расположено произвольное количество пробельных символов. К пробельным символам относятся пробел, таб, перевод строки, CR, form feed.
2021-09-21 02:18:13 +00:00
## Комментарии {#comments}
Поддерживаются комментарии в SQL-стиле и C-стиле.
2022-02-01 19:09:29 +00:00
Комментарии в SQL-стиле: от `--`, `#!` или `# ` до конца строки. Пробел после `--` и `#!` может не ставиться.
Комментарии в C-стиле: от `/*` до `*/`. Такие комментарии могут быть многострочными. Пробелы тоже не обязательны.
## Ключевые слова {#syntax-keywords}
Ключевые слова не зависят от регистра, если они соответствуют:
- Стандарту SQL. Например, применение любого из вариантов `SELECT`, `select` или `SeLeCt` не вызовет ошибки.
- Реализации в некоторых популярных DBMS (MySQL или Postgres). Например, `DateTime` и `datetime`.
Зависимость от регистра для имён типов данных можно проверить в таблице [system.data_type_families](../operations/system-tables/data_type_families.md#system_tables-data_type_families).
В отличие от стандарта SQL, все остальные ключевые слова, включая названия функций зависят от регистра.
Ключевые слова не зарезервированы (а всего лишь парсятся как ключевые слова в соответствующем контексте). Если вы используете [идентификаторы](#syntax-identifiers), совпадающие с ключевыми словами, заключите их в кавычки. Например, запрос `SELECT "FROM" FROM table_name` валиден, если таблица `table_name` имеет столбец с именем `"FROM"`.
## Идентификаторы {#syntax-identifiers}
Идентификаторы:
- Имена кластеров, баз данных, таблиц, разделов и столбцов;
- Функции;
- Типы данных;
- [Синонимы выражений](#syntax-expression_aliases).
Некоторые идентификаторы нужно указывать в кавычках (например, идентификаторы с пробелами). Прочие идентификаторы можно указывать без кавычек. Рекомендуется использовать идентификаторы, не требующие кавычек.
Идентификаторы не требующие кавычек соответствуют регулярному выражению `^[a-zA-Z_][0-9a-zA-Z_]*$` и не могут совпадать с [ключевыми словами](#syntax-keywords). Примеры: `x, _1, X_y__Z123_.`
Если вы хотите использовать идентификаторы, совпадающие с ключевыми словами, или использовать в идентификаторах символы, не входящие в регулярное выражение, заключите их в двойные или обратные кавычки, например, `"id"`, `` `id` ``.
DOCS-624: Fixing links to nowhere 2 (#10703) * enbaskakova-DOCSUP-652 (#101) * "docs(orNull&orDefault): Functions 'orNull&orDefault' have been edited" * "docs(orNull&orDefault): Functions 'orNull&orDefault' have been edited" * "docs(orNull&orDefault): Functions 'orNull&orDefault' have been edited" * Update docs/en/sql_reference/aggregate_functions/combinators.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/sql_reference/aggregate_functions/combinators.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/sql_reference/aggregate_functions/combinators.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/sql_reference/aggregate_functions/combinators.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/sql_reference/aggregate_functions/combinators.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * "docs(orNull&orDefault): Functions 'orNull&orDefault' have been edited" * "docs(orNull&orDefault): Functions 'orNull&orDefault' have been edited" * "docs(orNull&orDefault): Functions 'orNull&orDefault' have been edited" Co-authored-by: elenbaskakova <elenbaskakova@yandex-team.ru> Co-authored-by: BayoNet <da-daos@yandex.ru> * Revert "enbaskakova-DOCSUP-652 (#101)" (#107) This reverts commit 639fee7610f28e421d14e535b7def3f466e7efca. * CLICKHOUSEDOCS-624: Fixed en * CLICKHOUSEDOCS-624: Fixed RU. * CLICKHOUSEDOCS-624: Fixed ES and FR. * CLICKHOUSEDOCS-624: Fixed JA and TR * CLICKHOUSEDOCS-624: Fixed FA. * CLICKHOUSEDOCS-624: Fixed ZH. * Update docs/tools/test.py Co-authored-by: Ivan Blinkov <github@blinkov.ru> * Update docs/tools/test.py Co-authored-by: Ivan Blinkov <github@blinkov.ru> Co-authored-by: elenaspb2019 <47083263+elenaspb2019@users.noreply.github.com> Co-authored-by: elenbaskakova <elenbaskakova@yandex-team.ru> Co-authored-by: Sergei Shtykov <bayonet@yandex-team.ru> Co-authored-by: Ivan Blinkov <github@blinkov.ru>
2020-05-06 19:28:06 +00:00
## Литералы {#literals}
Существуют: числовые, строковые, составные литералы и `NULL`.
2021-09-21 02:18:13 +00:00
### Числовые {#numeric}
Числовой литерал пытается распарситься:
- Сначала как знаковое 64-разрядное число, функцией [strtoull](https://en.cppreference.com/w/cpp/string/byte/strtoul).
- Если не получилось, то как беззнаковое 64-разрядное число, функцией [strtoll](https://en.cppreference.com/w/cpp/string/byte/strtol).
- Если не получилось, то как число с плавающей запятой, функцией [strtod](https://en.cppreference.com/w/cpp/string/byte/strtof).
- Иначе — ошибка.
Соответствующее значение будет иметь тип минимального размера, который вмещает значение.
Например, 1 парсится как `UInt8`, а 256 как `UInt16`. Подробнее о типах данных читайте в разделе [Типы данных](../sql-reference/syntax.md).
Примеры: `1`, `18446744073709551615`, `0xDEADBEEF`, `01`, `0.1`, `1e100`, `-1e-100`, `inf`, `nan`.
2019-07-19 21:20:35 +00:00
### Строковые {#syntax-string-literal}
Поддерживаются только строковые литералы в одинарных кавычках. Символы внутри могут быть экранированы с помощью обратного слеша. Следующие escape-последовательности имеют соответствующее специальное значение: `\b`, `\f`, `\r`, `\n`, `\t`, `\0`, `\a`, `\v`, `\xHH`. Во всех остальных случаях, последовательности вида `\c`, где `c` — любой символ, преобразуется в `c` . Таким образом, могут быть использованы последовательности `\'` и `\\`. Значение будет иметь тип [String](../sql-reference/syntax.md).
Минимальный набор символов, которых вам необходимо экранировать в строковых литералах: `'` и `\`. Одинарная кавычка может быть экранирована одинарной кавычкой, литералы `'It\'s'` и `'It''s'` эквивалентны.
2021-09-21 02:18:13 +00:00
### Составные {#compound}
Поддерживаются конструкции для массивов: `[1, 2, 3]` и кортежей: `(1, 'Hello, world!', 2)`.
На самом деле, это вовсе не литералы, а выражение с оператором создания массива и оператором создания кортежа, соответственно.
Массив должен состоять хотя бы из одного элемента, а кортеж - хотя бы из двух.
Кортежи носят служебное значение для использования в секции `IN` запроса `SELECT`. Кортежи могут быть получены как результат запроса, но они не могут быть сохранены в базе данных (за исключением таблицы [Memory](../sql-reference/syntax.md).)
### NULL {#null-literal}
Обозначает, что значение отсутствует.
2021-06-03 12:15:46 +00:00
Чтобы в поле таблицы можно было хранить `NULL`, оно должно быть типа [Nullable](../sql-reference/data-types/nullable.md).
В зависимости от формата данных (входных или выходных) `NULL` может иметь различное представление. Подробнее смотрите в документации для [форматов данных](../interfaces/formats.md#formats).
При обработке `NULL` есть множество особенностей. Например, если хотя бы один из аргументов операции сравнения — `NULL`, то результатом такой операции тоже будет `NULL`. Этим же свойством обладают операции умножения, сложения и пр. Подробнее читайте в документации на каждую операцию.
В запросах можно проверить `NULL` с помощью операторов [IS NULL](operators/index.md#operator-is-null) и [IS NOT NULL](operators/index.md), а также соответствующих функций `isNull` и `isNotNull`.
2018-07-17 05:48:14 +00:00
2021-09-21 02:18:13 +00:00
### Heredoc {#heredeoc}
2022-02-01 19:09:29 +00:00
Синтаксис [heredoc](https://ru.wikipedia.org/wiki/Heredoc-синтаксис) — это способ определения строк с сохранением исходного формата (часто с переносом строки). `Heredoc` задается как произвольный строковый литерал между двумя символами `$`, например `$heredoc$`. Значение между двумя `heredoc` обрабатывается "как есть".
2021-09-21 02:18:13 +00:00
2022-02-01 19:09:29 +00:00
Синтаксис `heredoc` часто используют для вставки кусков кода SQL, HTML, XML и т.п.
2021-09-21 02:18:13 +00:00
**Пример**
Запрос:
```sql
SELECT $smth$SHOW CREATE VIEW my_view$smth$;
```
Результат:
```text
┌─'SHOW CREATE VIEW my_view'─┐
│ SHOW CREATE VIEW my_view │
└────────────────────────────┘
```
## Функции {#functions}
Функции записываются как идентификатор со списком аргументов (возможно, пустым) в скобках. В отличие от стандартного SQL, даже в случае пустого списка аргументов, скобки обязательны. Пример: `now()`.
Бывают обычные и агрегатные функции (смотрите раздел «Агрегатные функции»). Некоторые агрегатные функции могут содержать два списка аргументов в круглых скобках. Пример: `quantile(0.9)(x)`. Такие агрегатные функции называются «параметрическими», а первый список аргументов называется «параметрами». Синтаксис агрегатных функций без параметров ничем не отличается от обычных функций.
2021-09-21 02:18:13 +00:00
## Операторы {#operators}
Операторы преобразуются в соответствующие им функции во время парсинга запроса, с учётом их приоритета и ассоциативности.
Например, выражение `1 + 2 * 3 + 4` преобразуется в `plus(plus(1, multiply(2, 3)), 4)`.
2021-09-21 02:18:13 +00:00
## Типы данных и движки таблиц {#data_types-and-database-table-engines}
Типы данных и движки таблиц в запросе `CREATE` записываются также, как идентификаторы или также как функции. То есть, могут содержать или не содержать список аргументов в круглых скобках. Подробнее смотрите разделы «Типы данных», «Движки таблиц», «CREATE».
## Синонимы выражений {#syntax-expression_aliases}
Синоним — это пользовательское имя выражения в запросе.
``` sql
expr AS alias
```
- `AS` — ключевое слово для определения синонимов. Можно определить синоним для имени таблицы или столбца в секции `SELECT` без использования ключевого слова `AS` .
Например, `SELECT table_name_alias.column_name FROM table_name table_name_alias`.
2022-04-19 16:57:42 +00:00
В функции [CAST](../sql-reference/syntax.md#type_conversion_function-cast), ключевое слово `AS` имеет другое значение. Смотрите описание функции.
- `expr` — любое выражение, которое поддерживает ClickHouse.
Например, `SELECT column_name * 2 AS double FROM some_table`.
- `alias` — имя для `выражения`. Синонимы должны соответствовать синтаксису [идентификаторов](#syntax-identifiers).
Например, `SELECT "table t".column_name FROM table_name AS "table t"`.
2021-04-23 13:33:44 +00:00
### Примечания по использованию {#notes-on-usage}
Синонимы являются глобальными для запроса или подзапроса, и вы можете определить синоним в любой части запроса для любого выражения. Например, `SELECT (1 AS n) + 2, n`.
Синонимы не передаются в подзапросы и между подзапросами. Например, при выполнении запроса `SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a` ClickHouse сгенерирует исключение `Unknown identifier: num`.
Если синоним определен для результирующих столбцов в секции `SELECT` вложенного запроса, то эти столбцы отображаются во внешнем запросе. Например, `SELECT n + m FROM (SELECT 1 AS n, 2 AS m)`.
Будьте осторожны с синонимами, совпадающими с именами столбцов или таблиц. Рассмотрим следующий пример:
``` sql
CREATE TABLE t
(
a Int,
b Int
)
ENGINE = TinyLog()
```
``` sql
SELECT
argMax(a, b),
sum(b) AS b
FROM t
DOCAPI-8530: Code blocks markup fix (#7060) * Typo fix. * Links fix. * Fixed links in docs. * More fixes. * docs/en: cleaning some files * docs/en: cleaning data_types * docs/en: cleaning database_engines * docs/en: cleaning development * docs/en: cleaning getting_started * docs/en: cleaning interfaces * docs/en: cleaning operations * docs/en: cleaning query_lamguage * docs/en: cleaning en * docs/ru: cleaning data_types * docs/ru: cleaning index * docs/ru: cleaning database_engines * docs/ru: cleaning development * docs/ru: cleaning general * docs/ru: cleaning getting_started * docs/ru: cleaning interfaces * docs/ru: cleaning operations * docs/ru: cleaning query_language * docs: cleaning interfaces/http * Update docs/en/data_types/array.md decorated ``` Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/getting_started/example_datasets/nyc_taxi.md fixed typo Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/getting_started/example_datasets/ontime.md fixed typo Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/interfaces/formats.md fixed error Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/table_engines/custom_partitioning_key.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/utils/clickhouse-local.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/dicts/external_dicts_dict_sources.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/utils/clickhouse-local.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/json_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/json_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/other_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/other_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/query_language/functions/date_time_functions.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * Update docs/en/operations/table_engines/jdbc.md Co-Authored-By: BayoNet <da-daos@yandex.ru> * docs: fixed error * docs: fixed error
2019-09-23 15:31:46 +00:00
```
``` text
Received exception from server (version 18.14.17):
Code: 184. DB::Exception: Received from localhost:9000, 127.0.0.1. DB::Exception: Aggregate function sum(b) is found inside another aggregate function in query.
```
В этом примере мы объявили таблицу `t` со столбцом `b`. Затем, при выборе данных, мы определили синоним `sum(b) AS b`. Поскольку синонимы глобальные, то ClickHouse заменил литерал `b` в выражении `argMax(a, b)` выражением `sum(b)`. Эта замена вызвала исключение. Можно изменить это поведение, включив настройку [prefer_column_name_to_alias](../operations/settings/settings.md#prefer_column_name_to_alias), для этого нужно установить ее в значение `1`.
2021-04-23 13:33:44 +00:00
## Звёздочка {#asterisk}
В запросе `SELECT`, вместо выражения может стоять звёздочка. Подробнее смотрите раздел «SELECT».
## Выражения {#syntax-expressions}
Выражение представляет собой функцию, идентификатор, литерал, применение оператора, выражение в скобках, подзапрос, звёздочку. А также может содержать синоним.
Список выражений - одно выражение или несколько выражений через запятую.
Функции и операторы, в свою очередь, в качестве аргументов, могут иметь произвольные выражения.