mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
Merge branch 'master' into control-heavy-builds
This commit is contained in:
commit
8a3549ebd3
@ -1,7 +1,7 @@
|
||||
# docker build -t yandex/clickhouse-test-base .
|
||||
FROM ubuntu:19.10
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive LLVM_VERSION=10
|
||||
ENV DEBIAN_FRONTEND=noninteractive LLVM_VERSION=11
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install ca-certificates lsb-release wget gnupg apt-transport-https \
|
||||
@ -43,7 +43,6 @@ RUN apt-get update \
|
||||
llvm-${LLVM_VERSION} \
|
||||
moreutils \
|
||||
perl \
|
||||
perl \
|
||||
pigz \
|
||||
pkg-config \
|
||||
tzdata \
|
||||
|
@ -1,5 +1,5 @@
|
||||
# docker build -t yandex/clickhouse-integration-test .
|
||||
FROM ubuntu:19.10
|
||||
FROM yandex/clickhouse-test-base
|
||||
|
||||
RUN apt-get update \
|
||||
&& env DEBIAN_FRONTEND=noninteractive apt-get -y install \
|
||||
@ -8,7 +8,6 @@ RUN apt-get update \
|
||||
libreadline-dev \
|
||||
libicu-dev \
|
||||
bsdutils \
|
||||
llvm-9 \
|
||||
gdb \
|
||||
unixodbc \
|
||||
odbcinst \
|
||||
@ -29,9 +28,3 @@ RUN curl 'https://cdn.mysql.com//Downloads/Connector-ODBC/8.0/mysql-connector-od
|
||||
|
||||
ENV TZ=Europe/Moscow
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
# Sanitizer options
|
||||
RUN echo "TSAN_OPTIONS='verbosity=1000 halt_on_error=1 history_size=7'" >> /etc/environment; \
|
||||
echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment; \
|
||||
echo "MSAN_OPTIONS='abort_on_error=1'" >> /etc/environment; \
|
||||
ln -s /usr/lib/llvm-9/bin/llvm-symbolizer /usr/bin/llvm-symbolizer;
|
||||
|
@ -45,7 +45,7 @@ Action required for every item -- these are errors that must be fixed.
|
||||
|
||||
This table shows queries that take significantly longer to process on the client than on the server. A possible reason might be sending too much data to the client, e.g., a forgotten `format Null`.
|
||||
|
||||
#### Inconsistent Short Marking
|
||||
#### Unexpected Query Duration
|
||||
Action required for every item -- these are errors that must be fixed.
|
||||
|
||||
Queries that have "short" duration (on the order of 0.1 s) can't be reliably tested in a normal way, where we perform a small (about ten) measurements for each server, because the signal-to-noise ratio is much smaller. There is a special mode for such queries that instead runs them for a fixed amount of time, normally with much higher number of measurements (up to thousands). This mode must be explicitly enabled by the test author to avoid accidental errors. It must be used only for queries that are meant to complete "immediately", such as `select count(*)`. If your query is not supposed to be "immediate", try to make it run longer, by e.g. processing more data.
|
||||
|
@ -688,12 +688,13 @@ create view shortness
|
||||
-- Report of queries that have inconsistent 'short' markings:
|
||||
-- 1) have short duration, but are not marked as 'short'
|
||||
-- 2) the reverse -- marked 'short' but take too long.
|
||||
-- The threshold for 2) is twice the threshold for 1), to avoid jitter.
|
||||
-- The threshold for 2) is significantly larger than the threshold for 1), to
|
||||
-- avoid jitter.
|
||||
create table inconsistent_short_marking_report
|
||||
engine File(TSV, 'report/inconsistent-short-marking.tsv')
|
||||
engine File(TSV, 'report/unexpected-query-duration.tsv')
|
||||
as select
|
||||
multiIf(marked_short and time > 0.1, 'marked as short but is too long',
|
||||
not marked_short and time < 0.02, 'is short but not marked as such',
|
||||
multiIf(marked_short and time > 0.1, '"short" queries must run faster than 0.02 s',
|
||||
not marked_short and time < 0.02, '"normal" queries must run longer than 0.1 s',
|
||||
'') problem,
|
||||
marked_short, time,
|
||||
test, query_index, query_display_name
|
||||
|
@ -98,9 +98,9 @@ th {{
|
||||
|
||||
tr:nth-child(odd) td {{filter: brightness(90%);}}
|
||||
|
||||
.inconsistent-short-marking tr :nth-child(2),
|
||||
.inconsistent-short-marking tr :nth-child(3),
|
||||
.inconsistent-short-marking tr :nth-child(5),
|
||||
.unexpected-query-duration tr :nth-child(2),
|
||||
.unexpected-query-duration tr :nth-child(3),
|
||||
.unexpected-query-duration tr :nth-child(5),
|
||||
.all-query-times tr :nth-child(1),
|
||||
.all-query-times tr :nth-child(2),
|
||||
.all-query-times tr :nth-child(3),
|
||||
@ -325,13 +325,13 @@ if args.report == 'main':
|
||||
if slow_on_client_rows:
|
||||
errors_explained.append([f'<a href="#{currentTableAnchor()}">Some queries are taking noticeable time client-side (missing `FORMAT Null`?)</a>']);
|
||||
|
||||
unmarked_short_rows = tsvRows('report/inconsistent-short-marking.tsv')
|
||||
unmarked_short_rows = tsvRows('report/unexpected-query-duration.tsv')
|
||||
error_tests += len(unmarked_short_rows)
|
||||
addSimpleTable('Inconsistent Short Marking',
|
||||
['Problem', 'Is marked as short', 'New client time, s', 'Test', '#', 'Query'],
|
||||
addSimpleTable('Unexpected Query Duration',
|
||||
['Problem', 'Marked as "short"?', 'Run time, s', 'Test', '#', 'Query'],
|
||||
unmarked_short_rows)
|
||||
if unmarked_short_rows:
|
||||
errors_explained.append([f'<a href="#{currentTableAnchor()}">Some queries have inconsistent short marking</a>']);
|
||||
errors_explained.append([f'<a href="#{currentTableAnchor()}">Some queries have unexpected duration</a>']);
|
||||
|
||||
def add_partial():
|
||||
rows = tsvRows('report/partial-queries-report.tsv')
|
||||
|
@ -48,13 +48,6 @@ fi
|
||||
|
||||
ln -sf /usr/share/clickhouse-test/config/client_config.xml /etc/clickhouse-client/config.xml
|
||||
|
||||
echo "TSAN_OPTIONS='verbosity=1000 halt_on_error=1 history_size=7'" >> /etc/environment
|
||||
echo "TSAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment
|
||||
echo "ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
echo "UBSAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
echo "LLVM_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
|
||||
service zookeeper start
|
||||
sleep 5
|
||||
service clickhouse-server start && sleep 5
|
||||
|
@ -48,13 +48,6 @@ fi
|
||||
|
||||
ln -sf /usr/share/clickhouse-test/config/client_config.xml /etc/clickhouse-client/config.xml
|
||||
|
||||
echo "TSAN_OPTIONS='verbosity=1000 halt_on_error=1 history_size=7'" >> /etc/environment
|
||||
echo "TSAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment
|
||||
echo "ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
echo "UBSAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
echo "LLVM_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment
|
||||
|
||||
service zookeeper start
|
||||
sleep 5
|
||||
service clickhouse-server start && sleep 5
|
||||
|
@ -43,8 +43,6 @@ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/u
|
||||
ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/
|
||||
ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/
|
||||
|
||||
echo "TSAN_OPTIONS='halt_on_error=1 history_size=7 ignore_noninstrumented_modules=1 verbosity=1'" >> /etc/environment
|
||||
echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment
|
||||
echo "ASAN_OPTIONS='malloc_context_size=10 verbosity=1 allocator_release_to_os_interval_ms=10000'" >> /etc/environment
|
||||
|
||||
start
|
||||
|
@ -5,12 +5,5 @@ ENV TZ=Europe/Moscow
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
RUN apt-get install gdb
|
||||
|
||||
CMD ln -s /usr/lib/llvm-8/bin/llvm-symbolizer /usr/bin/llvm-symbolizer; \
|
||||
echo "TSAN_OPTIONS='halt_on_error=1 history_size=7'" >> /etc/environment; \
|
||||
echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment; \
|
||||
echo "ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-6.0/bin/llvm-symbolizer" >> /etc/environment; \
|
||||
echo "UBSAN_SYMBOLIZER_PATH=/usr/lib/llvm-6.0/bin/llvm-symbolizer" >> /etc/environment; \
|
||||
echo "TSAN_SYMBOLIZER_PATH=/usr/lib/llvm-8/bin/llvm-symbolizer" >> /etc/environment; \
|
||||
echo "LLVM_SYMBOLIZER_PATH=/usr/lib/llvm-6.0/bin/llvm-symbolizer" >> /etc/environment; \
|
||||
service zookeeper start && sleep 7 && /usr/share/zookeeper/bin/zkCli.sh -server localhost:2181 -create create /clickhouse_test ''; \
|
||||
CMD service zookeeper start && sleep 7 && /usr/share/zookeeper/bin/zkCli.sh -server localhost:2181 -create create /clickhouse_test ''; \
|
||||
gdb -q -ex 'set print inferior-events off' -ex 'set confirm off' -ex 'set print thread-events off' -ex run -ex bt -ex quit --args ./unit_tests_dbms | tee test_output/test_result.txt
|
||||
|
@ -521,6 +521,22 @@ For more information, see the MergeTreeSettings.h header file.
|
||||
</merge_tree>
|
||||
```
|
||||
|
||||
## replicated\_merge\_tree {#server_configuration_parameters-replicated_merge_tree}
|
||||
|
||||
Fine tuning for tables in the [ReplicatedMergeTree](../../engines/table-engines/mergetree-family/mergetree.md).
|
||||
|
||||
This setting has higher priority.
|
||||
|
||||
For more information, see the MergeTreeSettings.h header file.
|
||||
|
||||
**Example**
|
||||
|
||||
``` xml
|
||||
<replicated_merge_tree>
|
||||
<max_suspicious_broken_parts>5</max_suspicious_broken_parts>
|
||||
</replicated_merge_tree>
|
||||
```
|
||||
|
||||
## openSSL {#server_configuration_parameters-openssl}
|
||||
|
||||
SSL client/server configuration.
|
||||
|
@ -1817,7 +1817,7 @@ Default value: 8192.
|
||||
|
||||
Turns on or turns off using of single dictionary for the data part.
|
||||
|
||||
By default, ClickHouse server monitors the size of dictionaries and if a dictionary overflows then the server starts to write the next one. To prohibit creating several dictionaries set `low_cardinality_use_single_dictionary_for_part = 1`.
|
||||
By default, the ClickHouse server monitors the size of dictionaries and if a dictionary overflows then the server starts to write the next one. To prohibit creating several dictionaries set `low_cardinality_use_single_dictionary_for_part = 1`.
|
||||
|
||||
Possible values:
|
||||
|
||||
|
@ -21,7 +21,7 @@ LowCardinality(data_type)
|
||||
|
||||
`LowCardinality` is a superstructure that changes a data storage method and rules of data processing. ClickHouse applies [dictionary coding](https://en.wikipedia.org/wiki/Dictionary_coder) to `LowCardinality`-columns. Operating with dictionary encoded data significantly increases performance of [SELECT](../../sql-reference/statements/select/index.md) queries for many applications.
|
||||
|
||||
The efficiency of using `LowCarditality` data type depends on data diversity. If a dictionary contains less than 10,000 distinct values, then ClickHouse mostly shows higher efficiency of data reading and storing. If a dictionary contains more than 100,000 distinct values, then ClickHouse can perform worse in comparison with using ordinary data types.
|
||||
The efficiency of using `LowCardinality` data type depends on data diversity. If a dictionary contains less than 10,000 distinct values, then ClickHouse mostly shows higher efficiency of data reading and storing. If a dictionary contains more than 100,000 distinct values, then ClickHouse can perform worse in comparison with using ordinary data types.
|
||||
|
||||
Consider using `LowCardinality` instead of [Enum](../../sql-reference/data-types/enum.md) when working with strings. `LowCardinality` provides more flexibility in use and often reveals the same or higher efficiency.
|
||||
|
||||
|
@ -516,7 +516,7 @@ Result:
|
||||
|
||||
**See Also**
|
||||
|
||||
- \[ISO 8601 announcement by @xkcd\](https://xkcd.com/1179/)
|
||||
- [ISO 8601 announcement by @xkcd](https://xkcd.com/1179/)
|
||||
- [RFC 1123](https://tools.ietf.org/html/rfc1123)
|
||||
- [toDate](#todate)
|
||||
- [toDateTime](#todatetime)
|
||||
|
@ -6,4 +6,14 @@ toc_title: "\u041A\u043E\u043C\u043C\u0435\u0440\u0447\u0435\u0441\u043A\u0438\u
|
||||
\ \u0443\u0441\u043B\u0443\u0433\u0438"
|
||||
---
|
||||
|
||||
# Коммерческие услуги {#clickhouse-commercial-services}
|
||||
|
||||
Данный раздел содержит описание коммерческих услуг, предоставляемых для ClickHouse. Поставщики этих услуг — независимые компании, которые могут не быть аффилированы с Яндексом.
|
||||
|
||||
Категории услуг:
|
||||
|
||||
- Облачные услуги [Cloud](../commercial/cloud.md)
|
||||
- Поддержка [Support](../commercial/support.md)
|
||||
|
||||
!!! note "Для поставщиков услуг"
|
||||
Если вы — представитель компании-поставщика услуг, вы можете отправить запрос на добавление вашей компании и ваших услуг в соответствующий раздел данной документации (или на добавление нового раздела, если ваши услуги не соответствуют ни одной из существующих категорий). Чтобы отправить запрос (pull-request) на добавление описания в документацию, нажмите на значок "карандаша" в правом верхнем углу страницы. Если ваши услуги доступны в только отдельных регионах, не забудьте указать это на соответствующих локализованных страницах (и обязательно отметьте это при отправке заявки).
|
||||
|
@ -43,9 +43,6 @@ ORDER BY expr
|
||||
|
||||
Описание параметров смотрите в [описании запроса CREATE](../../../engines/table-engines/mergetree-family/mergetree.md).
|
||||
|
||||
!!! note "Примечание"
|
||||
`INDEX` — экспериментальная возможность, смотрите [Индексы пропуска данных](#table_engine-mergetree-data_skipping-indexes).
|
||||
|
||||
### Секции запроса {#mergetree-query-clauses}
|
||||
|
||||
- `ENGINE` — имя и параметры движка. `ENGINE = MergeTree()`. `MergeTree` не имеет параметров.
|
||||
@ -269,7 +266,7 @@ ClickHouse не может использовать индекс, если зн
|
||||
|
||||
ClickHouse использует эту логику не только для последовательностей дней месяца, но и для любого частично-монотонного первичного ключа.
|
||||
|
||||
### Индексы пропуска данных (экспериментальная функциональность) {#table_engine-mergetree-data_skipping-indexes}
|
||||
### Индексы пропуска данных {#table_engine-mergetree-data_skipping-indexes}
|
||||
|
||||
Объявление индексов при определении столбцов в запросе `CREATE`.
|
||||
|
||||
@ -566,7 +563,7 @@ ALTER TABLE example_table
|
||||
- `volume_name_N` — название тома. Названия томов должны быть уникальны.
|
||||
- `disk` — диск, находящийся внутри тома.
|
||||
- `max_data_part_size_bytes` — максимальный размер куска данных, который может находится на любом из дисков этого тома.
|
||||
- `move_factor` — доля свободного места, при превышении которого данные начинают перемещаться на следующий том, если он есть (по умолчанию 0.1).
|
||||
- `move_factor` — доля доступного свободного места на томе, если места становится меньше, то данные начнут перемещение на следующий том, если он есть (по умолчанию 0.1).
|
||||
|
||||
Примеры конфигураций:
|
||||
|
||||
|
@ -1050,13 +1050,13 @@ $ clickhouse-client --query="SELECT * FROM {some_table} FORMAT Parquet" > {some_
|
||||
|
||||
Для обмена данными с экосистемой Hadoop можно использовать движки таблиц [HDFS](../engines/table-engines/integrations/hdfs.md).
|
||||
|
||||
## Arrow {data-format-arrow}
|
||||
## Arrow {#data-format-arrow}
|
||||
|
||||
[Apache Arrow](https://arrow.apache.org/) поставляется с двумя встроенными поколоночнами форматами хранения. ClickHouse поддерживает операции чтения и записи для этих форматов.
|
||||
|
||||
`Arrow` — это Apache Arrow's "file mode" формат. Он предназначен для произвольного доступа в памяти.
|
||||
|
||||
## ArrowStream {data-format-arrow-stream}
|
||||
## ArrowStream {#data-format-arrow-stream}
|
||||
|
||||
`ArrowStream` — это Apache Arrow's "stream mode" формат. Он предназначен для обработки потоков в памяти.
|
||||
|
||||
|
@ -484,7 +484,7 @@ INSERT INTO test VALUES (lower('Hello')), (lower('world')), (lower('INSERT')), (
|
||||
|
||||
См. также:
|
||||
|
||||
- [JOIN strictness](../../sql-reference/statements/select/join.md#select-join-strictness)
|
||||
- [JOIN strictness](../../sql-reference/statements/select/join.md#join-settings)
|
||||
|
||||
## max\_block\_size {#setting-max_block_size}
|
||||
|
||||
@ -1616,6 +1616,63 @@ 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)
|
||||
|
||||
## low\_cardinality\_max\_dictionary\_size {#low_cardinality_max_dictionary_size}
|
||||
|
||||
Задает максимальный размер общего глобального словаря (в строках) для типа данных `LowCardinality`, который может быть записан в файловую систему хранилища. Настройка предотвращает проблемы с оперативной памятью в случае неограниченного увеличения словаря. Все данные, которые не могут быть закодированы из-за ограничения максимального размера словаря, ClickHouse записывает обычным способом.
|
||||
|
||||
Допустимые значения:
|
||||
|
||||
- Положительное целое число.
|
||||
|
||||
Значение по умолчанию: 8192.
|
||||
|
||||
## low\_cardinality\_use\_single\_dictionary\_for\_part {#low_cardinality_use_single_dictionary_for_part}
|
||||
|
||||
Включает или выключает использование единого словаря для куска (парта).
|
||||
|
||||
По умолчанию сервер ClickHouse следит за размером словарей, и если словарь переполняется, сервер создает следующий. Чтобы запретить создание нескольких словарей, задайте настройку `low_cardinality_use_single_dictionary_for_part = 1`.
|
||||
|
||||
Допустимые значения:
|
||||
|
||||
- 1 — Создание нескольких словарей для частей данных запрещено.
|
||||
- 0 — Создание нескольких словарей для частей данных не запрещено.
|
||||
|
||||
Значение по умолчанию: 0.
|
||||
|
||||
## low\_cardinality\_allow\_in\_native\_format {#low_cardinality_allow_in_native_format}
|
||||
|
||||
Разрешает или запрещает использование типа данных `LowCardinality` с форматом данных [Native](../../interfaces/formats.md#native).
|
||||
|
||||
Если использование типа `LowCardinality` ограничено, сервер CLickHouse преобразует столбцы `LowCardinality` в обычные столбцы для запросов `SELECT`, а обычные столбцы - в столбцы `LowCardinality` для запросов `INSERT`.
|
||||
|
||||
В основном настройка используется для сторонних клиентов, не поддерживающих тип данных `LowCardinality`.
|
||||
|
||||
Допустимые значения:
|
||||
|
||||
- 1 — Использование `LowCardinality` не ограничено.
|
||||
- 0 — Использование `LowCardinality` ограничено.
|
||||
|
||||
Значение по умолчанию: 1.
|
||||
|
||||
## allow\_suspicious\_low\_cardinality\_types {#allow_suspicious_low_cardinality_types}
|
||||
|
||||
Разрешает или запрещает использование типа данных `LowCardinality` с типами данных с фиксированным размером 8 байт или меньше: числовые типы данных и `FixedString (8_bytes_or_less)`.
|
||||
|
||||
Для небольших фиксированных значений использование `LowCardinality` обычно неэффективно, поскольку ClickHouse хранит числовой индекс для каждой строки. В результате:
|
||||
|
||||
- Используется больше дискового пространства.
|
||||
- Потребление ОЗУ увеличивается, в зависимости от размера словаря.
|
||||
- Некоторые функции работают медленнее из-за дополнительных операций кодирования.
|
||||
|
||||
Время слияния в таблицах на движке [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) также может увеличиться по описанным выше причинам.
|
||||
|
||||
Допустимые значения:
|
||||
|
||||
- 1 — Использование `LowCardinality` не ограничено.
|
||||
- 0 — Использование `LowCardinality` ограничено.
|
||||
|
||||
Значение по умолчанию: 0.
|
||||
|
||||
## background_buffer_flush_schedule_pool_size {#background_buffer_flush_schedule_pool_size}
|
||||
|
||||
Задает количество потоков для выполнения фонового сброса данных в таблицах с движком [Buffer](../../engines/table-engines/special/buffer.md). Настройка применяется при запуске сервера ClickHouse и не может быть изменена в пользовательском сеансе.
|
||||
|
@ -9,7 +9,7 @@
|
||||
- `volume_priority` ([UInt64](../../sql-reference/data-types/int-uint.md)) — порядковый номер тома согласно конфигурации.
|
||||
- `disks` ([Array(String)](../../sql-reference/data-types/array.md)) — имена дисков, содержащихся в политике хранения.
|
||||
- `max_data_part_size` ([UInt64](../../sql-reference/data-types/int-uint.md)) — максимальный размер куска данных, который может храниться на дисках тома (0 — без ограничений).
|
||||
- `move_factor` ([Float64](../../sql-reference/data-types/float.md))\` — доля свободного места, при превышении которой данные начинают перемещаться на следующий том.
|
||||
- `move_factor` — доля доступного свободного места на томе, если места становится меньше, то данные начнут перемещение на следующий том, если он есть (по умолчанию 0.1).
|
||||
|
||||
Если политика хранения содержит несколько томов, то каждому тому соответствует отдельная запись в таблице.
|
||||
|
||||
|
@ -24,13 +24,16 @@
|
||||
- [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-multiple-volumes)
|
||||
- [Distributed](../../engines/table-engines/special/distributed.md#distributed)
|
||||
|
||||
- `total_rows` (Nullable(UInt64)) - Общее количество строк, если есть возможность быстро определить точное количество строк в таблице, в противном случае `Null` (включая базовую таблицу `Buffer`).
|
||||
- `total_rows` (Nullable(UInt64)) - общее количество строк, если есть возможность быстро определить точное количество строк в таблице, в противном случае `Null` (включая базовую таблицу `Buffer`).
|
||||
|
||||
- `total_bytes` (Nullable(UInt64)) - Общее количество байт, если можно быстро определить точное количество байт для таблицы на накопителе, в противном случае `Null` (**не включает** в себя никакого базового хранилища).
|
||||
- `total_bytes` (Nullable(UInt64)) - общее количество байт, если можно быстро определить точное количество байт для таблицы на накопителе, в противном случае `Null` (**не включает** в себя никакого базового хранилища).
|
||||
|
||||
- Если таблица хранит данные на диске, возвращает используемое пространство на диске (т. е. сжатое).
|
||||
- Если таблица хранит данные в памяти, возвращает приблизительное количество используемых байт в памяти.
|
||||
|
||||
- `lifetime_rows` (Nullable(UInt64)) - общее количество строк, добавленных оператором `INSERT` с момента запуска сервера (только для таблиц `Buffer`).
|
||||
|
||||
- `lifetime_bytes` (Nullable(UInt64)) - общее количество байт, добавленных оператором `INSERT` с момента запуска сервера (только для таблиц `Buffer`).
|
||||
|
||||
Таблица `system.tables` используется при выполнении запроса `SHOW TABLES`.
|
||||
|
||||
|
@ -4,7 +4,7 @@ toc_priority: 128
|
||||
|
||||
# groupBitmap {#groupbitmap}
|
||||
|
||||
Bitmap или агрегатные вычисления для столбца с типом данных `UInt*`, возвращают кардинальность в виде значения типа UInt64, если добавить суффикс -State, то возвращают [объект bitmap](../../../sql-reference/functions/bitmap-functions.md).
|
||||
Bitmap или агрегатные вычисления для столбца с типом данных `UInt*`, возвращают кардинальность в виде значения типа UInt64, если добавить суффикс `-State`, то возвращают [объект bitmap](../../../sql-reference/functions/bitmap-functions.md#bitmap-functions).
|
||||
|
||||
``` sql
|
||||
groupBitmap(expr)
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
toc_priority: 53
|
||||
toc_title: AggregateFunction
|
||||
---
|
||||
|
||||
# AggregateFunction {#data-type-aggregatefunction}
|
||||
|
||||
Агрегатные функции могут обладать определяемым реализацией промежуточным состоянием, которое может быть сериализовано в тип данных, соответствующий AggregateFunction(…), и быть записано в таблицу обычно посредством [материализованного представления] (../../sql-reference/statements/create.md#create-view). Чтобы получить промежуточное состояние, обычно используются агрегатные функции с суффиксом `-State`. Чтобы в дальнейшем получить агрегированные данные необходимо использовать те же агрегатные функции с суффиксом `-Merge`.
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
toc_priority: 52
|
||||
toc_title: Array(T)
|
||||
---
|
||||
|
||||
# Array(T) {#data-type-array}
|
||||
|
||||
Массив из элементов типа `T`.
|
||||
|
59
docs/ru/sql-reference/data-types/lowcardinality.md
Normal file
59
docs/ru/sql-reference/data-types/lowcardinality.md
Normal file
@ -0,0 +1,59 @@
|
||||
---
|
||||
toc_priority: 51
|
||||
toc_title: LowCardinality
|
||||
---
|
||||
|
||||
# LowCardinality {#lowcardinality-data-type}
|
||||
|
||||
Изменяет внутреннее представление других типов данных, превращая их в тип со словарным кодированием.
|
||||
|
||||
## Синтаксис {#lowcardinality-syntax}
|
||||
|
||||
```sql
|
||||
LowCardinality(data_type)
|
||||
```
|
||||
|
||||
**Параметры**
|
||||
|
||||
- `data_type` — [String](string.md), [FixedString](fixedstring.md), [Date](date.md), [DateTime](datetime.md) и числа за исключением типа [Decimal](decimal.md). `LowCardinality` неэффективен для некоторых типов данных, см. описание настройки [allow_suspicious_low_cardinality_types](../../operations/settings/settings.md#allow_suspicious_low_cardinality_types).
|
||||
|
||||
## Описание {#lowcardinality-dscr}
|
||||
|
||||
`LowCardinality` — это надстройка, изменяющая способ хранения и правила обработки данных. ClickHouse применяет [словарное кодирование](https://en.wikipedia.org/wiki/Dictionary_coder) в столбцы типа `LowCardinality`. Работа с данными, представленными в словарном виде, может значительно увеличивать производительность запросов [SELECT](../statements/select/index.md) для многих приложений.
|
||||
|
||||
Эффективность использования типа данных `LowCarditality` зависит от разнообразия данных. Если словарь содержит менее 10 000 различных значений, ClickHouse в основном показывает более высокую эффективность чтения и хранения данных. Если же словарь содержит более 100 000 различных значений, ClickHouse может работать хуже, чем при использовании обычных типов данных.
|
||||
|
||||
При работе со строками, использование `LowCardinality` вместо [Enum](enum.md). `LowCardinality` обеспечивает большую гибкость в использовании и часто показывает такую же или более высокую эффективность.
|
||||
|
||||
## Пример
|
||||
|
||||
Создать таблицу со столбцами типа `LowCardinality`:
|
||||
|
||||
```sql
|
||||
CREATE TABLE lc_t
|
||||
(
|
||||
`id` UInt16,
|
||||
`strings` LowCardinality(String)
|
||||
)
|
||||
ENGINE = MergeTree()
|
||||
ORDER BY id
|
||||
```
|
||||
|
||||
## Связанные настройки и функции
|
||||
|
||||
Настройки:
|
||||
|
||||
- [low_cardinality_max_dictionary_size](../../operations/settings/settings.md#low_cardinality_max_dictionary_size)
|
||||
- [low_cardinality_use_single_dictionary_for_part](../../operations/settings/settings.md#low_cardinality_use_single_dictionary_for_part)
|
||||
- [low_cardinality_allow_in_native_format](../../operations/settings/settings.md#low_cardinality_allow_in_native_format)
|
||||
- [allow_suspicious_low_cardinality_types](../../operations/settings/settings.md#allow_suspicious_low_cardinality_types)
|
||||
|
||||
Функции:
|
||||
|
||||
- [toLowCardinality](../functions/type-conversion-functions.md#tolowcardinality)
|
||||
|
||||
## Смотрите также
|
||||
|
||||
- [A Magical Mystery Tour of the LowCardinality Data Type](https://www.altinity.com/blog/2019/3/27/low-cardinality).
|
||||
- [Reducing Clickhouse Storage Cost with the Low Cardinality Type – Lessons from an Instana Engineer](https://www.instana.com/blog/reducing-clickhouse-storage-cost-with-the-low-cardinality-type-lessons-from-an-instana-engineer/).
|
||||
- [String Optimization (video presentation in Russian)](https://youtu.be/rqf-ILRgBdY?list=PL0Z2YDlm0b3iwXCpEFiOOYmwXzVmjJfEt). [Slides in English](https://github.com/yandex/clickhouse-presentations/raw/master/meetup19/string_optimization.pdf).
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
toc_priority: 55
|
||||
toc_title: Nullable
|
||||
---
|
||||
|
||||
# Nullable(TypeName) {#data_type-nullable}
|
||||
|
||||
Позволяет работать как со значением типа `TypeName` так и с отсутствием этого значения ([NULL](../../sql-reference/data-types/nullable.md)) в одной и той же переменной, в том числе хранить `NULL` в таблицах вместе со значения типа `TypeName`. Например, в столбце типа `Nullable(Int8)` можно хранить значения типа `Int8`, а в тех строках, где значения нет, будет храниться `NULL`.
|
||||
|
@ -1,3 +1,8 @@
|
||||
---
|
||||
toc_priority: 54
|
||||
toc_title: Tuple(T1, T2, ...)
|
||||
---
|
||||
|
||||
# Tuple(T1, T2, …) {#tuplet1-t2}
|
||||
|
||||
Кортеж из элементов любого [типа](index.md#data_types). Элементы кортежа могут быть одного или разных типов.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Функции для битмапов {#funktsii-dlia-bitmapov}
|
||||
# Функции для битмапов {#bitmap-functions}
|
||||
|
||||
## bitmapBuild {#bitmap_functions-bitmapbuild}
|
||||
|
||||
@ -61,8 +61,8 @@ bitmapSubsetLimit(bitmap, range_start, cardinality_limit)
|
||||
**Параметры**
|
||||
|
||||
- `bitmap` – Битмап. [Bitmap object](#bitmap_functions-bitmapbuild).
|
||||
- `range_start` – Начальная точка подмножества. [UInt32](../../sql-reference/functions/bitmap-functions.md).
|
||||
- `cardinality_limit` – Верхний предел подмножества. [UInt32](../../sql-reference/functions/bitmap-functions.md).
|
||||
- `range_start` – Начальная точка подмножества. [UInt32](../../sql-reference/functions/bitmap-functions.md#bitmap-functions).
|
||||
- `cardinality_limit` – Верхний предел подмножества. [UInt32](../../sql-reference/functions/bitmap-functions.md#bitmap-functions).
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
@ -97,7 +97,7 @@ bitmapContains(haystack, needle)
|
||||
**Параметры**
|
||||
|
||||
- `haystack` – [объект Bitmap](#bitmap_functions-bitmapbuild), в котором функция ищет значение.
|
||||
- `needle` – значение, которое функция ищет. Тип — [UInt32](../../sql-reference/functions/bitmap-functions.md).
|
||||
- `needle` – значение, которое функция ищет. Тип — [UInt32](../../sql-reference/functions/bitmap-functions.md#bitmap-functions).
|
||||
|
||||
**Возвращаемые значения**
|
||||
|
||||
|
@ -100,5 +100,6 @@ FROM numbers(3)
|
||||
│ a*cjab+ │
|
||||
│ aeca2A │
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
|
||||
[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/functions/random_functions/) <!--hide-->
|
||||
|
@ -508,7 +508,7 @@ SELECT parseDateTimeBestEffort('10 20:19')
|
||||
|
||||
**См. также**
|
||||
|
||||
- \[Информация о формате ISO 8601 от @xkcd\](https://xkcd.com/1179/)
|
||||
- [Информация о формате ISO 8601 от @xkcd](https://xkcd.com/1179/)
|
||||
- [RFC 1123](https://tools.ietf.org/html/rfc1123)
|
||||
- [toDate](#todate)
|
||||
- [toDateTime](#todatetime)
|
||||
@ -678,4 +678,43 @@ SELECT fromUnixTimestamp64Milli(i64, 'UTC')
|
||||
└──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## toLowCardinality {#tolowcardinality}
|
||||
|
||||
Преобразует входные данные в версию [LowCardianlity](../data-types/lowcardinality.md) того же типа данных.
|
||||
|
||||
Чтобы преобразовать данные из типа `LowCardinality`, используйте функцию [CAST](#type_conversion_function-cast). Например, `CAST(x as String)`.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
```sql
|
||||
toLowCardinality(expr)
|
||||
```
|
||||
|
||||
**Параметры**
|
||||
|
||||
- `expr` — [Выражение](../syntax.md#syntax-expressions), которое в результате преобразуется в один из [поддерживаемых типов данных](../data-types/index.md#data_types).
|
||||
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- Результат преобразования `expr`.
|
||||
|
||||
Тип: `LowCardinality(expr_result_type)`
|
||||
|
||||
**Example**
|
||||
|
||||
Запрос:
|
||||
|
||||
```sql
|
||||
SELECT toLowCardinality('1')
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
```text
|
||||
┌─toLowCardinality('1')─┐
|
||||
│ 1 │
|
||||
└───────────────────────┘
|
||||
```
|
||||
|
||||
[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/functions/type_conversion_functions/) <!--hide-->
|
||||
|
@ -3,4 +3,28 @@ toc_folder_title: "\u0412\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u044F"
|
||||
toc_priority: 31
|
||||
---
|
||||
|
||||
# SQL выражения в ClickHouse {#clickhouse-sql-statements}
|
||||
|
||||
Выражения описывают различные действия, которые можно выполнить с помощью SQL запросов. Каждый вид выражения имеет свой синтаксис и особенности использования, которые описаны в соответствующих разделах документации:
|
||||
|
||||
- [SELECT](../../sql-reference/statements/select/index.md)
|
||||
- [INSERT INTO](../../sql-reference/statements/insert-into.md)
|
||||
- [CREATE](../../sql-reference/statements/create/index.md)
|
||||
- [ALTER](../../sql-reference/statements/alter/index.md)
|
||||
- [SYSTEM](../../sql-reference/statements/system.md)
|
||||
- [SHOW](../../sql-reference/statements/show.md)
|
||||
- [GRANT](../../sql-reference/statements/grant.md)
|
||||
- [REVOKE](../../sql-reference/statements/revoke.md)
|
||||
- [ATTACH](../../sql-reference/statements/attach.md)
|
||||
- [CHECK TABLE](../../sql-reference/statements/check-table.md)
|
||||
- [DESCRIBE TABLE](../../sql-reference/statements/describe-table.md)
|
||||
- [DETACH](../../sql-reference/statements/detach.md)
|
||||
- [DROP](../../sql-reference/statements/drop.md)
|
||||
- [EXISTS](../../sql-reference/statements/exists.md)
|
||||
- [KILL](../../sql-reference/statements/kill.md)
|
||||
- [OPTIMIZE](../../sql-reference/statements/optimize.md)
|
||||
- [RENAME](../../sql-reference/statements/rename.md)
|
||||
- [SET](../../sql-reference/statements/set.md)
|
||||
- [SET ROLE](../../sql-reference/statements/set-role.md)
|
||||
- [TRUNCATE](../../sql-reference/statements/truncate.md)
|
||||
- [USE](../../sql-reference/statements/use.md)
|
||||
|
@ -92,7 +92,7 @@ def test_single_page(input_path, lang):
|
||||
logging.warning('Found %d duplicate anchor points' % duplicate_anchor_points)
|
||||
|
||||
if links_to_nowhere:
|
||||
if lang == 'en': # TODO: check all languages again
|
||||
if lang == 'en' or lang == 'ru': # TODO: check all languages again
|
||||
logging.error(f'Found {links_to_nowhere} links to nowhere in {lang}')
|
||||
sys.exit(1)
|
||||
else:
|
||||
|
@ -629,6 +629,7 @@ int Server::main(const std::vector<std::string> & /*args*/)
|
||||
|
||||
/// Check sanity of MergeTreeSettings on server startup
|
||||
global_context->getMergeTreeSettings().sanityCheck(settings);
|
||||
global_context->getReplicatedMergeTreeSettings().sanityCheck(settings);
|
||||
|
||||
/// Limit on total memory usage
|
||||
size_t max_server_memory_usage = config().getUInt64("max_server_memory_usage", 0);
|
||||
|
@ -19,12 +19,12 @@ struct ConstSource;
|
||||
|
||||
using NumericArraySources = typename TypeListMap<NumericArraySource, TypeListNumbersAndUInt128>::Type;
|
||||
using BasicArraySources = typename AppendToTypeList<GenericArraySource, NumericArraySources>::Type;
|
||||
using NullableArraySources = typename TypeListMap<NullableArraySource, BasicArraySources>::Type;
|
||||
using BasicAndNullableArraySources = typename TypeListConcat<BasicArraySources, NullableArraySources>::Type;
|
||||
using ConstArraySources = typename TypeListMap<ConstSource, BasicAndNullableArraySources>::Type;
|
||||
using TypeListArraySources = typename TypeListConcat<BasicAndNullableArraySources, ConstArraySources>::Type;
|
||||
//using NullableArraySources = typename TypeListMap<NullableArraySource, BasicArraySources>::Type;
|
||||
//using BasicAndNullableArraySources = typename TypeListConcat<BasicArraySources, NullableArraySources>::Type;
|
||||
//using ConstArraySources = typename TypeListMap<ConstSource, BasicAndNullableArraySources>::Type;
|
||||
//using TypeListArraySources = typename TypeListConcat<BasicAndNullableArraySources, ConstArraySources>::Type;
|
||||
|
||||
class ArraySourceVisitor : public ApplyTypeListForClass<Visitor, TypeListArraySources>::Type
|
||||
class ArraySourceVisitor : public ApplyTypeListForClass<Visitor, BasicArraySources>::Type
|
||||
{
|
||||
protected:
|
||||
~ArraySourceVisitor() = default;
|
||||
|
@ -13,7 +13,6 @@ namespace ErrorCodes
|
||||
|
||||
namespace GatherUtils
|
||||
{
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
struct IArraySink
|
||||
{
|
||||
@ -25,6 +24,8 @@ struct IArraySink
|
||||
}
|
||||
};
|
||||
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
template <typename Derived>
|
||||
class ArraySinkImpl : public Visitable<Derived, IArraySink, ArraySinkVisitor> {};
|
||||
|
||||
|
@ -13,7 +13,6 @@ namespace ErrorCodes
|
||||
|
||||
namespace GatherUtils
|
||||
{
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
struct IArraySource
|
||||
{
|
||||
@ -31,6 +30,8 @@ struct IArraySource
|
||||
}
|
||||
};
|
||||
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
template <typename Derived>
|
||||
class ArraySourceImpl : public Visitable<Derived, IArraySource, ArraySourceVisitor> {};
|
||||
|
||||
|
@ -13,7 +13,6 @@ namespace ErrorCodes
|
||||
|
||||
namespace GatherUtils
|
||||
{
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
struct IValueSource
|
||||
{
|
||||
@ -27,6 +26,8 @@ struct IValueSource
|
||||
virtual bool isConst() const { return false; }
|
||||
};
|
||||
|
||||
#pragma GCC visibility push(hidden)
|
||||
|
||||
template <typename Derived>
|
||||
class ValueSourceImpl : public Visitable<Derived, IValueSource, ValueSourceVisitor> {};
|
||||
|
||||
|
@ -32,20 +32,30 @@ void callSelectMemberFunctionWithTupleArgument(Tuple & tuple, Args && ... args)
|
||||
callSelectMemberFunctionWithTupleArgument<Base, Tuple, index + 1>(tuple, args ..., std::get<index>(tuple));
|
||||
}
|
||||
|
||||
template <typename Base, typename Tuple, int index, typename ... Args>
|
||||
void callSelectSource(bool is_const, bool is_nullable, Tuple & tuple, Args && ... args)
|
||||
{
|
||||
if constexpr (index == std::tuple_size<Tuple>::value)
|
||||
Base::selectSource(is_const, is_nullable, args ...);
|
||||
else
|
||||
callSelectSource<Base, Tuple, index + 1>(is_const, is_nullable, tuple, args ..., std::get<index>(tuple));
|
||||
}
|
||||
|
||||
template <typename Base, typename ... Args>
|
||||
struct ArraySourceSelectorVisitor final : public ArraySourceVisitorImpl<ArraySourceSelectorVisitor<Base, Args ...>>
|
||||
{
|
||||
explicit ArraySourceSelectorVisitor(Args && ... args) : packed_args(args ...) {}
|
||||
explicit ArraySourceSelectorVisitor(IArraySource & source, Args && ... args) : packed_args(args ...), array_source(source) {}
|
||||
|
||||
using Tuple = std::tuple<Args && ...>;
|
||||
|
||||
template <typename Source>
|
||||
void visitImpl(Source & source)
|
||||
{
|
||||
callSelectMemberFunctionWithTupleArgument<Base, Tuple, 0>(packed_args, source);
|
||||
callSelectSource<Base, Tuple, 0>(array_source.isConst(), array_source.isNullable(), packed_args, source);
|
||||
}
|
||||
|
||||
Tuple packed_args;
|
||||
IArraySource & array_source;
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
@ -54,7 +64,7 @@ struct ArraySourceSelector
|
||||
template <typename ... Args>
|
||||
static void select(IArraySource & source, Args && ... args)
|
||||
{
|
||||
ArraySourceSelectorVisitor<Base, Args ...> visitor(args ...);
|
||||
ArraySourceSelectorVisitor<Base, Args ...> visitor(source, args ...);
|
||||
source.accept(visitor);
|
||||
}
|
||||
};
|
||||
@ -87,56 +97,6 @@ struct ArraySinkSelector
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Base, typename ... Args>
|
||||
struct ValueSourceSelectorVisitor final : public ValueSourceVisitorImpl<ValueSourceSelectorVisitor<Base, Args ...>>
|
||||
{
|
||||
explicit ValueSourceSelectorVisitor(Args && ... args) : packed_args(args ...) {}
|
||||
|
||||
using Tuple = std::tuple<Args && ...>;
|
||||
|
||||
template <typename Source>
|
||||
void visitImpl(Source & source)
|
||||
{
|
||||
callSelectMemberFunctionWithTupleArgument<Base, Tuple, 0>(packed_args, source);
|
||||
}
|
||||
|
||||
Tuple packed_args;
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
struct ValueSourceSelector
|
||||
{
|
||||
template <typename ... Args>
|
||||
static void select(IValueSource & source, Args && ... args)
|
||||
{
|
||||
ValueSourceSelectorVisitor<Base, Args ...> visitor(args ...);
|
||||
source.accept(visitor);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
struct ArraySinkSourceSelector
|
||||
{
|
||||
template <typename ... Args>
|
||||
static void select(IArraySource & source, IArraySink & sink, Args && ... args)
|
||||
{
|
||||
ArraySinkSelector<Base>::select(sink, source, args ...);
|
||||
}
|
||||
|
||||
template <typename Sink, typename ... Args>
|
||||
static void selectImpl(Sink && sink, IArraySource & source, Args && ... args)
|
||||
{
|
||||
ArraySourceSelector<Base>::select(source, sink, args ...);
|
||||
}
|
||||
|
||||
template <typename Source, typename Sink, typename ... Args>
|
||||
static void selectImpl(Source && source, Sink && sink, Args && ... args)
|
||||
{
|
||||
Base::selectSourceSink(source, sink, args ...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
struct ArraySourcePairSelector
|
||||
{
|
||||
@ -147,15 +107,17 @@ struct ArraySourcePairSelector
|
||||
}
|
||||
|
||||
template <typename FirstSource, typename ... Args>
|
||||
static void selectImpl(FirstSource && first, IArraySource & second, Args && ... args)
|
||||
static void selectSource(bool is_const, bool is_nullable, FirstSource && first, IArraySource & second, Args && ... args)
|
||||
{
|
||||
ArraySourceSelector<Base>::select(second, first, args ...);
|
||||
ArraySourceSelector<Base>::select(second, is_const, is_nullable, first, args ...);
|
||||
}
|
||||
|
||||
template <typename SecondSource, typename FirstSource, typename ... Args>
|
||||
static void selectImpl(SecondSource && second, FirstSource && first, Args && ... args)
|
||||
static void selectSource(bool is_second_const, bool is_second_nullable, SecondSource && second,
|
||||
bool is_first_const, bool is_first_nullable, FirstSource && first, Args && ... args)
|
||||
{
|
||||
Base::selectSourcePair(first, second, args ...);
|
||||
Base::selectSourcePair(is_first_const, is_first_nullable, first,
|
||||
is_second_const, is_second_nullable, second, args ...);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23,37 +23,54 @@ struct ArrayConcat : public ArraySourceSelector<ArrayConcat>
|
||||
{
|
||||
using Sources = std::vector<std::unique_ptr<IArraySource>>;
|
||||
|
||||
// template <typename Source>
|
||||
// static void selectSource(Source && source, const Sources & sources, ColumnArray::MutablePtr & result)
|
||||
// {
|
||||
// using SourceType = typename std::decay<Source>::type;
|
||||
// using Sink = typename SourceType::SinkType;
|
||||
// result = ColumnArray::create(source.createValuesColumn());
|
||||
// Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
//
|
||||
// concat<SourceType, Sink>(sources, std::move(sink));
|
||||
// }
|
||||
//
|
||||
// template <typename Source>
|
||||
// static void selectImpl(ConstSource<Source> && source, const Sources & sources, ColumnArray::MutablePtr & result)
|
||||
// {
|
||||
// using SourceType = typename std::decay<Source>::type;
|
||||
// using Sink = typename SourceType::SinkType;
|
||||
// result = ColumnArray::create(source.createValuesColumn());
|
||||
// Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
//
|
||||
// concat<SourceType, Sink>(sources, std::move(sink));
|
||||
// }
|
||||
|
||||
template <typename Source>
|
||||
static void selectImpl(Source && source, const Sources & sources, ColumnArray::MutablePtr & result)
|
||||
static void selectSource(bool /*is_const*/, bool is_nullable, Source & source, const Sources & sources, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
concat<SourceType, Sink>(sources, std::move(sink));
|
||||
}
|
||||
if (is_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
using NullableSink = typename NullableSource::SinkType;
|
||||
|
||||
template <typename Source>
|
||||
static void selectImpl(ConstSource<Source> && source, const Sources & sources, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
auto & nullable_source = static_cast<NullableSource &>(source);
|
||||
|
||||
concat<SourceType, Sink>(sources, std::move(sink));
|
||||
}
|
||||
|
||||
template <typename Source>
|
||||
static void selectImpl(ConstSource<Source> & source, const Sources & sources, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
result = ColumnArray::create(nullable_source.createValuesColumn());
|
||||
NullableSink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
concat<SourceType, Sink>(sources, std::move(sink));
|
||||
concat<NullableSource, NullableSink>(sources, std::move(sink));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
concat<SourceType, Sink>(sources, std::move(sink));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,9 +11,53 @@ namespace
|
||||
struct ArrayHasAllSelectArraySourcePair : public ArraySourcePairSelector<ArrayHasAllSelectArraySourcePair>
|
||||
{
|
||||
template <typename FirstSource, typename SecondSource>
|
||||
static void selectSourcePair(FirstSource && first, SecondSource && second, ColumnUInt8 & result)
|
||||
static void callFunction(FirstSource && first,
|
||||
bool is_second_const, bool is_second_nullable, SecondSource && second,
|
||||
ColumnUInt8 & result)
|
||||
{
|
||||
arrayAllAny<ArraySearchType::All>(first, second, result);
|
||||
using SourceType = typename std::decay<SecondSource>::type;
|
||||
|
||||
if (is_second_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
|
||||
if (is_second_const)
|
||||
arrayAllAny<ArraySearchType::All>(first, static_cast<ConstSource<NullableSource> &>(second), result);
|
||||
else
|
||||
arrayAllAny<ArraySearchType::All>(first, static_cast<NullableSource &>(second), result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_second_const)
|
||||
arrayAllAny<ArraySearchType::All>(first, static_cast<ConstSource<SourceType> &>(second), result);
|
||||
else
|
||||
arrayAllAny<ArraySearchType::All>(first, second, result);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FirstSource, typename SecondSource>
|
||||
static void selectSourcePair(bool is_first_const, bool is_first_nullable, FirstSource && first,
|
||||
bool is_second_const, bool is_second_nullable, SecondSource && second,
|
||||
ColumnUInt8 & result)
|
||||
{
|
||||
using SourceType = typename std::decay<FirstSource>::type;
|
||||
|
||||
if (is_first_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
|
||||
if (is_first_const)
|
||||
callFunction(static_cast<ConstSource<NullableSource> &>(first), is_second_const, is_second_nullable, second, result);
|
||||
else
|
||||
callFunction(static_cast<NullableSource &>(first), is_second_const, is_second_nullable, second, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_first_const)
|
||||
callFunction(static_cast<ConstSource<SourceType> &>(first), is_second_const, is_second_nullable, second, result);
|
||||
else
|
||||
callFunction(first, is_second_const, is_second_nullable, second, result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,9 +11,53 @@ namespace
|
||||
struct ArrayHasAnySelectArraySourcePair : public ArraySourcePairSelector<ArrayHasAnySelectArraySourcePair>
|
||||
{
|
||||
template <typename FirstSource, typename SecondSource>
|
||||
static void selectSourcePair(FirstSource && first, SecondSource && second, ColumnUInt8 & result)
|
||||
static void callFunction(FirstSource && first,
|
||||
bool is_second_const, bool is_second_nullable, SecondSource && second,
|
||||
ColumnUInt8 & result)
|
||||
{
|
||||
arrayAllAny<ArraySearchType::Any>(first, second, result);
|
||||
using SourceType = typename std::decay<SecondSource>::type;
|
||||
|
||||
if (is_second_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
|
||||
if (is_second_const)
|
||||
arrayAllAny<ArraySearchType::Any>(first, static_cast<ConstSource<NullableSource> &>(second), result);
|
||||
else
|
||||
arrayAllAny<ArraySearchType::Any>(first, static_cast<NullableSource &>(second), result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_second_const)
|
||||
arrayAllAny<ArraySearchType::Any>(first, static_cast<ConstSource<SourceType> &>(second), result);
|
||||
else
|
||||
arrayAllAny<ArraySearchType::Any>(first, second, result);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FirstSource, typename SecondSource>
|
||||
static void selectSourcePair(bool is_first_const, bool is_first_nullable, FirstSource && first,
|
||||
bool is_second_const, bool is_second_nullable, SecondSource && second,
|
||||
ColumnUInt8 & result)
|
||||
{
|
||||
using SourceType = typename std::decay<FirstSource>::type;
|
||||
|
||||
if (is_first_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
|
||||
if (is_first_const)
|
||||
callFunction(static_cast<ConstSource<NullableSource> &>(first), is_second_const, is_second_nullable, second, result);
|
||||
else
|
||||
callFunction(static_cast<NullableSource &>(first), is_second_const, is_second_nullable, second, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_first_const)
|
||||
callFunction(static_cast<ConstSource<SourceType> &>(first), is_second_const, is_second_nullable, second, result);
|
||||
else
|
||||
callFunction(first, is_second_const, is_second_nullable, second, result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,9 +11,53 @@ namespace
|
||||
struct ArrayHasSubstrSelectArraySourcePair : public ArraySourcePairSelector<ArrayHasSubstrSelectArraySourcePair>
|
||||
{
|
||||
template <typename FirstSource, typename SecondSource>
|
||||
static void selectSourcePair(FirstSource && first, SecondSource && second, ColumnUInt8 & result)
|
||||
static void callFunction(FirstSource && first,
|
||||
bool is_second_const, bool is_second_nullable, SecondSource && second,
|
||||
ColumnUInt8 & result)
|
||||
{
|
||||
arrayAllAny<ArraySearchType::Substr>(first, second, result);
|
||||
using SourceType = typename std::decay<SecondSource>::type;
|
||||
|
||||
if (is_second_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
|
||||
if (is_second_const)
|
||||
arrayAllAny<ArraySearchType::Substr>(first, static_cast<ConstSource<NullableSource> &>(second), result);
|
||||
else
|
||||
arrayAllAny<ArraySearchType::Substr>(first, static_cast<NullableSource &>(second), result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_second_const)
|
||||
arrayAllAny<ArraySearchType::Substr>(first, static_cast<ConstSource<SourceType> &>(second), result);
|
||||
else
|
||||
arrayAllAny<ArraySearchType::Substr>(first, second, result);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FirstSource, typename SecondSource>
|
||||
static void selectSourcePair(bool is_first_const, bool is_first_nullable, FirstSource && first,
|
||||
bool is_second_const, bool is_second_nullable, SecondSource && second,
|
||||
ColumnUInt8 & result)
|
||||
{
|
||||
using SourceType = typename std::decay<FirstSource>::type;
|
||||
|
||||
if (is_first_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
|
||||
if (is_first_const)
|
||||
callFunction(static_cast<ConstSource<NullableSource> &>(first), is_second_const, is_second_nullable, second, result);
|
||||
else
|
||||
callFunction(static_cast<NullableSource &>(first), is_second_const, is_second_nullable, second, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_first_const)
|
||||
callFunction(static_cast<ConstSource<SourceType> &>(first), is_second_const, is_second_nullable, second, result);
|
||||
else
|
||||
callFunction(first, is_second_const, is_second_nullable, second, result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,13 +13,37 @@ namespace
|
||||
struct SliceDynamicOffsetBoundedSelectArraySource : public ArraySourceSelector<SliceDynamicOffsetBoundedSelectArraySource>
|
||||
{
|
||||
template <typename Source>
|
||||
static void selectImpl(Source && source, const IColumn & offset_column, const IColumn & length_column, ColumnArray::MutablePtr & result)
|
||||
static void selectSource(bool is_const, bool is_nullable, Source && source,
|
||||
const IColumn & offset_column, const IColumn & length_column, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
sliceDynamicOffsetBounded(source, sink, offset_column, length_column);
|
||||
|
||||
if (is_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
using NullableSink = typename NullableSource::SinkType;
|
||||
|
||||
auto & nullable_source = static_cast<NullableSource &>(source);
|
||||
|
||||
result = ColumnArray::create(nullable_source.createValuesColumn());
|
||||
NullableSink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceDynamicOffsetBounded(static_cast<ConstSource<NullableSource> &>(source), sink, offset_column, length_column);
|
||||
else
|
||||
sliceDynamicOffsetBounded(static_cast<NullableSource &>(source), sink, offset_column, length_column);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceDynamicOffsetBounded(static_cast<ConstSource<SourceType> &>(source), sink, offset_column, length_column);
|
||||
else
|
||||
sliceDynamicOffsetBounded(source, sink, offset_column, length_column);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,13 +14,36 @@ struct SliceDynamicOffsetUnboundedSelectArraySource
|
||||
: public ArraySourceSelector<SliceDynamicOffsetUnboundedSelectArraySource>
|
||||
{
|
||||
template <typename Source>
|
||||
static void selectImpl(Source && source, const IColumn & offset_column, ColumnArray::MutablePtr & result)
|
||||
static void selectSource(bool is_const, bool is_nullable, Source && source, const IColumn & offset_column, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
sliceDynamicOffsetUnbounded(source, sink, offset_column);
|
||||
|
||||
if (is_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
using NullableSink = typename NullableSource::SinkType;
|
||||
|
||||
auto & nullable_source = static_cast<NullableSource &>(source);
|
||||
|
||||
result = ColumnArray::create(nullable_source.createValuesColumn());
|
||||
NullableSink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceDynamicOffsetUnbounded(static_cast<ConstSource<NullableSource> &>(source), sink, offset_column);
|
||||
else
|
||||
sliceDynamicOffsetUnbounded(static_cast<NullableSource &>(source), sink, offset_column);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceDynamicOffsetUnbounded(static_cast<ConstSource<SourceType> &>(source), sink, offset_column);
|
||||
else
|
||||
sliceDynamicOffsetUnbounded(source, sink, offset_column);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,13 +14,36 @@ struct SliceFromLeftConstantOffsetBoundedSelectArraySource
|
||||
: public ArraySourceSelector<SliceFromLeftConstantOffsetBoundedSelectArraySource>
|
||||
{
|
||||
template <typename Source>
|
||||
static void selectImpl(Source && source, size_t & offset, ssize_t & length, ColumnArray::MutablePtr & result)
|
||||
static void selectSource(bool is_const, bool is_nullable, Source && source, size_t & offset, ssize_t & length, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
sliceFromLeftConstantOffsetBounded(source, sink, offset, length);
|
||||
|
||||
if (is_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
using NullableSink = typename NullableSource::SinkType;
|
||||
|
||||
auto & nullable_source = static_cast<NullableSource &>(source);
|
||||
|
||||
result = ColumnArray::create(nullable_source.createValuesColumn());
|
||||
NullableSink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromLeftConstantOffsetBounded(static_cast<ConstSource<NullableSource> &>(source), sink, offset, length);
|
||||
else
|
||||
sliceFromLeftConstantOffsetBounded(static_cast<NullableSource &>(source), sink, offset, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromLeftConstantOffsetBounded(static_cast<ConstSource<SourceType> &>(source), sink, offset, length);
|
||||
else
|
||||
sliceFromLeftConstantOffsetBounded(source, sink, offset, length);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,13 +14,36 @@ struct SliceFromLeftConstantOffsetUnboundedSelectArraySource
|
||||
: public ArraySourceSelector<SliceFromLeftConstantOffsetUnboundedSelectArraySource>
|
||||
{
|
||||
template <typename Source>
|
||||
static void selectImpl(Source && source, size_t & offset, ColumnArray::MutablePtr & result)
|
||||
static void selectSource(bool is_const, bool is_nullable, Source && source, size_t & offset, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
sliceFromLeftConstantOffsetUnbounded(source, sink, offset);
|
||||
|
||||
if (is_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
using NullableSink = typename NullableSource::SinkType;
|
||||
|
||||
auto & nullable_source = static_cast<NullableSource &>(source);
|
||||
|
||||
result = ColumnArray::create(nullable_source.createValuesColumn());
|
||||
NullableSink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromLeftConstantOffsetUnbounded(static_cast<ConstSource<NullableSource> &>(source), sink, offset);
|
||||
else
|
||||
sliceFromLeftConstantOffsetUnbounded(static_cast<NullableSource &>(source), sink, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromLeftConstantOffsetUnbounded(static_cast<ConstSource<SourceType> &>(source), sink, offset);
|
||||
else
|
||||
sliceFromLeftConstantOffsetUnbounded(source, sink, offset);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,13 +14,36 @@ struct SliceFromRightConstantOffsetBoundedSelectArraySource
|
||||
: public ArraySourceSelector<SliceFromRightConstantOffsetBoundedSelectArraySource>
|
||||
{
|
||||
template <typename Source>
|
||||
static void selectImpl(Source && source, size_t & offset, ssize_t & length, ColumnArray::MutablePtr & result)
|
||||
static void selectSource(bool is_const, bool is_nullable, Source && source, size_t & offset, ssize_t & length, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
sliceFromRightConstantOffsetBounded(source, sink, offset, length);
|
||||
|
||||
if (is_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
using NullableSink = typename NullableSource::SinkType;
|
||||
|
||||
auto & nullable_source = static_cast<NullableSource &>(source);
|
||||
|
||||
result = ColumnArray::create(nullable_source.createValuesColumn());
|
||||
NullableSink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromRightConstantOffsetBounded(static_cast<ConstSource<NullableSource> &>(source), sink, offset, length);
|
||||
else
|
||||
sliceFromRightConstantOffsetBounded(static_cast<NullableSource &>(source), sink, offset, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromRightConstantOffsetBounded(static_cast<ConstSource<SourceType> &>(source), sink, offset, length);
|
||||
else
|
||||
sliceFromRightConstantOffsetBounded(source, sink, offset, length);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,13 +14,36 @@ struct SliceFromRightConstantOffsetUnboundedSelectArraySource
|
||||
: public ArraySourceSelector<SliceFromRightConstantOffsetUnboundedSelectArraySource>
|
||||
{
|
||||
template <typename Source>
|
||||
static void selectImpl(Source && source, size_t & offset, ColumnArray::MutablePtr & result)
|
||||
static void selectSource(bool is_const, bool is_nullable, Source && source, size_t & offset, ColumnArray::MutablePtr & result)
|
||||
{
|
||||
using SourceType = typename std::decay<Source>::type;
|
||||
using Sink = typename SourceType::SinkType;
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
sliceFromRightConstantOffsetUnbounded(source, sink, offset);
|
||||
|
||||
if (is_nullable)
|
||||
{
|
||||
using NullableSource = NullableArraySource<SourceType>;
|
||||
using NullableSink = typename NullableSource::SinkType;
|
||||
|
||||
auto & nullable_source = static_cast<NullableSource &>(source);
|
||||
|
||||
result = ColumnArray::create(nullable_source.createValuesColumn());
|
||||
NullableSink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromRightConstantOffsetUnbounded(static_cast<ConstSource<NullableSource> &>(source), sink, offset);
|
||||
else
|
||||
sliceFromRightConstantOffsetUnbounded(static_cast<NullableSource &>(source), sink, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ColumnArray::create(source.createValuesColumn());
|
||||
Sink sink(result->getData(), result->getOffsets(), source.getColumnSize());
|
||||
|
||||
if (is_const)
|
||||
sliceFromRightConstantOffsetUnbounded(static_cast<ConstSource<SourceType> &>(source), sink, offset);
|
||||
else
|
||||
sliceFromRightConstantOffsetUnbounded(source, sink, offset);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -355,6 +355,7 @@ struct ContextShared
|
||||
mutable std::shared_ptr<const StoragePolicySelector> merge_tree_storage_policy_selector;
|
||||
|
||||
std::optional<MergeTreeSettings> merge_tree_settings; /// Settings of MergeTree* engines.
|
||||
std::optional<MergeTreeSettings> replicated_merge_tree_settings; /// Settings of ReplicatedMergeTree* engines.
|
||||
std::atomic_size_t max_table_size_to_drop = 50000000000lu; /// Protects MergeTree tables from accidental DROP (50GB by default)
|
||||
std::atomic_size_t max_partition_size_to_drop = 50000000000lu; /// Protects MergeTree partitions from accidental DROP (50GB by default)
|
||||
String format_schema_path; /// Path to a directory that contains schema files used by input formats.
|
||||
@ -1887,6 +1888,22 @@ const MergeTreeSettings & Context::getMergeTreeSettings() const
|
||||
return *shared->merge_tree_settings;
|
||||
}
|
||||
|
||||
const MergeTreeSettings & Context::getReplicatedMergeTreeSettings() const
|
||||
{
|
||||
auto lock = getLock();
|
||||
|
||||
if (!shared->replicated_merge_tree_settings)
|
||||
{
|
||||
const auto & config = getConfigRef();
|
||||
MergeTreeSettings mt_settings;
|
||||
mt_settings.loadFromConfig("merge_tree", config);
|
||||
mt_settings.loadFromConfig("replicated_merge_tree", config);
|
||||
shared->replicated_merge_tree_settings.emplace(mt_settings);
|
||||
}
|
||||
|
||||
return *shared->replicated_merge_tree_settings;
|
||||
}
|
||||
|
||||
const StorageS3Settings & Context::getStorageS3Settings() const
|
||||
{
|
||||
#if !defined(ARCADIA_BUILD)
|
||||
|
@ -545,6 +545,7 @@ public:
|
||||
std::shared_ptr<PartLog> getPartLog(const String & part_database);
|
||||
|
||||
const MergeTreeSettings & getMergeTreeSettings() const;
|
||||
const MergeTreeSettings & getReplicatedMergeTreeSettings() const;
|
||||
const StorageS3Settings & getStorageS3Settings() const;
|
||||
|
||||
/// Prevents DROP TABLE if its size is greater than max_size (50GB by default, max_size=0 turn off this check)
|
||||
|
@ -33,7 +33,7 @@ void ReplicasStatusHandler::handleRequest(Poco::Net::HTTPServerRequest & request
|
||||
/// Even if lag is small, output detailed information about the lag.
|
||||
bool verbose = params.get("verbose", "") == "1";
|
||||
|
||||
const MergeTreeSettings & settings = context.getMergeTreeSettings();
|
||||
const MergeTreeSettings & settings = context.getReplicatedMergeTreeSettings();
|
||||
|
||||
bool ok = true;
|
||||
std::stringstream message;
|
||||
|
@ -535,7 +535,11 @@ static StoragePtr create(const StorageFactory::Arguments & args)
|
||||
StorageInMemoryMetadata metadata;
|
||||
metadata.columns = args.columns;
|
||||
|
||||
std::unique_ptr<MergeTreeSettings> storage_settings = std::make_unique<MergeTreeSettings>(args.context.getMergeTreeSettings());
|
||||
std::unique_ptr<MergeTreeSettings> storage_settings;
|
||||
if (replicated)
|
||||
storage_settings = std::make_unique<MergeTreeSettings>(args.context.getReplicatedMergeTreeSettings());
|
||||
else
|
||||
storage_settings = std::make_unique<MergeTreeSettings>(args.context.getMergeTreeSettings());
|
||||
|
||||
if (is_extended_storage_def)
|
||||
{
|
||||
|
@ -7,7 +7,8 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
NamesAndTypesList SystemMergeTreeSettings::getNamesAndTypes()
|
||||
template <bool replicated>
|
||||
NamesAndTypesList SystemMergeTreeSettings<replicated>::getNamesAndTypes()
|
||||
{
|
||||
return {
|
||||
{"name", std::make_shared<DataTypeString>()},
|
||||
@ -18,9 +19,11 @@ NamesAndTypesList SystemMergeTreeSettings::getNamesAndTypes()
|
||||
};
|
||||
}
|
||||
|
||||
void SystemMergeTreeSettings::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo &) const
|
||||
template <bool replicated>
|
||||
void SystemMergeTreeSettings<replicated>::fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo &) const
|
||||
{
|
||||
for (const auto & setting : context.getMergeTreeSettings().all())
|
||||
const auto & settings = replicated ? context.getReplicatedMergeTreeSettings().all() : context.getMergeTreeSettings().all();
|
||||
for (const auto & setting : settings)
|
||||
{
|
||||
res_columns[0]->insert(setting.getName());
|
||||
res_columns[1]->insert(setting.getValueString());
|
||||
@ -30,4 +33,6 @@ void SystemMergeTreeSettings::fillData(MutableColumns & res_columns, const Conte
|
||||
}
|
||||
}
|
||||
|
||||
template class SystemMergeTreeSettings<false>;
|
||||
template class SystemMergeTreeSettings<true>;
|
||||
}
|
||||
|
@ -11,18 +11,22 @@ namespace DB
|
||||
class Context;
|
||||
|
||||
|
||||
/** implements system table "merge_tree_settings", which allows to get information about the current MergeTree settings.
|
||||
/** implements system table "merge_tree_settings" and "replicated_merge_tree_settings",
|
||||
* which allows to get information about the current MergeTree settings.
|
||||
*/
|
||||
class SystemMergeTreeSettings final : public ext::shared_ptr_helper<SystemMergeTreeSettings>, public IStorageSystemOneBlock<SystemMergeTreeSettings>
|
||||
template <bool replicated>
|
||||
class SystemMergeTreeSettings final : public ext::shared_ptr_helper<SystemMergeTreeSettings<replicated>>,
|
||||
public IStorageSystemOneBlock<SystemMergeTreeSettings<replicated>>
|
||||
{
|
||||
friend struct ext::shared_ptr_helper<SystemMergeTreeSettings>;
|
||||
friend struct ext::shared_ptr_helper<SystemMergeTreeSettings<replicated>>;
|
||||
|
||||
public:
|
||||
std::string getName() const override { return "SystemMergeTreeSettings"; }
|
||||
std::string getName() const override { return replicated ? "SystemReplicatedMergeTreeSettings" : "SystemMergeTreeSettings"; }
|
||||
|
||||
static NamesAndTypesList getNamesAndTypes();
|
||||
|
||||
protected:
|
||||
using IStorageSystemOneBlock::IStorageSystemOneBlock;
|
||||
using IStorageSystemOneBlock<SystemMergeTreeSettings<replicated>>::IStorageSystemOneBlock;
|
||||
|
||||
void fillData(MutableColumns & res_columns, const Context & context, const SelectQueryInfo & query_info) const override;
|
||||
};
|
||||
|
@ -82,7 +82,8 @@ void attachSystemTablesLocal(IDatabase & system_database)
|
||||
attach<StorageSystemFunctions>(system_database, "functions");
|
||||
attach<StorageSystemEvents>(system_database, "events");
|
||||
attach<StorageSystemSettings>(system_database, "settings");
|
||||
attach<SystemMergeTreeSettings>(system_database, "merge_tree_settings");
|
||||
attach<SystemMergeTreeSettings<false>>(system_database, "merge_tree_settings");
|
||||
attach<SystemMergeTreeSettings<true>>(system_database, "replicated_merge_tree_settings");
|
||||
attach<StorageSystemBuildOptions>(system_database, "build_options");
|
||||
attach<StorageSystemFormats>(system_database, "formats");
|
||||
attach<StorageSystemTableFunctions>(system_database, "table_functions");
|
||||
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<yandex>
|
||||
<merge_tree>
|
||||
<index_granularity>100</index_granularity>
|
||||
</merge_tree>
|
||||
<replicated_merge_tree>
|
||||
<index_granularity>200</index_granularity>
|
||||
</replicated_merge_tree>
|
||||
</yandex>
|
36
tests/integration/test_replicated_merge_tree_config/test.py
Normal file
36
tests/integration/test_replicated_merge_tree_config/test.py
Normal file
@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
from helpers.cluster import ClickHouseCluster
|
||||
import logging
|
||||
|
||||
cluster = ClickHouseCluster(__file__)
|
||||
node = cluster.add_instance("node", main_configs=["configs/config.xml"], with_zookeeper=True)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def start_cluster():
|
||||
try:
|
||||
logging.info("Starting cluster...")
|
||||
cluster.start()
|
||||
logging.info("Cluster started")
|
||||
|
||||
yield cluster
|
||||
finally:
|
||||
cluster.shutdown()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def drop_table(start_cluster):
|
||||
yield
|
||||
for node in cluster.instances.values():
|
||||
node.query("DROP TABLE IF EXISTS test1")
|
||||
node.query("DROP TABLE IF EXISTS test2")
|
||||
|
||||
|
||||
def test_replicated_merge_tree_settings(start_cluster):
|
||||
node.query("CREATE TABLE test1 (id Int64) ENGINE MergeTree ORDER BY id")
|
||||
node.query(
|
||||
"CREATE TABLE test2 (id Int64) ENGINE ReplicatedMergeTree('/clickhouse/test', 'test') ORDER BY id"
|
||||
)
|
||||
|
||||
assert "index_granularity = 100" in node.query("SHOW CREATE test1")
|
||||
assert "index_granularity = 200" in node.query("SHOW CREATE test2")
|
Loading…
Reference in New Issue
Block a user