Merge branch 'master' into recompression_in_background

This commit is contained in:
alesapin 2020-09-01 10:31:10 +03:00
commit b751319f9e
63 changed files with 859 additions and 255 deletions

View File

@ -116,7 +116,7 @@ void Connection::connect(const char* db,
throw ConnectionFailed(errorMessage(driver.get()), mysql_errno(driver.get()));
/// Enables auto-reconnect.
my_bool reconnect = true;
bool reconnect = true;
if (mysql_options(driver.get(), MYSQL_OPT_RECONNECT, reinterpret_cast<const char *>(&reconnect)))
throw ConnectionFailed(errorMessage(driver.get()), mysql_errno(driver.get()));

View File

@ -1,9 +1,9 @@
# This strings autochanged from release_lib.sh:
SET(VERSION_REVISION 54438)
SET(VERSION_REVISION 54439)
SET(VERSION_MAJOR 20)
SET(VERSION_MINOR 8)
SET(VERSION_MINOR 9)
SET(VERSION_PATCH 1)
SET(VERSION_GITHASH 5d60ab33a511efd149c7c3de77c0dd4b81e65b13)
SET(VERSION_DESCRIBE v20.8.1.1-prestable)
SET(VERSION_STRING 20.8.1.1)
SET(VERSION_GITHASH 0586f0d555f7481b394afc55bbb29738cd573a1c)
SET(VERSION_DESCRIBE v20.9.1.1-prestable)
SET(VERSION_STRING 20.9.1.1)
# end of autochange

View File

@ -2,8 +2,8 @@ option (USE_INTERNAL_BOOST_LIBRARY "Use internal Boost library" ${NOT_UNBUNDLED}
if (NOT USE_INTERNAL_BOOST_LIBRARY)
# 1.70 like in contrib/boost
# 1.67 on CI
set(BOOST_VERSION 1.67)
# 1.71 on CI
set(BOOST_VERSION 1.71)
find_package(Boost ${BOOST_VERSION} COMPONENTS
system

4
debian/changelog vendored
View File

@ -1,5 +1,5 @@
clickhouse (20.8.1.1) unstable; urgency=low
clickhouse (20.9.1.1) unstable; urgency=low
* Modified source code
-- clickhouse-release <clickhouse-release@yandex-team.ru> Fri, 07 Aug 2020 21:45:46 +0300
-- clickhouse-release <clickhouse-release@yandex-team.ru> Mon, 31 Aug 2020 23:07:38 +0300

View File

@ -1,7 +1,7 @@
FROM ubuntu:18.04
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
ARG version=20.8.1.*
ARG version=20.9.1.*
RUN apt-get update \
&& apt-get install --yes --no-install-recommends \

View File

@ -143,7 +143,7 @@ def parse_env_variables(build_type, compiler, sanitizer, package_type, image_typ
if unbundled:
# TODO: fix build with ENABLE_RDKAFKA
cmake_flags.append('-DUNBUNDLED=1 -DUSE_INTERNAL_RDKAFKA_LIBRARY=1') # too old version in ubuntu 19.10
cmake_flags.append('-DUNBUNDLED=1 -DUSE_INTERNAL_RDKAFKA_LIBRARY=1 -DENABLE_ARROW=0 -DENABLE_ORC=0 -DENABLE_PARQUET=0')
if split_binary:
cmake_flags.append('-DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1 -DCLICKHOUSE_SPLIT_BINARY=1')

View File

@ -1,7 +1,7 @@
FROM ubuntu:20.04
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
ARG version=20.8.1.*
ARG version=20.9.1.*
ARG gosu_ver=1.10
RUN apt-get update \

View File

@ -1,7 +1,7 @@
FROM ubuntu:18.04
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
ARG version=20.8.1.*
ARG version=20.9.1.*
RUN apt-get update && \
apt-get install -y apt-transport-https dirmngr && \

View File

@ -211,6 +211,9 @@ TESTS_TO_SKIP=(
# to make some progress.
00646_url_engine
00974_query_profiler
# Look at DistributedFilesToInsert, so cannot run in parallel.
01460_DistributedFilesToInsert
)
clickhouse-test -j 4 --no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/test_log.txt

View File

@ -72,6 +72,7 @@ toc_title: Adopters
| <a href="https://www.qingcloud.com/" class="favicon">QINGCLOUD</a> | Cloud services | Main product | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/4.%20Cloud%20%2B%20TSDB%20for%20ClickHouse%20张健%20QingCloud.pdf) |
| <a href="https://qrator.net" class="favicon">Qrator</a> | DDoS protection | Main product | — | — | [Blog Post, March 2019](https://blog.qrator.net/en/clickhouse-ddos-mitigation_37/) |
| <a href="https://rambler.ru" class="favicon">Rambler</a> | Internet services | Analytics | — | — | [Talk in Russian, April 2018](https://medium.com/@ramblertop/разработка-api-clickhouse-для-рамблер-топ-100-f4c7e56f3141) |
| <a href="https://retell.cc/" class="favicon">Retell</a> | Speech synthesis | Analytics | — | — | [Blog Article, August 2020](https://vc.ru/services/153732-kak-sozdat-audiostati-na-vashem-sayte-i-zachem-eto-nuzhno) |
| <a href="https://rspamd.com/" class="favicon">Rspamd</a> | Antispam | Analytics | — | — | [Official Website](https://rspamd.com/doc/modules/clickhouse.html) |
| <a href="https://www.s7.ru" class="favicon">S7 Airlines</a> | Airlines | Metrics, Logging | — | — | [Talk in Russian, March 2019](https://www.youtube.com/watch?v=nwG68klRpPg&t=15s) |
| <a href="https://www.scireum.de/" class="favicon">scireum GmbH</a> | e-Commerce | Main product | — | — | [Talk in German, February 2020](https://www.youtube.com/watch?v=7QWAn5RbyR4) |

View File

@ -0,0 +1,24 @@
# system.grants {#system_tables-grants}
Privileges granted to ClickHouse user accounts.
Columns:
- `user_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — User name.
- `role_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Role assigned to user account.
- `access_type` ([Enum8](../../sql-reference/data-types/enum.md)) — Access parameters for ClickHouse user account.
- `database` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Name of a database.
- `table` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Name of a table.
- `column` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Name of a column to which access is granted.
- `is_partial_revoke` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Logical value. It shows whether some privileges have been revoked. Possible values:
- `0` — The row describes a partial revoke.
- `1` — The row describes a grant.
- `grant_option` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Permission is granted `WITH GRANT OPTION`, see [GRANT](../../sql-reference/statements/grant.md#grant-privigele-syntax).
[Original article](https://clickhouse.tech/docs/en/operations/system_tables/grants) <!--hide-->

View File

@ -0,0 +1,30 @@
# system.row_policies {#system_tables-row_policies}
Contains filters for one particular table, as well as a list of roles and/or users which should use this row policy.
Columns:
- `name` ([String](../../sql-reference/data-types/string.md)) — Name of a row policy.
- `short_name` ([String](../../sql-reference/data-types/string.md)) — Short name of a row policy. Names of row policies are compound, for example: myfilter ON mydb.mytable. Here "myfilter ON mydb.mytable" is the name of the row policy, "myfilter" is it's short name.
- `database` ([String](../../sql-reference/data-types/string.md)) — Database name.
- `table` ([String](../../sql-reference/data-types/string.md)) — Table name.
- `id` ([UUID](../../sql-reference/data-types/uuid.md)) — Row policy ID.
- `storage` ([String](../../sql-reference/data-types/string.md)) — Name of the directory where the row policy is stored.
- `select_filter` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Condition which is used to filter rows.
- `is_restrictive` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Shows whether the row policy restricts access to rows, see [CREATE ROW POLICY](../../sql-reference/statements/create/row-policy.md#create-row-policy-as). Value:
- `0` — The row policy is defined with `AS PERMISSIVE` clause.
- `1` — The row policy is defined with `AS RESTRICTIVE` clause.
- `apply_to_all` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Shows that the row policies set for all roles and/or users.
- `apply_to_list` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — List of the roles and/or users to which the row policies is applied.
- `apply_to_except` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — The row policies is applied to all roles and/or users excepting of the listed ones.
[Original article](https://clickhouse.tech/docs/en/operations/system_tables/row_policies) <!--hide-->

View File

@ -0,0 +1,30 @@
# system.settings_profile_elements {#system_tables-settings_profile_elements}
Describes the content of the settings profile:
- Сonstraints.
- Roles and users that the setting applies to.
- Parent settings profiles.
Columns:
- `profile_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Setting profile name.
- `user_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — User name.
- `role_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Role name.
- `index` ([UInt64](../../sql-reference/data-types/int-uint.md)) — Sequential number of the settings profile element.
- `setting_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Setting name.
- `value` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Setting value.
- `min` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — The minimum value of the setting. `NULL` if not set.
- `max` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — The maximum value of the setting. NULL if not set.
- `readonly` ([Nullable](../../sql-reference/data-types/nullable.md)([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges))) — Profile that allows only read queries.
- `inherit_profile` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — A parent profile for this setting profile. `NULL` if not set. Setting profile will inherit all the settings' values and constraints (`min`, `max`, `readonly`) from its parent profiles.
[Original article](https://clickhouse.tech/docs/en/operations/system_tables/settings_profile_elements) <!--hide-->

View File

@ -0,0 +1,20 @@
# system.settings_profiles {#system_tables-settings_profiles}
Contains properties of configured setting profiles.
Columns:
- `name` ([String](../../sql-reference/data-types/string.md)) — Setting profile name.
- `id` ([UUID](../../sql-reference/data-types/uuid.md)) — Setting profile ID.
- `storage` ([String](../../sql-reference/data-types/string.md)) — Path to the storage of setting profiles. Configured in the `access_control_path` parameter.
- `num_elements` ([UInt64](../../sql-reference/data-types/int-uint.md)) — Number of elements for this profile in the `system.settings_profile_elements` table.
- `apply_to_all` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Shows that the settings profile set for all roles and/or users.
- `apply_to_list` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — List of the roles and/or users to which the setting profile is applied.
- `apply_to_except` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — The setting profile is applied to all roles and/or users excepting of the listed ones.
[Original article](https://clickhouse.tech/docs/en/operations/system_tables/settings_profiles) <!--hide-->

View File

@ -0,0 +1,30 @@
# system.users {#system_tables-users}
Contains a list of [user accounts](../../operations/access-rights.md#user-account-management) configured at the server.
Columns:
- `name` ([String](../../sql-reference/data-types/string.md)) — User name.
- `id` ([UUID](../../sql-reference/data-types/uuid.md)) — User ID.
- `storage` ([String](../../sql-reference/data-types/string.md)) — Path to the storage of users. Configured in the `access_control_path` parameter.
- `auth_type` ([Enum8](../../sql-reference/data-types/enum.md)('no_password' = 0,'plaintext_password' = 1, 'sha256_password' = 2, 'double_sha1_password' = 3)) — Shows the authentication type. There are multiple ways of user identification: with no password, with plain text password, with [SHA256](https://ru.wikipedia.org/wiki/SHA-2)-encoded password or with [double SHA-1](https://ru.wikipedia.org/wiki/SHA-1)-encoded password.
- `auth_params` ([String](../../sql-reference/data-types/string.md)) — Authentication parameters in the JSON format depending on the `auth_type`.
- `host_ip` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — IP addresses of hosts that are allowed to connect to the ClickHouse server.
- `host_names` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Names of hosts that are allowed to connect to the ClickHouse server.
- `host_names_regexp` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Regular expression for host names that are allowed to connect to the ClickHouse server.
- `host_names_like` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Names of hosts that are allowed to connect to the ClickHouse server, set using the LIKE predicate.
- `default_roles_all` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Shows that all granted roles set for user by default.
- `default_roles_list` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — List of granted roles provided by default.
- `default_roles_except` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — All the granted roles set as default excepting of the listed ones.
[Original article](https://clickhouse.tech/docs/en/operations/system_tables/users) <!--hide-->

View File

@ -136,7 +136,7 @@ ENGINE = <Engine>
...
```
If a codec is specified, the default codec doesnt apply. Codecs can be combined in a pipeline, for example, `CODEC(Delta, ZSTD)`. To select the best codec combination for you project, pass benchmarks similar to described in the Altinity [New Encodings to Improve ClickHouse Efficiency](https://www.altinity.com/blog/2019/7/new-encodings-to-improve-clickhouse) article.
If a codec is specified, the default codec doesnt apply. Codecs can be combined in a pipeline, for example, `CODEC(Delta, ZSTD)`. To select the best codec combination for you project, pass benchmarks similar to described in the Altinity [New Encodings to Improve ClickHouse Efficiency](https://www.altinity.com/blog/2019/7/new-encodings-to-improve-clickhouse) article. One thing to note is that codec can't be applied for ALIAS column type.
!!! warning "Warning"
You cant decompress ClickHouse database files with external utilities like `lz4`. Instead, use the special [clickhouse-compressor](https://github.com/ClickHouse/ClickHouse/tree/master/programs/compressor) utility.

View File

@ -89,6 +89,10 @@
[clickhouse-flamegraph](https://github.com/Slach/clickhouse-flamegraph) — специализированный инструмент для визуализации `system.trace_log` в виде [flamegraph](http://www.brendangregg.com/flamegraphs.html).
### clickhouse-plantuml {#clickhouse-plantuml}
[cickhouse-plantuml](https://pypi.org/project/clickhouse-plantuml/) — скрипт, генерирующий [PlantUML](https://plantuml.com/) диаграммы схем таблиц.
## Коммерческие {#kommercheskie}
### DataGrip {#datagrip}

View File

@ -16,9 +16,12 @@
Подстановки могут также выполняться из ZooKeeper. Для этого укажите у элемента атрибут `from_zk = "/path/to/node"`. Значение элемента заменится на содержимое узла `/path/to/node` в ZooKeeper. В ZooKeeper-узел также можно положить целое XML-поддерево, оно будет целиком вставлено в исходный элемент.
В `config.xml` может быть указан отдельный конфиг с настройками пользователей, профилей и квот. Относительный путь к нему указывается в элементе users\_config. По умолчанию - `users.xml`. Если `users_config` не указан, то настройки пользователей, профилей и квот, указываются непосредственно в `config.xml`.
В элементе `users_config` файла `config.xml` можно указать относительный путь к конфигурационному файлу с настройками пользователей, профилей и квот. Значение `users_config` по умолчанию — `users.xml`. Если `users_config` не указан, то настройки пользователей, профилей и квот можно задать непосредственно в `config.xml`.
Для `users_config` могут также существовать переопределения в файлах из директории `users_config.d` (например, `users.d`) и подстановки. Например, можно иметь по отдельному конфигурационному файлу для каждого пользователя:
Настройки пользователя могут быть разделены в несколько отдельных файлов аналогичных `config.xml` и `config.d\`. Имя директории задаётся также как `users_config`.
Имя директории задаётся так же, как имя файла в `users_config`, с подстановкой `.d` вместо `.xml`.
Директория `users.d` используется по умолчанию, также как `users.xml` используется для `users_config`.
Например, можно иметь по отдельному конфигурационному файлу для каждого пользователя:
``` bash
$ cat /etc/clickhouse-server/users.d/alice.xml

View File

@ -520,31 +520,6 @@ ClickHouse использует этот параметр при чтении д
Значение по умолчанию: 0.
## network_compression_method {#network_compression_method}
Задает метод сжатия данных, используемый при обмене данными между серверами и при обмене между сервером и [clickhouse-client](../../interfaces/cli.md).
Возможные значения:
- `LZ4` — устанавливает метод сжатия LZ4.
- `ZSTD` — устанавливает метод сжатия ZSTD.
Значение по умолчанию: `LZ4`.
См. также:
- [network_zstd_compression_level](#network_zstd_compression_level)
## network_zstd_compression_level {#network_zstd_compression_level}
Регулирует уровень сжатия ZSTD. Используется только тогда, когда [network_compression_method](#network_compression_method) имеет значение `ZSTD`.
Возможные значения:
- Положительное целое число от 1 до 15.
Значение по умолчанию: `1`.
## log\_queries {#settings-log-queries}
Установка логирования запроса.
@ -557,6 +532,60 @@ ClickHouse использует этот параметр при чтении д
log_queries=1
```
## log\_queries\_min\_type {#settings-log-queries-min-type}
`query_log` минимальный уровень логирования.
Возможные значения:
- `QUERY_START` (`=1`)
- `QUERY_FINISH` (`=2`)
- `EXCEPTION_BEFORE_START` (`=3`)
- `EXCEPTION_WHILE_PROCESSING` (`=4`)
Значение по умолчанию: `QUERY_START`.
Можно использовать для ограничения того, какие объекты будут записаны в `query_log`, например, если вас интересуют ошибки, тогда вы можете использовать `EXCEPTION_WHILE_PROCESSING`:
``` text
log_queries_min_type='EXCEPTION_WHILE_PROCESSING'
```
## log\_queries\_min\_type {#settings-log-queries-min-type}
`query_log` минимальный уровень логирования.
Возможные значения:
- `QUERY_START` (`=1`)
- `QUERY_FINISH` (`=2`)
- `EXCEPTION_BEFORE_START` (`=3`)
- `EXCEPTION_WHILE_PROCESSING` (`=4`)
Значение по умолчанию: `QUERY_START`.
Можно использовать для ограничения того, какие объекты будут записаны в `query_log`, например, если вас интересуют ошибки, тогда вы можете использовать `EXCEPTION_WHILE_PROCESSING`:
``` text
log_queries_min_type='EXCEPTION_WHILE_PROCESSING'
```
## log\_queries\_min\_type {#settings-log-queries-min-type}
Задаёт минимальный уровень логирования в `query_log`.
Возможные значения:
- `QUERY_START` (`=1`)
- `QUERY_FINISH` (`=2`)
- `EXCEPTION_BEFORE_START` (`=3`)
- `EXCEPTION_WHILE_PROCESSING` (`=4`)
Значение по умолчанию: `QUERY_START`.
Можно использовать для ограничения того, какие объекты будут записаны в `query_log`, например, если вас интересуют ошибки, тогда вы можете использовать `EXCEPTION_WHILE_PROCESSING`:
``` text
log_queries_min_type='EXCEPTION_WHILE_PROCESSING'
```
## log\_query\_threads {#settings-log-query-threads}
Установка логирования информации о потоках выполнения запроса.
@ -571,7 +600,7 @@ log_query_threads=1
## max\_insert\_block\_size {#settings-max_insert_block_size}
Формировать блоки указанного размера (в количестве строк), при вставке в таблицу.
Формировать блоки указанного размера, при вставке в таблицу.
Эта настройка действует только в тех случаях, когда сервер сам формирует такие блоки.
Например, при INSERT-е через HTTP интерфейс, сервер парсит формат данных, и формирует блоки указанного размера.
А при использовании clickhouse-client, клиент сам парсит данные, и настройка max\_insert\_block\_size на сервере не влияет на размер вставляемых блоков.
@ -946,7 +975,6 @@ SELECT area/period FROM account_orders FORMAT JSON;
"type": "Float64"
}
],
"data":
[
{
@ -959,9 +987,7 @@ SELECT area/period FROM account_orders FORMAT JSON;
"divide(area, period)": null
}
],
"rows": 3,
"statistics":
{
"elapsed": 0.003648093,
@ -982,7 +1008,6 @@ SELECT area/period FROM account_orders FORMAT JSON;
"type": "Float64"
}
],
"data":
[
{
@ -995,9 +1020,7 @@ SELECT area/period FROM account_orders FORMAT JSON;
"divide(area, period)": "-inf"
}
],
"rows": 3,
"statistics":
{
"elapsed": 0.000070241,
@ -1007,6 +1030,7 @@ SELECT area/period FROM account_orders FORMAT JSON;
}
```
## format\_csv\_delimiter {#settings-format_csv_delimiter}
Символ, интерпретируемый как разделитель в данных формата CSV. По умолчанию — `,`.
@ -1220,7 +1244,7 @@ ClickHouse генерирует исключение
Значение по умолчанию: 0
## force\_optimize\_skip\_unused\_shards {#force-optimize-skip-unused-shards}
## force\_optimize\_skip\_unused\_shards {#settings-force_optimize_skip_unused_shards}
Разрешает или запрещает выполнение запроса, если настройка [optimize_skip_unused_shards](#optimize-skip-unused-shards) включена, а пропуск неиспользуемых шардов невозможен. Если данная настройка включена и пропуск невозможен, ClickHouse генерирует исключение.
@ -1234,19 +1258,30 @@ ClickHouse генерирует исключение
## force\_optimize\_skip\_unused\_shards\_nesting {#settings-force_optimize_skip_unused_shards_nesting}
Контролирует настройку [`force_optimize_skip_unused_shards`](#force-optimize-skip-unused-shards) (поэтому все еще требует `optimize_skip_unused_shards`) в зависимости от вложенности распределенного запроса (когда у вас есть `Distributed` таблица которая смотрит на другую `Distributed` таблицу).
Контролирует настройку [`force_optimize_skip_unused_shards`](#settings-force_optimize_skip_unused_shards) (поэтому все еще требует `optimize_skip_unused_shards`) в зависимости от вложенности распределенного запроса (когда у вас есть `Distributed` таблица которая смотрит на другую `Distributed` таблицу).
Возможные значения:
- 0 - Disabled, `force_optimize_skip_unused_shards` works on all levels.
- 1 — Enables `force_optimize_skip_unused_shards` only for the first level.
- 2 — Enables `force_optimize_skip_unused_shards` up to the second level.
- 0 - Выключена, `force_optimize_skip_unused_shards` работает всегда.
- 1 — Включает `force_optimize_skip_unused_shards` только для 1-ого уровня вложенности.
- 2 — Включает `force_optimize_skip_unused_shards` для 1-ого и 2-ого уровня вложенности.
Значение по умолчанию: 0
## force\_optimize\_skip\_unused\_shards\_no\_nested {#settings-force_optimize_skip_unused_shards_no_nested}
Сбрасывает [`optimize_skip_unused_shards`](#settings-force_optimize_skip_unused_shards) для вложенных `Distributed` таблиц.
Возможные значения:
- 1 — Включена.
- 0 — Выключена.
Значение по умолчанию: 0
## optimize\_throw\_if\_noop {#setting-optimize_throw_if_noop}
Включает или отключает генерирование исключения в в случаях, когда запрос [OPTIMIZE](../../sql-reference/statements/misc.md#misc_operations-optimize) не выполняет мёрж.
Включает или отключает генерирование исключения в случаях, когда запрос [OPTIMIZE](../../sql-reference/statements/misc.md#misc_operations-optimize) не выполняет мёрж.
По умолчанию, `OPTIMIZE` завершается успешно и в тех случаях, когда он ничего не сделал. Настройка позволяет отделить подобные случаи и включает генерирование исключения с поясняющим сообщением.
@ -1367,7 +1402,7 @@ Default value: 0.
- [Sampling Query Profiler](../optimizing-performance/sampling-query-profiler.md)
- System table [trace\_log](../../operations/system-tables/trace_log.md#system_tables-trace_log)
## background_pool_size {#background_pool_size}
## background\_pool\_size {#background_pool_size}
Задает количество потоков для выполнения фоновых операций в движках таблиц (например, слияния в таблицах c движком [MergeTree](../../engines/table-engines/mergetree-family/index.md)). Настройка применяется при запуске сервера ClickHouse и не может быть изменена во пользовательском сеансе. Настройка позволяет управлять загрузкой процессора и диска. Чем меньше пулл, тем ниже нагрузка на CPU и диск, при этом фоновые процессы замедляются, что может повлиять на скорость выполнения запроса.
@ -1381,7 +1416,7 @@ Default value: 0.
Включает параллельную обработку распределённых запросов `INSERT ... SELECT`.
Если при выполнении запроса `INSERT INTO distributed_table_a SELECT ... FROM distributed_table_b` оказывается, что обе таблицы находятся в одном кластере, то независимо от того [реплицируемые](../../engines/table-engines/mergetree-family/replication.md) они или нет, запрос выполняется локально на каждом шарде.
Если при выполнении запроса `INSERT INTO distributed_table_a SELECT ... FROM distributed_table_b` оказывается, что обе таблицы находятся в одном кластере, то независимо от того [реплицируемые](../../engines/table-engines/mergetree-family/replication.md) они или нет, запрос выполняется локально на каждом шарде.
Допустимые значения:
@ -1431,7 +1466,7 @@ Default value: 0.
Значение по умолчанию: 0.
**См. также:**
**См. также:**
- [Репликация данных](../../engines/table-engines/mergetree-family/replication.md)
@ -1448,7 +1483,7 @@ Possible values:
Значение по умолчанию: 0.
**Пример**
**Пример**
Рассмотрим таблицу `null_in`:
@ -1499,7 +1534,7 @@ SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 1;
└──────┴───────┘
```
**См. также**
**См. также**
- [Обработка значения NULL в операторе IN](../../sql-reference/operators/in.md#in-null-processing)
@ -1610,8 +1645,8 @@ SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 1;
Возможные значения:
- 0 - мутации выполняются асинхронно.
- 1 - запрос ждет завершения всех мутаций на текущем сервере.
- 0 - мутации выполняются асинхронно.
- 1 - запрос ждет завершения всех мутаций на текущем сервере.
- 2 - запрос ждет завершения всех мутаций на всех репликах (если они есть).
Значение по умолчанию: `0`.

View File

@ -0,0 +1,24 @@
# system.grants {#system_tables-grants}
Привилегии пользовательских аккаунтов ClickHouse.
Столбцы:
- `user_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Название учётной записи.
- `role_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Роль, назначенная учетной записи пользователя.
- `access_type` ([Enum8](../../sql-reference/data-types/enum.md)) — Параметры доступа для учетной записи пользователя ClickHouse.
- `database` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Имя базы данных.
- `table` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Имя таблицы.
- `column` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Имя столбца, к которому предоставляется доступ.
- `is_partial_revoke` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Логическое значение. Показывает, были ли отменены некоторые привилегии. Возможные значения:
- `0` — Строка описывает частичный отзыв.
- `1` — Строка описывает грант.
- `grant_option` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Разрешение предоставлено с опцией `WITH GRANT OPTION`, подробнее см. [GRANT](../../sql-reference/statements/grant.md#grant-privigele-syntax).
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system_tables/grants) <!--hide-->

View File

@ -0,0 +1,30 @@
# system.row_policies {#system_tables-row_policies}
Содержит фильтры безопасности уровня строк (политики строк) для каждой таблицы, а также список ролей и/или пользователей, к которым применяются эти политики.
Столбцы:
- `name` ([String](../../sql-reference/data-types/string.md)) — Имя политики строк.
- `short_name` ([String](../../sql-reference/data-types/string.md)) — Короткое имя политики строк. Имена политик строк являются составными, например: `myfilter ON mydb.mytable`. Здесь `myfilter ON mydb.mytable` — это имя политики строк, `myfilter` — короткое имя.
- `database` ([String](../../sql-reference/data-types/string.md)) — Имя базы данных.
- `table` ([String](../../sql-reference/data-types/string.md)) — Имя таблицы.
- `id` ([UUID](../../sql-reference/data-types/uuid.md)) — ID политики строк.
- `storage` ([String](../../sql-reference/data-types/string.md)) — Имя каталога, в котором хранится политика строк.
- `select_filter` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Условие, которое используется для фильтрации строк.
- `is_restrictive` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Показывает, ограничивает ли политика строк доступ к строкам, подробнее см. [CREATE ROW POLICY](../../sql-reference/statements/create/row-policy.md#create-row-policy-as). Значения:
- `0` — Политика строк определяется с помощью условия 'AS PERMISSIVE'.
- `1` — Политика строк определяется с помощью условия 'AS RESTRICTIVE'.
- `apply_to_all` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Показывает, что политики строк заданы для всех ролей и/или пользователей.
- `apply_to_list` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Список ролей и/или пользователей, к которым применяется политика строк.
- `apply_to_except` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Политики строк применяются ко всем ролям и/или пользователям, за исключением перечисленных.
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system_tables/row_policies) <!--hide-->

View File

@ -0,0 +1,30 @@
# system.settings_profile_elements {#system_tables-settings_profile_elements}
Описывает содержимое профиля настроек:
- Ограничения.
- Роли и пользователи, к которым применяется настройка.
- Родительские профили настроек.
Столбцы:
- `profile_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Имя профиля настроек.
- `user_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Имя пользователя.
- `role_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Имя роли.
- `index` ([UInt64](../../sql-reference/data-types/int-uint.md)) — Порядковый номер элемента профиля настроек.
- `setting_name` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Имя настройки.
- `value` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Значение настройки.
- `min` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Минимальное значение настройки. `NULL` если не задано.
- `max` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Максимальное значение настройки. `NULL` если не задано.
- `readonly` ([Nullable](../../sql-reference/data-types/nullable.md)([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges))) — Профиль разрешает только запросы на чтение.
- `inherit_profile` ([Nullable](../../sql-reference/data-types/nullable.md)([String](../../sql-reference/data-types/string.md))) — Родительский профиль для данного профиля настроек. `NULL` если не задано. Профиль настроек может наследовать все значения и ограничения настроек (`min`, `max`, `readonly`) от своего родительского профиля.
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system_tables/settings_profile_elements) <!--hide-->

View File

@ -0,0 +1,20 @@
# system.settings_profiles {#system_tables-settings_profiles}
Содержит свойства сконфигурированных профилей настроек.
Столбцы:
- `name` ([String](../../sql-reference/data-types/string.md)) — Имя профиля настроек.
- `id` ([UUID](../../sql-reference/data-types/uuid.md)) — ID профиля настроек.
- `storage` ([String](../../sql-reference/data-types/string.md)) — Путь к хранилищу профилей настроек. Настраивается в параметре `access_control_path`.
- `num_elements` ([UInt64](../../sql-reference/data-types/int-uint.md)) — Число элементов для этого профиля в таблице `system.settings_profile_elements`.
- `apply_to_all` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Признак, который показывает, что параметры профиля заданы для всех ролей и/или пользователей.
- `apply_to_list` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Список ролей и/или пользователей, к которым применяется профиль настроек.
- `apply_to_except` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Профиль настроек применяется ко всем ролям и/или пользователям, за исключением перечисленных.
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system_tables/settings_profiles) <!--hide-->

View File

@ -0,0 +1,30 @@
# system.users {#system_tables-users}
Содержит список [аккаунтов пользователей](../../operations/access-rights.md#user-account-management), настроенных на сервере.
Столбцы:
- `name` ([String](../../sql-reference/data-types/string.md)) — Имя пользователя.
- `id` ([UUID](../../sql-reference/data-types/uuid.md)) — ID пользователя.
- `storage` ([String](../../sql-reference/data-types/string.md)) — Путь к хранилищу пользователей. Настраивается в параметре `access_control_path`.
- `auth_type` ([Enum8](../../sql-reference/data-types/enum.md)('no_password' = 0,'plaintext_password' = 1, 'sha256_password' = 2, 'double_sha1_password' = 3)) — Показывает тип аутентификации. Существует несколько способов идентификации пользователя: без пароля, с помощью обычного текстового пароля, с помощью шифрования [SHA256] (https://ru.wikipedia.org/wiki/SHA-2) или с помощью шифрования [double SHA-1] (https://ru.wikipedia.org/wiki/SHA-1).
- `auth_params` ([String](../../sql-reference/data-types/string.md)) — Параметры аутентификации в формате JSON, зависят от `auth_type`.
- `host_ip` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — IP-адреса хостов, которым разрешено подключаться к серверу ClickHouse.
- `host_names` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Имена хостов, которым разрешено подключаться к серверу ClickHouse.
- `host_names_regexp` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Регулярное выражение для имен хостов, которым разрешено подключаться к серверу ClickHouse.
- `host_names_like` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Имена хостов, которым разрешено подключаться к серверу ClickHouse, заданные с помощью предиката LIKE.
- `default_roles_all` ([UInt8](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Показывает, что все предоставленные роли установлены для пользователя по умолчанию.
- `default_roles_list` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Список предоставленных ролей по умолчанию.
- `default_roles_except` ([Array](../../sql-reference/data-types/array.md)([String](../../sql-reference/data-types/string.md))) — Все предоставленные роли задаются по умолчанию, за исключением перечисленных.
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system_tables/users) <!--hide-->

View File

@ -2,15 +2,14 @@
toc_priority: 141
---
# sumMap {#agg_functions-summap}
Синтаксис: `sumMap(key, value)` или `sumMap(Tuple(key, value))`
## sumMap(key, value), sumMap(Tuple(key, value)) {#agg_functions-summap}
Производит суммирование массива value по соответствующим ключам заданным в массиве key.
Передача кортежа ключей и значений массива синонимично передаче двух массивов ключей и значений.
Количество элементов в key и value должно быть одинаковым для каждой строки, для которой происходит суммирование.
Возвращает кортеж из двух массивов - ключи в отсортированном порядке и значения, просуммированные по соответствующим ключам.
Пример:
**Пример:**
``` sql
CREATE TABLE sum_map(
@ -19,25 +18,28 @@ CREATE TABLE sum_map(
statusMap Nested(
status UInt16,
requests UInt64
)
),
statusMapTuple Tuple(Array(Int32), Array(Int32))
) ENGINE = Log;
INSERT INTO sum_map VALUES
('2000-01-01', '2000-01-01 00:00:00', [1, 2, 3], [10, 10, 10]),
('2000-01-01', '2000-01-01 00:00:00', [3, 4, 5], [10, 10, 10]),
('2000-01-01', '2000-01-01 00:01:00', [4, 5, 6], [10, 10, 10]),
('2000-01-01', '2000-01-01 00:01:00', [6, 7, 8], [10, 10, 10]);
('2000-01-01', '2000-01-01 00:00:00', [1, 2, 3], [10, 10, 10], ([1, 2, 3], [10, 10, 10])),
('2000-01-01', '2000-01-01 00:00:00', [3, 4, 5], [10, 10, 10], ([3, 4, 5], [10, 10, 10])),
('2000-01-01', '2000-01-01 00:01:00', [4, 5, 6], [10, 10, 10], ([4, 5, 6], [10, 10, 10])),
('2000-01-01', '2000-01-01 00:01:00', [6, 7, 8], [10, 10, 10], ([6, 7, 8], [10, 10, 10]));
SELECT
timeslot,
sumMap(statusMap.status, statusMap.requests)
sumMap(statusMap.status, statusMap.requests),
sumMap(statusMapTuple)
FROM sum_map
GROUP BY timeslot
```
``` text
┌────────────timeslot─┬─sumMap(statusMap.status, statusMap.requests)─┐
│ 2000-01-01 00:00:00 │ ([1,2,3,4,5],[10,10,20,10,10]) │
│ 2000-01-01 00:01:00 │ ([4,5,6,7,8],[10,10,20,10,10]) │
└─────────────────────┴──────────────────────────────────────────────┘
┌────────────timeslot─┬─sumMap(statusMap.status, statusMap.requests)─┬─sumMap(statusMapTuple)─────────
│ 2000-01-01 00:00:00 │ ([1,2,3,4,5],[10,10,20,10,10]) │ ([1,2,3,4,5],[10,10,20,10,10]) │
│ 2000-01-01 00:01:00 │ ([4,5,6,7,8],[10,10,20,10,10]) │ ([4,5,6,7,8],[10,10,20,10,10]) │
└─────────────────────┴──────────────────────────────────────────────┴────────────────────────────────
```
[Оригинальная статья](https://clickhouse.tech/docs/en/sql-reference/aggregate-functions/reference/summap/) <!--hide-->

View File

@ -1,8 +1,8 @@
# AggregateFunction {#data-type-aggregatefunction}
Промежуточное состояние агрегатной функции. Чтобы его получить, используются агрегатные функции с суффиксом `-State`. Чтобы в дальнейшем получить агрегированные данные необходимо использовать те же агрегатные функции с суффиксом `-Merge`.
Агрегатные функции могут обладать определяемым реализацией промежуточным состоянием, которое может быть сериализовано в тип данных, соответствующий AggregateFunction(…), и быть записано в таблицу обычно посредством [материализованного представления] (../../sql-reference/statements/create.md#create-view). Чтобы получить промежуточное состояние, обычно используются агрегатные функции с суффиксом `-State`. Чтобы в дальнейшем получить агрегированные данные необходимо использовать те же агрегатные функции с суффиксом `-Merge`.
`AggregateFunction(name, types_of_arguments…)` — параметрический тип данных.
`AggregateFunction(name, types\_of\_arguments…)` — параметрический тип данных.
**Параметры**
@ -23,7 +23,7 @@ CREATE TABLE t
) ENGINE = ...
```
[uniq](../../sql-reference/aggregate-functions/reference/uniq.md#agg_function-uniq), anyIf ([any](../../sql-reference/aggregate-functions/reference/any.md#agg_function-any)+[If](../../sql-reference/aggregate-functions/combinators.md#agg-functions-combinator-if)) и [quantiles](../../sql-reference/aggregate-functions/reference/quantiles.md) — агрегатные функции, поддержанные в ClickHouse.
[uniq](../../sql-reference/data-types/aggregatefunction.md#agg_function-uniq), anyIf ([any](../../sql-reference/data-types/aggregatefunction.md#agg_function-any)+[If](../../sql-reference/data-types/aggregatefunction.md#agg-functions-combinator-if)) и [quantiles](../../sql-reference/data-types/aggregatefunction.md) — агрегатные функции, поддержанные в ClickHouse.
## Особенности использования {#osobennosti-ispolzovaniia}
@ -58,6 +58,6 @@ SELECT uniqMerge(state) FROM (SELECT uniqState(UserID) AS state FROM table GROUP
## Пример использования {#primer-ispolzovaniia}
Смотрите в описании движка [AggregatingMergeTree](../../engines/table-engines/mergetree-family/aggregatingmergetree.md).
Смотрите в описании движка [AggregatingMergeTree](../../sql-reference/data-types/aggregatefunction.md).
[Оригинальная статья](https://clickhouse.tech/docs/ru/data_types/nested_data_structures/aggregatefunction/) <!--hide-->

View File

@ -851,7 +851,7 @@ SELECT arrayReduce('maxIf', [3, 5], [1, 0])
Пример с параметрической агрегатной функцией:
Запрос:
Запрос:
```sql
SELECT arrayReduce('uniqUpTo(3)', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
@ -1036,4 +1036,40 @@ SELECT arrayZip(['a', 'b', 'c'], [5, 2, 1])
└──────────────────────────────────────┘
```
## arrayAUC {#arrayauc}
Вычисляет площадь под кривой.
**Синтаксис**
``` sql
arrayAUC(arr_scores, arr_labels)
```
**Параметры**
- `arr_scores` — оценка, которую дает модель предсказания.
- `arr_labels` — ярлыки выборок, обычно 1 для содержательных выборок и 0 для бессодержательных выборок.
**Возвращаемое значение**
Значение площади под кривой.
Тип данных: `Float64`.
**Пример**
Запрос:
``` sql
select arrayAUC([0.1, 0.4, 0.35, 0.8], [0, 0, 1, 1])
```
Ответ:
``` text
┌─arrayAUC([0.1, 0.4, 0.35, 0.8], [0, 0, 1, 1])─┐
│ 0.75 │
└────────────────────────────────────────---──┘
```
[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/functions/array_functions/) <!--hide-->

View File

@ -127,9 +127,9 @@ SELECT IPv6NumToString(IPv4ToIPv6(IPv4StringToNum('192.168.0.1'))) AS addr
└────────────────────┘
```
## cutIPv6(x, bitsToCutForIPv6, bitsToCutForIPv4) {#cutipv6x-bitstocutforipv6-bitstocutforipv4}
## cutIPv6(x, bytesToCutForIPv6, bytesToCutForIPv4) {#cutipv6x-bytestocutforipv6-bytestocutforipv4}
Принимает значение типа FixedString(16), содержащее IPv6-адрес в бинарном виде. Возвращает строку, содержащую адрес из указанного количества битов, удаленных в текстовом формате. Например:
Принимает значение типа FixedString(16), содержащее IPv6-адрес в бинарном виде. Возвращает строку, содержащую адрес из указанного количества байтов, удаленных в текстовом формате. Например:
``` sql
WITH

View File

@ -2,13 +2,90 @@
## splitByChar(separator, s) {#splitbycharseparator-s}
Разбивает строку на подстроки, используя в качестве разделителя separator.
Разбивает строку на подстроки, используя в качестве разделителя `separator`.
separator должен быть константной строкой из ровно одного символа.
Возвращается массив выделенных подстрок. Могут выделяться пустые подстроки, если разделитель идёт в начале или в конце строки, или если идёт более одного разделителя подряд.
**Синтаксис**
``` sql
splitByChar(<separator>, <s>)
```
**Параметры**
- `separator` — Разделитель, состоящий из одного символа. [String](../../sql-reference/data-types/string.md).
- `s` — Разбиваемая строка. [String](../../sql-reference/data-types/string.md).
**Возвращаемые значения**
Возвращает массив подстрок. Пустая подстрока, может быть возвращена, когда:
- Разделитель находится в начале или конце строки;
- Задано несколько последовательных разделителей;
- Исходная строка `s` пуста.
Type: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-reference/data-types/string.md).
**Пример**
``` sql
SELECT splitByChar(',', '1,2,3,abcde')
```
``` text
┌─splitByChar(',', '1,2,3,abcde')─┐
│ ['1','2','3','abcde'] │
└─────────────────────────────────┘
```
## splitByString(separator, s) {#splitbystringseparator-s}
То же самое, но использует строку из нескольких символов в качестве разделителя. Строка должна быть непустой.
Разбивает строку на подстроки, разделенные строкой. В качестве разделителя использует константную строку `separator`, которая может состоять из нескольких символов. Если строка `separator` пуста, то функция разделит строку `s` на массив из символов.
**Синтаксис**
``` sql
splitByString(separator, s)
```
**Параметры**
- `separator` — Разделитель. [String](../../sql-reference/data-types/string.md).
- `s` — Разбиваемая строка. [String](../../sql-reference/data-types/string.md).
**Возвращаемые значения**
Возвращает массив подстрок. Пустая подстрока, может быть возвращена, когда:
- Разделитель находится в начале или конце строки;
- Задано несколько последовательных разделителей;
- Исходная строка `s` пуста.
Type: [Array](../../sql-reference/data-types/array.md) of [String](../../sql-reference/data-types/string.md).
**Примеры**
``` sql
SELECT splitByString(', ', '1, 2 3, 4,5, abcde')
```
``` text
┌─splitByString(', ', '1, 2 3, 4,5, abcde')─┐
│ ['1','2 3','4,5','abcde'] │
└───────────────────────────────────────────┘
```
``` sql
SELECT splitByString('', 'abcde')
```
``` text
┌─splitByString('', 'abcde')─┐
│ ['a','b','c','d','e'] │
└────────────────────────────┘
```
## arrayStringConcat(arr\[, separator\]) {#arraystringconcatarr-separator}
@ -33,42 +110,4 @@ SELECT alphaTokens('abca1abc')
└─────────────────────────┘
```
## extractAllGroups(text, regexp) {#extractallgroups}
Выделяет все группы из неперекрывающихся подстрок, которые соответствуют регулярному выражению.
**Синтаксис**
``` sql
extractAllGroups(text, regexp)
```
**Параметры**
- `text` — [String](../data-types/string.md) или [FixedString](../data-types/fixedstring.md).
- `regexp` — Регулярное выражение. Константа. [String](../data-types/string.md) или [FixedString](../data-types/fixedstring.md).
**Возвращаемые значения**
- Если найдена хотя бы одна подходящая группа, функция возвращает столбец вида `Array(Array(String))`, сгруппированный по идентификатору группы (от 1 до N, где N — количество групп с захватом содержимого в `regexp`).
- Если подходящих групп не найдено, возвращает пустой массив.
Тип: [Array](../data-types/array.md).
**Пример использования**
Запрос:
``` sql
SELECT extractAllGroups('abc=123, 8="hkl"', '("[^"]+"|\\w+)=("[^"]+"|\\w+)');
```
Результат:
``` text
┌─extractAllGroups('abc=123, 8="hkl"', '("[^"]+"|\\w+)=("[^"]+"|\\w+)')─┐
│ [['abc','123'],['8','"hkl"']] │
└───────────────────────────────────────────────────────────────────────┘
```
[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/functions/splitting_merging_functions/) <!--hide-->

View File

@ -21,15 +21,14 @@ namespace
{
bool isSchemaAllowed(SQLHDBC hdbc)
{
std::string identifier;
SQLSMALLINT t;
SQLRETURN r = POCO_SQL_ODBC_CLASS::SQLGetInfo(hdbc, SQL_SCHEMA_USAGE, nullptr, 0, &t);
SQLUINTEGER value;
SQLSMALLINT value_length = sizeof(value);
SQLRETURN r = POCO_SQL_ODBC_CLASS::SQLGetInfo(hdbc, SQL_SCHEMA_USAGE, &value, sizeof(value), &value_length);
if (POCO_SQL_ODBC_CLASS::Utility::isError(r))
throw POCO_SQL_ODBC_CLASS::ConnectionException(hdbc);
return t != 0;
return value != 0;
}
}

View File

@ -130,37 +130,25 @@ struct VarMoments
};
template <typename T, size_t _level>
struct VarMomentsDecimal
class VarMomentsDecimal
{
public:
using NativeType = typename T::NativeType;
UInt64 m0{};
NativeType m[_level]{};
NativeType & getM(size_t i)
{
return m[i - 1];
}
const NativeType & getM(size_t i) const
{
return m[i - 1];
}
void add(NativeType x)
{
++m0;
getM(1) += x;
NativeType tmp;
if (common::mulOverflow(x, x, tmp) || common::addOverflow(getM(2), tmp, getM(2)))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
bool overflow = common::mulOverflow(x, x, tmp) || common::addOverflow(getM(2), tmp, getM(2));
if constexpr (_level >= 3)
if (common::mulOverflow(tmp, x, tmp) || common::addOverflow(getM(3), tmp, getM(3)))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
overflow = overflow || common::mulOverflow(tmp, x, tmp) || common::addOverflow(getM(3), tmp, getM(3));
if constexpr (_level >= 4)
if (common::mulOverflow(tmp, x, tmp) || common::addOverflow(getM(4), tmp, getM(4)))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
overflow = overflow || common::mulOverflow(tmp, x, tmp) || common::addOverflow(getM(4), tmp, getM(4));
if (overflow)
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
}
void merge(const VarMomentsDecimal & rhs)
@ -168,14 +156,14 @@ struct VarMomentsDecimal
m0 += rhs.m0;
getM(1) += rhs.getM(1);
if (common::addOverflow(getM(2), rhs.getM(2), getM(2)))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
bool overflow = common::addOverflow(getM(2), rhs.getM(2), getM(2));
if constexpr (_level >= 3)
if (common::addOverflow(getM(3), rhs.getM(3), getM(3)))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
overflow = overflow || common::addOverflow(getM(3), rhs.getM(3), getM(3));
if constexpr (_level >= 4)
if (common::addOverflow(getM(4), rhs.getM(4), getM(4)))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
overflow = overflow || common::addOverflow(getM(4), rhs.getM(4), getM(4));
if (overflow)
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
}
void write(WriteBuffer & buf) const { writePODBinary(*this, buf); }
@ -190,7 +178,7 @@ struct VarMomentsDecimal
if (common::mulOverflow(getM(1), getM(1), tmp) ||
common::subOverflow(getM(2), NativeType(tmp / m0), tmp))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
return std::max(Float64{}, convertFromDecimal<DataTypeDecimal<T>, DataTypeNumber<Float64>>(tmp / m0, scale));
return std::max(Float64{}, DecimalUtils::convertTo<Float64>(T(tmp / m0), scale));
}
Float64 getSample(UInt32 scale) const
@ -204,7 +192,7 @@ struct VarMomentsDecimal
if (common::mulOverflow(getM(1), getM(1), tmp) ||
common::subOverflow(getM(2), NativeType(tmp / m0), tmp))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
return std::max(Float64{}, convertFromDecimal<DataTypeDecimal<T>, DataTypeNumber<Float64>>(tmp / (m0 - 1), scale));
return std::max(Float64{}, DecimalUtils::convertTo<Float64>(T(tmp / (m0 - 1)), scale));
}
Float64 getMoment3(UInt32 scale) const
@ -218,7 +206,7 @@ struct VarMomentsDecimal
common::mulOverflow(tmp, getM(1), tmp) ||
common::subOverflow(getM(3), NativeType(tmp / m0), tmp))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
return convertFromDecimal<DataTypeDecimal<T>, DataTypeNumber<Float64>>(tmp / m0, scale);
return DecimalUtils::convertTo<Float64>(T(tmp / m0), scale);
}
Float64 getMoment4(UInt32 scale) const
@ -234,8 +222,15 @@ struct VarMomentsDecimal
common::mulOverflow(tmp, getM(1), tmp) ||
common::subOverflow(getM(4), NativeType(tmp / m0), tmp))
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
return convertFromDecimal<DataTypeDecimal<T>, DataTypeNumber<Float64>>(tmp / m0, scale);
return DecimalUtils::convertTo<Float64>(T(tmp / m0), scale);
}
private:
UInt64 m0{};
NativeType m[_level]{};
NativeType & getM(size_t i) { return m[i - 1]; }
const NativeType & getM(size_t i) const { return m[i - 1]; }
};
/**

View File

@ -103,15 +103,15 @@ namespace MySQLReplication
= header.event_size - EVENT_HEADER_LENGTH - 4 - 4 - 1 - 2 - 2 - status_len - schema_len - 1 - CHECKSUM_CRC32_SIGNATURE_LENGTH;
query.resize(len);
payload.readStrict(reinterpret_cast<char *>(query.data()), len);
if (query.rfind("BEGIN", 0) == 0)
if (query.rfind("BEGIN", 0) == 0 || query.rfind("COMMIT") == 0)
{
typ = BEGIN;
typ = QUERY_EVENT_MULTI_TXN_FLAG;
}
else if (query.rfind("XA", 0) == 0)
{
if (query.rfind("XA ROLLBACK", 0) == 0)
throw ReplicationError("ParseQueryEvent: Unsupported query event:" + query, ErrorCodes::UNKNOWN_EXCEPTION);
typ = XA;
typ = QUERY_EVENT_XA;
}
else if (query.rfind("SAVEPOINT", 0) == 0)
{
@ -841,8 +841,8 @@ namespace MySQLReplication
auto query = std::static_pointer_cast<QueryEvent>(event);
switch (query->typ)
{
case BEGIN:
case XA: {
case QUERY_EVENT_MULTI_TXN_FLAG:
case QUERY_EVENT_XA: {
event = std::make_shared<DryRunEvent>();
break;
}

View File

@ -345,9 +345,9 @@ namespace MySQLReplication
enum QueryType
{
DDL = 0,
BEGIN = 1,
XA = 2
QUERY_EVENT_DDL = 0,
QUERY_EVENT_MULTI_TXN_FLAG = 1,
QUERY_EVENT_XA = 2
};
class QueryEvent : public EventBase
@ -361,7 +361,7 @@ namespace MySQLReplication
String status;
String schema;
String query;
QueryType typ = DDL;
QueryType typ = QUERY_EVENT_DDL;
QueryEvent() : thread_id(0), exec_time(0), schema_len(0), error_code(0), status_len(0) { }
void dump(std::ostream & out) const override;

View File

@ -158,7 +158,7 @@ protected:
template <typename T, typename U, template <typename> typename DecimalType>
typename std::enable_if_t<(sizeof(T) >= sizeof(U)), DecimalType<T>>
decimalResultType(const DecimalType<T> & tx, const DecimalType<U> & ty, bool is_multiply, bool is_divide)
inline decimalResultType(const DecimalType<T> & tx, const DecimalType<U> & ty, bool is_multiply, bool is_divide)
{
UInt32 scale = (tx.getScale() > ty.getScale() ? tx.getScale() : ty.getScale());
if (is_multiply)
@ -170,7 +170,7 @@ decimalResultType(const DecimalType<T> & tx, const DecimalType<U> & ty, bool is_
template <typename T, typename U, template <typename> typename DecimalType>
typename std::enable_if_t<(sizeof(T) < sizeof(U)), const DecimalType<U>>
decimalResultType(const DecimalType<T> & tx, const DecimalType<U> & ty, bool is_multiply, bool is_divide)
inline decimalResultType(const DecimalType<T> & tx, const DecimalType<U> & ty, bool is_multiply, bool is_divide)
{
UInt32 scale = (tx.getScale() > ty.getScale() ? tx.getScale() : ty.getScale());
if (is_multiply)
@ -181,19 +181,19 @@ decimalResultType(const DecimalType<T> & tx, const DecimalType<U> & ty, bool is_
}
template <typename T, typename U, template <typename> typename DecimalType>
const DecimalType<T> decimalResultType(const DecimalType<T> & tx, const DataTypeNumber<U> &, bool, bool)
inline const DecimalType<T> decimalResultType(const DecimalType<T> & tx, const DataTypeNumber<U> &, bool, bool)
{
return DecimalType<T>(DecimalUtils::maxPrecision<T>(), tx.getScale());
}
template <typename T, typename U, template <typename> typename DecimalType>
const DecimalType<U> decimalResultType(const DataTypeNumber<T> &, const DecimalType<U> & ty, bool, bool)
inline const DecimalType<U> decimalResultType(const DataTypeNumber<T> &, const DecimalType<U> & ty, bool, bool)
{
return DecimalType<U>(DecimalUtils::maxPrecision<U>(), ty.getScale());
}
template <template <typename> typename DecimalType>
DataTypePtr createDecimal(UInt64 precision_value, UInt64 scale_value)
inline DataTypePtr createDecimal(UInt64 precision_value, UInt64 scale_value)
{
if (precision_value < DecimalUtils::minPrecision() || precision_value > DecimalUtils::maxPrecision<Decimal256>())
throw Exception("Wrong precision", ErrorCodes::ARGUMENT_OUT_OF_BOUND);

View File

@ -179,4 +179,10 @@ convertToDecimal(const typename FromDataType::FieldType & value, UInt32 scale)
}
}
template <typename T>
inline DataTypePtr createDecimalMaxPrecision(UInt64 scale)
{
return std::make_shared<DataTypeDecimal<T>>(DecimalUtils::maxPrecision<T>(), scale);
}
}

View File

@ -246,7 +246,7 @@ static inline BlockOutputStreamPtr getTableOutput(const String & database_name,
if (iterator != insert_columns_names.begin())
insert_columns_str << ", ";
insert_columns_str << iterator->name;
insert_columns_str << backQuoteIfNeed(iterator->name);
}

View File

@ -558,7 +558,7 @@ private:
template <typename S>
void writeDecimal(const Decimal<S> & decimal, UInt32 scale)
{
castNumericAndWriteField(convertFromDecimal<DataTypeDecimal<Decimal<S>>, DataTypeNumber<ToType>>(decimal.value, scale));
castNumericAndWriteField(DecimalUtils::convertTo<ToType>(decimal, scale));
}
void writeField(ToType value)

View File

@ -140,7 +140,7 @@ private:
dst_data.resize(size);
for (size_t i = 0; i < size; ++i)
dst_data[i] = convertFromDecimal<DataTypeDecimal<T>, DataTypeNumber<ReturnType>>(src_data[i], scale);
dst_data[i] = DecimalUtils::convertTo<ReturnType>(src_data[i], scale);
executeInIterations(dst_data.data(), dst_data.data(), size);

View File

@ -1063,19 +1063,16 @@ public:
}
else if constexpr (to_decimal)
{
// if (!arguments[1].column)
// throw Exception("Second argument for function " + getName() + " must be constant", ErrorCodes::ILLEGAL_COLUMN);
UInt64 scale = extractToDecimalScale(arguments[1]);
if constexpr (std::is_same_v<Name, NameToDecimal32>)
return createDecimal<DataTypeDecimal>(9, scale);
return createDecimalMaxPrecision<Decimal32>(scale);
else if constexpr (std::is_same_v<Name, NameToDecimal64>)
return createDecimal<DataTypeDecimal>(18, scale);
return createDecimalMaxPrecision<Decimal64>(scale);
else if constexpr (std::is_same_v<Name, NameToDecimal128>)
return createDecimal<DataTypeDecimal>(38, scale);
return createDecimalMaxPrecision<Decimal128>(scale);
else if constexpr (std::is_same_v<Name, NameToDecimal256>)
return createDecimal<DataTypeDecimal>(77, scale);
return createDecimalMaxPrecision<Decimal256>(scale);
throw Exception("Something wrong with toDecimalNN()", ErrorCodes::LOGICAL_ERROR);
}
@ -1332,16 +1329,7 @@ public:
else if constexpr (to_decimal)
{
UInt64 scale = extractToDecimalScale(arguments[1]);
if constexpr (std::is_same_v<ToDataType, DataTypeDecimal<Decimal32>>)
res = createDecimal<DataTypeDecimal>(9, scale);
else if constexpr (std::is_same_v<ToDataType, DataTypeDecimal<Decimal64>>)
res = createDecimal<DataTypeDecimal>(18, scale);
else if constexpr (std::is_same_v<ToDataType, DataTypeDecimal<Decimal128>>)
res = createDecimal<DataTypeDecimal>(38, scale);
else if constexpr (std::is_same_v<ToDataType, DataTypeDecimal<Decimal256>>)
res = createDecimal<DataTypeDecimal>(77, scale);
res = createDecimalMaxPrecision<typename ToDataType::FieldType>(scale);
if (!res)
throw Exception("Something wrong with toDecimalNNOrZero() or toDecimalNNOrNull()", ErrorCodes::LOGICAL_ERROR);
}

View File

@ -18,7 +18,6 @@
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTIndexDeclaration.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTNameTypePair.h>
#include <Parsers/ASTInsertQuery.h>
#include <Parsers/ParserCreateQuery.h>
#include <Parsers/formatAST.h>
@ -30,11 +29,9 @@
#include <Interpreters/Context.h>
#include <Interpreters/DDLWorker.h>
#include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/TreeRewriter.h>
#include <Interpreters/InterpreterCreateQuery.h>
#include <Interpreters/InterpreterSelectWithUnionQuery.h>
#include <Interpreters/InterpreterInsertQuery.h>
#include <Interpreters/ExpressionActions.h>
#include <Interpreters/AddDefaultDatabaseVisitor.h>
#include <Access/AccessRightsElement.h>
@ -70,6 +67,7 @@ namespace ErrorCodes
extern const int UNKNOWN_DATABASE_ENGINE;
extern const int DUPLICATE_COLUMN;
extern const int DATABASE_ALREADY_EXISTS;
extern const int BAD_ARGUMENTS;
extern const int BAD_DATABASE_FOR_TEMPORARY_TABLE;
extern const int SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY;
extern const int DICTIONARY_ALREADY_EXISTS;
@ -415,7 +413,12 @@ ColumnsDescription InterpreterCreateQuery::getColumnsDescription(
column.comment = col_decl.comment->as<ASTLiteral &>().value.get<String>();
if (col_decl.codec)
column.codec = CompressionCodecFactory::instance().validateCodecAndGetPreprocessedAST(col_decl.codec, column.type, sanity_check_compression_codecs);
{
if (col_decl.default_specifier == "ALIAS")
throw Exception{"Cannot specify codec for column type ALIAS", ErrorCodes::BAD_ARGUMENTS};
column.codec = CompressionCodecFactory::instance().validateCodecAndGetPreprocessedAST(
col_decl.codec, column.type, sanity_check_compression_codecs);
}
if (col_decl.ttl)
column.ttl = col_decl.ttl;

View File

@ -27,7 +27,7 @@ Block MetricLogElement::createBlock()
{
std::string name;
name += "CurrentMetric_";
name += CurrentMetrics::getName(ProfileEvents::Event(i));
name += CurrentMetrics::getName(CurrentMetrics::Metric(i));
columns_with_type_and_name.emplace_back(std::make_shared<DataTypeInt64>(), std::move(name));
}

View File

@ -1,5 +1,3 @@
#include "MutationsInterpreter.h"
#include <Functions/FunctionFactory.h>
#include <Functions/IFunction.h>
#include <Interpreters/InDepthNodeVisitor.h>
@ -7,11 +5,12 @@
#include <Interpreters/MutationsInterpreter.h>
#include <Interpreters/TreeRewriter.h>
#include <Storages/MergeTree/MergeTreeData.h>
#include <DataStreams/FilterBlockInputStream.h>
#include <DataStreams/ExpressionBlockInputStream.h>
#include <DataStreams/CreatingSetsBlockInputStream.h>
#include <DataStreams/MaterializingBlockInputStream.h>
#include <DataStreams/NullBlockInputStream.h>
#include <Processors/Transforms/FilterTransform.h>
#include <Processors/Transforms/ExpressionTransform.h>
#include <Processors/Transforms/CreatingSetsTransform.h>
#include <Processors/Transforms/MaterializingTransform.h>
#include <Processors/Sources/NullSource.h>
#include <Processors/QueryPipeline.h>
#include <DataStreams/CheckSortedBlockInputStream.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTFunction.h>
@ -160,7 +159,7 @@ ColumnDependencies getAllColumnDependencies(const StorageMetadataPtr & metadata_
return dependencies;
}
};
}
bool isStorageTouchedByMutations(
StoragePtr storage,
@ -525,8 +524,10 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run)
SelectQueryOptions().analyze(/* dry_run = */ false).ignoreLimits()};
auto first_stage_header = interpreter.getSampleBlock();
auto in = std::make_shared<NullBlockInputStream>(first_stage_header);
updated_header = std::make_unique<Block>(addStreamsForLaterStages(stages_copy, in)->getHeader());
QueryPipeline pipeline;
pipeline.init(Pipe(std::make_shared<NullSource>(first_stage_header)));
addStreamsForLaterStages(stages_copy, pipeline);
updated_header = std::make_unique<Block>(pipeline.getHeader());
}
/// Special step to recalculate affected indices and TTL expressions.
@ -655,7 +656,7 @@ ASTPtr MutationsInterpreter::prepareInterpreterSelectQuery(std::vector<Stage> &
return select;
}
BlockInputStreamPtr MutationsInterpreter::addStreamsForLaterStages(const std::vector<Stage> & prepared_stages, BlockInputStreamPtr in) const
void MutationsInterpreter::addStreamsForLaterStages(const std::vector<Stage> & prepared_stages, QueryPipeline & pipeline) const
{
for (size_t i_stage = 1; i_stage < prepared_stages.size(); ++i_stage)
{
@ -667,23 +668,36 @@ BlockInputStreamPtr MutationsInterpreter::addStreamsForLaterStages(const std::ve
if (i < stage.filter_column_names.size())
{
/// Execute DELETEs.
in = std::make_shared<FilterBlockInputStream>(in, step->actions(), stage.filter_column_names[i]);
pipeline.addSimpleTransform([&](const Block & header)
{
return std::make_shared<FilterTransform>(header, step->actions(), stage.filter_column_names[i], false);
});
}
else
{
/// Execute UPDATE or final projection.
in = std::make_shared<ExpressionBlockInputStream>(in, step->actions());
pipeline.addSimpleTransform([&](const Block & header)
{
return std::make_shared<ExpressionTransform>(header, step->actions());
});
}
}
const SubqueriesForSets & subqueries_for_sets = stage.analyzer->getSubqueriesForSets();
if (!subqueries_for_sets.empty())
in = std::make_shared<CreatingSetsBlockInputStream>(in, subqueries_for_sets, context);
{
const Settings & settings = context.getSettingsRef();
SizeLimits network_transfer_limits(
settings.max_rows_to_transfer, settings.max_bytes_to_transfer, settings.transfer_overflow_mode);
pipeline.addCreatingSetsTransform(std::make_shared<CreatingSetsTransform>(
pipeline.getHeader(), subqueries_for_sets, network_transfer_limits, context));
}
}
in = std::make_shared<MaterializingBlockInputStream>(in);
return in;
pipeline.addSimpleTransform([&](const Block & header)
{
return std::make_shared<MaterializingTransform>(header);
});
}
void MutationsInterpreter::validate()
@ -705,10 +719,8 @@ void MutationsInterpreter::validate()
}
}
/// Do not use getSampleBlock in order to check the whole pipeline.
Block first_stage_header = select_interpreter->execute().getInputStream()->getHeader();
BlockInputStreamPtr in = std::make_shared<NullBlockInputStream>(first_stage_header);
addStreamsForLaterStages(stages, in)->getHeader();
auto block_io = select_interpreter->execute();
addStreamsForLaterStages(stages, block_io.pipeline);
}
BlockInputStreamPtr MutationsInterpreter::execute()
@ -716,9 +728,10 @@ BlockInputStreamPtr MutationsInterpreter::execute()
if (!can_execute)
throw Exception("Cannot execute mutations interpreter because can_execute flag set to false", ErrorCodes::LOGICAL_ERROR);
BlockInputStreamPtr in = select_interpreter->execute().getInputStream();
auto block_io = select_interpreter->execute();
addStreamsForLaterStages(stages, block_io.pipeline);
auto result_stream = addStreamsForLaterStages(stages, in);
auto result_stream = block_io.getInputStream();
/// Sometimes we update just part of columns (for example UPDATE mutation)
/// in this case we don't read sorting key, so just we don't check anything.

View File

@ -13,6 +13,7 @@ namespace DB
{
class Context;
class QueryPipeline;
/// Return false if the data isn't going to be changed by mutations.
bool isStorageTouchedByMutations(
@ -51,7 +52,7 @@ private:
struct Stage;
ASTPtr prepareInterpreterSelectQuery(std::vector<Stage> &prepared_stages, bool dry_run);
BlockInputStreamPtr addStreamsForLaterStages(const std::vector<Stage> & prepared_stages, BlockInputStreamPtr in) const;
void addStreamsForLaterStages(const std::vector<Stage> & prepared_stages, QueryPipeline & pipeline) const;
std::optional<SortDescription> getStorageSortDescriptionIfPossible(const Block & header) const;

View File

@ -146,13 +146,20 @@ Token Lexer::nextTokenImpl()
}
}
/// word character cannot go just after number (SELECT 123FROM)
/// Try to parse it to a identifier(1identifier_name), otherwise it return ErrorWrongNumber
if (pos < end && isWordCharASCII(*pos))
{
++pos;
while (pos < end && isWordCharASCII(*pos))
++pos;
return Token(TokenType::ErrorWrongNumber, token_begin, pos);
for (const char * iterator = token_begin; iterator < pos; ++iterator)
{
if (!isWordCharASCII(*iterator) && *iterator != '$')
return Token(TokenType::ErrorWrongNumber, token_begin, pos);
}
return Token(TokenType::BareWord, token_begin, pos);
}
return Token(TokenType::Number, token_begin, pos);
@ -313,10 +320,10 @@ Token Lexer::nextTokenImpl()
}
default:
if (isWordCharASCII(*pos))
if (isWordCharASCII(*pos) || *pos == '$')
{
++pos;
while (pos < end && isWordCharASCII(*pos))
while (pos < end && (isWordCharASCII(*pos) || *pos == '$'))
++pos;
return Token(TokenType::BareWord, token_begin, pos);
}

View File

@ -508,7 +508,7 @@ Processors AggregatingTransform::expandPipeline()
void AggregatingTransform::consume(Chunk chunk)
{
UInt64 num_rows = chunk.getNumRows();
const UInt64 num_rows = chunk.getNumRows();
if (num_rows == 0 && params->params.empty_result_for_aggregation_by_empty_set)
return;
@ -519,7 +519,7 @@ void AggregatingTransform::consume(Chunk chunk)
is_consume_started = true;
}
src_rows += chunk.getNumRows();
src_rows += num_rows;
src_bytes += chunk.bytes();
if (!params->aggregator.executeOnBlock(chunk.detachColumns(), num_rows, variants, key_columns, aggregate_columns, no_more_keys))

View File

@ -74,8 +74,11 @@ std::optional<AlterCommand> AlterCommand::parse(const ASTAlterCommand * command_
}
if (ast_col_decl.codec)
{
if (ast_col_decl.default_specifier == "ALIAS")
throw Exception{"Cannot specify codec for column type ALIAS", ErrorCodes::BAD_ARGUMENTS};
command.codec = ast_col_decl.codec;
}
if (command_ast->column)
command.after_column = getIdentifierName(command_ast->column);

View File

@ -94,6 +94,7 @@ StorageDistributedDirectoryMonitor::StorageDistributedDirectoryMonitor(
, log{&Poco::Logger::get(getLoggerName())}
, monitor_blocker(monitor_blocker_)
, bg_pool(bg_pool_)
, metric_pending_files(CurrentMetrics::DistributedFilesToInsert, 0)
{
task_handle = bg_pool.createTask(getLoggerName() + "/Bg", [this]{ run(); });
task_handle->activateAndSchedule();
@ -114,16 +115,15 @@ void StorageDistributedDirectoryMonitor::flushAllData()
if (quit)
return;
CurrentMetrics::Increment metric_pending_files{CurrentMetrics::DistributedFilesToInsert, 0};
std::unique_lock lock{mutex};
const auto & files = getFiles(metric_pending_files);
const auto & files = getFiles();
if (!files.empty())
{
processFiles(files, metric_pending_files);
processFiles(files);
/// Update counters
getFiles(metric_pending_files);
getFiles();
}
}
@ -143,15 +143,12 @@ void StorageDistributedDirectoryMonitor::run()
{
std::unique_lock lock{mutex};
/// This metric will be updated with the number of pending files later.
CurrentMetrics::Increment metric_pending_files{CurrentMetrics::DistributedFilesToInsert, 0};
bool do_sleep = false;
while (!quit)
{
do_sleep = true;
const auto & files = getFiles(metric_pending_files);
const auto & files = getFiles();
if (files.empty())
break;
@ -159,7 +156,7 @@ void StorageDistributedDirectoryMonitor::run()
{
try
{
do_sleep = !processFiles(files, metric_pending_files);
do_sleep = !processFiles(files);
std::unique_lock metrics_lock(metrics_mutex);
last_exception = std::exception_ptr{};
@ -196,7 +193,7 @@ void StorageDistributedDirectoryMonitor::run()
}
/// Update counters
getFiles(metric_pending_files);
getFiles();
if (!quit && do_sleep)
task_handle->scheduleAfter(sleep_time.count());
@ -253,7 +250,7 @@ ConnectionPoolPtr StorageDistributedDirectoryMonitor::createPool(const std::stri
}
std::map<UInt64, std::string> StorageDistributedDirectoryMonitor::getFiles(CurrentMetrics::Increment & metric_pending_files)
std::map<UInt64, std::string> StorageDistributedDirectoryMonitor::getFiles()
{
std::map<UInt64, std::string> files;
size_t new_bytes_count = 0;
@ -271,8 +268,6 @@ std::map<UInt64, std::string> StorageDistributedDirectoryMonitor::getFiles(Curre
}
}
/// Note: the value of this metric will be kept if this function will throw an exception.
/// This is needed, because in case of exception, files still pending.
metric_pending_files.changeTo(files.size());
{
@ -283,11 +278,11 @@ std::map<UInt64, std::string> StorageDistributedDirectoryMonitor::getFiles(Curre
return files;
}
bool StorageDistributedDirectoryMonitor::processFiles(const std::map<UInt64, std::string> & files, CurrentMetrics::Increment & metric_pending_files)
bool StorageDistributedDirectoryMonitor::processFiles(const std::map<UInt64, std::string> & files)
{
if (should_batch_inserts)
{
processFilesWithBatching(files, metric_pending_files);
processFilesWithBatching(files);
}
else
{
@ -296,14 +291,14 @@ bool StorageDistributedDirectoryMonitor::processFiles(const std::map<UInt64, std
if (quit)
return true;
processFile(file.second, metric_pending_files);
processFile(file.second);
}
}
return true;
}
void StorageDistributedDirectoryMonitor::processFile(const std::string & file_path, CurrentMetrics::Increment & metric_pending_files)
void StorageDistributedDirectoryMonitor::processFile(const std::string & file_path)
{
LOG_TRACE(log, "Started processing `{}`", file_path);
auto timeouts = ConnectionTimeouts::getTCPTimeoutsWithFailover(storage.global_context->getSettingsRef());
@ -645,9 +640,7 @@ StorageDistributedDirectoryMonitor::Status StorageDistributedDirectoryMonitor::g
};
}
void StorageDistributedDirectoryMonitor::processFilesWithBatching(
const std::map<UInt64, std::string> & files,
CurrentMetrics::Increment & metric_pending_files)
void StorageDistributedDirectoryMonitor::processFilesWithBatching(const std::map<UInt64, std::string> & files)
{
std::unordered_set<UInt64> file_indices_to_skip;

View File

@ -57,10 +57,10 @@ public:
private:
void run();
std::map<UInt64, std::string> getFiles(CurrentMetrics::Increment & metric_pending_files);
bool processFiles(const std::map<UInt64, std::string> & files, CurrentMetrics::Increment & metric_pending_files);
void processFile(const std::string & file_path, CurrentMetrics::Increment & metric_pending_files);
void processFilesWithBatching(const std::map<UInt64, std::string> & files, CurrentMetrics::Increment & metric_pending_files);
std::map<UInt64, std::string> getFiles();
bool processFiles(const std::map<UInt64, std::string> & files);
void processFile(const std::string & file_path);
void processFilesWithBatching(const std::map<UInt64, std::string> & files);
static bool isFileBrokenErrorCode(int code);
void markAsBroken(const std::string & file_path) const;
@ -98,6 +98,8 @@ private:
BackgroundSchedulePool & bg_pool;
BackgroundSchedulePoolTaskHolder task_handle;
CurrentMetrics::Increment metric_pending_files;
/// Read insert query and insert settings for backward compatible.
static void readHeader(ReadBuffer & in, Settings & insert_settings, std::string & insert_query, ClientInfo & client_info, Poco::Logger * log);

View File

@ -42,7 +42,8 @@ void KafkaBlockOutputStream::write(const Block & block)
void KafkaBlockOutputStream::writeSuffix()
{
child->writeSuffix();
if (child)
child->writeSuffix();
flush();
}

View File

@ -541,8 +541,9 @@ CompressionCodecPtr IMergeTreeDataPart::detectDefaultCompressionCodec() const
CompressionCodecPtr result = nullptr;
for (const auto & part_column : columns)
{
/// It was compressed with default codec
if (!storage_columns.hasCompressionCodec(part_column.name))
/// It was compressed with default codec and it's not empty
auto column_size = getColumnSize(part_column.name, *part_column.type);
if (column_size.data_compressed != 0 && !storage_columns.hasCompressionCodec(part_column.name))
{
result = getCompressionCodecForFile(volume->getDisk(), getFullRelativePath() + getFileNameForColumn(part_column) + ".bin");
break;

View File

@ -153,6 +153,7 @@ const char * auto_contributors[] {
"Dmitry Rubashkin",
"Dmitry S..ky / skype: dvska-at-skype",
"Doge",
"Dongdong Yang",
"DoomzD",
"Dr. Strange Looker",
"Eldar Zaitov",
@ -180,11 +181,14 @@ const char * auto_contributors[] {
"Francisco Barón",
"Frank Zhao",
"Fruit of Eden",
"Fullstop000",
"Gagan Arneja",
"Gao Qiang",
"Gary Dotzler",
"George",
"George G",
"George3d6",
"Gervasio Varela",
"Gleb Kanterov",
"Gleb Novikov",
"Gleb-Tretyakov",
@ -206,6 +210,7 @@ const char * auto_contributors[] {
"Ildus Kurbangaliev",
"Ilya",
"Ilya Breev",
"Ilya Golshtein",
"Ilya Khomutov",
"Ilya Korol",
"Ilya Korolev",
@ -227,8 +232,11 @@ const char * auto_contributors[] {
"Ivan Zhukov",
"JaosnHsieh",
"Jason",
"Javi Santana",
"Javi santana bot",
"Jean Baptiste Favre",
"Jiading Guo",
"Jiang Tao",
"Jochen Schalanda",
"Jonatas Freitas",
"Karl Pietrzak",
@ -300,6 +308,7 @@ const char * auto_contributors[] {
"MicrochipQ",
"Mihail Fandyushin",
"Mikahil Nacharov",
"Mike",
"Mike F",
"Mikhail",
"Mikhail Fandyushin",
@ -343,6 +352,7 @@ const char * auto_contributors[] {
"Oleg Matrokhin",
"Oleg Obleukhov",
"Olga Khvostikova",
"Olga Revyakina",
"Orivej Desh",
"Oskar Wojciski",
"Paramtamtam",
@ -393,6 +403,7 @@ const char * auto_contributors[] {
"Sergey Kononenko",
"Sergey Lazarev",
"Sergey Magidovich",
"Sergey Mirvoda",
"Sergey Shtykov",
"Sergey V. Galtsev",
"Sergey Zaikin",
@ -467,6 +478,7 @@ const char * auto_contributors[] {
"Weiqing Xu",
"William Shallum",
"Winter Zhang",
"Y Lu",
"Yangkuan Liu",
"Yatsishin Ilya",
"Yegor Andreenko",
@ -478,6 +490,7 @@ const char * auto_contributors[] {
"Yuriy",
"Yuriy Baranov",
"Yuriy Chernyshov",
"Yuriy Korzhenevskiy",
"Yury Karpovich",
"Yury Stankevich",
"Zhichang Yu",
@ -528,6 +541,7 @@ const char * auto_contributors[] {
"decaseal",
"dependabot-preview[bot]",
"dependabot[bot]",
"dfenelonov",
"dgrr",
"dimarub2000",
"dinosaur",
@ -538,6 +552,7 @@ const char * auto_contributors[] {
"egatov",
"elBroom",
"elenaspb2019",
"emakarov",
"emironyuk",
"evtan",
"exprmntr",
@ -585,6 +600,7 @@ const char * auto_contributors[] {
"levushkin aleksej",
"levysh",
"liangqian",
"libenwang",
"linceyou",
"litao91",
"liu-bov",
@ -603,12 +619,14 @@ const char * auto_contributors[] {
"maxim-babenko",
"maxkuzn",
"maxulan",
"melin",
"memo",
"meo",
"mergify[bot]",
"mf5137",
"mfridental",
"miha-g",
"mikepop7",
"millb",
"mnkonkova",
"morty",
@ -639,6 +657,7 @@ const char * auto_contributors[] {
"ritaank",
"robot-clickhouse",
"robot-metrika-test",
"roman",
"root",
"santaux",
"sdk2",
@ -657,12 +676,14 @@ const char * auto_contributors[] {
"svladykin",
"tai",
"taiyang-li",
"tao jiang",
"tavplubix",
"topvisor",
"tyrionhuang",
"unegare",
"unknown",
"urgordeadbeef",
"vdimir",
"velom",
"vicdashkov",
"vinity",
@ -674,6 +695,7 @@ const char * auto_contributors[] {
"wangchao",
"xPoSx",
"yhgcn",
"ylchou",
"yonesko",
"zamulla",
"zhang2014",
@ -697,6 +719,7 @@ const char * auto_contributors[] {
"极客青年",
"谢磊",
"贾顺名(Jarvis)",
"陈小玉",
"黄朝晖",
"黄璞",
"박현우",

View File

@ -2164,6 +2164,35 @@ def test_kafka_unavailable(kafka_cluster):
print("Waiting for consume")
time.sleep(1)
@pytest.mark.timeout(180)
def test_kafka_issue14202(kafka_cluster):
instance.query('''
CREATE TABLE test.empty_table (
dt Date,
some_string String
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(dt)
ORDER BY some_string;
CREATE TABLE test.kafka_q (t UInt64, `some_string` String)
ENGINE = Kafka
SETTINGS kafka_broker_list = 'kafka1:19092',
kafka_topic_list = 'issue14202',
kafka_group_name = 'issue14202',
kafka_format = 'JSONEachRow';
''')
time.sleep(3)
instance.query('INSERT INTO test.kafka_q SELECT t, some_string FROM ( SELECT dt AS t, some_string FROM test.empty_table )')
# check instance is alive
assert TSV(instance.query('SELECT 1')) == TSV('1')
instance.query('''
DROP TABLE test.empty_table;
DROP TABLE test.kafka_q;
''')
if __name__ == '__main__':
cluster.start()
raw_input("Cluster created, press any key to destroy...")

View File

@ -0,0 +1,27 @@
<test max_ignored_relative_change="0.15">
<settings>
<max_memory_usage>10G</max_memory_usage>
</settings>
<create_query>CREATE TABLE t (x UInt64, d32 Decimal32(3), d64 Decimal64(4), d128 Decimal128(5)) ENGINE = Memory</create_query>
<!-- use less threads to save memory -->
<fill_query>INSERT INTO t SELECT number AS x, x % 1000000 AS d32, x AS d64, x d128 FROM numbers_mt(25000000) SETTINGS max_threads = 8</fill_query>
<drop_query>DROP TABLE IF EXISTS t</drop_query>
<query>SELECT toUInt32(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toInt32(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toInt64(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toUInt64(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toInt128(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toInt256(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toUInt256(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toFloat32(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toFloat64(x) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM t FORMAT Null</query>
<query>SELECT toInt32(d32), toInt64(d32), toInt128(d32) FROM t FORMAT Null</query>
<query>SELECT toInt32(d64), toInt64(d64), toInt128(d64) FROM t FORMAT Null</query>
<query>SELECT toInt32(d128), toInt64(d128), toInt128(d128) FROM t FORMAT Null</query>
<query>SELECT toFloat32(d32), toFloat32(d64), toFloat32(d128) FROM t FORMAT Null</query>
<query>SELECT toFloat64(d32), toFloat64(d64), toFloat64(d128) FROM t FORMAT Null</query>
<query>SELECT toInt256(d32), toInt256(d64), toInt256(d128) FROM t FORMAT Null</query>
</test>

View File

@ -0,0 +1,15 @@
0 0.0 0.00000 0.000000 0.0000000
1 1.0 1.00000 1.000000 1.0000000
2 2.0 2.00000 2.000000 2.0000000
3 3.0 3.00000 3.000000 3.0000000
4 4.0 4.00000 4.000000 4.0000000
5 5.0 5.00000 5.000000 5.0000000
6 6.0 6.00000 6.000000 6.0000000
7 7.0 7.00000 7.000000 7.0000000
8 8.0 8.00000 8.000000 8.0000000
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
14 14 14

View File

@ -0,0 +1,16 @@
SELECT toUInt32(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(1);
SELECT toInt32(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(1, 1);
SELECT toInt64(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(2, 1);
SELECT toUInt64(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(3, 1);
SELECT toInt128(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(4, 1);
SELECT toInt256(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(5, 1);
SELECT toUInt256(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(6, 1);
SELECT toFloat32(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(7, 1);
SELECT toFloat64(number) y, toDecimal32(y, 1), toDecimal64(y, 5), toDecimal128(y, 6), toDecimal256(y, 7) FROM numbers(8, 1);
SELECT toInt32(toDecimal32(number, 1)), toInt64(toDecimal32(number, 1)), toInt128(toDecimal32(number, 1)) FROM numbers(9, 1);
SELECT toInt32(toDecimal64(number, 2)), toInt64(toDecimal64(number, 2)), toInt128(toDecimal64(number, 2)) FROM numbers(10, 1);
SELECT toInt32(toDecimal128(number, 3)), toInt64(toDecimal128(number, 3)), toInt128(toDecimal128(number, 3)) FROM numbers(11, 1);
SELECT toFloat32(toDecimal32(number, 1)), toFloat32(toDecimal64(number, 2)), toFloat32(toDecimal128(number, 3)) FROM numbers(12, 1);
SELECT toFloat64(toDecimal32(number, 1)), toFloat64(toDecimal64(number, 2)), toFloat64(toDecimal128(number, 3)) FROM numbers(13, 1);
SELECT toInt256(toDecimal32(number, 1)), toInt256(toDecimal64(number, 2)), toInt256(toDecimal128(number, 3)) FROM numbers(14, 1);

View File

@ -0,0 +1,12 @@
INSERT
0
0
STOP/START DISTRIBUTED SENDS
1
0
FLUSH DISTRIBUTED
1
0
DROP TABLE
1
0

View File

@ -0,0 +1,42 @@
-- otherwise SYSTEM STOP DISTRIBUTED SENDS does not makes any effect (for localhost)
-- (i.e. no .bin files and hence no sending is required)
set prefer_localhost_replica=0;
set distributed_directory_monitor_sleep_time_ms=50;
drop table if exists data_01460;
drop table if exists dist_01460;
create table data_01460 as system.one engine=Null();
create table dist_01460 as data_01460 engine=Distributed(test_shard_localhost, currentDatabase(), data_01460);
select 'INSERT';
select value from system.metrics where metric = 'DistributedFilesToInsert';
insert into dist_01460 select * from system.one;
select sleep(1) format Null; -- distributed_directory_monitor_sleep_time_ms
select value from system.metrics where metric = 'DistributedFilesToInsert';
select 'STOP/START DISTRIBUTED SENDS';
system stop distributed sends dist_01460;
insert into dist_01460 select * from system.one;
select sleep(1) format Null; -- distributed_directory_monitor_sleep_time_ms
select value from system.metrics where metric = 'DistributedFilesToInsert';
system start distributed sends dist_01460;
select sleep(1) format Null; -- distributed_directory_monitor_sleep_time_ms
select value from system.metrics where metric = 'DistributedFilesToInsert';
select 'FLUSH DISTRIBUTED';
system stop distributed sends dist_01460;
insert into dist_01460 select * from system.one;
select sleep(1) format Null; -- distributed_directory_monitor_sleep_time_ms
select value from system.metrics where metric = 'DistributedFilesToInsert';
system flush distributed dist_01460;
select value from system.metrics where metric = 'DistributedFilesToInsert';
select 'DROP TABLE';
system stop distributed sends dist_01460;
insert into dist_01460 select * from system.one;
select sleep(1) format Null; -- distributed_directory_monitor_sleep_time_ms
select value from system.metrics where metric = 'DistributedFilesToInsert';
drop table dist_01460;
select value from system.metrics where metric = 'DistributedFilesToInsert';

View File

@ -0,0 +1,4 @@
$alias$name$
1
1alias1name1
1

View File

@ -0,0 +1,2 @@
SELECT 1 AS $alias$name$ FORMAT TSVWithNames;
SELECT 1 AS 1alias1name1 FORMAT TSVWithNames;

View File

@ -0,0 +1,4 @@
create table compression_codec_on_alias with CODEC on ALIAS type
create table compression_codec_on_alias with proper CODEC
alter table compression_codec_on_alias add column (ALIAS type) with CODEC
alter table compression_codec_on_alias add column (NOT ALIAS type) with CODEC

View File

@ -0,0 +1,25 @@
DROP TABLE IF EXISTS compression_codec_on_alias;
select 'create table compression_codec_on_alias with CODEC on ALIAS type';
CREATE TABLE compression_codec_on_alias (
`c0` ALIAS c1 CODEC(ZSTD),
c1 UInt64
) ENGINE = MergeTree() PARTITION BY c0 ORDER BY c1; -- { serverError 36 }
select 'create table compression_codec_on_alias with proper CODEC';
CREATE TABLE compression_codec_on_alias (
c0 UInt64 CODEC(ZSTD),
c1 UInt64
) ENGINE = MergeTree() PARTITION BY c0 ORDER BY c1; -- success
select 'alter table compression_codec_on_alias add column (ALIAS type) with CODEC';
ALTER TABLE compression_codec_on_alias ADD COLUMN `c3` ALIAS c2 CODEC(ZSTD) AFTER c2; -- { serverError 36 }
select 'alter table compression_codec_on_alias add column (NOT ALIAS type) with CODEC';
ALTER TABLE compression_codec_on_alias ADD COLUMN c2 UInt64 CODEC(ZSTD) AFTER c1; -- success
DROP TABLE IF EXISTS compression_codec_on_alias;

View File

@ -137,3 +137,4 @@
01411_bayesian_ab_testing
01455_time_zones
01456_ast_optimizations_over_distributed
01460_DistributedFilesToInsert

View File

@ -1,3 +1,4 @@
v20.7.2.30-stable 2020-08-31
v20.6.4.44-stable 2020-08-20
v20.6.3.28-stable 2020-08-07
v20.5.5.74-stable 2020-08-20

1 v20.6.4.44-stable v20.7.2.30-stable 2020-08-20 2020-08-31
1 v20.7.2.30-stable 2020-08-31
2 v20.6.4.44-stable v20.6.4.44-stable 2020-08-20 2020-08-20
3 v20.6.3.28-stable v20.6.3.28-stable 2020-08-07 2020-08-07
4 v20.5.5.74-stable v20.5.5.74-stable 2020-08-20 2020-08-20