mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Merge branch 'master' into bugfix/lc-nullability-checker
This commit is contained in:
commit
91edd2bba1
10
CHANGELOG.md
10
CHANGELOG.md
@ -22,14 +22,14 @@
|
|||||||
* Add setting `allow_non_metadata_alters` which restricts to execute `ALTER` queries which modify data on disk. Disabled be default. Closes [#11547](https://github.com/ClickHouse/ClickHouse/issues/11547). [#12635](https://github.com/ClickHouse/ClickHouse/pull/12635) ([alesapin](https://github.com/alesapin)).
|
* Add setting `allow_non_metadata_alters` which restricts to execute `ALTER` queries which modify data on disk. Disabled be default. Closes [#11547](https://github.com/ClickHouse/ClickHouse/issues/11547). [#12635](https://github.com/ClickHouse/ClickHouse/pull/12635) ([alesapin](https://github.com/alesapin)).
|
||||||
* A function `formatRow` is added to support turning arbitrary expressions into a string via given format. It's useful for manipulating SQL outputs and is quite versatile combined with the `columns` function. [#12574](https://github.com/ClickHouse/ClickHouse/pull/12574) ([Amos Bird](https://github.com/amosbird)).
|
* A function `formatRow` is added to support turning arbitrary expressions into a string via given format. It's useful for manipulating SQL outputs and is quite versatile combined with the `columns` function. [#12574](https://github.com/ClickHouse/ClickHouse/pull/12574) ([Amos Bird](https://github.com/amosbird)).
|
||||||
* Add `FROM_UNIXTIME` function for compatibility with MySQL, related to [12149](https://github.com/ClickHouse/ClickHouse/issues/12149). [#12484](https://github.com/ClickHouse/ClickHouse/pull/12484) ([flynn](https://github.com/ucasFL)).
|
* Add `FROM_UNIXTIME` function for compatibility with MySQL, related to [12149](https://github.com/ClickHouse/ClickHouse/issues/12149). [#12484](https://github.com/ClickHouse/ClickHouse/pull/12484) ([flynn](https://github.com/ucasFL)).
|
||||||
* Allow Nullable types as keys in MergeTree tables if `allow_nullable_key` table setting is enabled. https://github.com/ClickHouse/ClickHouse/issues/5319. [#12433](https://github.com/ClickHouse/ClickHouse/pull/12433) ([Amos Bird](https://github.com/amosbird)).
|
* Allow Nullable types as keys in MergeTree tables if `allow_nullable_key` table setting is enabled. Closes [#5319](https://github.com/ClickHouse/ClickHouse/issues/5319). [#12433](https://github.com/ClickHouse/ClickHouse/pull/12433) ([Amos Bird](https://github.com/amosbird)).
|
||||||
* Integration with [COS](https://intl.cloud.tencent.com/product/cos). [#12386](https://github.com/ClickHouse/ClickHouse/pull/12386) ([fastio](https://github.com/fastio)).
|
* Integration with [COS](https://intl.cloud.tencent.com/product/cos). [#12386](https://github.com/ClickHouse/ClickHouse/pull/12386) ([fastio](https://github.com/fastio)).
|
||||||
* Add mapAdd and mapSubtract functions for adding/subtracting key-mapped values. [#11735](https://github.com/ClickHouse/ClickHouse/pull/11735) ([Ildus Kurbangaliev](https://github.com/ildus)).
|
* Add mapAdd and mapSubtract functions for adding/subtracting key-mapped values. [#11735](https://github.com/ClickHouse/ClickHouse/pull/11735) ([Ildus Kurbangaliev](https://github.com/ildus)).
|
||||||
|
|
||||||
#### Bug Fix
|
#### Bug Fix
|
||||||
|
|
||||||
* Fix premature `ON CLUSTER` timeouts for queries that must be executed on a single replica. Fixes [#6704](https://github.com/ClickHouse/ClickHouse/issues/6704), [#7228](https://github.com/ClickHouse/ClickHouse/issues/7228), [#13361](https://github.com/ClickHouse/ClickHouse/issues/13361), [#11884](https://github.com/ClickHouse/ClickHouse/issues/11884). [#13450](https://github.com/ClickHouse/ClickHouse/pull/13450) ([alesapin](https://github.com/alesapin)).
|
* Fix premature `ON CLUSTER` timeouts for queries that must be executed on a single replica. Fixes [#6704](https://github.com/ClickHouse/ClickHouse/issues/6704), [#7228](https://github.com/ClickHouse/ClickHouse/issues/7228), [#13361](https://github.com/ClickHouse/ClickHouse/issues/13361), [#11884](https://github.com/ClickHouse/ClickHouse/issues/11884). [#13450](https://github.com/ClickHouse/ClickHouse/pull/13450) ([alesapin](https://github.com/alesapin)).
|
||||||
* Fix crash in mark inclusion search introduced in https://github.com/ClickHouse/ClickHouse/pull/12277. [#14225](https://github.com/ClickHouse/ClickHouse/pull/14225) ([Amos Bird](https://github.com/amosbird)).
|
* Fix crash in mark inclusion search introduced in [#12277](https://github.com/ClickHouse/ClickHouse/pull/12277). [#14225](https://github.com/ClickHouse/ClickHouse/pull/14225) ([Amos Bird](https://github.com/amosbird)).
|
||||||
* Fix race condition in external dictionaries with cache layout which can lead server crash. [#12566](https://github.com/ClickHouse/ClickHouse/pull/12566) ([alesapin](https://github.com/alesapin)).
|
* Fix race condition in external dictionaries with cache layout which can lead server crash. [#12566](https://github.com/ClickHouse/ClickHouse/pull/12566) ([alesapin](https://github.com/alesapin)).
|
||||||
* Fix visible data clobbering by progress bar in client in interactive mode. This fixes [#12562](https://github.com/ClickHouse/ClickHouse/issues/12562) and [#13369](https://github.com/ClickHouse/ClickHouse/issues/13369) and [#13584](https://github.com/ClickHouse/ClickHouse/issues/13584) and fixes [#12964](https://github.com/ClickHouse/ClickHouse/issues/12964). [#13691](https://github.com/ClickHouse/ClickHouse/pull/13691) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
* Fix visible data clobbering by progress bar in client in interactive mode. This fixes [#12562](https://github.com/ClickHouse/ClickHouse/issues/12562) and [#13369](https://github.com/ClickHouse/ClickHouse/issues/13369) and [#13584](https://github.com/ClickHouse/ClickHouse/issues/13584) and fixes [#12964](https://github.com/ClickHouse/ClickHouse/issues/12964). [#13691](https://github.com/ClickHouse/ClickHouse/pull/13691) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||||
* Fixed incorrect sorting order for `LowCardinality` columns when ORDER BY multiple columns is used. This fixes [#13958](https://github.com/ClickHouse/ClickHouse/issues/13958). [#14223](https://github.com/ClickHouse/ClickHouse/pull/14223) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
* Fixed incorrect sorting order for `LowCardinality` columns when ORDER BY multiple columns is used. This fixes [#13958](https://github.com/ClickHouse/ClickHouse/issues/13958). [#14223](https://github.com/ClickHouse/ClickHouse/pull/14223) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
|
||||||
@ -71,7 +71,7 @@
|
|||||||
* Fix function if with nullable constexpr as cond that is not literal NULL. Fixes [#12463](https://github.com/ClickHouse/ClickHouse/issues/12463). [#13226](https://github.com/ClickHouse/ClickHouse/pull/13226) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
* Fix function if with nullable constexpr as cond that is not literal NULL. Fixes [#12463](https://github.com/ClickHouse/ClickHouse/issues/12463). [#13226](https://github.com/ClickHouse/ClickHouse/pull/13226) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||||
* Fix assert in `arrayElement` function in case of array elements are Nullable and array subscript is also Nullable. This fixes [#12172](https://github.com/ClickHouse/ClickHouse/issues/12172). [#13224](https://github.com/ClickHouse/ClickHouse/pull/13224) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
* Fix assert in `arrayElement` function in case of array elements are Nullable and array subscript is also Nullable. This fixes [#12172](https://github.com/ClickHouse/ClickHouse/issues/12172). [#13224](https://github.com/ClickHouse/ClickHouse/pull/13224) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||||
* Fix DateTime64 conversion functions with constant argument. [#13205](https://github.com/ClickHouse/ClickHouse/pull/13205) ([Azat Khuzhin](https://github.com/azat)).
|
* Fix DateTime64 conversion functions with constant argument. [#13205](https://github.com/ClickHouse/ClickHouse/pull/13205) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
* Fix parsing row policies from users.xml when names of databases or tables contain dots. This fixes https://github.com/ClickHouse/ClickHouse/issues/5779, https://github.com/ClickHouse/ClickHouse/issues/12527. [#13199](https://github.com/ClickHouse/ClickHouse/pull/13199) ([Vitaly Baranov](https://github.com/vitlibar)).
|
* Fix parsing row policies from users.xml when names of databases or tables contain dots. This fixes [#5779](https://github.com/ClickHouse/ClickHouse/issues/5779), [#12527](https://github.com/ClickHouse/ClickHouse/issues/12527). [#13199](https://github.com/ClickHouse/ClickHouse/pull/13199) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||||
* Fix access to `redis` dictionary after connection was dropped once. It may happen with `cache` and `direct` dictionary layouts. [#13082](https://github.com/ClickHouse/ClickHouse/pull/13082) ([Anton Popov](https://github.com/CurtizJ)).
|
* Fix access to `redis` dictionary after connection was dropped once. It may happen with `cache` and `direct` dictionary layouts. [#13082](https://github.com/ClickHouse/ClickHouse/pull/13082) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
* Fix wrong index analysis with functions. It could lead to some data parts being skipped when reading from `MergeTree` tables. Fixes [#13060](https://github.com/ClickHouse/ClickHouse/issues/13060). Fixes [#12406](https://github.com/ClickHouse/ClickHouse/issues/12406). [#13081](https://github.com/ClickHouse/ClickHouse/pull/13081) ([Anton Popov](https://github.com/CurtizJ)).
|
* Fix wrong index analysis with functions. It could lead to some data parts being skipped when reading from `MergeTree` tables. Fixes [#13060](https://github.com/ClickHouse/ClickHouse/issues/13060). Fixes [#12406](https://github.com/ClickHouse/ClickHouse/issues/12406). [#13081](https://github.com/ClickHouse/ClickHouse/pull/13081) ([Anton Popov](https://github.com/CurtizJ)).
|
||||||
* Fix error `Cannot convert column because it is constant but values of constants are different in source and result` for remote queries which use deterministic functions in scope of query, but not deterministic between queries, like `now()`, `now64()`, `randConstant()`. Fixes [#11327](https://github.com/ClickHouse/ClickHouse/issues/11327). [#13075](https://github.com/ClickHouse/ClickHouse/pull/13075) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
* Fix error `Cannot convert column because it is constant but values of constants are different in source and result` for remote queries which use deterministic functions in scope of query, but not deterministic between queries, like `now()`, `now64()`, `randConstant()`. Fixes [#11327](https://github.com/ClickHouse/ClickHouse/issues/11327). [#13075](https://github.com/ClickHouse/ClickHouse/pull/13075) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
@ -89,7 +89,7 @@
|
|||||||
* Fixed [#10572](https://github.com/ClickHouse/ClickHouse/issues/10572) fix bloom filter index with const expression. [#12659](https://github.com/ClickHouse/ClickHouse/pull/12659) ([Winter Zhang](https://github.com/zhang2014)).
|
* Fixed [#10572](https://github.com/ClickHouse/ClickHouse/issues/10572) fix bloom filter index with const expression. [#12659](https://github.com/ClickHouse/ClickHouse/pull/12659) ([Winter Zhang](https://github.com/zhang2014)).
|
||||||
* Fix SIGSEGV in StorageKafka when broker is unavailable (and not only). [#12658](https://github.com/ClickHouse/ClickHouse/pull/12658) ([Azat Khuzhin](https://github.com/azat)).
|
* Fix SIGSEGV in StorageKafka when broker is unavailable (and not only). [#12658](https://github.com/ClickHouse/ClickHouse/pull/12658) ([Azat Khuzhin](https://github.com/azat)).
|
||||||
* Add support for function `if` with `Array(UUID)` arguments. This fixes [#11066](https://github.com/ClickHouse/ClickHouse/issues/11066). [#12648](https://github.com/ClickHouse/ClickHouse/pull/12648) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
* Add support for function `if` with `Array(UUID)` arguments. This fixes [#11066](https://github.com/ClickHouse/ClickHouse/issues/11066). [#12648](https://github.com/ClickHouse/ClickHouse/pull/12648) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||||
* CREATE USER IF NOT EXISTS now doesn't throw exception if the user exists. This fixes https://github.com/ClickHouse/ClickHouse/issues/12507. [#12646](https://github.com/ClickHouse/ClickHouse/pull/12646) ([Vitaly Baranov](https://github.com/vitlibar)).
|
* CREATE USER IF NOT EXISTS now doesn't throw exception if the user exists. This fixes [#12507](https://github.com/ClickHouse/ClickHouse/issues/12507). [#12646](https://github.com/ClickHouse/ClickHouse/pull/12646) ([Vitaly Baranov](https://github.com/vitlibar)).
|
||||||
* Exception `There is no supertype...` can be thrown during `ALTER ... UPDATE` in unexpected cases (e.g. when subtracting from UInt64 column). This fixes [#7306](https://github.com/ClickHouse/ClickHouse/issues/7306). This fixes [#4165](https://github.com/ClickHouse/ClickHouse/issues/4165). [#12633](https://github.com/ClickHouse/ClickHouse/pull/12633) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
* Exception `There is no supertype...` can be thrown during `ALTER ... UPDATE` in unexpected cases (e.g. when subtracting from UInt64 column). This fixes [#7306](https://github.com/ClickHouse/ClickHouse/issues/7306). This fixes [#4165](https://github.com/ClickHouse/ClickHouse/issues/4165). [#12633](https://github.com/ClickHouse/ClickHouse/pull/12633) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||||
* Fix possible `Pipeline stuck` error for queries with external sorting. Fixes [#12617](https://github.com/ClickHouse/ClickHouse/issues/12617). [#12618](https://github.com/ClickHouse/ClickHouse/pull/12618) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
* Fix possible `Pipeline stuck` error for queries with external sorting. Fixes [#12617](https://github.com/ClickHouse/ClickHouse/issues/12617). [#12618](https://github.com/ClickHouse/ClickHouse/pull/12618) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
* Fix error `Output of TreeExecutor is not sorted` for `OPTIMIZE DEDUPLICATE`. Fixes [#11572](https://github.com/ClickHouse/ClickHouse/issues/11572). [#12613](https://github.com/ClickHouse/ClickHouse/pull/12613) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
* Fix error `Output of TreeExecutor is not sorted` for `OPTIMIZE DEDUPLICATE`. Fixes [#11572](https://github.com/ClickHouse/ClickHouse/issues/11572). [#12613](https://github.com/ClickHouse/ClickHouse/pull/12613) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
|
||||||
@ -123,7 +123,7 @@
|
|||||||
* Fix assert in `parseDateTimeBestEffort`. This fixes [#12649](https://github.com/ClickHouse/ClickHouse/issues/12649). [#13227](https://github.com/ClickHouse/ClickHouse/pull/13227) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
* Fix assert in `parseDateTimeBestEffort`. This fixes [#12649](https://github.com/ClickHouse/ClickHouse/issues/12649). [#13227](https://github.com/ClickHouse/ClickHouse/pull/13227) ([alexey-milovidov](https://github.com/alexey-milovidov)).
|
||||||
* Minor optimization in Processors/PipelineExecutor: breaking out of a loop because it makes sense to do so. [#13058](https://github.com/ClickHouse/ClickHouse/pull/13058) ([Mark Papadakis](https://github.com/markpapadakis)).
|
* Minor optimization in Processors/PipelineExecutor: breaking out of a loop because it makes sense to do so. [#13058](https://github.com/ClickHouse/ClickHouse/pull/13058) ([Mark Papadakis](https://github.com/markpapadakis)).
|
||||||
* Support TRUNCATE table without TABLE keyword. [#12653](https://github.com/ClickHouse/ClickHouse/pull/12653) ([Winter Zhang](https://github.com/zhang2014)).
|
* Support TRUNCATE table without TABLE keyword. [#12653](https://github.com/ClickHouse/ClickHouse/pull/12653) ([Winter Zhang](https://github.com/zhang2014)).
|
||||||
* Fix explain query format overwrite by default, issue https://github.com/ClickHouse/ClickHouse/issues/12432. [#12541](https://github.com/ClickHouse/ClickHouse/pull/12541) ([BohuTANG](https://github.com/BohuTANG)).
|
* Fix explain query format overwrite by default. This fixes [#12541](https://github.com/ClickHouse/ClickHouse/issues/12432). [#12541](https://github.com/ClickHouse/ClickHouse/pull/12541) ([BohuTANG](https://github.com/BohuTANG)).
|
||||||
* Allow to set JOIN kind and type in more standad way: `LEFT SEMI JOIN` instead of `SEMI LEFT JOIN`. For now both are correct. [#12520](https://github.com/ClickHouse/ClickHouse/pull/12520) ([Artem Zuikov](https://github.com/4ertus2)).
|
* Allow to set JOIN kind and type in more standad way: `LEFT SEMI JOIN` instead of `SEMI LEFT JOIN`. For now both are correct. [#12520](https://github.com/ClickHouse/ClickHouse/pull/12520) ([Artem Zuikov](https://github.com/4ertus2)).
|
||||||
* Changes default value for `multiple_joins_rewriter_version` to 2. It enables new multiple joins rewriter that knows about column names. [#12469](https://github.com/ClickHouse/ClickHouse/pull/12469) ([Artem Zuikov](https://github.com/4ertus2)).
|
* Changes default value for `multiple_joins_rewriter_version` to 2. It enables new multiple joins rewriter that knows about column names. [#12469](https://github.com/ClickHouse/ClickHouse/pull/12469) ([Artem Zuikov](https://github.com/4ertus2)).
|
||||||
* Add several metrics for requests to S3 storages. [#12464](https://github.com/ClickHouse/ClickHouse/pull/12464) ([ianton-ru](https://github.com/ianton-ru)).
|
* Add several metrics for requests to S3 storages. [#12464](https://github.com/ClickHouse/ClickHouse/pull/12464) ([ianton-ru](https://github.com/ianton-ru)).
|
||||||
|
@ -18,3 +18,4 @@ ClickHouse is an open-source column-oriented database management system that all
|
|||||||
## Upcoming Events
|
## Upcoming Events
|
||||||
|
|
||||||
* [ClickHouse Data Integration Virtual Meetup](https://www.eventbrite.com/e/clickhouse-september-virtual-meetup-data-integration-tickets-117421895049) on September 10, 2020.
|
* [ClickHouse Data Integration Virtual Meetup](https://www.eventbrite.com/e/clickhouse-september-virtual-meetup-data-integration-tickets-117421895049) on September 10, 2020.
|
||||||
|
* [ClickHouse talk at Ya.Subbotnik (in Russian)](https://ya.cc/t/cIBI-3yECj5JF) on September 12, 2020.
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# This strings autochanged from release_lib.sh:
|
# This strings autochanged from release_lib.sh:
|
||||||
SET(VERSION_REVISION 54439)
|
SET(VERSION_REVISION 54440)
|
||||||
SET(VERSION_MAJOR 20)
|
SET(VERSION_MAJOR 20)
|
||||||
SET(VERSION_MINOR 9)
|
SET(VERSION_MINOR 10)
|
||||||
SET(VERSION_PATCH 1)
|
SET(VERSION_PATCH 1)
|
||||||
SET(VERSION_GITHASH 0586f0d555f7481b394afc55bbb29738cd573a1c)
|
SET(VERSION_GITHASH 11a247d2f42010c1a17bf678c3e00a4bc89b23f8)
|
||||||
SET(VERSION_DESCRIBE v20.9.1.1-prestable)
|
SET(VERSION_DESCRIBE v20.10.1.1-prestable)
|
||||||
SET(VERSION_STRING 20.9.1.1)
|
SET(VERSION_STRING 20.10.1.1)
|
||||||
# end of autochange
|
# end of autochange
|
||||||
|
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -1,5 +1,5 @@
|
|||||||
clickhouse (20.9.1.1) unstable; urgency=low
|
clickhouse (20.10.1.1) unstable; urgency=low
|
||||||
|
|
||||||
* Modified source code
|
* Modified source code
|
||||||
|
|
||||||
-- clickhouse-release <clickhouse-release@yandex-team.ru> Mon, 31 Aug 2020 23:07:38 +0300
|
-- clickhouse-release <clickhouse-release@yandex-team.ru> Tue, 08 Sep 2020 17:04:39 +0300
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
FROM ubuntu:18.04
|
FROM ubuntu:18.04
|
||||||
|
|
||||||
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
||||||
ARG version=20.9.1.*
|
ARG version=20.10.1.*
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install --yes --no-install-recommends \
|
&& apt-get install --yes --no-install-recommends \
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
FROM ubuntu:20.04
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
||||||
ARG version=20.9.1.*
|
ARG version=20.10.1.*
|
||||||
ARG gosu_ver=1.10
|
ARG gosu_ver=1.10
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
FROM ubuntu:18.04
|
FROM ubuntu:18.04
|
||||||
|
|
||||||
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
||||||
ARG version=20.9.1.*
|
ARG version=20.10.1.*
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y apt-transport-https dirmngr && \
|
apt-get install -y apt-transport-https dirmngr && \
|
||||||
|
@ -5,4 +5,4 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 6380:6379
|
- 6380:6379
|
||||||
command: redis-server --requirepass "clickhouse"
|
command: redis-server --requirepass "clickhouse" --databases 32
|
||||||
|
@ -82,8 +82,8 @@ res: /lib/x86_64-linux-gnu/libc-2.27.so
|
|||||||
|
|
||||||
- [Introspection Functions](../../sql-reference/functions/introspection.md) — Which introspection functions are available and how to use them.
|
- [Introspection Functions](../../sql-reference/functions/introspection.md) — Which introspection functions are available and how to use them.
|
||||||
- [system.trace_log](../system-tables/trace_log.md) — Contains stack traces collected by the sampling query profiler.
|
- [system.trace_log](../system-tables/trace_log.md) — Contains stack traces collected by the sampling query profiler.
|
||||||
- [arrayMap](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-map) — Description and usage example of the `arrayMap` function.
|
- [arrayMap](../../sql-reference/functions/array-functions.md#array-map) — Description and usage example of the `arrayMap` function.
|
||||||
- [arrayFilter](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-filter) — Description and usage example of the `arrayFilter` function.
|
- [arrayFilter](../../sql-reference/functions/array-functions.md#array-filter) — Description and usage example of the `arrayFilter` function.
|
||||||
|
|
||||||
|
|
||||||
[Original article](https://clickhouse.tech/docs/en/operations/system-tables/stack_trace) <!--hide-->
|
[Original article](https://clickhouse.tech/docs/en/operations/system-tables/stack_trace) <!--hide-->
|
||||||
|
@ -7,7 +7,7 @@ toc_title: Tuple(T1, T2, ...)
|
|||||||
|
|
||||||
A tuple of elements, each having an individual [type](../../sql-reference/data-types/index.md#data_types).
|
A tuple of elements, each having an individual [type](../../sql-reference/data-types/index.md#data_types).
|
||||||
|
|
||||||
Tuples are used for temporary column grouping. Columns can be grouped when an IN expression is used in a query, and for specifying certain formal parameters of lambda functions. For more information, see the sections [IN operators](../../sql-reference/operators/in.md) and [Higher order functions](../../sql-reference/functions/higher-order-functions.md).
|
Tuples are used for temporary column grouping. Columns can be grouped when an IN expression is used in a query, and for specifying certain formal parameters of lambda functions. For more information, see the sections [IN operators](../../sql-reference/operators/in.md) and [Higher order functions](../../sql-reference/functions/index.md#higher-order-functions).
|
||||||
|
|
||||||
Tuples can be the result of a query. In this case, for text formats other than JSON, values are comma-separated in brackets. In JSON formats, tuples are output as arrays (in square brackets).
|
Tuples can be the result of a query. In this case, for text formats other than JSON, values are comma-separated in brackets. In JSON formats, tuples are output as arrays (in square brackets).
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
toc_priority: 35
|
toc_priority: 34
|
||||||
toc_title: Arithmetic
|
toc_title: Arithmetic
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
toc_priority: 46
|
toc_priority: 35
|
||||||
toc_title: Arrays
|
toc_title: Arrays
|
||||||
---
|
---
|
||||||
|
|
||||||
# Functions for Working with Arrays {#functions-for-working-with-arrays}
|
# Array Functions {#functions-for-working-with-arrays}
|
||||||
|
|
||||||
## empty {#function-empty}
|
## empty {#function-empty}
|
||||||
|
|
||||||
@ -241,6 +241,12 @@ SELECT indexOf([1, 3, NULL, NULL], NULL)
|
|||||||
|
|
||||||
Elements set to `NULL` are handled as normal values.
|
Elements set to `NULL` are handled as normal values.
|
||||||
|
|
||||||
|
## arrayCount(\[func,\] arr1, …) {#array-count}
|
||||||
|
|
||||||
|
Returns the number of elements in the arr array for which func returns something other than 0. If ‘func’ is not specified, it returns the number of non-zero elements in the array.
|
||||||
|
|
||||||
|
Note that the `arrayCount` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument.
|
||||||
|
|
||||||
## countEqual(arr, x) {#countequalarr-x}
|
## countEqual(arr, x) {#countequalarr-x}
|
||||||
|
|
||||||
Returns the number of elements in the array equal to x. Equivalent to arrayCount (elem -\> elem = x, arr).
|
Returns the number of elements in the array equal to x. Equivalent to arrayCount (elem -\> elem = x, arr).
|
||||||
@ -568,7 +574,7 @@ SELECT arraySort([1, nan, 2, NULL, 3, nan, -4, NULL, inf, -inf]);
|
|||||||
- `NaN` values are right before `NULL`.
|
- `NaN` values are right before `NULL`.
|
||||||
- `Inf` values are right before `NaN`.
|
- `Inf` values are right before `NaN`.
|
||||||
|
|
||||||
Note that `arraySort` is a [higher-order function](../../sql-reference/functions/higher-order-functions.md). You can pass a lambda function to it as the first argument. In this case, sorting order is determined by the result of the lambda function applied to the elements of the array.
|
Note that `arraySort` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument. In this case, sorting order is determined by the result of the lambda function applied to the elements of the array.
|
||||||
|
|
||||||
Let’s consider the following example:
|
Let’s consider the following example:
|
||||||
|
|
||||||
@ -668,7 +674,7 @@ SELECT arrayReverseSort([1, nan, 2, NULL, 3, nan, -4, NULL, inf, -inf]) as res;
|
|||||||
- `NaN` values are right before `NULL`.
|
- `NaN` values are right before `NULL`.
|
||||||
- `-Inf` values are right before `NaN`.
|
- `-Inf` values are right before `NaN`.
|
||||||
|
|
||||||
Note that the `arrayReverseSort` is a [higher-order function](../../sql-reference/functions/higher-order-functions.md). You can pass a lambda function to it as the first argument. Example is shown below.
|
Note that the `arrayReverseSort` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument. Example is shown below.
|
||||||
|
|
||||||
``` sql
|
``` sql
|
||||||
SELECT arrayReverseSort((x) -> -x, [1, 2, 3]) as res;
|
SELECT arrayReverseSort((x) -> -x, [1, 2, 3]) as res;
|
||||||
@ -1120,7 +1126,205 @@ Result:
|
|||||||
``` text
|
``` text
|
||||||
┌─arrayAUC([0.1, 0.4, 0.35, 0.8], [0, 0, 1, 1])─┐
|
┌─arrayAUC([0.1, 0.4, 0.35, 0.8], [0, 0, 1, 1])─┐
|
||||||
│ 0.75 │
|
│ 0.75 │
|
||||||
└────────────────────────────────────────---──┘
|
└───────────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## arrayMap(func, arr1, …) {#array-map}
|
||||||
|
|
||||||
|
Returns an array obtained from the original application of the `func` function to each element in the `arr` array.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayMap(x -> (x + 2), [1, 2, 3]) as res;
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res─────┐
|
||||||
|
│ [3,4,5] │
|
||||||
|
└─────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
The following example shows how to create a tuple of elements from different arrays:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayMap((x, y) -> (x, y), [1, 2, 3], [4, 5, 6]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res─────────────────┐
|
||||||
|
│ [(1,4),(2,5),(3,6)] │
|
||||||
|
└─────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `arrayMap` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arrayFilter(func, arr1, …) {#array-filter}
|
||||||
|
|
||||||
|
Returns an array containing only the elements in `arr1` for which `func` returns something other than 0.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayFilter(x -> x LIKE '%World%', ['Hello', 'abc World']) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res───────────┐
|
||||||
|
│ ['abc World'] │
|
||||||
|
└───────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT
|
||||||
|
arrayFilter(
|
||||||
|
(i, x) -> x LIKE '%World%',
|
||||||
|
arrayEnumerate(arr),
|
||||||
|
['Hello', 'abc World'] AS arr)
|
||||||
|
AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res─┐
|
||||||
|
│ [2] │
|
||||||
|
└─────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `arrayFilter` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arrayFill(func, arr1, …) {#array-fill}
|
||||||
|
|
||||||
|
Scan through `arr1` from the first element to the last element and replace `arr1[i]` by `arr1[i - 1]` if `func` returns 0. The first element of `arr1` will not be replaced.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayFill(x -> not isNull(x), [1, null, 3, 11, 12, null, null, 5, 6, 14, null, null]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res──────────────────────────────┐
|
||||||
|
│ [1,1,3,11,12,12,12,5,6,14,14,14] │
|
||||||
|
└──────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `arrayFill` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arrayReverseFill(func, arr1, …) {#array-reverse-fill}
|
||||||
|
|
||||||
|
Scan through `arr1` from the last element to the first element and replace `arr1[i]` by `arr1[i + 1]` if `func` returns 0. The last element of `arr1` will not be replaced.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayReverseFill(x -> not isNull(x), [1, null, 3, 11, 12, null, null, 5, 6, 14, null, null]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res────────────────────────────────┐
|
||||||
|
│ [1,3,3,11,12,5,5,5,6,14,NULL,NULL] │
|
||||||
|
└────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `arrayReverseFilter` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arraySplit(func, arr1, …) {#array-split}
|
||||||
|
|
||||||
|
Split `arr1` into multiple arrays. When `func` returns something other than 0, the array will be split on the left hand side of the element. The array will not be split before the first element.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arraySplit((x, y) -> y, [1, 2, 3, 4, 5], [1, 0, 0, 1, 0]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res─────────────┐
|
||||||
|
│ [[1,2,3],[4,5]] │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `arraySplit` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arrayReverseSplit(func, arr1, …) {#array-reverse-split}
|
||||||
|
|
||||||
|
Split `arr1` into multiple arrays. When `func` returns something other than 0, the array will be split on the right hand side of the element. The array will not be split after the last element.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayReverseSplit((x, y) -> y, [1, 2, 3, 4, 5], [1, 0, 0, 1, 0]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res───────────────┐
|
||||||
|
│ [[1],[2,3,4],[5]] │
|
||||||
|
└───────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `arrayReverseSplit` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arrayExists(\[func,\] arr1, …) {#arrayexistsfunc-arr1}
|
||||||
|
|
||||||
|
Returns 1 if there is at least one element in `arr` for which `func` returns something other than 0. Otherwise, it returns 0.
|
||||||
|
|
||||||
|
Note that the `arrayExists` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument.
|
||||||
|
|
||||||
|
## arrayAll(\[func,\] arr1, …) {#arrayallfunc-arr1}
|
||||||
|
|
||||||
|
Returns 1 if `func` returns something other than 0 for all the elements in `arr`. Otherwise, it returns 0.
|
||||||
|
|
||||||
|
Note that the `arrayAll` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument.
|
||||||
|
|
||||||
|
## arrayFirst(func, arr1, …) {#array-first}
|
||||||
|
|
||||||
|
Returns the first element in the `arr1` array for which `func` returns something other than 0.
|
||||||
|
|
||||||
|
Note that the `arrayFirst` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arrayFirstIndex(func, arr1, …) {#array-first-index}
|
||||||
|
|
||||||
|
Returns the index of the first element in the `arr1` array for which `func` returns something other than 0.
|
||||||
|
|
||||||
|
Note that the `arrayFirstIndex` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You must pass a lambda function to it as the first argument, and it can’t be omitted.
|
||||||
|
|
||||||
|
## arraySum(\[func,\] arr1, …) {#array-sum}
|
||||||
|
|
||||||
|
Returns the sum of the `func` values. If the function is omitted, it just returns the sum of the array elements.
|
||||||
|
|
||||||
|
Note that the `arraySum` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument.
|
||||||
|
|
||||||
|
## arrayCumSum(\[func,\] arr1, …) {#arraycumsumfunc-arr1}
|
||||||
|
|
||||||
|
Returns an array of partial sums of elements in the source array (a running sum). If the `func` function is specified, then the values of the array elements are converted by this function before summing.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayCumSum([1, 1, 1, 1]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res──────────┐
|
||||||
|
│ [1, 2, 3, 4] │
|
||||||
|
└──────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `arrayCumSum` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument.
|
||||||
|
|
||||||
|
## arrayCumSumNonNegative(arr) {#arraycumsumnonnegativearr}
|
||||||
|
|
||||||
|
Same as `arrayCumSum`, returns an array of partial sums of elements in the source array (a running sum). Different `arrayCumSum`, when then returned value contains a value less than zero, the value is replace with zero and the subsequent calculation is performed with zero parameters. For example:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayCumSumNonNegative([1, 1, -4, 1]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res───────┐
|
||||||
|
│ [1,2,0,1] │
|
||||||
|
└───────────┘
|
||||||
|
```
|
||||||
|
Note that the `arraySumNonNegative` is a [higher-order function](../../sql-reference/functions/index.md#higher-order-functions). You can pass a lambda function to it as the first argument.
|
||||||
|
|
||||||
[Original article](https://clickhouse.tech/docs/en/query_language/functions/array_functions/) <!--hide-->
|
[Original article](https://clickhouse.tech/docs/en/query_language/functions/array_functions/) <!--hide-->
|
||||||
|
@ -1,262 +0,0 @@
|
|||||||
---
|
|
||||||
toc_priority: 57
|
|
||||||
toc_title: Higher-Order
|
|
||||||
---
|
|
||||||
|
|
||||||
# Higher-order Functions {#higher-order-functions}
|
|
||||||
|
|
||||||
## `->` operator, lambda(params, expr) function {#operator-lambdaparams-expr-function}
|
|
||||||
|
|
||||||
Allows describing a lambda function for passing to a higher-order function. The left side of the arrow has a formal parameter, which is any ID, or multiple formal parameters – any IDs in a tuple. The right side of the arrow has an expression that can use these formal parameters, as well as any table columns.
|
|
||||||
|
|
||||||
Examples: `x -> 2 * x, str -> str != Referer.`
|
|
||||||
|
|
||||||
Higher-order functions can only accept lambda functions as their functional argument.
|
|
||||||
|
|
||||||
A lambda function that accepts multiple arguments can be passed to a higher-order function. In this case, the higher-order function is passed several arrays of identical length that these arguments will correspond to.
|
|
||||||
|
|
||||||
For some functions, such as [arrayCount](#higher_order_functions-array-count) or [arraySum](#higher_order_functions-array-count), the first argument (the lambda function) can be omitted. In this case, identical mapping is assumed.
|
|
||||||
|
|
||||||
A lambda function can’t be omitted for the following functions:
|
|
||||||
|
|
||||||
- [arrayMap](#higher_order_functions-array-map)
|
|
||||||
- [arrayFilter](#higher_order_functions-array-filter)
|
|
||||||
- [arrayFill](#higher_order_functions-array-fill)
|
|
||||||
- [arrayReverseFill](#higher_order_functions-array-reverse-fill)
|
|
||||||
- [arraySplit](#higher_order_functions-array-split)
|
|
||||||
- [arrayReverseSplit](#higher_order_functions-array-reverse-split)
|
|
||||||
- [arrayFirst](#higher_order_functions-array-first)
|
|
||||||
- [arrayFirstIndex](#higher_order_functions-array-first-index)
|
|
||||||
|
|
||||||
### arrayMap(func, arr1, …) {#higher_order_functions-array-map}
|
|
||||||
|
|
||||||
Returns an array obtained from the original application of the `func` function to each element in the `arr` array.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayMap(x -> (x + 2), [1, 2, 3]) as res;
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res─────┐
|
|
||||||
│ [3,4,5] │
|
|
||||||
└─────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
The following example shows how to create a tuple of elements from different arrays:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayMap((x, y) -> (x, y), [1, 2, 3], [4, 5, 6]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res─────────────────┐
|
|
||||||
│ [(1,4),(2,5),(3,6)] │
|
|
||||||
└─────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arrayMap` function.
|
|
||||||
|
|
||||||
### arrayFilter(func, arr1, …) {#higher_order_functions-array-filter}
|
|
||||||
|
|
||||||
Returns an array containing only the elements in `arr1` for which `func` returns something other than 0.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayFilter(x -> x LIKE '%World%', ['Hello', 'abc World']) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res───────────┐
|
|
||||||
│ ['abc World'] │
|
|
||||||
└───────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT
|
|
||||||
arrayFilter(
|
|
||||||
(i, x) -> x LIKE '%World%',
|
|
||||||
arrayEnumerate(arr),
|
|
||||||
['Hello', 'abc World'] AS arr)
|
|
||||||
AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res─┐
|
|
||||||
│ [2] │
|
|
||||||
└─────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arrayFilter` function.
|
|
||||||
|
|
||||||
### arrayFill(func, arr1, …) {#higher_order_functions-array-fill}
|
|
||||||
|
|
||||||
Scan through `arr1` from the first element to the last element and replace `arr1[i]` by `arr1[i - 1]` if `func` returns 0. The first element of `arr1` will not be replaced.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayFill(x -> not isNull(x), [1, null, 3, 11, 12, null, null, 5, 6, 14, null, null]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res──────────────────────────────┐
|
|
||||||
│ [1,1,3,11,12,12,12,5,6,14,14,14] │
|
|
||||||
└──────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arrayFill` function.
|
|
||||||
|
|
||||||
### arrayReverseFill(func, arr1, …) {#higher_order_functions-array-reverse-fill}
|
|
||||||
|
|
||||||
Scan through `arr1` from the last element to the first element and replace `arr1[i]` by `arr1[i + 1]` if `func` returns 0. The last element of `arr1` will not be replaced.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayReverseFill(x -> not isNull(x), [1, null, 3, 11, 12, null, null, 5, 6, 14, null, null]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res────────────────────────────────┐
|
|
||||||
│ [1,3,3,11,12,5,5,5,6,14,NULL,NULL] │
|
|
||||||
└────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arrayReverseFill` function.
|
|
||||||
|
|
||||||
### arraySplit(func, arr1, …) {#higher_order_functions-array-split}
|
|
||||||
|
|
||||||
Split `arr1` into multiple arrays. When `func` returns something other than 0, the array will be split on the left hand side of the element. The array will not be split before the first element.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arraySplit((x, y) -> y, [1, 2, 3, 4, 5], [1, 0, 0, 1, 0]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res─────────────┐
|
|
||||||
│ [[1,2,3],[4,5]] │
|
|
||||||
└─────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arraySplit` function.
|
|
||||||
|
|
||||||
### arrayReverseSplit(func, arr1, …) {#higher_order_functions-array-reverse-split}
|
|
||||||
|
|
||||||
Split `arr1` into multiple arrays. When `func` returns something other than 0, the array will be split on the right hand side of the element. The array will not be split after the last element.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayReverseSplit((x, y) -> y, [1, 2, 3, 4, 5], [1, 0, 0, 1, 0]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res───────────────┐
|
|
||||||
│ [[1],[2,3,4],[5]] │
|
|
||||||
└───────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arraySplit` function.
|
|
||||||
|
|
||||||
### arrayCount(\[func,\] arr1, …) {#higher_order_functions-array-count}
|
|
||||||
|
|
||||||
Returns the number of elements in the arr array for which func returns something other than 0. If ‘func’ is not specified, it returns the number of non-zero elements in the array.
|
|
||||||
|
|
||||||
### arrayExists(\[func,\] arr1, …) {#arrayexistsfunc-arr1}
|
|
||||||
|
|
||||||
Returns 1 if there is at least one element in ‘arr’ for which ‘func’ returns something other than 0. Otherwise, it returns 0.
|
|
||||||
|
|
||||||
### arrayAll(\[func,\] arr1, …) {#arrayallfunc-arr1}
|
|
||||||
|
|
||||||
Returns 1 if ‘func’ returns something other than 0 for all the elements in ‘arr’. Otherwise, it returns 0.
|
|
||||||
|
|
||||||
### arraySum(\[func,\] arr1, …) {#higher-order-functions-array-sum}
|
|
||||||
|
|
||||||
Returns the sum of the ‘func’ values. If the function is omitted, it just returns the sum of the array elements.
|
|
||||||
|
|
||||||
### arrayFirst(func, arr1, …) {#higher_order_functions-array-first}
|
|
||||||
|
|
||||||
Returns the first element in the ‘arr1’ array for which ‘func’ returns something other than 0.
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arrayFirst` function.
|
|
||||||
|
|
||||||
### arrayFirstIndex(func, arr1, …) {#higher_order_functions-array-first-index}
|
|
||||||
|
|
||||||
Returns the index of the first element in the ‘arr1’ array for which ‘func’ returns something other than 0.
|
|
||||||
|
|
||||||
Note that the first argument (lambda function) can’t be omitted in the `arrayFirstIndex` function.
|
|
||||||
|
|
||||||
### arrayCumSum(\[func,\] arr1, …) {#arraycumsumfunc-arr1}
|
|
||||||
|
|
||||||
Returns an array of partial sums of elements in the source array (a running sum). If the `func` function is specified, then the values of the array elements are converted by this function before summing.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayCumSum([1, 1, 1, 1]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res──────────┐
|
|
||||||
│ [1, 2, 3, 4] │
|
|
||||||
└──────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### arrayCumSumNonNegative(arr) {#arraycumsumnonnegativearr}
|
|
||||||
|
|
||||||
Same as `arrayCumSum`, returns an array of partial sums of elements in the source array (a running sum). Different `arrayCumSum`, when then returned value contains a value less than zero, the value is replace with zero and the subsequent calculation is performed with zero parameters. For example:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayCumSumNonNegative([1, 1, -4, 1]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res───────┐
|
|
||||||
│ [1,2,0,1] │
|
|
||||||
└───────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### arraySort(\[func,\] arr1, …) {#arraysortfunc-arr1}
|
|
||||||
|
|
||||||
Returns an array as result of sorting the elements of `arr1` in ascending order. If the `func` function is specified, sorting order is determined by the result of the function `func` applied to the elements of array (arrays)
|
|
||||||
|
|
||||||
The [Schwartzian transform](https://en.wikipedia.org/wiki/Schwartzian_transform) is used to improve sorting efficiency.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arraySort((x, y) -> y, ['hello', 'world'], [2, 1]);
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res────────────────┐
|
|
||||||
│ ['world', 'hello'] │
|
|
||||||
└────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
For more information about the `arraySort` method, see the [Functions for Working With Arrays](../../sql-reference/functions/array-functions.md#array_functions-sort) section.
|
|
||||||
|
|
||||||
### arrayReverseSort(\[func,\] arr1, …) {#arrayreversesortfunc-arr1}
|
|
||||||
|
|
||||||
Returns an array as result of sorting the elements of `arr1` in descending order. If the `func` function is specified, sorting order is determined by the result of the function `func` applied to the elements of array (arrays).
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayReverseSort((x, y) -> y, ['hello', 'world'], [2, 1]) as res;
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res───────────────┐
|
|
||||||
│ ['hello','world'] │
|
|
||||||
└───────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
For more information about the `arrayReverseSort` method, see the [Functions for Working With Arrays](../../sql-reference/functions/array-functions.md#array_functions-reverse-sort) section.
|
|
||||||
|
|
||||||
[Original article](https://clickhouse.tech/docs/en/query_language/functions/higher_order_functions/) <!--hide-->
|
|
@ -44,6 +44,21 @@ Functions have the following behaviors:
|
|||||||
|
|
||||||
Functions can’t change the values of their arguments – any changes are returned as the result. Thus, the result of calculating separate functions does not depend on the order in which the functions are written in the query.
|
Functions can’t change the values of their arguments – any changes are returned as the result. Thus, the result of calculating separate functions does not depend on the order in which the functions are written in the query.
|
||||||
|
|
||||||
|
## Higher-order functions, `->` operator and lambda(params, expr) function {#higher-order-functions}
|
||||||
|
|
||||||
|
Higher-order functions can only accept lambda functions as their functional argument. To pass a lambda function to a higher-order function use `->` operator. The left side of the arrow has a formal parameter, which is any ID, or multiple formal parameters – any IDs in a tuple. The right side of the arrow has an expression that can use these formal parameters, as well as any table columns.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```
|
||||||
|
x -> 2 * x
|
||||||
|
str -> str != Referer
|
||||||
|
```
|
||||||
|
|
||||||
|
A lambda function that accepts multiple arguments can also be passed to a higher-order function. In this case, the higher-order function is passed several arrays of identical length that these arguments will correspond to.
|
||||||
|
|
||||||
|
For some functions the first argument (the lambda function) can be omitted. In this case, identical mapping is assumed.
|
||||||
|
|
||||||
## Error Handling {#error-handling}
|
## Error Handling {#error-handling}
|
||||||
|
|
||||||
Some functions might throw an exception if the data is invalid. In this case, the query is canceled and an error text is returned to the client. For distributed processing, when an exception occurs on one of the servers, the other servers also attempt to abort the query.
|
Some functions might throw an exception if the data is invalid. In this case, the query is canceled and an error text is returned to the client. For distributed processing, when an exception occurs on one of the servers, the other servers also attempt to abort the query.
|
||||||
|
@ -98,7 +98,7 @@ LIMIT 1
|
|||||||
\G
|
\G
|
||||||
```
|
```
|
||||||
|
|
||||||
The [arrayMap](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-map) function allows to process each individual element of the `trace` array by the `addressToLine` function. The result of this processing you see in the `trace_source_code_lines` column of output.
|
The [arrayMap](../../sql-reference/functions/array-functions.md#array-map) function allows to process each individual element of the `trace` array by the `addressToLine` function. The result of this processing you see in the `trace_source_code_lines` column of output.
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
Row 1:
|
Row 1:
|
||||||
@ -184,7 +184,7 @@ LIMIT 1
|
|||||||
\G
|
\G
|
||||||
```
|
```
|
||||||
|
|
||||||
The [arrayMap](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-map) function allows to process each individual element of the `trace` array by the `addressToSymbols` function. The result of this processing you see in the `trace_symbols` column of output.
|
The [arrayMap](../../sql-reference/functions/array-functions.md#array-map) function allows to process each individual element of the `trace` array by the `addressToSymbols` function. The result of this processing you see in the `trace_symbols` column of output.
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
Row 1:
|
Row 1:
|
||||||
@ -281,7 +281,7 @@ LIMIT 1
|
|||||||
\G
|
\G
|
||||||
```
|
```
|
||||||
|
|
||||||
The [arrayMap](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-map) function allows to process each individual element of the `trace` array by the `demangle` function. The result of this processing you see in the `trace_functions` column of output.
|
The [arrayMap](../../sql-reference/functions/array-functions.md#array-map) function allows to process each individual element of the `trace` array by the `demangle` function. The result of this processing you see in the `trace_functions` column of output.
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
Row 1:
|
Row 1:
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
---
|
||||||
|
toc_priority: 30
|
||||||
|
toc_title: MergeTree
|
||||||
|
---
|
||||||
|
|
||||||
# MergeTree {#table_engines-mergetree}
|
# MergeTree {#table_engines-mergetree}
|
||||||
|
|
||||||
Движок `MergeTree`, а также другие движки этого семейства (`*MergeTree`) — это наиболее функциональные движки таблиц ClickHouse.
|
Движок `MergeTree`, а также другие движки этого семейства (`*MergeTree`) — это наиболее функциональные движки таблиц ClickHouse.
|
||||||
@ -28,8 +33,8 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
|||||||
INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
|
INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
|
||||||
INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
|
INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
|
||||||
) ENGINE = MergeTree()
|
) ENGINE = MergeTree()
|
||||||
|
ORDER BY expr
|
||||||
[PARTITION BY expr]
|
[PARTITION BY expr]
|
||||||
[ORDER BY expr]
|
|
||||||
[PRIMARY KEY expr]
|
[PRIMARY KEY expr]
|
||||||
[SAMPLE BY expr]
|
[SAMPLE BY expr]
|
||||||
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
|
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
|
||||||
@ -38,27 +43,42 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
|||||||
|
|
||||||
Описание параметров смотрите в [описании запроса CREATE](../../../engines/table-engines/mergetree-family/mergetree.md).
|
Описание параметров смотрите в [описании запроса CREATE](../../../engines/table-engines/mergetree-family/mergetree.md).
|
||||||
|
|
||||||
!!! note "Note"
|
!!! note "Примечание"
|
||||||
`INDEX` — экспериментальная возможность, смотрите [Индексы пропуска данных](#table_engine-mergetree-data_skipping-indexes).
|
`INDEX` — экспериментальная возможность, смотрите [Индексы пропуска данных](#table_engine-mergetree-data_skipping-indexes).
|
||||||
|
|
||||||
### Секции запроса {#mergetree-query-clauses}
|
### Секции запроса {#mergetree-query-clauses}
|
||||||
|
|
||||||
- `ENGINE` — имя и параметры движка. `ENGINE = MergeTree()`. `MergeTree` не имеет параметров.
|
- `ENGINE` — имя и параметры движка. `ENGINE = MergeTree()`. `MergeTree` не имеет параметров.
|
||||||
|
|
||||||
- `PARTITION BY` — [ключ партиционирования](custom-partitioning-key.md). Для партиционирования по месяцам используйте выражение `toYYYYMM(date_column)`, где `date_column` — столбец с датой типа [Date](../../../engines/table-engines/mergetree-family/mergetree.md). В этом случае имена партиций имеют формат `"YYYYMM"`.
|
- `ORDER BY` — ключ сортировки.
|
||||||
|
|
||||||
|
Кортеж столбцов или произвольных выражений. Пример: `ORDER BY (CounterID, EventDate)`.
|
||||||
|
|
||||||
- `ORDER BY` — ключ сортировки. Кортеж столбцов или произвольных выражений. Пример: `ORDER BY (CounterID, EventDate)`.
|
ClickHouse использует ключ сортировки в качестве первичного ключа, если первичный ключ не задан в секции `PRIMARY KEY`.
|
||||||
|
|
||||||
- `PRIMARY KEY` — первичный ключ, если он [отличается от ключа сортировки](#pervichnyi-kliuch-otlichnyi-ot-kliucha-sortirovki). По умолчанию первичный ключ совпадает с ключом сортировки (который задаётся секцией `ORDER BY`.) Поэтому в большинстве случаев секцию `PRIMARY KEY` отдельно указывать не нужно.
|
Чтобы отключить сортировку, используйте синтаксис `ORDER BY tuple()`. Смотрите [выбор первичного ключа](#vybor-pervichnogo-kliucha).
|
||||||
|
|
||||||
- `SAMPLE BY` — выражение для сэмплирования. Если используется выражение для сэмплирования, то первичный ключ должен содержать его. Пример: `SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID))`.
|
- `PARTITION BY` — [ключ партиционирования](custom-partitioning-key.md). Необязательный параметр.
|
||||||
|
|
||||||
- `TTL` — список правил, определяющих длительности хранения строк, а также задающих правила перемещения частей на определённые тома или диски. Выражение должно возвращать столбец `Date` или `DateTime`. Пример: `TTL date + INTERVAL 1 DAY`.
|
Для партиционирования по месяцам используйте выражение `toYYYYMM(date_column)`, где `date_column` — столбец с датой типа [Date](../../../engines/table-engines/mergetree-family/mergetree.md). В этом случае имена партиций имеют формат `"YYYYMM"`.
|
||||||
- Тип правила `DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'` указывает действие, которое будет выполнено с частью, удаление строк (прореживание), перемещение (при выполнении условия для всех строк части) на определённый диск (`TO DISK 'xxx'`) или том (`TO VOLUME 'xxx'`).
|
|
||||||
- Поведение по умолчанию соответствует удалению строк (`DELETE`). В списке правил может быть указано только одно выражение с поведением `DELETE`.
|
|
||||||
- Дополнительные сведения смотрите в разделе [TTL для столбцов и таблиц](#table_engine-mergetree-ttl)
|
|
||||||
|
|
||||||
- `SETTINGS` — дополнительные параметры, регулирующие поведение `MergeTree`:
|
- `PRIMARY KEY` — первичный ключ, если он [отличается от ключа сортировки](#pervichnyi-kliuch-otlichnyi-ot-kliucha-sortirovki). Необязательный параметр.
|
||||||
|
|
||||||
|
По умолчанию первичный ключ совпадает с ключом сортировки (который задаётся секцией `ORDER BY`.) Поэтому в большинстве случаев секцию `PRIMARY KEY` отдельно указывать не нужно.
|
||||||
|
|
||||||
|
- `SAMPLE BY` — выражение для сэмплирования. Необязательный параметр.
|
||||||
|
|
||||||
|
Если используется выражение для сэмплирования, то первичный ключ должен содержать его. Пример: `SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID))`.
|
||||||
|
|
||||||
|
- `TTL` — список правил, определяющих длительности хранения строк, а также задающих правила перемещения частей на определённые тома или диски. Необязательный параметр.
|
||||||
|
|
||||||
|
Выражение должно возвращать столбец `Date` или `DateTime`. Пример: `TTL date + INTERVAL 1 DAY`.
|
||||||
|
|
||||||
|
Тип правила `DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'` указывает действие, которое будет выполнено с частью, удаление строк (прореживание), перемещение (при выполнении условия для всех строк части) на определённый диск (`TO DISK 'xxx'`) или том (`TO VOLUME 'xxx'`). Поведение по умолчанию соответствует удалению строк (`DELETE`). В списке правил может быть указано только одно выражение с поведением `DELETE`.
|
||||||
|
|
||||||
|
Дополнительные сведения смотрите в разделе [TTL для столбцов и таблиц](#table_engine-mergetree-ttl)
|
||||||
|
|
||||||
|
- `SETTINGS` — дополнительные параметры, регулирующие поведение `MergeTree` (необязательные):
|
||||||
|
|
||||||
- `index_granularity` — максимальное количество строк данных между засечками индекса. По умолчанию — 8192. Смотрите [Хранение данных](#mergetree-data-storage).
|
- `index_granularity` — максимальное количество строк данных между засечками индекса. По умолчанию — 8192. Смотрите [Хранение данных](#mergetree-data-storage).
|
||||||
- `index_granularity_bytes` — максимальный размер гранул данных в байтах. По умолчанию — 10Mb. Чтобы ограничить размер гранул только количеством строк, установите значение 0 (не рекомендовано). Смотрите [Хранение данных](#mergetree-data-storage).
|
- `index_granularity_bytes` — максимальный размер гранул данных в байтах. По умолчанию — 10Mb. Чтобы ограничить размер гранул только количеством строк, установите значение 0 (не рекомендовано). Смотрите [Хранение данных](#mergetree-data-storage).
|
||||||
@ -180,6 +200,14 @@ ClickHouse не требует уникального первичного кл
|
|||||||
|
|
||||||
Длинный первичный ключ будет негативно влиять на производительность вставки и потребление памяти, однако на производительность ClickHouse при запросах `SELECT` лишние столбцы в первичном ключе не влияют.
|
Длинный первичный ключ будет негативно влиять на производительность вставки и потребление памяти, однако на производительность ClickHouse при запросах `SELECT` лишние столбцы в первичном ключе не влияют.
|
||||||
|
|
||||||
|
Вы можете создать таблицу без первичного ключа, используя синтаксис `ORDER BY tuple()`. В этом случае ClickHouse хранит данные в порядке вставки. Если вы хотите сохранить порядок данных при вставке данных с помощью запросов `INSERT ... SELECT`, установите [max\_insert\_threads = 1](../../../operations/settings/settings.md#settings-max-insert-threads).
|
||||||
|
|
||||||
|
Чтобы выбрать данные в первоначальном порядке, используйте
|
||||||
|
[однопоточные](../../../operations/settings/settings.md#settings-max_threads) запросы `SELECT.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Первичный ключ, отличный от ключа сортировки {#pervichnyi-kliuch-otlichnyi-ot-kliucha-sortirovki}
|
### Первичный ключ, отличный от ключа сортировки {#pervichnyi-kliuch-otlichnyi-ot-kliucha-sortirovki}
|
||||||
|
|
||||||
Существует возможность задать первичный ключ (выражение, значения которого будут записаны в индексный файл для
|
Существует возможность задать первичный ключ (выражение, значения которого будут записаны в индексный файл для
|
||||||
|
4
docs/ru/interfaces/third-party/gui.md
vendored
4
docs/ru/interfaces/third-party/gui.md
vendored
@ -93,6 +93,10 @@
|
|||||||
|
|
||||||
[cickhouse-plantuml](https://pypi.org/project/clickhouse-plantuml/) — скрипт, генерирующий [PlantUML](https://plantuml.com/) диаграммы схем таблиц.
|
[cickhouse-plantuml](https://pypi.org/project/clickhouse-plantuml/) — скрипт, генерирующий [PlantUML](https://plantuml.com/) диаграммы схем таблиц.
|
||||||
|
|
||||||
|
### xeus-clickhouse {#xeus-clickhouse}
|
||||||
|
|
||||||
|
[xeus-clickhouse](https://github.com/wangfenjin/xeus-clickhouse) — это ядро Jupyter для ClickHouse, которое поддерживает запрос ClickHouse-данных с использованием SQL в Jupyter.
|
||||||
|
|
||||||
## Коммерческие {#kommercheskie}
|
## Коммерческие {#kommercheskie}
|
||||||
|
|
||||||
### DataGrip {#datagrip}
|
### DataGrip {#datagrip}
|
||||||
|
@ -7,10 +7,38 @@ toc_title: Системные таблицы
|
|||||||
|
|
||||||
## Введение {#system-tables-introduction}
|
## Введение {#system-tables-introduction}
|
||||||
|
|
||||||
Системные таблицы используются для реализации части функциональности системы, а также предоставляют доступ к информации о работе системы.
|
Системные таблицы содержат информацию о:
|
||||||
Вы не можете удалить системную таблицу (хотя можете сделать DETACH).
|
|
||||||
Для системных таблиц нет файлов с данными на диске и файлов с метаданными. Сервер создаёт все системные таблицы при старте.
|
- Состоянии сервера, процессов и окружении.
|
||||||
В системные таблицы нельзя записывать данные - можно только читать.
|
- Внутренних процессах сервера.
|
||||||
Системные таблицы расположены в базе данных system.
|
|
||||||
|
Системные таблицы:
|
||||||
|
|
||||||
|
- Находятся в базе данных `system`.
|
||||||
|
- Доступны только для чтения данных.
|
||||||
|
- Не могут быть удалены или изменены, но их можно отсоединить.
|
||||||
|
|
||||||
|
Системные таблицы `metric_log`, `query_log`, `query_thread_log`, `trace_log` системные таблицы хранят данные в файловой системе. Остальные системные таблицы хранят свои данные в оперативной памяти. Сервер ClickHouse создает такие системные таблицы при запуске.
|
||||||
|
|
||||||
|
### Источники системных показателей
|
||||||
|
|
||||||
|
Для сбора системных показателей сервер ClickHouse использует:
|
||||||
|
|
||||||
|
- Возможности `CAP_NET_ADMIN`.
|
||||||
|
- [procfs](https://ru.wikipedia.org/wiki/Procfs) (только Linux).
|
||||||
|
|
||||||
|
**procfs**
|
||||||
|
|
||||||
|
Если для сервера ClickHouse не включено `CAP_NET_ADMIN`, он пытается обратиться к `ProcfsMetricsProvider`. `ProcfsMetricsProvider` позволяет собирать системные показатели для каждого запроса (для CPU и I/O).
|
||||||
|
|
||||||
|
Если procfs поддерживается и включена в системе, то сервер ClickHouse собирает следующие системные показатели:
|
||||||
|
|
||||||
|
- `OSCPUVirtualTimeMicroseconds`
|
||||||
|
- `OSCPUWaitMicroseconds`
|
||||||
|
- `OSIOWaitMicroseconds`
|
||||||
|
- `OSReadChars`
|
||||||
|
- `OSWriteChars`
|
||||||
|
- `OSReadBytes`
|
||||||
|
- `OSWriteBytes`
|
||||||
|
|
||||||
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system-tables/) <!--hide-->
|
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system-tables/) <!--hide-->
|
||||||
|
@ -82,7 +82,7 @@ res: /lib/x86_64-linux-gnu/libc-2.27.so
|
|||||||
|
|
||||||
- [Функции интроспекции](../../sql-reference/functions/introspection.md) — Что такое функции интроспекции и как их использовать.
|
- [Функции интроспекции](../../sql-reference/functions/introspection.md) — Что такое функции интроспекции и как их использовать.
|
||||||
- [system.trace_log](../../operations/system-tables/trace_log.md#system_tables-trace_log) — Содержит трассировки стека, собранные профилировщиком выборочных запросов.
|
- [system.trace_log](../../operations/system-tables/trace_log.md#system_tables-trace_log) — Содержит трассировки стека, собранные профилировщиком выборочных запросов.
|
||||||
- [arrayMap](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-map) — Описание и пример использования функции `arrayMap`.
|
- [arrayMap](../../sql-reference/functions/array-functions.md#array-map) — Описание и пример использования функции `arrayMap`.
|
||||||
- [arrayFilter](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-filter) — Описание и пример использования функции `arrayFilter`.
|
- [arrayFilter](../../sql-reference/functions/array-functions.md#array-filter) — Описание и пример использования функции `arrayFilter`.
|
||||||
|
|
||||||
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system_tables/stack_trace) <!--hide-->
|
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/system_tables/stack_trace) <!--hide-->
|
||||||
|
@ -9,6 +9,7 @@ The following aggregate functions are supported:
|
|||||||
- [`min`](../../sql-reference/aggregate-functions/reference/min.md#agg_function-min)
|
- [`min`](../../sql-reference/aggregate-functions/reference/min.md#agg_function-min)
|
||||||
- [`max`](../../sql-reference/aggregate-functions/reference/max.md#agg_function-max)
|
- [`max`](../../sql-reference/aggregate-functions/reference/max.md#agg_function-max)
|
||||||
- [`sum`](../../sql-reference/aggregate-functions/reference/sum.md#agg_function-sum)
|
- [`sum`](../../sql-reference/aggregate-functions/reference/sum.md#agg_function-sum)
|
||||||
|
- [`sumWithOverflow`](../../sql-reference/aggregate-functions/reference/sumwithoverflow.md#sumwithoverflowx)
|
||||||
- [`groupBitAnd`](../../sql-reference/aggregate-functions/reference/groupbitand.md#groupbitand)
|
- [`groupBitAnd`](../../sql-reference/aggregate-functions/reference/groupbitand.md#groupbitand)
|
||||||
- [`groupBitOr`](../../sql-reference/aggregate-functions/reference/groupbitor.md#groupbitor)
|
- [`groupBitOr`](../../sql-reference/aggregate-functions/reference/groupbitor.md#groupbitor)
|
||||||
- [`groupBitXor`](../../sql-reference/aggregate-functions/reference/groupbitxor.md#groupbitxor)
|
- [`groupBitXor`](../../sql-reference/aggregate-functions/reference/groupbitxor.md#groupbitxor)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Кортеж из элементов любого [типа](index.md#data_types). Элементы кортежа могут быть одного или разных типов.
|
Кортеж из элементов любого [типа](index.md#data_types). Элементы кортежа могут быть одного или разных типов.
|
||||||
|
|
||||||
Кортежи используются для временной группировки столбцов. Столбцы могут группироваться при использовании выражения IN в запросе, а также для указания нескольких формальных параметров лямбда-функций. Подробнее смотрите разделы [Операторы IN](../../sql-reference/data-types/tuple.md), [Функции высшего порядка](../../sql-reference/functions/higher-order-functions.md#higher-order-functions).
|
Кортежи используются для временной группировки столбцов. Столбцы могут группироваться при использовании выражения IN в запросе, а также для указания нескольких формальных параметров лямбда-функций. Подробнее смотрите разделы [Операторы IN](../../sql-reference/data-types/tuple.md), [Функции высшего порядка](../../sql-reference/functions/index.md#higher-order-functions).
|
||||||
|
|
||||||
Кортежи могут быть результатом запроса. В этом случае, в текстовых форматах кроме JSON, значения выводятся в круглых скобках через запятую. В форматах JSON, кортежи выводятся в виде массивов (в квадратных скобках).
|
Кортежи могут быть результатом запроса. В этом случае, в текстовых форматах кроме JSON, значения выводятся в круглых скобках через запятую. В форматах JSON, кортежи выводятся в виде массивов (в квадратных скобках).
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Функции по работе с массивами {#funktsii-po-rabote-s-massivami}
|
# Массивы {#functions-for-working-with-arrays}
|
||||||
|
|
||||||
## empty {#function-empty}
|
## empty {#function-empty}
|
||||||
|
|
||||||
@ -186,6 +186,13 @@ SELECT indexOf([1, 3, NULL, NULL], NULL)
|
|||||||
|
|
||||||
Элементы, равные `NULL`, обрабатываются как обычные значения.
|
Элементы, равные `NULL`, обрабатываются как обычные значения.
|
||||||
|
|
||||||
|
## arrayCount(\[func,\] arr1, …) {#array-count}
|
||||||
|
|
||||||
|
Возвращает количество элементов массива `arr`, для которых функция `func` возвращает не 0. Если `func` не указана - возвращает количество ненулевых элементов массива.
|
||||||
|
|
||||||
|
Функция `arrayCount` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) — в качестве первого аргумента ей можно передать лямбда-функцию.
|
||||||
|
|
||||||
|
|
||||||
## countEqual(arr, x) {#countequalarr-x}
|
## countEqual(arr, x) {#countequalarr-x}
|
||||||
|
|
||||||
Возвращает количество элементов массива, равных x. Эквивалентно arrayCount(elem -\> elem = x, arr).
|
Возвращает количество элементов массива, равных x. Эквивалентно arrayCount(elem -\> elem = x, arr).
|
||||||
@ -513,7 +520,7 @@ SELECT arraySort([1, nan, 2, NULL, 3, nan, -4, NULL, inf, -inf]);
|
|||||||
- Значения `NaN` идут перед `NULL`.
|
- Значения `NaN` идут перед `NULL`.
|
||||||
- Значения `Inf` идут перед `NaN`.
|
- Значения `Inf` идут перед `NaN`.
|
||||||
|
|
||||||
Функция `arraySort` является [функцией высшего порядка](higher-order-functions.md) — в качестве первого аргумента ей можно передать лямбда-функцию. В этом случае порядок сортировки определяется результатом применения лямбда-функции на элементы массива.
|
Функция `arraySort` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) — в качестве первого аргумента ей можно передать лямбда-функцию. В этом случае порядок сортировки определяется результатом применения лямбда-функции на элементы массива.
|
||||||
|
|
||||||
Рассмотрим пример:
|
Рассмотрим пример:
|
||||||
|
|
||||||
@ -613,7 +620,7 @@ SELECT arrayReverseSort([1, nan, 2, NULL, 3, nan, -4, NULL, inf, -inf]) as res;
|
|||||||
- Значения `NaN` идут перед `NULL`.
|
- Значения `NaN` идут перед `NULL`.
|
||||||
- Значения `-Inf` идут перед `NaN`.
|
- Значения `-Inf` идут перед `NaN`.
|
||||||
|
|
||||||
Функция `arrayReverseSort` является [функцией высшего порядка](higher-order-functions.md). Вы можете передать ей в качестве первого аргумента лямбда-функцию. Например:
|
Функция `arrayReverseSort` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) — в качестве первого аргумента ей можно передать лямбда-функцию. Например:
|
||||||
|
|
||||||
``` sql
|
``` sql
|
||||||
SELECT arrayReverseSort((x) -> -x, [1, 2, 3]) as res;
|
SELECT arrayReverseSort((x) -> -x, [1, 2, 3]) as res;
|
||||||
@ -1036,6 +1043,116 @@ SELECT arrayZip(['a', 'b', 'c'], [5, 2, 1])
|
|||||||
└──────────────────────────────────────┘
|
└──────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## arrayMap(func, arr1, …) {#array-map}
|
||||||
|
|
||||||
|
Возвращает массив, полученный на основе результатов применения функции `func` к каждому элементу массива `arr`.
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayMap(x -> (x + 2), [1, 2, 3]) as res;
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res─────┐
|
||||||
|
│ [3,4,5] │
|
||||||
|
└─────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Следующий пример показывает, как создать кортежи из элементов разных массивов:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayMap((x, y) -> (x, y), [1, 2, 3], [4, 5, 6]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res─────────────────┐
|
||||||
|
│ [(1,4),(2,5),(3,6)] │
|
||||||
|
└─────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Функция `arrayMap` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) — в качестве первого аргумента ей нужно передать лямбда-функцию, и этот аргумент не может быть опущен.
|
||||||
|
|
||||||
|
## arrayFilter(func, arr1, …) {#array-filter}
|
||||||
|
|
||||||
|
Возвращает массив, содержащий только те элементы массива `arr1`, для которых функция `func` возвращает не 0.
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayFilter(x -> x LIKE '%World%', ['Hello', 'abc World']) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res───────────┐
|
||||||
|
│ ['abc World'] │
|
||||||
|
└───────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT
|
||||||
|
arrayFilter(
|
||||||
|
(i, x) -> x LIKE '%World%',
|
||||||
|
arrayEnumerate(arr),
|
||||||
|
['Hello', 'abc World'] AS arr)
|
||||||
|
AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res─┐
|
||||||
|
│ [2] │
|
||||||
|
└─────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Функция `arrayFilter` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) — в качестве первого аргумента ей нужно передать лямбда-функцию, и этот аргумент не может быть опущен.
|
||||||
|
|
||||||
|
## arrayExists(\[func,\] arr1, …) {#arrayexistsfunc-arr1}
|
||||||
|
|
||||||
|
Возвращает 1, если существует хотя бы один элемент массива `arr`, для которого функция func возвращает не 0. Иначе возвращает 0.
|
||||||
|
|
||||||
|
Функция `arrayExists` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) - в качестве первого аргумента ей можно передать лямбда-функцию.
|
||||||
|
|
||||||
|
## arrayAll(\[func,\] arr1, …) {#arrayallfunc-arr1}
|
||||||
|
|
||||||
|
Возвращает 1, если для всех элементов массива `arr`, функция `func` возвращает не 0. Иначе возвращает 0.
|
||||||
|
|
||||||
|
Функция `arrayAll` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) - в качестве первого аргумента ей можно передать лямбда-функцию.
|
||||||
|
|
||||||
|
## arrayFirst(func, arr1, …) {#array-first}
|
||||||
|
|
||||||
|
Возвращает первый элемент массива `arr1`, для которого функция func возвращает не 0.
|
||||||
|
|
||||||
|
Функция `arrayFirst` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) — в качестве первого аргумента ей нужно передать лямбда-функцию, и этот аргумент не может быть опущен.
|
||||||
|
|
||||||
|
## arrayFirstIndex(func, arr1, …) {#array-first-index}
|
||||||
|
|
||||||
|
Возвращает индекс первого элемента массива `arr1`, для которого функция func возвращает не 0.
|
||||||
|
|
||||||
|
Функция `arrayFirstIndex` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) — в качестве первого аргумента ей нужно передать лямбда-функцию, и этот аргумент не может быть опущен.
|
||||||
|
|
||||||
|
## arraySum(\[func,\] arr1, …) {#array-sum}
|
||||||
|
|
||||||
|
Возвращает сумму значений функции `func`. Если функция не указана - просто возвращает сумму элементов массива.
|
||||||
|
|
||||||
|
Функция `arraySum` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) - в качестве первого аргумента ей можно передать лямбда-функцию.
|
||||||
|
|
||||||
|
## arrayCumSum(\[func,\] arr1, …) {#arraycumsumfunc-arr1}
|
||||||
|
|
||||||
|
Возвращает массив из частичных сумм элементов исходного массива (сумма с накоплением). Если указана функция `func`, то значения элементов массива преобразуются этой функцией перед суммированием.
|
||||||
|
|
||||||
|
Функция `arrayCumSum` является [функцией высшего порядка](../../sql-reference/functions/index.md#higher-order-functions) - в качестве первого аргумента ей можно передать лямбда-функцию.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
SELECT arrayCumSum([1, 1, 1, 1]) AS res
|
||||||
|
```
|
||||||
|
|
||||||
|
``` text
|
||||||
|
┌─res──────────┐
|
||||||
|
│ [1, 2, 3, 4] │
|
||||||
|
└──────────────┘
|
||||||
|
|
||||||
## arrayAUC {#arrayauc}
|
## arrayAUC {#arrayauc}
|
||||||
|
|
||||||
Вычисляет площадь под кривой.
|
Вычисляет площадь под кривой.
|
||||||
|
@ -1,167 +0,0 @@
|
|||||||
# Функции высшего порядка {#higher-order-functions}
|
|
||||||
|
|
||||||
## Оператор `->`, функция lambda(params, expr) {#operator-funktsiia-lambdaparams-expr}
|
|
||||||
|
|
||||||
Позволяет описать лямбда-функцию для передачи в функцию высшего порядка. Слева от стрелочки стоит формальный параметр - произвольный идентификатор, или несколько формальных параметров - произвольные идентификаторы в кортеже. Справа от стрелочки стоит выражение, в котором могут использоваться эти формальные параметры, а также любые столбцы таблицы.
|
|
||||||
|
|
||||||
Примеры: `x -> 2 * x, str -> str != Referer.`
|
|
||||||
|
|
||||||
Функции высшего порядка, в качестве своего функционального аргумента могут принимать только лямбда-функции.
|
|
||||||
|
|
||||||
В функции высшего порядка может быть передана лямбда-функция, принимающая несколько аргументов. В этом случае, в функцию высшего порядка передаётся несколько массивов одинаковых длин, которым эти аргументы будут соответствовать.
|
|
||||||
|
|
||||||
Для некоторых функций, например [arrayCount](#higher_order_functions-array-count) или [arraySum](#higher_order_functions-array-sum), первый аргумент (лямбда-функция) может отсутствовать. В этом случае, подразумевается тождественное отображение.
|
|
||||||
|
|
||||||
Для функций, перечисленных ниже, лямбда-функцию должна быть указана всегда:
|
|
||||||
|
|
||||||
- [arrayMap](#higher_order_functions-array-map)
|
|
||||||
- [arrayFilter](#higher_order_functions-array-filter)
|
|
||||||
- [arrayFirst](#higher_order_functions-array-first)
|
|
||||||
- [arrayFirstIndex](#higher_order_functions-array-first-index)
|
|
||||||
|
|
||||||
### arrayMap(func, arr1, …) {#higher_order_functions-array-map}
|
|
||||||
|
|
||||||
Вернуть массив, полученный на основе результатов применения функции `func` к каждому элементу массива `arr`.
|
|
||||||
|
|
||||||
Примеры:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayMap(x -> (x + 2), [1, 2, 3]) as res;
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res─────┐
|
|
||||||
│ [3,4,5] │
|
|
||||||
└─────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Следующий пример показывает, как создать кортежи из элементов разных массивов:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayMap((x, y) -> (x, y), [1, 2, 3], [4, 5, 6]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res─────────────────┐
|
|
||||||
│ [(1,4),(2,5),(3,6)] │
|
|
||||||
└─────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Обратите внимание, что у функции `arrayMap` первый аргумент (лямбда-функция) не может быть опущен.
|
|
||||||
|
|
||||||
### arrayFilter(func, arr1, …) {#higher_order_functions-array-filter}
|
|
||||||
|
|
||||||
Вернуть массив, содержащий только те элементы массива `arr1`, для которых функция `func` возвращает не 0.
|
|
||||||
|
|
||||||
Примеры:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayFilter(x -> x LIKE '%World%', ['Hello', 'abc World']) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res───────────┐
|
|
||||||
│ ['abc World'] │
|
|
||||||
└───────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT
|
|
||||||
arrayFilter(
|
|
||||||
(i, x) -> x LIKE '%World%',
|
|
||||||
arrayEnumerate(arr),
|
|
||||||
['Hello', 'abc World'] AS arr)
|
|
||||||
AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res─┐
|
|
||||||
│ [2] │
|
|
||||||
└─────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Обратите внимание, что у функции `arrayFilter` первый аргумент (лямбда-функция) не может быть опущен.
|
|
||||||
|
|
||||||
### arrayCount(\[func,\] arr1, …) {#higher_order_functions-array-count}
|
|
||||||
|
|
||||||
Вернуть количество элементов массива `arr`, для которых функция func возвращает не 0. Если func не указана - вернуть количество ненулевых элементов массива.
|
|
||||||
|
|
||||||
### arrayExists(\[func,\] arr1, …) {#arrayexistsfunc-arr1}
|
|
||||||
|
|
||||||
Вернуть 1, если существует хотя бы один элемент массива `arr`, для которого функция func возвращает не 0. Иначе вернуть 0.
|
|
||||||
|
|
||||||
### arrayAll(\[func,\] arr1, …) {#arrayallfunc-arr1}
|
|
||||||
|
|
||||||
Вернуть 1, если для всех элементов массива `arr`, функция `func` возвращает не 0. Иначе вернуть 0.
|
|
||||||
|
|
||||||
### arraySum(\[func,\] arr1, …) {#higher_order_functions-array-sum}
|
|
||||||
|
|
||||||
Вернуть сумму значений функции `func`. Если функция не указана - просто вернуть сумму элементов массива.
|
|
||||||
|
|
||||||
### arrayFirst(func, arr1, …) {#higher_order_functions-array-first}
|
|
||||||
|
|
||||||
Вернуть первый элемент массива `arr1`, для которого функция func возвращает не 0.
|
|
||||||
|
|
||||||
Обратите внимание, что у функции `arrayFirst` первый аргумент (лямбда-функция) не может быть опущен.
|
|
||||||
|
|
||||||
### arrayFirstIndex(func, arr1, …) {#higher_order_functions-array-first-index}
|
|
||||||
|
|
||||||
Вернуть индекс первого элемента массива `arr1`, для которого функция func возвращает не 0.
|
|
||||||
|
|
||||||
Обратите внимание, что у функции `arrayFirstFilter` первый аргумент (лямбда-функция) не может быть опущен.
|
|
||||||
|
|
||||||
### arrayCumSum(\[func,\] arr1, …) {#arraycumsumfunc-arr1}
|
|
||||||
|
|
||||||
Возвращает массив из частичных сумм элементов исходного массива (сумма с накоплением). Если указана функция `func`, то значения элементов массива преобразуются этой функцией перед суммированием.
|
|
||||||
|
|
||||||
Пример:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayCumSum([1, 1, 1, 1]) AS res
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res──────────┐
|
|
||||||
│ [1, 2, 3, 4] │
|
|
||||||
└──────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### arraySort(\[func,\] arr1, …) {#arraysortfunc-arr1}
|
|
||||||
|
|
||||||
Возвращает отсортированный в восходящем порядке массив `arr1`. Если задана функция `func`, то порядок сортировки определяется результатом применения функции `func` на элементы массива (массивов).
|
|
||||||
|
|
||||||
Для улучшения эффективности сортировки применяется [Преобразование Шварца](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%A8%D0%B2%D0%B0%D1%80%D1%86%D0%B0).
|
|
||||||
|
|
||||||
Пример:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arraySort((x, y) -> y, ['hello', 'world'], [2, 1]);
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res────────────────┐
|
|
||||||
│ ['world', 'hello'] │
|
|
||||||
└────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Подробная информация о методе `arraySort` приведена в разделе [Функции по работе с массивами](array-functions.md#array_functions-sort).
|
|
||||||
|
|
||||||
### arrayReverseSort(\[func,\] arr1, …) {#arrayreversesortfunc-arr1}
|
|
||||||
|
|
||||||
Возвращает отсортированный в нисходящем порядке массив `arr1`. Если задана функция `func`, то порядок сортировки определяется результатом применения функции `func` на элементы массива (массивов).
|
|
||||||
|
|
||||||
Пример:
|
|
||||||
|
|
||||||
``` sql
|
|
||||||
SELECT arrayReverseSort((x, y) -> y, ['hello', 'world'], [2, 1]) as res;
|
|
||||||
```
|
|
||||||
|
|
||||||
``` text
|
|
||||||
┌─res───────────────┐
|
|
||||||
│ ['hello','world'] │
|
|
||||||
└───────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Подробная информация о методе `arrayReverseSort` приведена в разделе [Функции по работе с массивами](array-functions.md#array_functions-reverse-sort).
|
|
||||||
|
|
||||||
[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/functions/higher_order_functions/) <!--hide-->
|
|
@ -38,6 +38,20 @@
|
|||||||
|
|
||||||
Функции не могут поменять значения своих аргументов - любые изменения возвращаются в качестве результата. Соответственно, от порядка записи функций в запросе, результат вычислений отдельных функций не зависит.
|
Функции не могут поменять значения своих аргументов - любые изменения возвращаются в качестве результата. Соответственно, от порядка записи функций в запросе, результат вычислений отдельных функций не зависит.
|
||||||
|
|
||||||
|
## Функции высшего порядка, оператор `->` и функция lambda(params, expr) {#higher-order-functions}
|
||||||
|
|
||||||
|
Функции высшего порядка, в качестве своего функционального аргумента могут принимать только лямбда-функции. Чтобы передать лямбда-функцию в функцию высшего порядка, используйте оператор `->`. Слева от стрелочки стоит формальный параметр — произвольный идентификатор, или несколько формальных параметров — произвольные идентификаторы в кортеже. Справа от стрелочки стоит выражение, в котором могут использоваться эти формальные параметры, а также любые столбцы таблицы.
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
```
|
||||||
|
x -> 2 * x
|
||||||
|
str -> str != Referer
|
||||||
|
```
|
||||||
|
|
||||||
|
В функции высшего порядка может быть передана лямбда-функция, принимающая несколько аргументов. В этом случае в функцию высшего порядка передаётся несколько массивов одинаковой длины, которым эти аргументы будут соответствовать.
|
||||||
|
|
||||||
|
Для некоторых функций первый аргумент (лямбда-функция) может отсутствовать. В этом случае подразумевается тождественное отображение.
|
||||||
|
|
||||||
## Обработка ошибок {#obrabotka-oshibok}
|
## Обработка ошибок {#obrabotka-oshibok}
|
||||||
|
|
||||||
Некоторые функции могут кидать исключения в случае ошибочных данных. В этом случае, выполнение запроса прерывается, и текст ошибки выводится клиенту. При распределённой обработке запроса, при возникновении исключения на одном из серверов, на другие серверы пытается отправиться просьба тоже прервать выполнение запроса.
|
Некоторые функции могут кидать исключения в случае ошибочных данных. В этом случае, выполнение запроса прерывается, и текст ошибки выводится клиенту. При распределённой обработке запроса, при возникновении исключения на одном из серверов, на другие серверы пытается отправиться просьба тоже прервать выполнение запроса.
|
||||||
|
@ -93,7 +93,7 @@ LIMIT 1
|
|||||||
\G
|
\G
|
||||||
```
|
```
|
||||||
|
|
||||||
Функция [arrayMap](higher-order-functions.md#higher_order_functions-array-map) позволяет обрабатывать каждый отдельный элемент массива `trace` с помощью функции `addressToLine`. Результат этой обработки вы видите в виде `trace_source_code_lines` колонки выходных данных.
|
Функция [arrayMap](../../sql-reference/functions/array-functions.md#array-map) позволяет обрабатывать каждый отдельный элемент массива `trace` с помощью функции `addressToLine`. Результат этой обработки вы видите в виде `trace_source_code_lines` колонки выходных данных.
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
Row 1:
|
Row 1:
|
||||||
@ -179,7 +179,7 @@ LIMIT 1
|
|||||||
\G
|
\G
|
||||||
```
|
```
|
||||||
|
|
||||||
То [arrayMap](higher-order-functions.md#higher_order_functions-array-map) функция позволяет обрабатывать каждый отдельный элемент системы. `trace` массив по типу `addressToSymbols` функция. Результат этой обработки вы видите в виде `trace_symbols` колонка выходных данных.
|
То [arrayMap](../../sql-reference/functions/array-functions.md#array-map) функция позволяет обрабатывать каждый отдельный элемент системы. `trace` массив по типу `addressToSymbols` функция. Результат этой обработки вы видите в виде `trace_symbols` колонка выходных данных.
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
Row 1:
|
Row 1:
|
||||||
@ -276,7 +276,7 @@ LIMIT 1
|
|||||||
\G
|
\G
|
||||||
```
|
```
|
||||||
|
|
||||||
Функция [arrayMap](higher-order-functions.md#higher_order_functions-array-map) позволяет обрабатывать каждый отдельный элемент массива `trace` с помощью функции `demangle`.
|
Функция [arrayMap](../../sql-reference/functions/array-functions.md#array-map) позволяет обрабатывать каждый отдельный элемент массива `trace` с помощью функции `demangle`.
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
Row 1:
|
Row 1:
|
||||||
|
@ -15,7 +15,7 @@ toc_title: "\u5E94\u7528CatBoost\u6A21\u578B"
|
|||||||
|
|
||||||
1. [创建表](#create-table).
|
1. [创建表](#create-table).
|
||||||
2. [将数据插入到表中](#insert-data-to-table).
|
2. [将数据插入到表中](#insert-data-to-table).
|
||||||
3. [碌莽禄into拢Integrate010-68520682\<url\>](#integrate-catboost-into-clickhouse) (可选步骤)。
|
3. [将CatBoost集成到ClickHouse中](#integrate-catboost-into-clickhouse) (可选步骤)。
|
||||||
4. [从SQL运行模型推理](#run-model-inference).
|
4. [从SQL运行模型推理](#run-model-inference).
|
||||||
|
|
||||||
有关训练CatBoost模型的详细信息,请参阅 [培训和应用模型](https://catboost.ai/docs/features/training.html#training).
|
有关训练CatBoost模型的详细信息,请参阅 [培训和应用模型](https://catboost.ai/docs/features/training.html#training).
|
||||||
@ -119,12 +119,12 @@ FROM amazon_train
|
|||||||
+-------+
|
+-------+
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 碌莽禄into拢Integrate010-68520682\<url\> {#integrate-catboost-into-clickhouse}
|
## 3. 将CatBoost集成到ClickHouse中 {#integrate-catboost-into-clickhouse}
|
||||||
|
|
||||||
!!! note "注"
|
!!! note "注"
|
||||||
**可选步骤。** Docker映像包含运行CatBoost和ClickHouse所需的所有内容。
|
**可选步骤。** Docker映像包含运行CatBoost和ClickHouse所需的所有内容。
|
||||||
|
|
||||||
碌莽禄to拢integrate010-68520682\<url\>:
|
CatBoost集成到ClickHouse步骤:
|
||||||
|
|
||||||
**1.** 构建评估库。
|
**1.** 构建评估库。
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class AggregateFunctionCombinatorArray final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorArray final : public IAggregateFunctionCombinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -45,6 +48,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorArray(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorArray(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorArray>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorArray>());
|
||||||
|
@ -6,12 +6,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
{
|
{
|
||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class AggregateFunctionCombinatorDistinct final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorDistinct final : public IAggregateFunctionCombinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -56,6 +58,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorDistinct(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorDistinct(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorDistinct>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorDistinct>());
|
||||||
|
@ -12,6 +12,9 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class AggregateFunctionCombinatorForEach final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorForEach final : public IAggregateFunctionCombinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -42,6 +45,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorForEach(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorForEach(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorForEach>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorForEach>());
|
||||||
|
@ -13,6 +13,9 @@ namespace ErrorCodes
|
|||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class AggregateFunctionCombinatorMerge final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorMerge final : public IAggregateFunctionCombinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -55,6 +58,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorMerge(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorMerge(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorMerge>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorMerge>());
|
||||||
|
@ -15,6 +15,9 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class AggregateFunctionCombinatorNull final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorNull final : public IAggregateFunctionCombinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -119,6 +122,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorNull(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorNull(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorNull>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorNull>());
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <bool UseNull>
|
template <bool UseNull>
|
||||||
class AggregateFunctionCombinatorOrFill final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorOrFill final : public IAggregateFunctionCombinator
|
||||||
@ -32,6 +34,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorOrFill(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorOrFill(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorOrFill<false>>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorOrFill<false>>());
|
||||||
|
@ -13,6 +13,9 @@ namespace ErrorCodes
|
|||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class AggregateFunctionCombinatorResample final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorResample final : public IAggregateFunctionCombinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -93,6 +96,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorResample(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorResample(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorResample>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorResample>());
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <Columns/ColumnArray.h>
|
#include <Columns/ColumnArray.h>
|
||||||
#include <DataTypes/DataTypeArray.h>
|
#include <DataTypes/DataTypeArray.h>
|
||||||
#include <Common/assert_cast.h>
|
#include <Common/assert_cast.h>
|
||||||
|
#include <common/arithmeticOverflow.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -60,7 +61,18 @@ public:
|
|||||||
if (end < begin)
|
if (end < begin)
|
||||||
total = 0;
|
total = 0;
|
||||||
else
|
else
|
||||||
total = (end - begin + step - 1) / step;
|
{
|
||||||
|
Key dif;
|
||||||
|
size_t sum;
|
||||||
|
if (common::subOverflow(end, begin, dif)
|
||||||
|
|| common::addOverflow(static_cast<size_t>(dif), step, sum))
|
||||||
|
{
|
||||||
|
throw Exception("Overflow in internal computations in function " + getName()
|
||||||
|
+ ". Too large arguments", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
total = (sum - 1) / step; // total = (end - begin + step - 1) / step
|
||||||
|
}
|
||||||
|
|
||||||
if (total > MAX_ELEMENTS)
|
if (total > MAX_ELEMENTS)
|
||||||
throw Exception("The range given in function "
|
throw Exception("The range given in function "
|
||||||
|
@ -13,6 +13,9 @@ namespace ErrorCodes
|
|||||||
extern const int BAD_ARGUMENTS;
|
extern const int BAD_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class AggregateFunctionCombinatorState final : public IAggregateFunctionCombinator
|
class AggregateFunctionCombinatorState final : public IAggregateFunctionCombinator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -33,6 +36,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerAggregateFunctionCombinatorState(AggregateFunctionCombinatorFactory & factory)
|
void registerAggregateFunctionCombinatorState(AggregateFunctionCombinatorFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorState>());
|
factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorState>());
|
||||||
|
@ -439,6 +439,7 @@ class IColumn;
|
|||||||
M(String, output_format_avro_codec, "", "Compression codec used for output. Possible values: 'null', 'deflate', 'snappy'.", 0) \
|
M(String, output_format_avro_codec, "", "Compression codec used for output. Possible values: 'null', 'deflate', 'snappy'.", 0) \
|
||||||
M(UInt64, output_format_avro_sync_interval, 16 * 1024, "Sync interval in bytes.", 0) \
|
M(UInt64, output_format_avro_sync_interval, 16 * 1024, "Sync interval in bytes.", 0) \
|
||||||
M(Bool, output_format_tsv_crlf_end_of_line, false, "If it is set true, end of line in TSV format will be \\r\\n instead of \\n.", 0) \
|
M(Bool, output_format_tsv_crlf_end_of_line, false, "If it is set true, end of line in TSV format will be \\r\\n instead of \\n.", 0) \
|
||||||
|
M(String, output_format_tsv_null_representation, "\\N", "Custom NULL representation in TSV format", 0) \
|
||||||
\
|
\
|
||||||
M(UInt64, input_format_allow_errors_num, 0, "Maximum absolute amount of errors while reading text formats (like CSV, TSV). In case of error, if at least absolute or relative amount of errors is lower than corresponding value, will skip until next line and continue.", 0) \
|
M(UInt64, input_format_allow_errors_num, 0, "Maximum absolute amount of errors while reading text formats (like CSV, TSV). In case of error, if at least absolute or relative amount of errors is lower than corresponding value, will skip until next line and continue.", 0) \
|
||||||
M(Float, input_format_allow_errors_ratio, 0, "Maximum relative amount of errors while reading text formats (like CSV, TSV). In case of error, if at least absolute or relative amount of errors is lower than corresponding value, will skip until next line and continue.", 0) \
|
M(Float, input_format_allow_errors_ratio, 0, "Maximum relative amount of errors while reading text formats (like CSV, TSV). In case of error, if at least absolute or relative amount of errors is lower than corresponding value, will skip until next line and continue.", 0) \
|
||||||
|
@ -18,7 +18,7 @@ String ExpressionBlockInputStream::getName() const { return "Expression"; }
|
|||||||
Block ExpressionBlockInputStream::getTotals()
|
Block ExpressionBlockInputStream::getTotals()
|
||||||
{
|
{
|
||||||
totals = children.back()->getTotals();
|
totals = children.back()->getTotals();
|
||||||
expression->executeOnTotals(totals);
|
expression->execute(totals);
|
||||||
|
|
||||||
return totals;
|
return totals;
|
||||||
}
|
}
|
||||||
@ -30,14 +30,6 @@ Block ExpressionBlockInputStream::getHeader() const
|
|||||||
|
|
||||||
Block ExpressionBlockInputStream::readImpl()
|
Block ExpressionBlockInputStream::readImpl()
|
||||||
{
|
{
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
if (expression->resultIsAlwaysEmpty())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Block res = children.back()->read();
|
Block res = children.back()->read();
|
||||||
if (res)
|
if (res)
|
||||||
expression->execute(res);
|
expression->execute(res);
|
||||||
|
@ -25,7 +25,6 @@ public:
|
|||||||
Block getHeader() const override;
|
Block getHeader() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool initialized = false;
|
|
||||||
ExpressionActionsPtr expression;
|
ExpressionActionsPtr expression;
|
||||||
|
|
||||||
Block readImpl() override;
|
Block readImpl() override;
|
||||||
|
@ -54,7 +54,7 @@ String FilterBlockInputStream::getName() const { return "Filter"; }
|
|||||||
Block FilterBlockInputStream::getTotals()
|
Block FilterBlockInputStream::getTotals()
|
||||||
{
|
{
|
||||||
totals = children.back()->getTotals();
|
totals = children.back()->getTotals();
|
||||||
expression->executeOnTotals(totals);
|
expression->execute(totals);
|
||||||
|
|
||||||
return totals;
|
return totals;
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ void DataTypeNullable::serializeTextEscaped(const IColumn & column, size_t row_n
|
|||||||
const ColumnNullable & col = assert_cast<const ColumnNullable &>(column);
|
const ColumnNullable & col = assert_cast<const ColumnNullable &>(column);
|
||||||
|
|
||||||
if (col.isNullAt(row_num))
|
if (col.isNullAt(row_num))
|
||||||
writeCString("\\N", ostr);
|
writeString(settings.tsv.null_representation, ostr);
|
||||||
else
|
else
|
||||||
nested_data_type->serializeAsTextEscaped(col.getNestedColumn(), row_num, ostr, settings);
|
nested_data_type->serializeAsTextEscaped(col.getNestedColumn(), row_num, ostr, settings);
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,12 @@ void registerDiskS3(DiskFactory & factory)
|
|||||||
config.getUInt64(config_prefix + ".min_bytes_for_seek", 1024 * 1024));
|
config.getUInt64(config_prefix + ".min_bytes_for_seek", 1024 * 1024));
|
||||||
|
|
||||||
/// This code is used only to check access to the corresponding disk.
|
/// This code is used only to check access to the corresponding disk.
|
||||||
checkWriteAccess(*s3disk);
|
if (!config.getBool(config_prefix + ".skip_access_check", false))
|
||||||
checkReadAccess(name, *s3disk);
|
{
|
||||||
checkRemoveAccess(*s3disk);
|
checkWriteAccess(*s3disk);
|
||||||
|
checkReadAccess(name, *s3disk);
|
||||||
|
checkRemoveAccess(*s3disk);
|
||||||
|
}
|
||||||
|
|
||||||
bool cache_enabled = config.getBool(config_prefix + ".cache_enabled", true);
|
bool cache_enabled = config.getBool(config_prefix + ".cache_enabled", true);
|
||||||
|
|
||||||
|
@ -111,6 +111,7 @@ static FormatSettings getOutputFormatSetting(const Settings & settings, const Co
|
|||||||
format_settings.template_settings.row_format = settings.format_template_row;
|
format_settings.template_settings.row_format = settings.format_template_row;
|
||||||
format_settings.template_settings.row_between_delimiter = settings.format_template_rows_between_delimiter;
|
format_settings.template_settings.row_between_delimiter = settings.format_template_rows_between_delimiter;
|
||||||
format_settings.tsv.crlf_end_of_line = settings.output_format_tsv_crlf_end_of_line;
|
format_settings.tsv.crlf_end_of_line = settings.output_format_tsv_crlf_end_of_line;
|
||||||
|
format_settings.tsv.null_representation = settings.output_format_tsv_null_representation;
|
||||||
format_settings.write_statistics = settings.output_format_write_statistics;
|
format_settings.write_statistics = settings.output_format_write_statistics;
|
||||||
format_settings.parquet.row_group_size = settings.output_format_parquet_row_group_size;
|
format_settings.parquet.row_group_size = settings.output_format_parquet_row_group_size;
|
||||||
format_settings.schema.format_schema = settings.format_schema;
|
format_settings.schema.format_schema = settings.format_schema;
|
||||||
|
@ -78,6 +78,7 @@ struct FormatSettings
|
|||||||
{
|
{
|
||||||
bool empty_as_default = false;
|
bool empty_as_default = false;
|
||||||
bool crlf_end_of_line = false;
|
bool crlf_end_of_line = false;
|
||||||
|
String null_representation = "\\N";
|
||||||
};
|
};
|
||||||
|
|
||||||
TSV tsv;
|
TSV tsv;
|
||||||
|
@ -72,6 +72,9 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
struct CRCFunctionWrapper
|
struct CRCFunctionWrapper
|
||||||
{
|
{
|
||||||
@ -127,6 +130,8 @@ using FunctionCRC32IEEE = FunctionCRC<CRC32IEEEImpl>;
|
|||||||
// Uses CRC-64-ECMA polynomial
|
// Uses CRC-64-ECMA polynomial
|
||||||
using FunctionCRC64ECMA = FunctionCRC<CRC64ECMAImpl>;
|
using FunctionCRC64ECMA = FunctionCRC<CRC64ECMAImpl>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void registerFunctionCRCImpl(FunctionFactory & factory)
|
void registerFunctionCRCImpl(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <Columns/ColumnAggregateFunction.h>
|
#include <Columns/ColumnAggregateFunction.h>
|
||||||
#include "IFunctionImpl.h"
|
#include "IFunctionImpl.h"
|
||||||
#include "FunctionHelpers.h"
|
#include "FunctionHelpers.h"
|
||||||
|
#include "IsOperation.h"
|
||||||
#include "DivisionUtils.h"
|
#include "DivisionUtils.h"
|
||||||
#include "castTypeToEither.h"
|
#include "castTypeToEither.h"
|
||||||
#include "FunctionFactory.h"
|
#include "FunctionFactory.h"
|
||||||
@ -167,17 +168,6 @@ struct BinaryOperationImpl : BinaryOperationImplBase<A, B, Op, ResultType>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename, typename> struct PlusImpl;
|
|
||||||
template <typename, typename> struct MinusImpl;
|
|
||||||
template <typename, typename> struct MultiplyImpl;
|
|
||||||
template <typename, typename> struct DivideFloatingImpl;
|
|
||||||
template <typename, typename> struct DivideIntegralImpl;
|
|
||||||
template <typename, typename> struct DivideIntegralOrZeroImpl;
|
|
||||||
template <typename, typename> struct LeastBaseImpl;
|
|
||||||
template <typename, typename> struct GreatestBaseImpl;
|
|
||||||
template <typename, typename> struct ModuloImpl;
|
|
||||||
|
|
||||||
|
|
||||||
/// Binary operations for Decimals need scale args
|
/// Binary operations for Decimals need scale args
|
||||||
/// +|- scale one of args (which scale factor is not 1). ScaleR = oneof(Scale1, Scale2);
|
/// +|- scale one of args (which scale factor is not 1). ScaleR = oneof(Scale1, Scale2);
|
||||||
/// * no agrs scale. ScaleR = Scale1 + Scale2;
|
/// * no agrs scale. ScaleR = Scale1 + Scale2;
|
||||||
@ -185,15 +175,15 @@ template <typename, typename> struct ModuloImpl;
|
|||||||
template <typename A, typename B, template <typename, typename> typename Operation, typename ResultType_, bool _check_overflow = true>
|
template <typename A, typename B, template <typename, typename> typename Operation, typename ResultType_, bool _check_overflow = true>
|
||||||
struct DecimalBinaryOperation
|
struct DecimalBinaryOperation
|
||||||
{
|
{
|
||||||
static constexpr bool is_plus_minus = std::is_same_v<Operation<Int32, Int32>, PlusImpl<Int32, Int32>> ||
|
static constexpr bool is_plus_minus = IsOperation<Operation>::plus ||
|
||||||
std::is_same_v<Operation<Int32, Int32>, MinusImpl<Int32, Int32>>;
|
IsOperation<Operation>::minus;
|
||||||
static constexpr bool is_multiply = std::is_same_v<Operation<Int32, Int32>, MultiplyImpl<Int32, Int32>>;
|
static constexpr bool is_multiply = IsOperation<Operation>::multiply;
|
||||||
static constexpr bool is_float_division = std::is_same_v<Operation<Int32, Int32>, DivideFloatingImpl<Int32, Int32>>;
|
static constexpr bool is_float_division = IsOperation<Operation>::div_floating;
|
||||||
static constexpr bool is_int_division = std::is_same_v<Operation<Int32, Int32>, DivideIntegralImpl<Int32, Int32>> ||
|
static constexpr bool is_int_division = IsOperation<Operation>::div_int ||
|
||||||
std::is_same_v<Operation<Int32, Int32>, DivideIntegralOrZeroImpl<Int32, Int32>>;
|
IsOperation<Operation>::div_int_or_zero;
|
||||||
static constexpr bool is_division = is_float_division || is_int_division;
|
static constexpr bool is_division = is_float_division || is_int_division;
|
||||||
static constexpr bool is_compare = std::is_same_v<Operation<Int32, Int32>, LeastBaseImpl<Int32, Int32>> ||
|
static constexpr bool is_compare = IsOperation<Operation>::least ||
|
||||||
std::is_same_v<Operation<Int32, Int32>, GreatestBaseImpl<Int32, Int32>>;
|
IsOperation<Operation>::greatest;
|
||||||
static constexpr bool is_plus_minus_compare = is_plus_minus || is_compare;
|
static constexpr bool is_plus_minus_compare = is_plus_minus || is_compare;
|
||||||
static constexpr bool can_overflow = is_plus_minus || is_multiply;
|
static constexpr bool can_overflow = is_plus_minus || is_multiply;
|
||||||
|
|
||||||
@ -529,15 +519,7 @@ private: /// it's not correct for Decimal
|
|||||||
using Op = Operation<T0, T1>;
|
using Op = Operation<T0, T1>;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static constexpr bool allow_decimal =
|
static constexpr bool allow_decimal = IsOperation<Operation>::allow_decimal;
|
||||||
std::is_same_v<Operation<T0, T0>, PlusImpl<T0, T0>> ||
|
|
||||||
std::is_same_v<Operation<T0, T0>, MinusImpl<T0, T0>> ||
|
|
||||||
std::is_same_v<Operation<T0, T0>, MultiplyImpl<T0, T0>> ||
|
|
||||||
std::is_same_v<Operation<T0, T0>, DivideFloatingImpl<T0, T0>> ||
|
|
||||||
std::is_same_v<Operation<T0, T0>, DivideIntegralImpl<T0, T0>> ||
|
|
||||||
std::is_same_v<Operation<T0, T0>, DivideIntegralOrZeroImpl<T0, T0>> ||
|
|
||||||
std::is_same_v<Operation<T0, T0>, LeastBaseImpl<T0, T0>> ||
|
|
||||||
std::is_same_v<Operation<T0, T0>, GreatestBaseImpl<T0, T0>>;
|
|
||||||
|
|
||||||
/// Appropriate result type for binary operator on numeric types. "Date" can also mean
|
/// Appropriate result type for binary operator on numeric types. "Date" can also mean
|
||||||
/// DateTime, but if both operands are Dates, their type must be the same (e.g. Date - DateTime is invalid).
|
/// DateTime, but if both operands are Dates, their type must be the same (e.g. Date - DateTime is invalid).
|
||||||
@ -556,21 +538,21 @@ public:
|
|||||||
DataTypeFromFieldType<typename Op::ResultType>>,
|
DataTypeFromFieldType<typename Op::ResultType>>,
|
||||||
/// Date + Integral -> Date
|
/// Date + Integral -> Date
|
||||||
/// Integral + Date -> Date
|
/// Integral + Date -> Date
|
||||||
Case<std::is_same_v<Op, PlusImpl<T0, T1>>, Switch<
|
Case<IsOperation<Operation>::plus, Switch<
|
||||||
Case<IsIntegral<RightDataType>, LeftDataType>,
|
Case<IsIntegral<RightDataType>, LeftDataType>,
|
||||||
Case<IsIntegral<LeftDataType>, RightDataType>>>,
|
Case<IsIntegral<LeftDataType>, RightDataType>>>,
|
||||||
/// Date - Date -> Int32
|
/// Date - Date -> Int32
|
||||||
/// Date - Integral -> Date
|
/// Date - Integral -> Date
|
||||||
Case<std::is_same_v<Op, MinusImpl<T0, T1>>, Switch<
|
Case<IsOperation<Operation>::minus, Switch<
|
||||||
Case<std::is_same_v<LeftDataType, RightDataType>, DataTypeInt32>,
|
Case<std::is_same_v<LeftDataType, RightDataType>, DataTypeInt32>,
|
||||||
Case<IsDateOrDateTime<LeftDataType> && IsIntegral<RightDataType>, LeftDataType>>>,
|
Case<IsDateOrDateTime<LeftDataType> && IsIntegral<RightDataType>, LeftDataType>>>,
|
||||||
/// least(Date, Date) -> Date
|
/// least(Date, Date) -> Date
|
||||||
/// greatest(Date, Date) -> Date
|
/// greatest(Date, Date) -> Date
|
||||||
Case<std::is_same_v<LeftDataType, RightDataType> && (std::is_same_v<Op, LeastBaseImpl<T0, T1>> || std::is_same_v<Op, GreatestBaseImpl<T0, T1>>),
|
Case<std::is_same_v<LeftDataType, RightDataType> && (IsOperation<Operation>::least || IsOperation<Operation>::greatest),
|
||||||
LeftDataType>,
|
LeftDataType>,
|
||||||
/// Date % Int32 -> Int32
|
/// Date % Int32 -> Int32
|
||||||
/// Date % Float -> Float64
|
/// Date % Float -> Float64
|
||||||
Case<std::is_same_v<Op, ModuloImpl<T0, T1>>, Switch<
|
Case<IsOperation<Operation>::modulo, Switch<
|
||||||
Case<IsDateOrDateTime<LeftDataType> && IsIntegral<RightDataType>, RightDataType>,
|
Case<IsDateOrDateTime<LeftDataType> && IsIntegral<RightDataType>, RightDataType>,
|
||||||
Case<IsDateOrDateTime<LeftDataType> && IsFloatingPoint<RightDataType>, DataTypeFloat64>>>>;
|
Case<IsDateOrDateTime<LeftDataType> && IsFloatingPoint<RightDataType>, DataTypeFloat64>>>>;
|
||||||
};
|
};
|
||||||
@ -627,10 +609,9 @@ class FunctionBinaryArithmetic : public IFunction
|
|||||||
/// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval.
|
/// Special case when the function is plus or minus, one of arguments is Date/DateTime and another is Interval.
|
||||||
/// We construct another function (example: addMonths) and call it.
|
/// We construct another function (example: addMonths) and call it.
|
||||||
|
|
||||||
static constexpr bool function_is_plus = std::is_same_v<Op<UInt8, UInt8>, PlusImpl<UInt8, UInt8>>;
|
static constexpr bool function_is_plus = IsOperation<Op>::plus;
|
||||||
static constexpr bool function_is_minus = std::is_same_v<Op<UInt8, UInt8>, MinusImpl<UInt8, UInt8>>;
|
static constexpr bool function_is_minus = IsOperation<Op>::minus;
|
||||||
|
if constexpr (!function_is_plus && !function_is_minus)
|
||||||
if (!function_is_plus && !function_is_minus)
|
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const DataTypePtr & type_time = first_is_date_or_datetime ? type0 : type1;
|
const DataTypePtr & type_time = first_is_date_or_datetime ? type0 : type1;
|
||||||
@ -669,7 +650,7 @@ class FunctionBinaryArithmetic : public IFunction
|
|||||||
|
|
||||||
bool isAggregateMultiply(const DataTypePtr & type0, const DataTypePtr & type1) const
|
bool isAggregateMultiply(const DataTypePtr & type0, const DataTypePtr & type1) const
|
||||||
{
|
{
|
||||||
if constexpr (!std::is_same_v<Op<UInt8, UInt8>, MultiplyImpl<UInt8, UInt8>>)
|
if constexpr (!IsOperation<Op>::multiply)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WhichDataType which0(type0);
|
WhichDataType which0(type0);
|
||||||
@ -681,7 +662,7 @@ class FunctionBinaryArithmetic : public IFunction
|
|||||||
|
|
||||||
bool isAggregateAddition(const DataTypePtr & type0, const DataTypePtr & type1) const
|
bool isAggregateAddition(const DataTypePtr & type0, const DataTypePtr & type1) const
|
||||||
{
|
{
|
||||||
if constexpr (!std::is_same_v<Op<UInt8, UInt8>, PlusImpl<UInt8, UInt8>>)
|
if constexpr (!IsOperation<Op>::plus)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WhichDataType which0(type0);
|
WhichDataType which0(type0);
|
||||||
@ -891,10 +872,8 @@ public:
|
|||||||
{
|
{
|
||||||
if constexpr (IsDataTypeDecimal<LeftDataType> && IsDataTypeDecimal<RightDataType>)
|
if constexpr (IsDataTypeDecimal<LeftDataType> && IsDataTypeDecimal<RightDataType>)
|
||||||
{
|
{
|
||||||
constexpr bool is_multiply = std::is_same_v<Op<UInt8, UInt8>, MultiplyImpl<UInt8, UInt8>>;
|
constexpr bool is_multiply = IsOperation<Op>::multiply;
|
||||||
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>> ||
|
constexpr bool is_division = IsOperation<Op>::division;
|
||||||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralImpl<UInt8, UInt8>> ||
|
|
||||||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralOrZeroImpl<UInt8, UInt8>>;
|
|
||||||
|
|
||||||
ResultDataType result_type = decimalResultType(left, right, is_multiply, is_division);
|
ResultDataType result_type = decimalResultType(left, right, is_multiply, is_division);
|
||||||
type_res = std::make_shared<ResultDataType>(result_type.getPrecision(), result_type.getScale());
|
type_res = std::make_shared<ResultDataType>(result_type.getPrecision(), result_type.getScale());
|
||||||
@ -1016,10 +995,8 @@ public:
|
|||||||
if constexpr (!std::is_same_v<ResultDataType, InvalidType>)
|
if constexpr (!std::is_same_v<ResultDataType, InvalidType>)
|
||||||
{
|
{
|
||||||
constexpr bool result_is_decimal = IsDataTypeDecimal<LeftDataType> || IsDataTypeDecimal<RightDataType>;
|
constexpr bool result_is_decimal = IsDataTypeDecimal<LeftDataType> || IsDataTypeDecimal<RightDataType>;
|
||||||
constexpr bool is_multiply = std::is_same_v<Op<UInt8, UInt8>, MultiplyImpl<UInt8, UInt8>>;
|
constexpr bool is_multiply = IsOperation<Op>::multiply;
|
||||||
constexpr bool is_division = std::is_same_v<Op<UInt8, UInt8>, DivideFloatingImpl<UInt8, UInt8>> ||
|
constexpr bool is_division = IsOperation<Op>::division;
|
||||||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralImpl<UInt8, UInt8>> ||
|
|
||||||
std::is_same_v<Op<UInt8, UInt8>, DivideIntegralOrZeroImpl<UInt8, UInt8>>;
|
|
||||||
|
|
||||||
using T0 = typename LeftDataType::FieldType;
|
using T0 = typename LeftDataType::FieldType;
|
||||||
using T1 = typename RightDataType::FieldType;
|
using T1 = typename RightDataType::FieldType;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <Columns/ColumnFixedString.h>
|
#include <Columns/ColumnFixedString.h>
|
||||||
#include <Functions/IFunctionImpl.h>
|
#include <Functions/IFunctionImpl.h>
|
||||||
#include <Functions/FunctionHelpers.h>
|
#include <Functions/FunctionHelpers.h>
|
||||||
|
#include <Functions/IsOperation.h>
|
||||||
#include <Functions/castTypeToEither.h>
|
#include <Functions/castTypeToEither.h>
|
||||||
|
|
||||||
#if !defined(ARCADIA_BUILD)
|
#if !defined(ARCADIA_BUILD)
|
||||||
@ -71,9 +72,6 @@ struct FixedStringUnaryOperationImpl
|
|||||||
template <typename FunctionName>
|
template <typename FunctionName>
|
||||||
struct FunctionUnaryArithmeticMonotonicity;
|
struct FunctionUnaryArithmeticMonotonicity;
|
||||||
|
|
||||||
template <typename> struct AbsImpl;
|
|
||||||
template <typename> struct NegateImpl;
|
|
||||||
|
|
||||||
/// Used to indicate undefined operation
|
/// Used to indicate undefined operation
|
||||||
struct InvalidType;
|
struct InvalidType;
|
||||||
|
|
||||||
@ -81,7 +79,7 @@ struct InvalidType;
|
|||||||
template <template <typename> class Op, typename Name, bool is_injective>
|
template <template <typename> class Op, typename Name, bool is_injective>
|
||||||
class FunctionUnaryArithmetic : public IFunction
|
class FunctionUnaryArithmetic : public IFunction
|
||||||
{
|
{
|
||||||
static constexpr bool allow_decimal = std::is_same_v<Op<Int8>, NegateImpl<Int8>> || std::is_same_v<Op<Int8>, AbsImpl<Int8>>;
|
static constexpr bool allow_decimal = IsUnaryOperation<Op>::negate || IsUnaryOperation<Op>::abs;
|
||||||
static constexpr bool allow_fixed_string = Op<UInt8>::allow_fixed_string;
|
static constexpr bool allow_fixed_string = Op<UInt8>::allow_fixed_string;
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <Functions/IFunctionAdaptors.h>
|
#include <Functions/IFunctionAdaptors.h>
|
||||||
#include <Functions/FunctionHelpers.h>
|
#include <Functions/FunctionHelpers.h>
|
||||||
|
#include <Functions/IsOperation.h>
|
||||||
|
|
||||||
#include <Core/AccurateComparison.h>
|
#include <Core/AccurateComparison.h>
|
||||||
#include <Core/DecimalComparison.h>
|
#include <Core/DecimalComparison.h>
|
||||||
@ -845,8 +846,7 @@ private:
|
|||||||
/// If not possible to convert, comparison with =, <, >, <=, >= yields to false and comparison with != yields to true.
|
/// If not possible to convert, comparison with =, <, >, <=, >= yields to false and comparison with != yields to true.
|
||||||
if (converted.isNull())
|
if (converted.isNull())
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = DataTypeUInt8().createColumnConst(input_rows_count,
|
block.getByPosition(result).column = DataTypeUInt8().createColumnConst(input_rows_count, IsOperation<Op>::not_equals);
|
||||||
std::is_same_v<Op<int, int>, NotEqualsOp<int, int>>);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1190,9 +1190,9 @@ public:
|
|||||||
if (left_type->equals(*right_type) && !left_type->isNullable() && !isTuple(left_type) && col_left_untyped == col_right_untyped)
|
if (left_type->equals(*right_type) && !left_type->isNullable() && !isTuple(left_type) && col_left_untyped == col_right_untyped)
|
||||||
{
|
{
|
||||||
/// Always true: =, <=, >=
|
/// Always true: =, <=, >=
|
||||||
if constexpr (std::is_same_v<Op<int, int>, EqualsOp<int, int>>
|
if constexpr (IsOperation<Op>::equals
|
||||||
|| std::is_same_v<Op<int, int>, LessOrEqualsOp<int, int>>
|
|| IsOperation<Op>::less_or_equals
|
||||||
|| std::is_same_v<Op<int, int>, GreaterOrEqualsOp<int, int>>)
|
|| IsOperation<Op>::greater_or_equals)
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = DataTypeUInt8().createColumnConst(input_rows_count, 1u);
|
block.getByPosition(result).column = DataTypeUInt8().createColumnConst(input_rows_count, 1u);
|
||||||
return;
|
return;
|
||||||
|
@ -207,7 +207,7 @@ public:
|
|||||||
{
|
{
|
||||||
/// Check that expression does not contain unusual actions that will break blocks structure.
|
/// Check that expression does not contain unusual actions that will break blocks structure.
|
||||||
for (const auto & action : expression_actions->getActions())
|
for (const auto & action : expression_actions->getActions())
|
||||||
if (action.type == ExpressionAction::Type::JOIN || action.type == ExpressionAction::Type::ARRAY_JOIN)
|
if (action.type == ExpressionAction::Type::ARRAY_JOIN)
|
||||||
throw Exception("Expression with arrayJoin or other unusual action cannot be captured", ErrorCodes::BAD_ARGUMENTS);
|
throw Exception("Expression with arrayJoin or other unusual action cannot be captured", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
std::unordered_map<std::string, DataTypePtr> arguments_map;
|
std::unordered_map<std::string, DataTypePtr> arguments_map;
|
||||||
|
62
src/Functions/IsOperation.h
Normal file
62
src/Functions/IsOperation.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
/// These classes should be present in DB namespace (cannot place them into nemelesspace)
|
||||||
|
template <typename> struct AbsImpl;
|
||||||
|
template <typename> struct NegateImpl;
|
||||||
|
template <typename, typename> struct PlusImpl;
|
||||||
|
template <typename, typename> struct MinusImpl;
|
||||||
|
template <typename, typename> struct MultiplyImpl;
|
||||||
|
template <typename, typename> struct DivideFloatingImpl;
|
||||||
|
template <typename, typename> struct DivideIntegralImpl;
|
||||||
|
template <typename, typename> struct DivideIntegralOrZeroImpl;
|
||||||
|
template <typename, typename> struct LeastBaseImpl;
|
||||||
|
template <typename, typename> struct GreatestBaseImpl;
|
||||||
|
template <typename, typename> struct ModuloImpl;
|
||||||
|
template <typename, typename> struct EqualsOp;
|
||||||
|
template <typename, typename> struct NotEqualsOp;
|
||||||
|
template <typename, typename> struct LessOrEqualsOp;
|
||||||
|
template <typename, typename> struct GreaterOrEqualsOp;
|
||||||
|
|
||||||
|
template <template <typename, typename> typename Op1, template <typename, typename> typename Op2>
|
||||||
|
struct IsSameOperation
|
||||||
|
{
|
||||||
|
static constexpr bool value = std::is_same_v<Op1<UInt8, UInt8>, Op2<UInt8, UInt8>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <typename> typename Op>
|
||||||
|
struct IsUnaryOperation
|
||||||
|
{
|
||||||
|
static constexpr bool abs = std::is_same_v<Op<Int8>, AbsImpl<Int8>>;
|
||||||
|
static constexpr bool negate = std::is_same_v<Op<Int8>, NegateImpl<Int8>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <typename, typename> typename Op>
|
||||||
|
struct IsOperation
|
||||||
|
{
|
||||||
|
static constexpr bool equals = IsSameOperation<Op, EqualsOp>::value;
|
||||||
|
static constexpr bool not_equals = IsSameOperation<Op, NotEqualsOp>::value;
|
||||||
|
static constexpr bool less_or_equals = IsSameOperation<Op, LessOrEqualsOp>::value;
|
||||||
|
static constexpr bool greater_or_equals = IsSameOperation<Op, GreaterOrEqualsOp>::value;
|
||||||
|
|
||||||
|
static constexpr bool plus = IsSameOperation<Op, PlusImpl>::value;
|
||||||
|
static constexpr bool minus = IsSameOperation<Op, MinusImpl>::value;
|
||||||
|
static constexpr bool multiply = IsSameOperation<Op, MultiplyImpl>::value;
|
||||||
|
static constexpr bool div_floating = IsSameOperation<Op, DivideFloatingImpl>::value;
|
||||||
|
static constexpr bool div_int = IsSameOperation<Op, DivideIntegralImpl>::value;
|
||||||
|
static constexpr bool div_int_or_zero = IsSameOperation<Op, DivideIntegralOrZeroImpl>::value;
|
||||||
|
static constexpr bool modulo = IsSameOperation<Op, ModuloImpl>::value;
|
||||||
|
static constexpr bool least = IsSameOperation<Op, LeastBaseImpl>::value;
|
||||||
|
static constexpr bool greatest = IsSameOperation<Op, GreatestBaseImpl>::value;
|
||||||
|
|
||||||
|
static constexpr bool division = div_floating || div_int || div_int_or_zero;
|
||||||
|
|
||||||
|
static constexpr bool allow_decimal =
|
||||||
|
plus || minus || multiply ||
|
||||||
|
div_floating || div_int || div_int_or_zero ||
|
||||||
|
least || greatest;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -4,10 +4,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct AcosName { static constexpr auto name = "acos"; };
|
struct AcosName { static constexpr auto name = "acos"; };
|
||||||
using FunctionAcos = FunctionMathUnary<UnaryFunctionVectorized<AcosName, acos>>;
|
using FunctionAcos = FunctionMathUnary<UnaryFunctionVectorized<AcosName, acos>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionAcos(FunctionFactory & factory)
|
void registerFunctionAcos(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionAcos>(FunctionFactory::CaseInsensitive);
|
factory.registerFunction<FunctionAcos>(FunctionFactory::CaseInsensitive);
|
||||||
|
@ -29,6 +29,9 @@ namespace ErrorCodes
|
|||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class FunctionAddressToLine : public IFunction
|
class FunctionAddressToLine : public IFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -144,6 +147,8 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionAddressToLine(FunctionFactory & factory)
|
void registerFunctionAddressToLine(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionAddressToLine>();
|
factory.registerFunction<FunctionAddressToLine>();
|
||||||
|
@ -21,6 +21,9 @@ namespace ErrorCodes
|
|||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class FunctionAddressToSymbol : public IFunction
|
class FunctionAddressToSymbol : public IFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -86,6 +89,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionAddressToSymbol(FunctionFactory & factory)
|
void registerFunctionAddressToSymbol(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionAddressToSymbol>();
|
factory.registerFunction<FunctionAddressToSymbol>();
|
||||||
|
@ -17,6 +17,8 @@ namespace ErrorCodes
|
|||||||
extern const int BAD_ARGUMENTS;
|
extern const int BAD_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class FunctionAppendTrailingCharIfAbsent : public IFunction
|
class FunctionAppendTrailingCharIfAbsent : public IFunction
|
||||||
{
|
{
|
||||||
@ -109,6 +111,8 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionAppendTrailingCharIfAbsent(FunctionFactory & factory)
|
void registerFunctionAppendTrailingCharIfAbsent(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionAppendTrailingCharIfAbsent>();
|
factory.registerFunction<FunctionAppendTrailingCharIfAbsent>();
|
||||||
|
@ -4,10 +4,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct AsinName { static constexpr auto name = "asin"; };
|
struct AsinName { static constexpr auto name = "asin"; };
|
||||||
using FunctionAsin = FunctionMathUnary<UnaryFunctionVectorized<AsinName, asin>>;
|
using FunctionAsin = FunctionMathUnary<UnaryFunctionVectorized<AsinName, asin>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionAsin(FunctionFactory & factory)
|
void registerFunctionAsin(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionAsin>(FunctionFactory::CaseInsensitive);
|
factory.registerFunction<FunctionAsin>(FunctionFactory::CaseInsensitive);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Implements the function assumeNotNull which takes 1 argument and works as follows:
|
/// Implements the function assumeNotNull which takes 1 argument and works as follows:
|
||||||
/// - if the argument is a nullable column, return its embedded column;
|
/// - if the argument is a nullable column, return its embedded column;
|
||||||
@ -49,6 +51,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionAssumeNotNull(FunctionFactory & factory)
|
void registerFunctionAssumeNotNull(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -4,10 +4,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct AtanName { static constexpr auto name = "atan"; };
|
struct AtanName { static constexpr auto name = "atan"; };
|
||||||
using FunctionAtan = FunctionMathUnary<UnaryFunctionVectorized<AtanName, atan>>;
|
using FunctionAtan = FunctionMathUnary<UnaryFunctionVectorized<AtanName, atan>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionAtan(FunctionFactory & factory)
|
void registerFunctionAtan(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionAtan>(FunctionFactory::CaseInsensitive);
|
factory.registerFunction<FunctionAtan>(FunctionFactory::CaseInsensitive);
|
||||||
|
@ -19,6 +19,9 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/** bar(x, min, max, width) - draws a strip from the number of characters proportional to (x - min) and equal to width for x == max.
|
/** bar(x, min, max, width) - draws a strip from the number of characters proportional to (x - min) and equal to width for x == max.
|
||||||
* Returns a string with nice Unicode-art bar with resolution of 1/8 part of symbol.
|
* Returns a string with nice Unicode-art bar with resolution of 1/8 part of symbol.
|
||||||
*/
|
*/
|
||||||
@ -160,6 +163,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBar(FunctionFactory & factory)
|
void registerFunctionBar(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitAndImpl
|
struct BitAndImpl
|
||||||
{
|
{
|
||||||
@ -36,6 +39,8 @@ struct BitAndImpl
|
|||||||
struct NameBitAnd { static constexpr auto name = "bitAnd"; };
|
struct NameBitAnd { static constexpr auto name = "bitAnd"; };
|
||||||
using FunctionBitAnd = FunctionBinaryArithmetic<BitAndImpl, NameBitAnd, true>;
|
using FunctionBitAnd = FunctionBinaryArithmetic<BitAndImpl, NameBitAnd, true>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitAnd(FunctionFactory & factory)
|
void registerFunctionBitAnd(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitAnd>();
|
factory.registerFunction<FunctionBitAnd>();
|
||||||
|
@ -5,44 +5,50 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
||||||
|
/// This function provides "AND" operation for BoolMasks.
|
||||||
|
/// Returns: "can be true" = A."can be true" AND B."can be true"
|
||||||
|
/// "can be false" = A."can be false" OR B."can be false"
|
||||||
|
template <typename A, typename B>
|
||||||
|
struct BitBoolMaskAndImpl
|
||||||
|
{
|
||||||
|
using ResultType = UInt8;
|
||||||
|
static const constexpr bool allow_fixed_string = false;
|
||||||
|
|
||||||
|
template <typename Result = ResultType>
|
||||||
|
static inline Result apply([[maybe_unused]] A left, [[maybe_unused]] B right)
|
||||||
{
|
{
|
||||||
extern const int BAD_ARGUMENTS;
|
// Should be a logical error, but this function is callable from SQL.
|
||||||
|
// Need to investigate this.
|
||||||
|
if constexpr (!std::is_same_v<A, ResultType> || !std::is_same_v<B, ResultType>)
|
||||||
|
throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitBoolMaskAnd.", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
|
auto left_bits = littleBits<A>(left);
|
||||||
|
auto right_bits = littleBits<B>(right);
|
||||||
|
return static_cast<ResultType>((left_bits & right_bits & 1) | ((((left_bits >> 1) | (right_bits >> 1)) & 1) << 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
|
||||||
/// This function provides "AND" operation for BoolMasks.
|
|
||||||
/// Returns: "can be true" = A."can be true" AND B."can be true"
|
|
||||||
/// "can be false" = A."can be false" OR B."can be false"
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct BitBoolMaskAndImpl
|
|
||||||
{
|
|
||||||
using ResultType = UInt8;
|
|
||||||
static const constexpr bool allow_fixed_string = false;
|
|
||||||
|
|
||||||
template <typename Result = ResultType>
|
|
||||||
static inline Result apply([[maybe_unused]] A left, [[maybe_unused]] B right)
|
|
||||||
{
|
|
||||||
// Should be a logical error, but this function is callable from SQL.
|
|
||||||
// Need to investigate this.
|
|
||||||
if constexpr (!std::is_same_v<A, ResultType> || !std::is_same_v<B, ResultType>)
|
|
||||||
throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitBoolMaskAnd.", ErrorCodes::BAD_ARGUMENTS);
|
|
||||||
|
|
||||||
auto left_bits = littleBits<A>(left);
|
|
||||||
auto right_bits = littleBits<B>(right);
|
|
||||||
return static_cast<ResultType>((left_bits & right_bits & 1) | ((((left_bits >> 1) | (right_bits >> 1)) & 1) << 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if USE_EMBEDDED_COMPILER
|
#if USE_EMBEDDED_COMPILER
|
||||||
static constexpr bool compilable = false;
|
static constexpr bool compilable = false;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NameBitBoolMaskAnd { static constexpr auto name = "__bitBoolMaskAnd"; };
|
struct NameBitBoolMaskAnd { static constexpr auto name = "__bitBoolMaskAnd"; };
|
||||||
using FunctionBitBoolMaskAnd = FunctionBinaryArithmetic<BitBoolMaskAndImpl, NameBitBoolMaskAnd>;
|
using FunctionBitBoolMaskAnd = FunctionBinaryArithmetic<BitBoolMaskAndImpl, NameBitBoolMaskAnd>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerFunctionBitBoolMaskAnd(FunctionFactory & factory)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionBitBoolMaskAnd>();
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitBoolMaskAnd(FunctionFactory & factory)
|
|
||||||
{
|
|
||||||
factory.registerFunction<FunctionBitBoolMaskAnd>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,44 +5,50 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
||||||
|
/// This function provides "OR" operation for BoolMasks.
|
||||||
|
/// Returns: "can be true" = A."can be true" OR B."can be true"
|
||||||
|
/// "can be false" = A."can be false" AND B."can be false"
|
||||||
|
template <typename A, typename B>
|
||||||
|
struct BitBoolMaskOrImpl
|
||||||
|
{
|
||||||
|
using ResultType = UInt8;
|
||||||
|
static const constexpr bool allow_fixed_string = false;
|
||||||
|
|
||||||
|
template <typename Result = ResultType>
|
||||||
|
static inline Result apply([[maybe_unused]] A left, [[maybe_unused]] B right)
|
||||||
{
|
{
|
||||||
extern const int BAD_ARGUMENTS;
|
if constexpr (!std::is_same_v<A, ResultType> || !std::is_same_v<B, ResultType>)
|
||||||
|
// Should be a logical error, but this function is callable from SQL.
|
||||||
|
// Need to investigate this.
|
||||||
|
throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitBoolMaskOr.", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
|
auto left_bits = littleBits<A>(left);
|
||||||
|
auto right_bits = littleBits<B>(right);
|
||||||
|
return static_cast<ResultType>(((left_bits | right_bits) & 1) | ((((left_bits >> 1) & (right_bits >> 1)) & 1) << 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
|
||||||
/// This function provides "OR" operation for BoolMasks.
|
|
||||||
/// Returns: "can be true" = A."can be true" OR B."can be true"
|
|
||||||
/// "can be false" = A."can be false" AND B."can be false"
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct BitBoolMaskOrImpl
|
|
||||||
{
|
|
||||||
using ResultType = UInt8;
|
|
||||||
static const constexpr bool allow_fixed_string = false;
|
|
||||||
|
|
||||||
template <typename Result = ResultType>
|
|
||||||
static inline Result apply([[maybe_unused]] A left, [[maybe_unused]] B right)
|
|
||||||
{
|
|
||||||
if constexpr (!std::is_same_v<A, ResultType> || !std::is_same_v<B, ResultType>)
|
|
||||||
// Should be a logical error, but this function is callable from SQL.
|
|
||||||
// Need to investigate this.
|
|
||||||
throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitBoolMaskOr.", ErrorCodes::BAD_ARGUMENTS);
|
|
||||||
|
|
||||||
auto left_bits = littleBits<A>(left);
|
|
||||||
auto right_bits = littleBits<B>(right);
|
|
||||||
return static_cast<ResultType>(((left_bits | right_bits) & 1) | ((((left_bits >> 1) & (right_bits >> 1)) & 1) << 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if USE_EMBEDDED_COMPILER
|
#if USE_EMBEDDED_COMPILER
|
||||||
static constexpr bool compilable = false;
|
static constexpr bool compilable = false;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NameBitBoolMaskOr { static constexpr auto name = "__bitBoolMaskOr"; };
|
struct NameBitBoolMaskOr { static constexpr auto name = "__bitBoolMaskOr"; };
|
||||||
using FunctionBitBoolMaskOr = FunctionBinaryArithmetic<BitBoolMaskOrImpl, NameBitBoolMaskOr>;
|
using FunctionBitBoolMaskOr = FunctionBinaryArithmetic<BitBoolMaskOrImpl, NameBitBoolMaskOr>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerFunctionBitBoolMaskOr(FunctionFactory & factory)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionBitBoolMaskOr>();
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitBoolMaskOr(FunctionFactory & factory)
|
|
||||||
{
|
|
||||||
factory.registerFunction<FunctionBitBoolMaskOr>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A>
|
template <typename A>
|
||||||
struct BitCountImpl
|
struct BitCountImpl
|
||||||
{
|
{
|
||||||
@ -37,6 +40,8 @@ struct BitCountImpl
|
|||||||
struct NameBitCount { static constexpr auto name = "bitCount"; };
|
struct NameBitCount { static constexpr auto name = "bitCount"; };
|
||||||
using FunctionBitCount = FunctionUnaryArithmetic<BitCountImpl, NameBitCount, false /* is injective */>;
|
using FunctionBitCount = FunctionUnaryArithmetic<BitCountImpl, NameBitCount, false /* is injective */>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// The function has no ranges of monotonicity.
|
/// The function has no ranges of monotonicity.
|
||||||
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitCount>
|
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitCount>
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A>
|
template <typename A>
|
||||||
struct BitNotImpl
|
struct BitNotImpl
|
||||||
{
|
{
|
||||||
@ -36,6 +39,8 @@ struct BitNotImpl
|
|||||||
struct NameBitNot { static constexpr auto name = "bitNot"; };
|
struct NameBitNot { static constexpr auto name = "bitNot"; };
|
||||||
using FunctionBitNot = FunctionUnaryArithmetic<BitNotImpl, NameBitNot, true>;
|
using FunctionBitNot = FunctionUnaryArithmetic<BitNotImpl, NameBitNot, true>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitNot>
|
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitNot>
|
||||||
{
|
{
|
||||||
static bool has() { return false; }
|
static bool has() { return false; }
|
||||||
|
@ -8,6 +8,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitOrImpl
|
struct BitOrImpl
|
||||||
{
|
{
|
||||||
@ -35,6 +38,8 @@ struct BitOrImpl
|
|||||||
struct NameBitOr { static constexpr auto name = "bitOr"; };
|
struct NameBitOr { static constexpr auto name = "bitOr"; };
|
||||||
using FunctionBitOr = FunctionBinaryArithmetic<BitOrImpl, NameBitOr, true>;
|
using FunctionBitOr = FunctionBinaryArithmetic<BitOrImpl, NameBitOr, true>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitOr(FunctionFactory & factory)
|
void registerFunctionBitOr(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitOr>();
|
factory.registerFunction<FunctionBitOr>();
|
||||||
|
@ -9,6 +9,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitRotateLeftImpl
|
struct BitRotateLeftImpl
|
||||||
{
|
{
|
||||||
@ -42,6 +45,8 @@ struct BitRotateLeftImpl
|
|||||||
struct NameBitRotateLeft { static constexpr auto name = "bitRotateLeft"; };
|
struct NameBitRotateLeft { static constexpr auto name = "bitRotateLeft"; };
|
||||||
using FunctionBitRotateLeft = FunctionBinaryArithmetic<BitRotateLeftImpl, NameBitRotateLeft>;
|
using FunctionBitRotateLeft = FunctionBinaryArithmetic<BitRotateLeftImpl, NameBitRotateLeft>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitRotateLeft(FunctionFactory & factory)
|
void registerFunctionBitRotateLeft(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitRotateLeft>();
|
factory.registerFunction<FunctionBitRotateLeft>();
|
||||||
|
@ -9,6 +9,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitRotateRightImpl
|
struct BitRotateRightImpl
|
||||||
{
|
{
|
||||||
@ -41,6 +44,8 @@ struct BitRotateRightImpl
|
|||||||
struct NameBitRotateRight { static constexpr auto name = "bitRotateRight"; };
|
struct NameBitRotateRight { static constexpr auto name = "bitRotateRight"; };
|
||||||
using FunctionBitRotateRight = FunctionBinaryArithmetic<BitRotateRightImpl, NameBitRotateRight>;
|
using FunctionBitRotateRight = FunctionBinaryArithmetic<BitRotateRightImpl, NameBitRotateRight>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitRotateRight(FunctionFactory & factory)
|
void registerFunctionBitRotateRight(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitRotateRight>();
|
factory.registerFunction<FunctionBitRotateRight>();
|
||||||
|
@ -9,6 +9,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitShiftLeftImpl
|
struct BitShiftLeftImpl
|
||||||
{
|
{
|
||||||
@ -41,6 +44,8 @@ struct BitShiftLeftImpl
|
|||||||
struct NameBitShiftLeft { static constexpr auto name = "bitShiftLeft"; };
|
struct NameBitShiftLeft { static constexpr auto name = "bitShiftLeft"; };
|
||||||
using FunctionBitShiftLeft = FunctionBinaryArithmetic<BitShiftLeftImpl, NameBitShiftLeft>;
|
using FunctionBitShiftLeft = FunctionBinaryArithmetic<BitShiftLeftImpl, NameBitShiftLeft>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitShiftLeft(FunctionFactory & factory)
|
void registerFunctionBitShiftLeft(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitShiftLeft>();
|
factory.registerFunction<FunctionBitShiftLeft>();
|
||||||
|
@ -9,6 +9,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitShiftRightImpl
|
struct BitShiftRightImpl
|
||||||
{
|
{
|
||||||
@ -41,6 +44,8 @@ struct BitShiftRightImpl
|
|||||||
struct NameBitShiftRight { static constexpr auto name = "bitShiftRight"; };
|
struct NameBitShiftRight { static constexpr auto name = "bitShiftRight"; };
|
||||||
using FunctionBitShiftRight = FunctionBinaryArithmetic<BitShiftRightImpl, NameBitShiftRight>;
|
using FunctionBitShiftRight = FunctionBinaryArithmetic<BitShiftRightImpl, NameBitShiftRight>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitShiftRight(FunctionFactory & factory)
|
void registerFunctionBitShiftRight(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitShiftRight>();
|
factory.registerFunction<FunctionBitShiftRight>();
|
||||||
|
@ -4,60 +4,66 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int LOGICAL_ERROR;
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
||||||
|
/// This function provides "NOT" operation for BoolMasks by swapping last two bits ("can be true" <-> "can be false").
|
||||||
|
template <typename A>
|
||||||
|
struct BitSwapLastTwoImpl
|
||||||
|
{
|
||||||
|
using ResultType = UInt8;
|
||||||
|
static constexpr const bool allow_fixed_string = false;
|
||||||
|
|
||||||
|
static inline ResultType NO_SANITIZE_UNDEFINED apply([[maybe_unused]] A a)
|
||||||
{
|
{
|
||||||
extern const int LOGICAL_ERROR;
|
if constexpr (!std::is_same_v<A, ResultType>)
|
||||||
extern const int BAD_ARGUMENTS;
|
// Should be a logical error, but this function is callable from SQL.
|
||||||
|
// Need to investigate this.
|
||||||
|
throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitSwapLastTwo.", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
|
auto little_bits = littleBits<A>(a);
|
||||||
|
return static_cast<ResultType>(((little_bits & 1) << 1) | ((little_bits >> 1) & 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
|
||||||
/// This function provides "NOT" operation for BoolMasks by swapping last two bits ("can be true" <-> "can be false").
|
|
||||||
template <typename A>
|
|
||||||
struct BitSwapLastTwoImpl
|
|
||||||
{
|
|
||||||
using ResultType = UInt8;
|
|
||||||
static constexpr const bool allow_fixed_string = false;
|
|
||||||
|
|
||||||
static inline ResultType NO_SANITIZE_UNDEFINED apply([[maybe_unused]] A a)
|
|
||||||
{
|
|
||||||
if constexpr (!std::is_same_v<A, ResultType>)
|
|
||||||
// Should be a logical error, but this function is callable from SQL.
|
|
||||||
// Need to investigate this.
|
|
||||||
throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitSwapLastTwo.", ErrorCodes::BAD_ARGUMENTS);
|
|
||||||
|
|
||||||
auto little_bits = littleBits<A>(a);
|
|
||||||
return static_cast<ResultType>(((little_bits & 1) << 1) | ((little_bits >> 1) & 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if USE_EMBEDDED_COMPILER
|
#if USE_EMBEDDED_COMPILER
|
||||||
static constexpr bool compilable = true;
|
static constexpr bool compilable = true;
|
||||||
|
|
||||||
|
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * arg, bool)
|
||||||
|
{
|
||||||
|
if (!arg->getType()->isIntegerTy())
|
||||||
|
throw Exception("__bitSwapLastTwo expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
||||||
|
return b.CreateOr(
|
||||||
|
b.CreateShl(b.CreateAnd(arg, 1), 1),
|
||||||
|
b.CreateAnd(b.CreateLShr(arg, 1), 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NameBitSwapLastTwo { static constexpr auto name = "__bitSwapLastTwo"; };
|
||||||
|
using FunctionBitSwapLastTwo = FunctionUnaryArithmetic<BitSwapLastTwoImpl, NameBitSwapLastTwo, true>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitSwapLastTwo>
|
||||||
|
{
|
||||||
|
static bool has() { return false; }
|
||||||
|
static IFunction::Monotonicity get(const Field &, const Field &)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void registerFunctionBitSwapLastTwo(FunctionFactory & factory)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionBitSwapLastTwo>();
|
||||||
|
}
|
||||||
|
|
||||||
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * arg, bool)
|
|
||||||
{
|
|
||||||
if (!arg->getType()->isIntegerTy())
|
|
||||||
throw Exception("__bitSwapLastTwo expected an integral type", ErrorCodes::LOGICAL_ERROR);
|
|
||||||
return b.CreateOr(
|
|
||||||
b.CreateShl(b.CreateAnd(arg, 1), 1),
|
|
||||||
b.CreateAnd(b.CreateLShr(arg, 1), 1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NameBitSwapLastTwo { static constexpr auto name = "__bitSwapLastTwo"; };
|
|
||||||
using FunctionBitSwapLastTwo = FunctionUnaryArithmetic<BitSwapLastTwoImpl, NameBitSwapLastTwo, true>;
|
|
||||||
|
|
||||||
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitSwapLastTwo>
|
|
||||||
{
|
|
||||||
static bool has() { return false; }
|
|
||||||
static IFunction::Monotonicity get(const Field &, const Field &)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void registerFunctionBitSwapLastTwo(FunctionFactory & factory)
|
|
||||||
{
|
|
||||||
factory.registerFunction<FunctionBitSwapLastTwo>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@ namespace ErrorCodes
|
|||||||
extern const int NOT_IMPLEMENTED;
|
extern const int NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitTestImpl
|
struct BitTestImpl
|
||||||
{
|
{
|
||||||
@ -33,6 +36,8 @@ struct BitTestImpl
|
|||||||
struct NameBitTest { static constexpr auto name = "bitTest"; };
|
struct NameBitTest { static constexpr auto name = "bitTest"; };
|
||||||
using FunctionBitTest = FunctionBinaryArithmetic<BitTestImpl, NameBitTest>;
|
using FunctionBitTest = FunctionBinaryArithmetic<BitTestImpl, NameBitTest>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitTest(FunctionFactory & factory)
|
void registerFunctionBitTest(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitTest>();
|
factory.registerFunction<FunctionBitTest>();
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct BitTestAllImpl
|
struct BitTestAllImpl
|
||||||
{
|
{
|
||||||
@ -13,6 +15,8 @@ struct BitTestAllImpl
|
|||||||
struct NameBitTestAll { static constexpr auto name = "bitTestAll"; };
|
struct NameBitTestAll { static constexpr auto name = "bitTestAll"; };
|
||||||
using FunctionBitTestAll = FunctionBitTestMany<BitTestAllImpl, NameBitTestAll>;
|
using FunctionBitTestAll = FunctionBitTestMany<BitTestAllImpl, NameBitTestAll>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitTestAll(FunctionFactory & factory)
|
void registerFunctionBitTestAll(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitTestAll>();
|
factory.registerFunction<FunctionBitTestAll>();
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct BitTestAnyImpl
|
struct BitTestAnyImpl
|
||||||
{
|
{
|
||||||
@ -13,6 +15,8 @@ struct BitTestAnyImpl
|
|||||||
struct NameBitTestAny { static constexpr auto name = "bitTestAny"; };
|
struct NameBitTestAny { static constexpr auto name = "bitTestAny"; };
|
||||||
using FunctionBitTestAny = FunctionBitTestMany<BitTestAnyImpl, NameBitTestAny>;
|
using FunctionBitTestAny = FunctionBitTestMany<BitTestAnyImpl, NameBitTestAny>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitTestAny(FunctionFactory & factory)
|
void registerFunctionBitTestAny(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitTestAny>();
|
factory.registerFunction<FunctionBitTestAny>();
|
||||||
|
@ -4,49 +4,53 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace ErrorCodes
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
||||||
|
/// This function wraps bool atomic functions
|
||||||
|
/// and transforms their boolean return value to the BoolMask ("can be false" and "can be true" bits).
|
||||||
|
template <typename A>
|
||||||
|
struct BitWrapperFuncImpl
|
||||||
|
{
|
||||||
|
using ResultType = UInt8;
|
||||||
|
static constexpr const bool allow_fixed_string = false;
|
||||||
|
|
||||||
|
static inline ResultType NO_SANITIZE_UNDEFINED apply(A a [[maybe_unused]])
|
||||||
{
|
{
|
||||||
extern const int BAD_ARGUMENTS;
|
// Should be a logical error, but this function is callable from SQL.
|
||||||
|
// Need to investigate this.
|
||||||
|
if constexpr (!is_integer_v<A>)
|
||||||
|
throw DB::Exception("It's a bug! Only integer types are supported by __bitWrapperFunc.", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
return a == 0 ? static_cast<ResultType>(0b10) : static_cast<ResultType >(0b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
|
|
||||||
/// This function wraps bool atomic functions
|
|
||||||
/// and transforms their boolean return value to the BoolMask ("can be false" and "can be true" bits).
|
|
||||||
template <typename A>
|
|
||||||
struct BitWrapperFuncImpl
|
|
||||||
{
|
|
||||||
using ResultType = UInt8;
|
|
||||||
static constexpr const bool allow_fixed_string = false;
|
|
||||||
|
|
||||||
static inline ResultType NO_SANITIZE_UNDEFINED apply(A a [[maybe_unused]])
|
|
||||||
{
|
|
||||||
// Should be a logical error, but this function is callable from SQL.
|
|
||||||
// Need to investigate this.
|
|
||||||
if constexpr (!is_integer_v<A>)
|
|
||||||
throw DB::Exception("It's a bug! Only integer types are supported by __bitWrapperFunc.", ErrorCodes::BAD_ARGUMENTS);
|
|
||||||
return a == 0 ? static_cast<ResultType>(0b10) : static_cast<ResultType >(0b1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if USE_EMBEDDED_COMPILER
|
#if USE_EMBEDDED_COMPILER
|
||||||
static constexpr bool compilable = false;
|
static constexpr bool compilable = false;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NameBitWrapperFunc { static constexpr auto name = "__bitWrapperFunc"; };
|
struct NameBitWrapperFunc { static constexpr auto name = "__bitWrapperFunc"; };
|
||||||
using FunctionBitWrapperFunc = FunctionUnaryArithmetic<BitWrapperFuncImpl, NameBitWrapperFunc, true>;
|
using FunctionBitWrapperFunc = FunctionUnaryArithmetic<BitWrapperFuncImpl, NameBitWrapperFunc, true>;
|
||||||
|
|
||||||
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitWrapperFunc>
|
|
||||||
{
|
|
||||||
static bool has() { return false; }
|
|
||||||
static IFunction::Monotonicity get(const Field &, const Field &)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void registerFunctionBitWrapperFunc(FunctionFactory & factory)
|
|
||||||
{
|
|
||||||
factory.registerFunction<FunctionBitWrapperFunc>();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> struct FunctionUnaryArithmeticMonotonicity<NameBitWrapperFunc>
|
||||||
|
{
|
||||||
|
static bool has() { return false; }
|
||||||
|
static IFunction::Monotonicity get(const Field &, const Field &)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void registerFunctionBitWrapperFunc(FunctionFactory & factory)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionBitWrapperFunc>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,6 +8,9 @@ namespace ErrorCodes
|
|||||||
extern const int LOGICAL_ERROR;
|
extern const int LOGICAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
struct BitXorImpl
|
struct BitXorImpl
|
||||||
{
|
{
|
||||||
@ -35,6 +38,8 @@ struct BitXorImpl
|
|||||||
struct NameBitXor { static constexpr auto name = "bitXor"; };
|
struct NameBitXor { static constexpr auto name = "bitXor"; };
|
||||||
using FunctionBitXor = FunctionBinaryArithmetic<BitXorImpl, NameBitXor, true>;
|
using FunctionBitXor = FunctionBinaryArithmetic<BitXorImpl, NameBitXor, true>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBitXor(FunctionFactory & factory)
|
void registerFunctionBitXor(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionBitXor>();
|
factory.registerFunction<FunctionBitXor>();
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/** Incremental block number among calls of this function. */
|
/** Incremental block number among calls of this function. */
|
||||||
class FunctionBlockNumber : public IFunction
|
class FunctionBlockNumber : public IFunction
|
||||||
@ -56,6 +58,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBlockNumber(FunctionFactory & factory)
|
void registerFunctionBlockNumber(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Returns size on disk for *block* (without taking into account compression).
|
/// Returns size on disk for *block* (without taking into account compression).
|
||||||
class FunctionBlockSerializedSize : public IFunction
|
class FunctionBlockSerializedSize : public IFunction
|
||||||
@ -60,6 +62,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBlockSerializedSize(FunctionFactory & factory)
|
void registerFunctionBlockSerializedSize(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/** blockSize() - get the block size in number of rows.
|
/** blockSize() - get the block size in number of rows.
|
||||||
*/
|
*/
|
||||||
@ -47,6 +49,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBlockSize(FunctionFactory & factory)
|
void registerFunctionBlockSize(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/** buildId() - returns the compiler build id of the running binary.
|
/** buildId() - returns the compiler build id of the running binary.
|
||||||
*/
|
*/
|
||||||
@ -42,6 +44,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionBuildId(FunctionFactory & factory)
|
void registerFunctionBuildId(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,9 @@ namespace ErrorCodes
|
|||||||
extern const int TOO_FEW_ARGUMENTS_FOR_FUNCTION;
|
extern const int TOO_FEW_ARGUMENTS_FOR_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Implements the CASE construction when it is
|
/// Implements the CASE construction when it is
|
||||||
/// provided an expression. Users should not call this function.
|
/// provided an expression. Users should not call this function.
|
||||||
class FunctionCaseWithExpression : public IFunction
|
class FunctionCaseWithExpression : public IFunction
|
||||||
@ -112,6 +115,8 @@ private:
|
|||||||
const Context & context;
|
const Context & context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionCaseWithExpression(FunctionFactory & factory)
|
void registerFunctionCaseWithExpression(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionCaseWithExpression>();
|
factory.registerFunction<FunctionCaseWithExpression>();
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct CbrtName { static constexpr auto name = "cbrt"; };
|
struct CbrtName { static constexpr auto name = "cbrt"; };
|
||||||
using FunctionCbrt = FunctionMathUnary<UnaryFunctionVectorized<CbrtName, cbrt>>;
|
using FunctionCbrt = FunctionMathUnary<UnaryFunctionVectorized<CbrtName, cbrt>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionCbrt(FunctionFactory & factory)
|
void registerFunctionCbrt(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionCbrt>();
|
factory.registerFunction<FunctionCbrt>();
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Implements the function coalesce which takes a set of arguments and
|
/// Implements the function coalesce which takes a set of arguments and
|
||||||
/// returns the value of the leftmost non-null argument. If no such value is
|
/// returns the value of the leftmost non-null argument. If no such value is
|
||||||
@ -175,6 +177,7 @@ private:
|
|||||||
const Context & context;
|
const Context & context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionCoalesce(FunctionFactory & factory)
|
void registerFunctionCoalesce(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,8 @@ namespace ErrorCodes
|
|||||||
|
|
||||||
using namespace GatherUtils;
|
using namespace GatherUtils;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
template <typename Name, bool is_injective>
|
template <typename Name, bool is_injective>
|
||||||
class ConcatImpl : public IFunction
|
class ConcatImpl : public IFunction
|
||||||
@ -225,6 +227,7 @@ private:
|
|||||||
const Context & context;
|
const Context & context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionsConcat(FunctionFactory & factory)
|
void registerFunctionsConcat(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,8 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_COLUMN;
|
extern const int ILLEGAL_COLUMN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/** convertCharset(s, from, to)
|
/** convertCharset(s, from, to)
|
||||||
*
|
*
|
||||||
@ -210,6 +212,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionConvertCharset(FunctionFactory & factory)
|
void registerFunctionConvertCharset(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct CosName { static constexpr auto name = "cos"; };
|
struct CosName { static constexpr auto name = "cos"; };
|
||||||
using FunctionCos = FunctionMathUnary<UnaryFunctionVectorized<CosName, cos>>;
|
using FunctionCos = FunctionMathUnary<UnaryFunctionVectorized<CosName, cos>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionCos(FunctionFactory & factory)
|
void registerFunctionCos(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionCos>(FunctionFactory::CaseInsensitive);
|
factory.registerFunction<FunctionCos>(FunctionFactory::CaseInsensitive);
|
||||||
|
@ -16,6 +16,9 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_COLUMN;
|
extern const int ILLEGAL_COLUMN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Returns number of decimal digits you need to represent the value.
|
/// Returns number of decimal digits you need to represent the value.
|
||||||
/// For Decimal values takes in account their scales: calculates result over underlying int type which is (value * scale).
|
/// For Decimal values takes in account their scales: calculates result over underlying int type which is (value * scale).
|
||||||
/// countDigits(42) = 2, countDigits(42.000) = 5, countDigits(0.04200) = 4.
|
/// countDigits(42) = 2, countDigits(42.000) = 5, countDigits(0.04200) = 4.
|
||||||
@ -136,6 +139,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionCountDigits(FunctionFactory & factory)
|
void registerFunctionCountDigits(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class FunctionCurrentDatabase : public IFunction
|
class FunctionCurrentDatabase : public IFunction
|
||||||
{
|
{
|
||||||
@ -45,6 +47,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionCurrentDatabase(FunctionFactory & factory)
|
void registerFunctionCurrentDatabase(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class FunctionCurrentUser : public IFunction
|
class FunctionCurrentUser : public IFunction
|
||||||
{
|
{
|
||||||
@ -45,6 +47,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionCurrentUser(FunctionFactory & factory)
|
void registerFunctionCurrentUser(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,9 @@ namespace ErrorCodes
|
|||||||
extern const int BAD_ARGUMENTS;
|
extern const int BAD_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/** dateDiff('unit', t1, t2, [timezone])
|
/** dateDiff('unit', t1, t2, [timezone])
|
||||||
* t1 and t2 can be Date or DateTime
|
* t1 and t2 can be Date or DateTime
|
||||||
*
|
*
|
||||||
@ -212,6 +215,8 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionDateDiff(FunctionFactory & factory)
|
void registerFunctionDateDiff(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionDateDiff>(FunctionFactory::CaseInsensitive);
|
factory.registerFunction<FunctionDateDiff>(FunctionFactory::CaseInsensitive);
|
||||||
|
@ -17,6 +17,8 @@ namespace ErrorCodes
|
|||||||
extern const int BAD_ARGUMENTS;
|
extern const int BAD_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class FunctionDateTrunc : public IFunction
|
class FunctionDateTrunc : public IFunction
|
||||||
{
|
{
|
||||||
@ -159,6 +161,7 @@ private:
|
|||||||
mutable IntervalKind::Kind datepart_kind = IntervalKind::Kind::Second;
|
mutable IntervalKind::Kind datepart_kind = IntervalKind::Kind::Second;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionDateTrunc(FunctionFactory & factory)
|
void registerFunctionDateTrunc(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Returns global default value for type of passed argument (example: 0 for numeric types, '' for String).
|
/// Returns global default value for type of passed argument (example: 0 for numeric types, '' for String).
|
||||||
class FunctionDefaultValueOfArgumentType : public IFunction
|
class FunctionDefaultValueOfArgumentType : public IFunction
|
||||||
@ -47,6 +49,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionDefaultValueOfArgumentType(FunctionFactory & factory)
|
void registerFunctionDefaultValueOfArgumentType(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,9 @@ namespace ErrorCodes
|
|||||||
extern const int ILLEGAL_COLUMN;
|
extern const int ILLEGAL_COLUMN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Returns global default value for type name (example: 0 for numeric types, '' for String).
|
/// Returns global default value for type name (example: 0 for numeric types, '' for String).
|
||||||
class FunctionDefaultValueOfTypeName : public IFunction
|
class FunctionDefaultValueOfTypeName : public IFunction
|
||||||
{
|
{
|
||||||
@ -53,6 +56,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionDefaultValueOfTypeName(FunctionFactory & factory)
|
void registerFunctionDefaultValueOfTypeName(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,9 @@ namespace ErrorCodes
|
|||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class FunctionDemangle : public IFunction
|
class FunctionDemangle : public IFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -86,6 +89,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionDemangle(FunctionFactory & factory)
|
void registerFunctionDemangle(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionDemangle>();
|
factory.registerFunction<FunctionDemangle>();
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
/// Dump the structure of type and column.
|
/// Dump the structure of type and column.
|
||||||
class FunctionDumpColumnStructure : public IFunction
|
class FunctionDumpColumnStructure : public IFunction
|
||||||
@ -46,6 +48,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionDumpColumnStructure(FunctionFactory & factory)
|
void registerFunctionDumpColumnStructure(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct EImpl
|
struct EImpl
|
||||||
{
|
{
|
||||||
@ -12,6 +14,8 @@ struct EImpl
|
|||||||
|
|
||||||
using FunctionE = FunctionMathConstFloat64<EImpl>;
|
using FunctionE = FunctionMathConstFloat64<EImpl>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionE(FunctionFactory & factory)
|
void registerFunctionE(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionE>();
|
factory.registerFunction<FunctionE>();
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct NameEmpty
|
struct NameEmpty
|
||||||
{
|
{
|
||||||
@ -13,6 +15,8 @@ struct NameEmpty
|
|||||||
};
|
};
|
||||||
using FunctionEmpty = FunctionStringOrArrayToT<EmptyImpl<false>, NameEmpty, UInt8>;
|
using FunctionEmpty = FunctionStringOrArrayToT<EmptyImpl<false>, NameEmpty, UInt8>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionEmpty(FunctionFactory & factory)
|
void registerFunctionEmpty(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionEmpty>();
|
factory.registerFunction<FunctionEmpty>();
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct ErfName { static constexpr auto name = "erf"; };
|
struct ErfName { static constexpr auto name = "erf"; };
|
||||||
using FunctionErf = FunctionMathUnary<UnaryFunctionPlain<ErfName, std::erf>>;
|
using FunctionErf = FunctionMathUnary<UnaryFunctionPlain<ErfName, std::erf>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionErf(FunctionFactory & factory)
|
void registerFunctionErf(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionErf>();
|
factory.registerFunction<FunctionErf>();
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct ErfcName { static constexpr auto name = "erfc"; };
|
struct ErfcName { static constexpr auto name = "erfc"; };
|
||||||
using FunctionErfc = FunctionMathUnary<UnaryFunctionPlain<ErfcName, std::erfc>>;
|
using FunctionErfc = FunctionMathUnary<UnaryFunctionPlain<ErfcName, std::erfc>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionErfc(FunctionFactory & factory)
|
void registerFunctionErfc(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionErfc>();
|
factory.registerFunction<FunctionErfc>();
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
|
extern const int ILLEGAL_COLUMN;
|
||||||
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ErrorCodes
|
namespace
|
||||||
{
|
{
|
||||||
extern const int BAD_ARGUMENTS;
|
|
||||||
extern const int ILLEGAL_COLUMN;
|
|
||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** finalizeAggregation(agg_state) - get the result from the aggregation state.
|
/** finalizeAggregation(agg_state) - get the result from the aggregation state.
|
||||||
* Takes state of aggregate function. Returns result of aggregation (finalized state).
|
* Takes state of aggregate function. Returns result of aggregation (finalized state).
|
||||||
@ -83,6 +84,8 @@ public:
|
|||||||
const Context & context;
|
const Context & context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionEvalMLMethod(FunctionFactory & factory)
|
void registerFunctionEvalMLMethod(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionEvalMLMethod>();
|
factory.registerFunction<FunctionEvalMLMethod>();
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct ExpName { static constexpr auto name = "exp"; };
|
struct ExpName { static constexpr auto name = "exp"; };
|
||||||
|
|
||||||
@ -30,6 +32,8 @@ using FunctionExp = FunctionMathUnary<Impl>;
|
|||||||
using FunctionExp = FunctionMathUnary<UnaryFunctionVectorized<ExpName, exp>>;
|
using FunctionExp = FunctionMathUnary<UnaryFunctionVectorized<ExpName, exp>>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionExp(FunctionFactory & factory)
|
void registerFunctionExp(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionExp>(FunctionFactory::CaseInsensitive);
|
factory.registerFunction<FunctionExp>(FunctionFactory::CaseInsensitive);
|
||||||
|
@ -4,11 +4,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct Exp10Name { static constexpr auto name = "exp10"; };
|
struct Exp10Name { static constexpr auto name = "exp10"; };
|
||||||
|
|
||||||
using FunctionExp10 = FunctionMathUnary<UnaryFunctionVectorized<Exp10Name, preciseExp10>>;
|
using FunctionExp10 = FunctionMathUnary<UnaryFunctionVectorized<Exp10Name, preciseExp10>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionExp10(FunctionFactory & factory)
|
void registerFunctionExp10(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionExp10>();
|
factory.registerFunction<FunctionExp10>();
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
struct Exp2Name { static constexpr auto name = "exp2"; };
|
struct Exp2Name { static constexpr auto name = "exp2"; };
|
||||||
using FunctionExp2 = FunctionMathUnary<UnaryFunctionVectorized<Exp2Name, exp2>>;
|
using FunctionExp2 = FunctionMathUnary<UnaryFunctionVectorized<Exp2Name, exp2>>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void registerFunctionExp2(FunctionFactory & factory)
|
void registerFunctionExp2(FunctionFactory & factory)
|
||||||
{
|
{
|
||||||
factory.registerFunction<FunctionExp2>();
|
factory.registerFunction<FunctionExp2>();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user