mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-14 19:45:11 +00:00
Merge branch 'master' into jepsen-label
This commit is contained in:
commit
621da05145
@ -77,10 +77,9 @@ option(USE_STATIC_LIBRARIES "Disable to use shared libraries" ON)
|
||||
# DEVELOPER ONLY.
|
||||
# Faster linking if turned on.
|
||||
option(SPLIT_SHARED_LIBRARIES "Keep all internal libraries as separate .so files" OFF)
|
||||
option(CLICKHOUSE_SPLIT_BINARY "Make several binaries (clickhouse-server, clickhouse-client etc.) instead of one bundled" OFF)
|
||||
|
||||
if (USE_STATIC_LIBRARIES AND (SPLIT_SHARED_LIBRARIES OR CLICKHOUSE_SPLIT_BINARY))
|
||||
message(FATAL_ERROR "SPLIT_SHARED_LIBRARIES=1 or CLICKHOUSE_SPLIT_BINARY=1 must not be used together with USE_STATIC_LIBRARIES=1")
|
||||
if (USE_STATIC_LIBRARIES AND SPLIT_SHARED_LIBRARIES)
|
||||
message(FATAL_ERROR "SPLIT_SHARED_LIBRARIES=1 must not be used together with USE_STATIC_LIBRARIES=1")
|
||||
endif()
|
||||
|
||||
if (NOT USE_STATIC_LIBRARIES AND SPLIT_SHARED_LIBRARIES)
|
||||
@ -502,7 +501,7 @@ endif ()
|
||||
message (STATUS
|
||||
"Building for: ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_LIBRARY_ARCHITECTURE} ;
|
||||
USE_STATIC_LIBRARIES=${USE_STATIC_LIBRARIES}
|
||||
SPLIT_SHARED=${SPLIT_SHARED_LIBRARIES}")
|
||||
SPLIT_SHARED_LIBRARIES=${SPLIT_SHARED_LIBRARIES}")
|
||||
|
||||
include (GNUInstallDirs)
|
||||
|
||||
|
@ -16,5 +16,3 @@ ClickHouse® is an open-source column-oriented database management system that a
|
||||
|
||||
## Upcoming events
|
||||
* **v22.8 Release Webinar** Original creator, co-founder, and CTO of ClickHouse Alexey Milovidov will walk us through the highlights of the release, provide live demos, and share vision into what is coming in the roadmap.
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ option (ENABLE_SSE41 "Use SSE4.1 instructions on x86_64" 1)
|
||||
option (ENABLE_SSE42 "Use SSE4.2 instructions on x86_64" 1)
|
||||
option (ENABLE_PCLMULQDQ "Use pclmulqdq instructions on x86_64" 1)
|
||||
option (ENABLE_POPCNT "Use popcnt instructions on x86_64" 1)
|
||||
option (ENABLE_AVX "Use AVX instructions on x86_64" 0)
|
||||
option (ENABLE_AVX "Use AVX instructions on x86_64" 1)
|
||||
option (ENABLE_AVX2 "Use AVX2 instructions on x86_64" 0)
|
||||
option (ENABLE_AVX512 "Use AVX512 instructions on x86_64" 0)
|
||||
option (ENABLE_AVX512_VBMI "Use AVX512_VBMI instruction on x86_64 (depends on ENABLE_AVX512)" 0)
|
||||
|
2
contrib/arrow
vendored
2
contrib/arrow
vendored
@ -1 +1 @@
|
||||
Subproject commit efdcd015cfdee1b6aa349c9ca227ca12c3d697f5
|
||||
Subproject commit 3e03c6de41a86df2fc54a61e9be1abaefeff6b0e
|
@ -266,8 +266,7 @@ def parse_env_variables(
|
||||
|
||||
if split_binary:
|
||||
cmake_flags.append(
|
||||
"-DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1 "
|
||||
"-DCLICKHOUSE_SPLIT_BINARY=1"
|
||||
"-DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1"
|
||||
)
|
||||
# We can't always build utils because it requires too much space, but
|
||||
# we have to build them at least in some way in CI. The split build is
|
||||
|
@ -38,6 +38,7 @@ FORMAT_SCHEMA_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_
|
||||
|
||||
# There could be many disks declared in config
|
||||
readarray -t FILESYSTEM_CACHE_PATHS < <(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key='storage_configuration.disks.*.data_cache_path' || true)
|
||||
readarray -t DISKS_PATHS < <(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key='storage_configuration.disks.*.path' || true)
|
||||
|
||||
CLICKHOUSE_USER="${CLICKHOUSE_USER:-default}"
|
||||
CLICKHOUSE_PASSWORD="${CLICKHOUSE_PASSWORD:-}"
|
||||
@ -50,7 +51,8 @@ for dir in "$DATA_DIR" \
|
||||
"$TMP_DIR" \
|
||||
"$USER_PATH" \
|
||||
"$FORMAT_SCHEMA_PATH" \
|
||||
"${FILESYSTEM_CACHE_PATHS[@]}"
|
||||
"${FILESYSTEM_CACHE_PATHS[@]}" \
|
||||
"${DISKS_PATHS[@]}"
|
||||
do
|
||||
# check if variable not empty
|
||||
[ -z "$dir" ] && continue
|
||||
|
@ -171,11 +171,11 @@ concurrency-related errors. If it fails:
|
||||
|
||||
## Split Build Smoke Test
|
||||
|
||||
Checks that the server build in [split build](../development/build.md#split-build)
|
||||
Checks that the server build in [split build](../development/developer-instruction.md#split-build)
|
||||
configuration can start and run simple queries. If it fails:
|
||||
|
||||
* Fix other test errors first;
|
||||
* Build the server in [split build](../development/build.md#split-build) configuration
|
||||
* Build the server in [split build](../development/developer-instruction.md#split-build) configuration
|
||||
locally and check whether it can start and run `select 1`.
|
||||
|
||||
|
||||
|
@ -269,17 +269,11 @@ Most probably some of the builds will fail at first times. This is due to the fa
|
||||
|
||||
## Faster builds for development: Split build configuration {#split-build}
|
||||
|
||||
ClickHouse is normally statically linked into a single static `clickhouse` binary with minimal dependencies. This is convenient for distribution, but it means that for every change the entire binary needs to be re-linked, which is slow and inconvenient for development. As an alternative, you can instead build dynamically linked shared libraries and separate binaries `clickhouse-server`, `clickhouse-client` etc., allowing for faster incremental builds. To use it, add the following flags to your `cmake` invocation:
|
||||
ClickHouse is normally statically linked into a single static `clickhouse` binary with minimal dependencies. This is convenient for distribution, but it means that for every change the entire binary needs to be re-linked, which is slow and inconvenient for development. As an alternative, you can instead build dynamically linked shared libraries, allowing for faster incremental builds. To use it, add the following flags to your `cmake` invocation:
|
||||
```
|
||||
-DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1 -DCLICKHOUSE_SPLIT_BINARY=1
|
||||
-DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1
|
||||
```
|
||||
|
||||
Note that the split build has several drawbacks:
|
||||
* There is no single `clickhouse` binary, and you have to run `clickhouse-server`, `clickhouse-client`, etc.
|
||||
* Risk of segfault if you run any of the programs while rebuilding the project.
|
||||
* You cannot run the integration tests since they only work a single complete binary.
|
||||
* You can't easily copy the binaries elsewhere. Instead of moving a single binary you'll need to copy all binaries and libraries.
|
||||
|
||||
If you are not interested in functionality provided by third-party libraries, you can further speed up the build using `cmake` options
|
||||
```
|
||||
-DENABLE_LIBRARIES=0 -DENABLE_EMBEDDED_COMPILER=0
|
||||
|
2
docs/en/interfaces/third-party/gui.md
vendored
2
docs/en/interfaces/third-party/gui.md
vendored
@ -149,7 +149,7 @@ Features:
|
||||
|
||||
### ClickCat {#clickcat}
|
||||
|
||||
[ClickCat](https://github.com/clickcat-project/ClickCat) is a firendly user interface that lets you search, explore and visualize your ClickHouse Data.
|
||||
[ClickCat](https://github.com/clickcat-project/ClickCat) is a friendly user interface that lets you search, explore and visualize your ClickHouse Data.
|
||||
|
||||
Features:
|
||||
|
||||
|
@ -5,12 +5,12 @@ sidebar_label: Testing Hardware
|
||||
|
||||
# How to Test Your Hardware with ClickHouse
|
||||
|
||||
You can run basic ClickHouse performance test on any server without installation of ClickHouse packages.
|
||||
You can run a basic ClickHouse performance test on any server without installation of ClickHouse packages.
|
||||
|
||||
|
||||
## Automated Run
|
||||
|
||||
You can run benchmark with a single script.
|
||||
You can run the benchmark with a single script.
|
||||
|
||||
1. Download the script.
|
||||
```
|
||||
@ -26,58 +26,3 @@ chmod a+x ./hardware.sh
|
||||
3. Copy the output and send it to feedback@clickhouse.com
|
||||
|
||||
All the results are published here: https://clickhouse.com/benchmark/hardware/
|
||||
|
||||
|
||||
## Manual Run
|
||||
|
||||
Alternatively you can perform benchmark in the following steps.
|
||||
|
||||
1. ssh to the server and download the binary with wget:
|
||||
```bash
|
||||
# For amd64:
|
||||
wget https://builds.clickhouse.com/master/amd64/clickhouse
|
||||
# For aarch64:
|
||||
wget https://builds.clickhouse.com/master/aarch64/clickhouse
|
||||
# For powerpc64le:
|
||||
wget https://builds.clickhouse.com/master/powerpc64le/clickhouse
|
||||
# For freebsd:
|
||||
wget https://builds.clickhouse.com/master/freebsd/clickhouse
|
||||
# For freebsd-aarch64:
|
||||
wget https://builds.clickhouse.com/master/freebsd-aarch64/clickhouse
|
||||
# For freebsd-powerpc64le:
|
||||
wget https://builds.clickhouse.com/master/freebsd-powerpc64le/clickhouse
|
||||
# For macos:
|
||||
wget https://builds.clickhouse.com/master/macos/clickhouse
|
||||
# For macos-aarch64:
|
||||
wget https://builds.clickhouse.com/master/macos-aarch64/clickhouse
|
||||
# Then do:
|
||||
chmod a+x clickhouse
|
||||
```
|
||||
2. Download benchmark files:
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/benchmark/hardware/benchmark-new.sh
|
||||
chmod a+x benchmark-new.sh
|
||||
wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/benchmark/hardware/queries.sql
|
||||
```
|
||||
3. Download the [web analytics dataset](../getting-started/example-datasets/metrica.md) (“hits” table containing 100 million rows).
|
||||
```bash
|
||||
wget https://datasets.clickhouse.com/hits/partitions/hits_100m_obfuscated_v1.tar.xz
|
||||
tar xvf hits_100m_obfuscated_v1.tar.xz -C .
|
||||
mv hits_100m_obfuscated_v1/* .
|
||||
```
|
||||
4. Run the server:
|
||||
```bash
|
||||
./clickhouse server
|
||||
```
|
||||
5. Check the data: ssh to the server in another terminal
|
||||
```bash
|
||||
./clickhouse client --query "SELECT count() FROM hits_100m_obfuscated"
|
||||
100000000
|
||||
```
|
||||
6. Run the benchmark:
|
||||
```bash
|
||||
./benchmark-new.sh hits_100m_obfuscated
|
||||
```
|
||||
7. Send the numbers and the info about your hardware configuration to feedback@clickhouse.com
|
||||
|
||||
All the results are published here: https://clickhouse.com/benchmark/hardware/
|
||||
|
@ -956,9 +956,28 @@ SELECT
|
||||
|
||||
## timeSlots(StartTime, Duration,\[, Size\])
|
||||
|
||||
For a time interval starting at ‘StartTime’ and continuing for ‘Duration’ seconds, it returns an array of moments in time, consisting of points from this interval rounded down to the ‘Size’ in seconds. ‘Size’ is an optional parameter: a constant UInt32, set to 1800 by default.
|
||||
For example, `timeSlots(toDateTime('2012-01-01 12:20:00'), 600) = [toDateTime('2012-01-01 12:00:00'), toDateTime('2012-01-01 12:30:00')]`.
|
||||
This is necessary for searching for pageviews in the corresponding session.
|
||||
For a time interval starting at ‘StartTime’ and continuing for ‘Duration’ seconds, it returns an array of moments in time, consisting of points from this interval rounded down to the ‘Size’ in seconds. ‘Size’ is an optional parameter set to 1800 (30 minutes) by default.
|
||||
This is necessary, for example, when searching for pageviews in the corresponding session.
|
||||
Accepts DateTime and DateTime64 as ’StartTime’ argument. For DateTime, ’Duration’ and ’Size’ arguments must be `UInt32`. For ’DateTime64’ they must be `Decimal64`.
|
||||
Returns an array of DateTime/DateTime64 (return type matches the type of ’StartTime’). For DateTime64, the return value's scale can differ from the scale of ’StartTime’ --- the highest scale among all given arguments is taken.
|
||||
|
||||
Example:
|
||||
```sql
|
||||
SELECT timeSlots(toDateTime('2012-01-01 12:20:00'), toUInt32(600));
|
||||
SELECT timeSlots(toDateTime('1980-12-12 21:01:02', 'UTC'), toUInt32(600), 299);
|
||||
SELECT timeSlots(toDateTime64('1980-12-12 21:01:02.1234', 4, 'UTC'), toDecimal64(600.1, 1), toDecimal64(299, 0));
|
||||
```
|
||||
``` text
|
||||
┌─timeSlots(toDateTime('2012-01-01 12:20:00'), toUInt32(600))─┐
|
||||
│ ['2012-01-01 12:00:00','2012-01-01 12:30:00'] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
┌─timeSlots(toDateTime('1980-12-12 21:01:02', 'UTC'), toUInt32(600), 299)─┐
|
||||
│ ['1980-12-12 20:56:13','1980-12-12 21:01:12','1980-12-12 21:06:11'] │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
┌─timeSlots(toDateTime64('1980-12-12 21:01:02.1234', 4, 'UTC'), toDecimal64(600.1, 1), toDecimal64(299, 0))─┐
|
||||
│ ['1980-12-12 20:56:13.0000','1980-12-12 21:01:12.0000','1980-12-12 21:06:11.0000'] │
|
||||
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## formatDateTime
|
||||
|
||||
|
@ -12,12 +12,13 @@ Reads file as a String. The file content is not parsed, so any information is re
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
file(path)
|
||||
file(path[, default])
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `path` — The relative path to the file from [user_files_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_files_path). Path to file support following wildcards: `*`, `?`, `{abc,def}` and `{N..M}` where `N`, `M` — numbers, `'abc', 'def'` — strings.
|
||||
- `default` — The value that will be returned in the case when a file does not exist or cannot be accessed. Data types supported: [String](../../sql-reference/data-types/string.md) and [NULL](../../sql-reference/syntax.md#null-literal).
|
||||
|
||||
**Example**
|
||||
|
||||
|
@ -170,7 +170,7 @@ sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
|
||||
|
||||
В случае использования на разработческой машине старого HDD или SSD, а также при желании использовать меньше места для артефактов сборки можно использовать следующую команду:
|
||||
```bash
|
||||
cmake -DUSE_DEBUG_HELPERS=1 -DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1 -DCLICKHOUSE_SPLIT_BINARY=1 ..
|
||||
cmake -DUSE_DEBUG_HELPERS=1 -DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1 ..
|
||||
```
|
||||
При этом надо учесть, что получаемые в результате сборки исполнимые файлы будут динамически слинкованы с библиотеками, и поэтому фактически станут непереносимыми на другие компьютеры (либо для этого нужно будет предпринять значительно больше усилий по сравнению со статической сборкой). Плюсом же в данном случае является значительно меньшее время сборки (это проявляется не на первой сборке, а на последующих, после внесения изменений в исходный код - тратится меньшее время на линковку по сравнению со статической сборкой) и значительно меньшее использование места на жёстком диске (экономия более, чем в 3 раза по сравнению со статической сборкой). Для целей разработки, когда планируются только отладочные запуски на том же компьютере, где осуществлялась сборка, это может быть наиболее удобным вариантом.
|
||||
|
||||
|
@ -944,14 +944,31 @@ SELECT now('Europe/Moscow');
|
||||
## timeSlot {#timeslot}
|
||||
|
||||
Округляет время до получаса.
|
||||
Эта функция является специфичной для Яндекс.Метрики, так как пол часа - минимальное время, для которого, если соседние по времени хиты одного посетителя на одном счётчике отстоят друг от друга строго более, чем на это время, визит может быть разбит на два визита. То есть, кортежи (номер счётчика, идентификатор посетителя, тайм-слот) могут использоваться для поиска хитов, входящий в соответствующий визит.
|
||||
Эта функция является специфичной для Яндекс.Метрики, так как полчаса - минимальное время, для которого, если соседние по времени хиты одного посетителя на одном счётчике отстоят друг от друга строго более, чем на это время, визит может быть разбит на два визита. То есть, кортежи (номер счётчика, идентификатор посетителя, тайм-слот) могут использоваться для поиска хитов, входящий в соответствующий визит.
|
||||
|
||||
## timeSlots(StartTime, Duration,\[, Size\]) {#timeslotsstarttime-duration-size}
|
||||
Для интервала, начинающегося в `StartTime` и длящегося `Duration` секунд, возвращает массив моментов времени, кратных `Size`. Параметр `Size` указывать необязательно, по умолчанию он равен 1800 секундам (30 минутам) - необязательный параметр.
|
||||
Данная функция может использоваться, например, для анализа количества просмотров страницы за соответствующую сессию.
|
||||
Аргумент `StartTime` может иметь тип `DateTime` или `DateTime64`. В случае, если используется `DateTime`, аргументы `Duration` и `Size` должны иметь тип `UInt32`; Для DateTime64 они должны быть типа `Decimal64`.
|
||||
Возвращает массив DateTime/DateTime64 (тип будет совпадать с типом параметра ’StartTime’). Для DateTime64 масштаб(scale) возвращаемой величины может отличаться от масштаба фргумента ’StartTime’ --- результат будет иметь наибольший масштаб среди всех данных аргументов.
|
||||
|
||||
Для интервала времени, начинающегося в ‘StartTime’ и продолжающегося ‘Duration’ секунд, возвращает массив моментов времени, состоящий из округлений вниз до ‘Size’ точек в секундах из этого интервала. ‘Size’ - необязательный параметр, константный UInt32, по умолчанию равен 1800.
|
||||
|
||||
Например, `timeSlots(toDateTime('2012-01-01 12:20:00'), toUInt32(600)) = [toDateTime('2012-01-01 12:00:00'), toDateTime('2012-01-01 12:30:00')]`.
|
||||
Это нужно для поиска хитов, входящих в соответствующий визит.
|
||||
Пример использования:
|
||||
```sql
|
||||
SELECT timeSlots(toDateTime('2012-01-01 12:20:00'), toUInt32(600));
|
||||
SELECT timeSlots(toDateTime('1980-12-12 21:01:02', 'UTC'), toUInt32(600), 299);
|
||||
SELECT timeSlots(toDateTime64('1980-12-12 21:01:02.1234', 4, 'UTC'), toDecimal64(600.1, 1), toDecimal64(299, 0));
|
||||
```
|
||||
``` text
|
||||
┌─timeSlots(toDateTime('2012-01-01 12:20:00'), toUInt32(600))─┐
|
||||
│ ['2012-01-01 12:00:00','2012-01-01 12:30:00'] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
┌─timeSlots(toDateTime('1980-12-12 21:01:02', 'UTC'), toUInt32(600), 299)─┐
|
||||
│ ['1980-12-12 20:56:13','1980-12-12 21:01:12','1980-12-12 21:06:11'] │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
┌─timeSlots(toDateTime64('1980-12-12 21:01:02.1234', 4, 'UTC'), toDecimal64(600.1, 1), toDecimal64(299, 0))─┐
|
||||
│ ['1980-12-12 20:56:13.0000','1980-12-12 21:01:12.0000','1980-12-12 21:06:11.0000'] │
|
||||
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## toYYYYMM
|
||||
|
||||
|
@ -12,12 +12,13 @@ sidebar_label: "Функции для работы с файлами"
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
file(path)
|
||||
file(path[, default])
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `path` — относительный путь до файла от [user_files_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_files_path). Путь к файлу может включать следующие символы подстановки и шаблоны: `*`, `?`, `{abc,def}` и `{N..M}`, где `N`, `M` — числа, `'abc', 'def'` — строки.
|
||||
- `default` — Значение возвращаемое в случае, если указанный файл не существует. Поддерживаемые типы данных: [String](../../sql-reference/data-types/string.md) и [NULL](../../sql-reference/syntax.md#null-literal).
|
||||
|
||||
**Примеры**
|
||||
|
||||
|
@ -62,6 +62,8 @@ ORDER BY expr
|
||||
|
||||
- `PARTITION BY` — [分区键](custom-partitioning-key.md) ,可选项。
|
||||
|
||||
大多数情况下,不需要分使用区键。即使需要使用,也不需要使用比月更细粒度的分区键。分区不会加快查询(这与 ORDER BY 表达式不同)。永远也别使用过细粒度的分区键。不要使用客户端指定分区标识符或分区字段名称来对数据进行分区(而是将分区字段标识或名称作为 ORDER BY 表达式的第一列来指定分区)。
|
||||
|
||||
要按月分区,可以使用表达式 `toYYYYMM(date_column)` ,这里的 `date_column` 是一个 [Date](../../../engines/table-engines/mergetree-family/mergetree.md) 类型的列。分区名的格式会是 `"YYYYMM"` 。
|
||||
|
||||
- `PRIMARY KEY` - 如果要 [选择与排序键不同的主键](#choosing-a-primary-key-that-differs-from-the-sorting-key),在这里指定,可选项。
|
||||
|
@ -18,11 +18,7 @@ option (ENABLE_CLICKHOUSE_SERVER "Server mode (main mode)" ${ENABLE_CLICKHOUSE_A
|
||||
option (ENABLE_CLICKHOUSE_CLIENT "Client mode (interactive tui/shell that connects to the server)"
|
||||
${ENABLE_CLICKHOUSE_ALL})
|
||||
|
||||
if (CLICKHOUSE_SPLIT_BINARY)
|
||||
option (ENABLE_CLICKHOUSE_SELF_EXTRACTING "Self-extracting executable" OFF)
|
||||
else ()
|
||||
option (ENABLE_CLICKHOUSE_SELF_EXTRACTING "Self-extracting executable" ON)
|
||||
endif ()
|
||||
option (ENABLE_CLICKHOUSE_SELF_EXTRACTING "Self-extracting executable" ON)
|
||||
|
||||
# https://clickhouse.com/docs/en/operations/utilities/clickhouse-local/
|
||||
option (ENABLE_CLICKHOUSE_LOCAL "Local files fast processing mode" ${ENABLE_CLICKHOUSE_ALL})
|
||||
@ -80,12 +76,7 @@ if (NOT ENABLE_NURAFT)
|
||||
set(ENABLE_CLICKHOUSE_KEEPER_CONVERTER OFF)
|
||||
endif()
|
||||
|
||||
if (CLICKHOUSE_SPLIT_BINARY)
|
||||
option(ENABLE_CLICKHOUSE_INSTALL "Install ClickHouse without .deb/.rpm/.tgz packages (having the binary only)" OFF)
|
||||
else ()
|
||||
option(ENABLE_CLICKHOUSE_INSTALL "Install ClickHouse without .deb/.rpm/.tgz packages (having the binary only)"
|
||||
${ENABLE_CLICKHOUSE_ALL})
|
||||
endif ()
|
||||
option(ENABLE_CLICKHOUSE_INSTALL "Install ClickHouse without .deb/.rpm/.tgz packages (having the binary only)" ${ENABLE_CLICKHOUSE_ALL})
|
||||
|
||||
message(STATUS "ClickHouse modes:")
|
||||
|
||||
@ -211,10 +202,6 @@ macro(clickhouse_target_link_split_lib target name)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(clickhouse_program_link_split_binary name)
|
||||
clickhouse_target_link_split_lib(clickhouse-${name} ${name})
|
||||
endmacro()
|
||||
|
||||
macro(clickhouse_program_add_library name)
|
||||
string(TOUPPER ${name} name_uc)
|
||||
string(REPLACE "-" "_" name_uc ${name_uc})
|
||||
@ -239,17 +226,8 @@ macro(clickhouse_program_add_library name)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(clickhouse_program_add_executable name)
|
||||
if(CLICKHOUSE_SPLIT_BINARY)
|
||||
clickhouse_add_executable(clickhouse-${name} clickhouse-${name}.cpp)
|
||||
clickhouse_program_link_split_binary(${name})
|
||||
install(TARGETS clickhouse-${name} ${CLICKHOUSE_ALL_TARGETS} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(clickhouse_program_add name)
|
||||
clickhouse_program_add_library(${name})
|
||||
clickhouse_program_add_executable(${name})
|
||||
endmacro()
|
||||
|
||||
add_subdirectory (server)
|
||||
@ -342,210 +320,173 @@ if (CLICKHOUSE_ONE_SHARED)
|
||||
install (TARGETS clickhouse-lib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT clickhouse)
|
||||
endif()
|
||||
|
||||
if (CLICKHOUSE_SPLIT_BINARY)
|
||||
set (CLICKHOUSE_ALL_TARGETS
|
||||
clickhouse-server
|
||||
clickhouse-client
|
||||
clickhouse-local
|
||||
clickhouse-benchmark
|
||||
clickhouse-extract-from-config
|
||||
clickhouse-compressor
|
||||
clickhouse-format
|
||||
clickhouse-obfuscator
|
||||
clickhouse-git-import
|
||||
clickhouse-copier
|
||||
clickhouse-static-files-disk-uploader
|
||||
clickhouse-disks)
|
||||
clickhouse_add_executable (clickhouse main.cpp)
|
||||
|
||||
if (ENABLE_CLICKHOUSE_ODBC_BRIDGE)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-odbc-bridge)
|
||||
endif ()
|
||||
if (NOT USE_STATIC_LIBRARIES AND SPLIT_SHARED_LIBRARIES)
|
||||
# Shared split (dev) build: In CI, the server is run with custom LD_LIBRARY_PATH. This makes the harmful env check re-execute the
|
||||
# process in a clean environment but as in CI the containing directory is not included in DT_RUNPATH/DT_RPATH, the server won't come up.
|
||||
target_compile_definitions(clickhouse PRIVATE DISABLE_HARMFUL_ENV_VAR_CHECK)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_CLICKHOUSE_LIBRARY_BRIDGE)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-library-bridge)
|
||||
endif ()
|
||||
# A library that prevent usage of several functions from libc.
|
||||
if (ARCH_AMD64 AND OS_LINUX AND NOT OS_ANDROID)
|
||||
set (HARMFUL_LIB harmful)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-keeper)
|
||||
endif ()
|
||||
target_link_libraries (clickhouse PRIVATE clickhouse_common_io string_utils ${HARMFUL_LIB})
|
||||
target_include_directories (clickhouse PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if (ENABLE_CLICKHOUSE_KEEPER_CONVERTER)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-keeper-converter)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_SERVER)
|
||||
clickhouse_target_link_split_lib(clickhouse server)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_CLIENT)
|
||||
clickhouse_target_link_split_lib(clickhouse client)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_LOCAL)
|
||||
clickhouse_target_link_split_lib(clickhouse local)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_BENCHMARK)
|
||||
clickhouse_target_link_split_lib(clickhouse benchmark)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COPIER)
|
||||
clickhouse_target_link_split_lib(clickhouse copier)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_EXTRACT_FROM_CONFIG)
|
||||
clickhouse_target_link_split_lib(clickhouse extract-from-config)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COMPRESSOR)
|
||||
clickhouse_target_link_split_lib(clickhouse compressor)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_FORMAT)
|
||||
clickhouse_target_link_split_lib(clickhouse format)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_OBFUSCATOR)
|
||||
clickhouse_target_link_split_lib(clickhouse obfuscator)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_GIT_IMPORT)
|
||||
clickhouse_target_link_split_lib(clickhouse git-import)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_STATIC_FILES_DISK_UPLOADER)
|
||||
clickhouse_target_link_split_lib(clickhouse static-files-disk-uploader)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_SU)
|
||||
clickhouse_target_link_split_lib(clickhouse su)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
clickhouse_target_link_split_lib(clickhouse keeper)
|
||||
endif()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER_CONVERTER)
|
||||
clickhouse_target_link_split_lib(clickhouse keeper-converter)
|
||||
endif()
|
||||
if (ENABLE_CLICKHOUSE_INSTALL)
|
||||
clickhouse_target_link_split_lib(clickhouse install)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_DISKS)
|
||||
clickhouse_target_link_split_lib(clickhouse disks)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_CLICKHOUSE_SU)
|
||||
list (APPEND CLICKHOUSE_ALL_TARGETS clickhouse-su)
|
||||
endif ()
|
||||
set (CLICKHOUSE_BUNDLE)
|
||||
if (ENABLE_CLICKHOUSE_SELF_EXTRACTING)
|
||||
list(APPEND CLICKHOUSE_BUNDLE self-extracting)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_SERVER)
|
||||
add_custom_target (clickhouse-server ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-server DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-server" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-server)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_CLIENT)
|
||||
add_custom_target (clickhouse-client ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-client DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-client" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-client)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_LOCAL)
|
||||
add_custom_target (clickhouse-local ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-local DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-local" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-local)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_BENCHMARK)
|
||||
add_custom_target (clickhouse-benchmark ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-benchmark DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-benchmark" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-benchmark)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COPIER)
|
||||
add_custom_target (clickhouse-copier ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-copier DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-copier" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-copier)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_EXTRACT_FROM_CONFIG)
|
||||
add_custom_target (clickhouse-extract-from-config ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-extract-from-config DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-extract-from-config" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-extract-from-config)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COMPRESSOR)
|
||||
add_custom_target (clickhouse-compressor ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-compressor DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-compressor" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-compressor)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_FORMAT)
|
||||
add_custom_target (clickhouse-format ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-format DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-format" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-format)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_OBFUSCATOR)
|
||||
add_custom_target (clickhouse-obfuscator ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-obfuscator DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-obfuscator" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-obfuscator)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_GIT_IMPORT)
|
||||
add_custom_target (clickhouse-git-import ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-git-import DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-git-import" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-git-import)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_STATIC_FILES_DISK_UPLOADER)
|
||||
add_custom_target (clickhouse-static-files-disk-uploader ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-static-files-disk-uploader DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-static-files-disk-uploader" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-static-files-disk-uploader)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_SU)
|
||||
add_custom_target (clickhouse-su ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-su DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-su" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-su)
|
||||
endif ()
|
||||
|
||||
set_target_properties(${CLICKHOUSE_ALL_TARGETS} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ..)
|
||||
|
||||
add_custom_target (clickhouse-bundle ALL DEPENDS ${CLICKHOUSE_ALL_TARGETS})
|
||||
add_custom_target (clickhouse ALL DEPENDS clickhouse-bundle)
|
||||
|
||||
install(PROGRAMS clickhouse-split-helper DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME clickhouse COMPONENT clickhouse)
|
||||
else ()
|
||||
clickhouse_add_executable (clickhouse main.cpp)
|
||||
|
||||
# A library that prevent usage of several functions from libc.
|
||||
if (ARCH_AMD64 AND OS_LINUX AND NOT OS_ANDROID)
|
||||
set (HARMFUL_LIB harmful)
|
||||
endif ()
|
||||
|
||||
target_link_libraries (clickhouse PRIVATE clickhouse_common_io string_utils ${HARMFUL_LIB})
|
||||
target_include_directories (clickhouse PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if (ENABLE_CLICKHOUSE_SERVER)
|
||||
clickhouse_target_link_split_lib(clickhouse server)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_CLIENT)
|
||||
clickhouse_target_link_split_lib(clickhouse client)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_LOCAL)
|
||||
clickhouse_target_link_split_lib(clickhouse local)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_BENCHMARK)
|
||||
clickhouse_target_link_split_lib(clickhouse benchmark)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COPIER)
|
||||
clickhouse_target_link_split_lib(clickhouse copier)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_EXTRACT_FROM_CONFIG)
|
||||
clickhouse_target_link_split_lib(clickhouse extract-from-config)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COMPRESSOR)
|
||||
clickhouse_target_link_split_lib(clickhouse compressor)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_FORMAT)
|
||||
clickhouse_target_link_split_lib(clickhouse format)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_OBFUSCATOR)
|
||||
clickhouse_target_link_split_lib(clickhouse obfuscator)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_GIT_IMPORT)
|
||||
clickhouse_target_link_split_lib(clickhouse git-import)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_STATIC_FILES_DISK_UPLOADER)
|
||||
clickhouse_target_link_split_lib(clickhouse static-files-disk-uploader)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_SU)
|
||||
clickhouse_target_link_split_lib(clickhouse su)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
clickhouse_target_link_split_lib(clickhouse keeper)
|
||||
endif()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER_CONVERTER)
|
||||
clickhouse_target_link_split_lib(clickhouse keeper-converter)
|
||||
endif()
|
||||
if (ENABLE_CLICKHOUSE_INSTALL)
|
||||
clickhouse_target_link_split_lib(clickhouse install)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_DISKS)
|
||||
clickhouse_target_link_split_lib(clickhouse disks)
|
||||
endif ()
|
||||
|
||||
set (CLICKHOUSE_BUNDLE)
|
||||
if (ENABLE_CLICKHOUSE_SELF_EXTRACTING)
|
||||
list(APPEND CLICKHOUSE_BUNDLE self-extracting)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_SERVER)
|
||||
add_custom_target (clickhouse-server ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-server DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-server" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-server)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_CLIENT)
|
||||
add_custom_target (clickhouse-client ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-client DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-client" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-client)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_LOCAL)
|
||||
add_custom_target (clickhouse-local ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-local DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-local" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-local)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_BENCHMARK)
|
||||
add_custom_target (clickhouse-benchmark ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-benchmark DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-benchmark" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-benchmark)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COPIER)
|
||||
add_custom_target (clickhouse-copier ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-copier DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-copier" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-copier)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_EXTRACT_FROM_CONFIG)
|
||||
add_custom_target (clickhouse-extract-from-config ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-extract-from-config DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-extract-from-config" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-extract-from-config)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_COMPRESSOR)
|
||||
add_custom_target (clickhouse-compressor ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-compressor DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-compressor" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-compressor)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_FORMAT)
|
||||
add_custom_target (clickhouse-format ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-format DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-format" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-format)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_OBFUSCATOR)
|
||||
add_custom_target (clickhouse-obfuscator ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-obfuscator DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-obfuscator" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-obfuscator)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_GIT_IMPORT)
|
||||
add_custom_target (clickhouse-git-import ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-git-import DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-git-import" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-git-import)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_STATIC_FILES_DISK_UPLOADER)
|
||||
add_custom_target (clickhouse-static-files-disk-uploader ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-static-files-disk-uploader DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-static-files-disk-uploader" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-static-files-disk-uploader)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_SU)
|
||||
add_custom_target (clickhouse-su ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-su DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-su" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-su)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
if (NOT BUILD_STANDALONE_KEEPER AND CREATE_KEEPER_SYMLINK)
|
||||
add_custom_target (clickhouse-keeper ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-keeper DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-keeper" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
endif()
|
||||
|
||||
# otherwise we don't build keeper
|
||||
if (BUILD_STANDALONE_KEEPER OR CREATE_KEEPER_SYMLINK)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-keeper)
|
||||
endif()
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER_CONVERTER)
|
||||
add_custom_target (clickhouse-keeper-converter ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-keeper-converter DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-keeper-converter" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-keeper-converter)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_DISKS)
|
||||
add_custom_target (clickhouse-disks ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-disks DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-disks" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-disks)
|
||||
endif ()
|
||||
|
||||
add_custom_target (clickhouse-bundle ALL DEPENDS ${CLICKHOUSE_BUNDLE})
|
||||
|
||||
if (USE_GDB_ADD_INDEX)
|
||||
add_custom_command(TARGET clickhouse POST_BUILD COMMAND ${GDB_ADD_INDEX_EXE} clickhouse COMMENT "Adding .gdb-index to clickhouse" VERBATIM)
|
||||
if (ENABLE_CLICKHOUSE_KEEPER)
|
||||
if (NOT BUILD_STANDALONE_KEEPER AND CREATE_KEEPER_SYMLINK)
|
||||
add_custom_target (clickhouse-keeper ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-keeper DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-keeper" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
endif()
|
||||
|
||||
if (USE_BINARY_HASH)
|
||||
add_custom_command(TARGET clickhouse POST_BUILD COMMAND ./clickhouse hash-binary > hash && ${OBJCOPY_PATH} --add-section .clickhouse.hash=hash clickhouse COMMENT "Adding section '.clickhouse.hash' to clickhouse binary" VERBATIM)
|
||||
# otherwise we don't build keeper
|
||||
if (BUILD_STANDALONE_KEEPER OR CREATE_KEEPER_SYMLINK)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-keeper)
|
||||
endif()
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_KEEPER_CONVERTER)
|
||||
add_custom_target (clickhouse-keeper-converter ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-keeper-converter DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-keeper-converter" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-keeper-converter)
|
||||
endif ()
|
||||
if (ENABLE_CLICKHOUSE_DISKS)
|
||||
add_custom_target (clickhouse-disks ALL COMMAND ${CMAKE_COMMAND} -E create_symlink clickhouse clickhouse-disks DEPENDS clickhouse)
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/clickhouse-disks" DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
list(APPEND CLICKHOUSE_BUNDLE clickhouse-disks)
|
||||
endif ()
|
||||
|
||||
if (SPLIT_DEBUG_SYMBOLS)
|
||||
clickhouse_split_debug_symbols(TARGET clickhouse DESTINATION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SPLITTED_DEBUG_SYMBOLS_DIR} BINARY_PATH clickhouse)
|
||||
else()
|
||||
clickhouse_make_empty_debug_info_for_nfpm(TARGET clickhouse DESTINATION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SPLITTED_DEBUG_SYMBOLS_DIR})
|
||||
install (TARGETS clickhouse RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
endif()
|
||||
add_custom_target (clickhouse-bundle ALL DEPENDS ${CLICKHOUSE_BUNDLE})
|
||||
|
||||
if (USE_GDB_ADD_INDEX)
|
||||
add_custom_command(TARGET clickhouse POST_BUILD COMMAND ${GDB_ADD_INDEX_EXE} clickhouse COMMENT "Adding .gdb-index to clickhouse" VERBATIM)
|
||||
endif()
|
||||
|
||||
if (USE_BINARY_HASH)
|
||||
add_custom_command(TARGET clickhouse POST_BUILD COMMAND ./clickhouse hash-binary > hash && ${OBJCOPY_PATH} --add-section .clickhouse.hash=hash clickhouse COMMENT "Adding section '.clickhouse.hash' to clickhouse binary" VERBATIM)
|
||||
endif()
|
||||
|
||||
if (SPLIT_DEBUG_SYMBOLS)
|
||||
clickhouse_split_debug_symbols(TARGET clickhouse DESTINATION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SPLITTED_DEBUG_SYMBOLS_DIR} BINARY_PATH clickhouse)
|
||||
else()
|
||||
clickhouse_make_empty_debug_info_for_nfpm(TARGET clickhouse DESTINATION_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SPLITTED_DEBUG_SYMBOLS_DIR})
|
||||
install (TARGETS clickhouse RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT clickhouse)
|
||||
endif()
|
||||
|
||||
if (ENABLE_TESTS)
|
||||
|
@ -352,6 +352,9 @@ try
|
||||
{
|
||||
UseSSL use_ssl;
|
||||
ThreadStatus thread_status;
|
||||
|
||||
StackTrace::setShowAddresses(config().getBool("show_addresses_in_stack_traces", true));
|
||||
|
||||
setupSignalHandler();
|
||||
|
||||
std::cout << std::fixed << std::setprecision(3);
|
||||
|
@ -345,6 +345,7 @@ struct Checker
|
||||
;
|
||||
|
||||
|
||||
#ifndef DISABLE_HARMFUL_ENV_VAR_CHECK
|
||||
/// NOTE: We will migrate to full static linking or our own dynamic loader to make this code obsolete.
|
||||
void checkHarmfulEnvironmentVariables(char ** argv)
|
||||
{
|
||||
@ -396,6 +397,7 @@ void checkHarmfulEnvironmentVariables(char ** argv)
|
||||
_exit(error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -422,7 +424,9 @@ int main(int argc_, char ** argv_)
|
||||
/// will work only after additional call of this function.
|
||||
updatePHDRCache();
|
||||
|
||||
#ifndef DISABLE_HARMFUL_ENV_VAR_CHECK
|
||||
checkHarmfulEnvironmentVariables(argv_);
|
||||
#endif
|
||||
|
||||
/// Reset new handler to default (that throws std::bad_alloc)
|
||||
/// It is needed because LLVM library clobbers it.
|
||||
|
@ -627,6 +627,8 @@ int Server::main(const std::vector<std::string> & /*args*/)
|
||||
|
||||
MainThreadStatus::getInstance();
|
||||
|
||||
StackTrace::setShowAddresses(config().getBool("show_addresses_in_stack_traces", true));
|
||||
|
||||
registerFunctions();
|
||||
registerAggregateFunctions();
|
||||
registerTableFunctions();
|
||||
|
@ -1386,4 +1386,13 @@
|
||||
<lru_cache_size>268435456</lru_cache_size>
|
||||
<continue_if_corrupted>true</continue_if_corrupted>
|
||||
</merge_tree_metadata_cache-->
|
||||
|
||||
<!-- This allows to disable exposing addresses in stack traces for security reasons.
|
||||
Please be aware that it does not improve security much, but makes debugging much harder.
|
||||
The addresses that are small offsets from zero will be displayed nevertheless to show nullptr dereferences.
|
||||
Regardless of this configuration, the addresses are visible in the system.stack_trace and system.trace_log tables
|
||||
if the user has access to these tables.
|
||||
I don't recommend to change this setting.
|
||||
-->
|
||||
<show_addresses_in_stack_traces>false</show_addresses_in_stack_traces>
|
||||
</clickhouse>
|
||||
|
@ -144,8 +144,8 @@ endif ()
|
||||
list (APPEND clickhouse_common_io_sources ${CONFIG_BUILD})
|
||||
list (APPEND clickhouse_common_io_headers ${CONFIG_VERSION} ${CONFIG_COMMON})
|
||||
|
||||
list (APPEND dbms_sources Functions/IFunction.cpp Functions/FunctionFactory.cpp Functions/FunctionHelpers.cpp Functions/extractTimeZoneFromFunctionArguments.cpp Functions/replicate.cpp Functions/FunctionsLogical.cpp)
|
||||
list (APPEND dbms_headers Functions/IFunction.h Functions/FunctionFactory.h Functions/FunctionHelpers.h Functions/extractTimeZoneFromFunctionArguments.h Functions/replicate.h Functions/FunctionsLogical.h)
|
||||
list (APPEND dbms_sources Functions/IFunction.cpp Functions/FunctionFactory.cpp Functions/FunctionHelpers.cpp Functions/extractTimeZoneFromFunctionArguments.cpp Functions/FunctionsLogical.cpp)
|
||||
list (APPEND dbms_headers Functions/IFunction.h Functions/FunctionFactory.h Functions/FunctionHelpers.h Functions/extractTimeZoneFromFunctionArguments.h Functions/FunctionsLogical.h)
|
||||
|
||||
list (APPEND dbms_sources
|
||||
AggregateFunctions/IAggregateFunction.cpp
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include <Common/StackTrace.h>
|
||||
|
||||
#include <Core/Defines.h>
|
||||
#include <Common/Dwarf.h>
|
||||
#include <Common/Elf.h>
|
||||
#include <Common/SymbolIndex.h>
|
||||
@ -8,6 +7,7 @@
|
||||
#include <base/CachedFn.h>
|
||||
#include <base/demangle.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <sstream>
|
||||
@ -19,6 +19,32 @@
|
||||
# include <libunwind.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
/// Currently this variable is set up once on server startup.
|
||||
/// But we use atomic just in case, so it is possible to be modified at runtime.
|
||||
std::atomic<bool> show_addresses = true;
|
||||
|
||||
bool shouldShowAddress(const void * addr)
|
||||
{
|
||||
/// If the address is less than 4096, most likely it is a nullptr dereference with offset,
|
||||
/// and showing this offset is secure nevertheless.
|
||||
/// NOTE: 4096 is the page size on x86 and it can be different on other systems,
|
||||
/// but for the purpose of this branch, it does not matter.
|
||||
if (reinterpret_cast<uintptr_t>(addr) < 4096)
|
||||
return true;
|
||||
|
||||
return show_addresses.load(std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
void StackTrace::setShowAddresses(bool show)
|
||||
{
|
||||
show_addresses.store(show, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
|
||||
std::string signalToErrorMessage(int sig, const siginfo_t & info, [[maybe_unused]] const ucontext_t & context)
|
||||
{
|
||||
std::stringstream error; // STYLE_CHECK_ALLOW_STD_STRING_STREAM
|
||||
@ -30,7 +56,7 @@ std::string signalToErrorMessage(int sig, const siginfo_t & info, [[maybe_unused
|
||||
/// Print info about address and reason.
|
||||
if (nullptr == info.si_addr)
|
||||
error << "Address: NULL pointer.";
|
||||
else
|
||||
else if (shouldShowAddress(info.si_addr))
|
||||
error << "Address: " << info.si_addr;
|
||||
|
||||
#if defined(__x86_64__) && !defined(OS_FREEBSD) && !defined(OS_DARWIN) && !defined(__arm__) && !defined(__powerpc__)
|
||||
@ -372,7 +398,9 @@ static void toStringEveryLineImpl(
|
||||
else
|
||||
out << "?";
|
||||
|
||||
out << " @ " << physical_addr;
|
||||
if (shouldShowAddress(physical_addr))
|
||||
out << " @ " << physical_addr;
|
||||
|
||||
out << " in " << (object ? object->name : "?");
|
||||
|
||||
for (size_t j = 0; j < inline_frames.size(); ++j)
|
||||
@ -393,10 +421,13 @@ static void toStringEveryLineImpl(
|
||||
for (size_t i = offset; i < size; ++i)
|
||||
{
|
||||
const void * addr = frame_pointers[i];
|
||||
out << i << ". " << addr;
|
||||
if (shouldShowAddress(addr))
|
||||
{
|
||||
out << i << ". " << addr;
|
||||
|
||||
callback(out.str());
|
||||
out.str({});
|
||||
callback(out.str());
|
||||
out.str({});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -67,6 +67,11 @@ public:
|
||||
|
||||
void toStringEveryLine(std::function<void(const std::string &)> callback) const;
|
||||
|
||||
/// Displaying the addresses can be disabled for security reasons.
|
||||
/// If you turn off addresses, it will be more secure, but we will be unable to help you with debugging.
|
||||
/// Please note: addresses are also available in the system.stack_trace and system.trace_log tables.
|
||||
static void setShowAddresses(bool show);
|
||||
|
||||
protected:
|
||||
void tryCapture();
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#cmakedefine01 USE_DATASKETCHES
|
||||
#cmakedefine01 USE_YAML_CPP
|
||||
#cmakedefine01 CLICKHOUSE_SPLIT_BINARY
|
||||
#cmakedefine01 USE_BZIP2
|
||||
#cmakedefine01 USE_MINIZIP
|
||||
#cmakedefine01 USE_SNAPPY
|
||||
|
12
src/Common/register_objects.cpp
Normal file
12
src/Common/register_objects.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include <Common/register_objects.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
FunctionRegisterMap & FunctionRegisterMap::instance()
|
||||
{
|
||||
static FunctionRegisterMap map;
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
33
src/Common/register_objects.h
Normal file
33
src/Common/register_objects.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
class FunctionFactory;
|
||||
|
||||
using FunctionRegisterFunctionPtr = void (*)(::DB::FunctionFactory &);
|
||||
|
||||
struct FunctionRegisterMap : public std::unordered_map<std::string_view, FunctionRegisterFunctionPtr>
|
||||
{
|
||||
static FunctionRegisterMap & instance();
|
||||
};
|
||||
|
||||
struct FunctionRegister
|
||||
{
|
||||
FunctionRegister(std::string_view name, FunctionRegisterFunctionPtr func_ptr)
|
||||
{
|
||||
FunctionRegisterMap::instance().emplace(std::move(name), func_ptr);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define REGISTER_FUNCTION_IMPL(fn, func_name, register_name) \
|
||||
void func_name(::DB::FunctionFactory & factory); \
|
||||
static ::DB::FunctionRegister register_name(#fn, func_name); \
|
||||
void func_name(::DB::FunctionFactory & factory)
|
||||
|
||||
#define REGISTER_FUNCTION(fn) REGISTER_FUNCTION_IMPL(fn, registerFunction##fn, REGISTER_FUNCTION_##fn)
|
79
src/Core/Joins.cpp
Normal file
79
src/Core/Joins.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include <Core/Joins.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
const char * toString(JoinKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case JoinKind::Inner: return "INNER";
|
||||
case JoinKind::Left: return "LEFT";
|
||||
case JoinKind::Right: return "RIGHT";
|
||||
case JoinKind::Full: return "FULL";
|
||||
case JoinKind::Cross: return "CROSS";
|
||||
case JoinKind::Comma: return "COMMA";
|
||||
}
|
||||
};
|
||||
|
||||
const char * toString(JoinStrictness strictness)
|
||||
{
|
||||
switch (strictness)
|
||||
{
|
||||
case JoinStrictness::Unspecified: return "UNSPECIFIED";
|
||||
case JoinStrictness::RightAny: return "RIGHT_ANY";
|
||||
case JoinStrictness::Any: return "ANY";
|
||||
case JoinStrictness::All: return "ALL";
|
||||
case JoinStrictness::Asof: return "ASOF";
|
||||
case JoinStrictness::Semi: return "SEMI";
|
||||
case JoinStrictness::Anti: return "ANTI";
|
||||
}
|
||||
}
|
||||
|
||||
const char * toString(JoinLocality locality)
|
||||
{
|
||||
switch (locality)
|
||||
{
|
||||
case JoinLocality::Unspecified: return "UNSPECIFIED";
|
||||
case JoinLocality::Local: return "LOCAL";
|
||||
case JoinLocality::Global: return "GLOBAL";
|
||||
}
|
||||
}
|
||||
|
||||
const char * toString(ASOFJoinInequality asof_join_inequality)
|
||||
{
|
||||
switch (asof_join_inequality)
|
||||
{
|
||||
case ASOFJoinInequality::None: return "NONE";
|
||||
case ASOFJoinInequality::Less: return "LESS";
|
||||
case ASOFJoinInequality::Greater: return "GREATER";
|
||||
case ASOFJoinInequality::LessOrEquals: return "LESS_OR_EQUALS";
|
||||
case ASOFJoinInequality::GreaterOrEquals: return "GREATER_OR_EQUALS";
|
||||
}
|
||||
}
|
||||
|
||||
const char * toString(JoinAlgorithm join_algorithm)
|
||||
{
|
||||
switch (join_algorithm)
|
||||
{
|
||||
case JoinAlgorithm::DEFAULT: return "DEFAULT";
|
||||
case JoinAlgorithm::AUTO: return "AUTO";
|
||||
case JoinAlgorithm::HASH: return "HASH";
|
||||
case JoinAlgorithm::PARTIAL_MERGE: return "PARTIAL_MERGE";
|
||||
case JoinAlgorithm::PREFER_PARTIAL_MERGE: return "PREFER_PARTIAL_MERGE";
|
||||
case JoinAlgorithm::PARALLEL_HASH: return "PARALLEL_HASH";
|
||||
case JoinAlgorithm::DIRECT: return "DIRECT";
|
||||
case JoinAlgorithm::FULL_SORTING_MERGE: return "FULL_SORTING_MERGE";
|
||||
}
|
||||
}
|
||||
|
||||
const char * toString(JoinTableSide join_table_side)
|
||||
{
|
||||
switch (join_table_side)
|
||||
{
|
||||
case JoinTableSide::Left: return "LEFT";
|
||||
case JoinTableSide::Right: return "RIGHT";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
119
src/Core/Joins.h
Normal file
119
src/Core/Joins.h
Normal file
@ -0,0 +1,119 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/// Join method.
|
||||
enum class JoinKind
|
||||
{
|
||||
Inner, /// Leave only rows that was JOINed.
|
||||
Left, /// If in "right" table there is no corresponding rows, use default values instead.
|
||||
Right,
|
||||
Full,
|
||||
Cross, /// Direct product. Strictness and condition doesn't matter.
|
||||
Comma /// Same as direct product. Intended to be converted to INNER JOIN with conditions from WHERE.
|
||||
};
|
||||
|
||||
const char * toString(JoinKind kind);
|
||||
|
||||
inline constexpr bool isLeft(JoinKind kind) { return kind == JoinKind::Left; }
|
||||
inline constexpr bool isRight(JoinKind kind) { return kind == JoinKind::Right; }
|
||||
inline constexpr bool isInner(JoinKind kind) { return kind == JoinKind::Inner; }
|
||||
inline constexpr bool isFull(JoinKind kind) { return kind == JoinKind::Full; }
|
||||
inline constexpr bool isCrossOrComma(JoinKind kind) { return kind == JoinKind::Comma || kind == JoinKind::Cross; }
|
||||
inline constexpr bool isRightOrFull(JoinKind kind) { return kind == JoinKind::Right || kind == JoinKind::Full; }
|
||||
inline constexpr bool isLeftOrFull(JoinKind kind) { return kind == JoinKind::Left || kind == JoinKind::Full; }
|
||||
inline constexpr bool isInnerOrRight(JoinKind kind) { return kind == JoinKind::Inner || kind == JoinKind::Right; }
|
||||
inline constexpr bool isInnerOrLeft(JoinKind kind) { return kind == JoinKind::Inner || kind == JoinKind::Left; }
|
||||
|
||||
/// Allows more optimal JOIN for typical cases.
|
||||
enum class JoinStrictness
|
||||
{
|
||||
Unspecified,
|
||||
RightAny, /// Old ANY JOIN. If there are many suitable rows in right table, use any from them to join.
|
||||
Any, /// Semi Join with any value from filtering table. For LEFT JOIN with Any and RightAny are the same.
|
||||
All, /// If there are many suitable rows to join, use all of them and replicate rows of "left" table (usual semantic of JOIN).
|
||||
Asof, /// For the last JOIN column, pick the latest value
|
||||
Semi, /// LEFT or RIGHT. SEMI LEFT JOIN filters left table by values exists in right table. SEMI RIGHT - otherwise.
|
||||
Anti, /// LEFT or RIGHT. Same as SEMI JOIN but filter values that are NOT exists in other table.
|
||||
};
|
||||
|
||||
const char * toString(JoinStrictness strictness);
|
||||
|
||||
/// Algorithm for distributed query processing.
|
||||
enum class JoinLocality
|
||||
{
|
||||
Unspecified,
|
||||
Local, /// Perform JOIN, using only data available on same servers (co-located data).
|
||||
Global /// Collect and merge data from remote servers, and broadcast it to each server.
|
||||
};
|
||||
|
||||
const char * toString(JoinLocality locality);
|
||||
|
||||
/// ASOF JOIN inequality type
|
||||
enum class ASOFJoinInequality
|
||||
{
|
||||
None,
|
||||
Less,
|
||||
Greater,
|
||||
LessOrEquals,
|
||||
GreaterOrEquals,
|
||||
};
|
||||
|
||||
const char * toString(ASOFJoinInequality asof_join_inequality);
|
||||
|
||||
inline constexpr ASOFJoinInequality getASOFJoinInequality(std::string_view func_name)
|
||||
{
|
||||
ASOFJoinInequality inequality = ASOFJoinInequality::None;
|
||||
|
||||
if (func_name == "less")
|
||||
inequality = ASOFJoinInequality::Less;
|
||||
else if (func_name == "greater")
|
||||
inequality = ASOFJoinInequality::Greater;
|
||||
else if (func_name == "lessOrEquals")
|
||||
inequality = ASOFJoinInequality::LessOrEquals;
|
||||
else if (func_name == "greaterOrEquals")
|
||||
inequality = ASOFJoinInequality::GreaterOrEquals;
|
||||
|
||||
return inequality;
|
||||
}
|
||||
|
||||
inline constexpr ASOFJoinInequality reverseASOFJoinInequality(ASOFJoinInequality inequality)
|
||||
{
|
||||
if (inequality == ASOFJoinInequality::Less)
|
||||
return ASOFJoinInequality::Greater;
|
||||
else if (inequality == ASOFJoinInequality::Greater)
|
||||
return ASOFJoinInequality::Less;
|
||||
else if (inequality == ASOFJoinInequality::LessOrEquals)
|
||||
return ASOFJoinInequality::GreaterOrEquals;
|
||||
else if (inequality == ASOFJoinInequality::GreaterOrEquals)
|
||||
return ASOFJoinInequality::LessOrEquals;
|
||||
|
||||
return ASOFJoinInequality::None;
|
||||
}
|
||||
|
||||
enum class JoinAlgorithm
|
||||
{
|
||||
DEFAULT = 0,
|
||||
AUTO,
|
||||
HASH,
|
||||
PARTIAL_MERGE,
|
||||
PREFER_PARTIAL_MERGE,
|
||||
PARALLEL_HASH,
|
||||
DIRECT,
|
||||
FULL_SORTING_MERGE,
|
||||
};
|
||||
|
||||
const char * toString(JoinAlgorithm join_algorithm);
|
||||
|
||||
enum class JoinTableSide
|
||||
{
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
const char * toString(JoinTableSide join_table_side);
|
||||
|
||||
}
|
@ -247,7 +247,7 @@ static constexpr UInt64 operator""_GiB(unsigned long long value)
|
||||
\
|
||||
M(Bool, join_use_nulls, false, "Use NULLs for non-joined rows of outer JOINs for types that can be inside Nullable. If false, use default value of corresponding columns data type.", IMPORTANT) \
|
||||
\
|
||||
M(JoinStrictness, join_default_strictness, JoinStrictness::ALL, "Set default strictness in JOIN query. Possible values: empty string, 'ANY', 'ALL'. If empty, query without strictness will throw exception.", 0) \
|
||||
M(JoinStrictness, join_default_strictness, JoinStrictness::All, "Set default strictness in JOIN query. Possible values: empty string, 'ANY', 'ALL'. If empty, query without strictness will throw exception.", 0) \
|
||||
M(Bool, any_join_distinct_right_table_keys, false, "Enable old ANY JOIN logic with many-to-one left-to-right table keys mapping for all ANY JOINs. It leads to confusing not equal results for 't1 ANY LEFT JOIN t2' and 't2 ANY RIGHT JOIN t1'. ANY RIGHT JOIN needs one-to-many keys mapping to be consistent with LEFT one.", IMPORTANT) \
|
||||
\
|
||||
M(UInt64, preferred_block_size_bytes, 1000000, "", 0) \
|
||||
@ -344,7 +344,7 @@ static constexpr UInt64 operator""_GiB(unsigned long long value)
|
||||
M(UInt64, max_temporary_non_const_columns, 0, "", 0) \
|
||||
\
|
||||
M(UInt64, max_subquery_depth, 100, "", 0) \
|
||||
M(UInt64, max_pipeline_depth, 1000, "", 0) \
|
||||
M(UInt64, max_pipeline_depth, 10000, "", 0) \
|
||||
M(UInt64, max_ast_depth, 1000, "Maximum depth of query syntax tree. Checked after parsing.", 0) \
|
||||
M(UInt64, max_ast_elements, 50000, "Maximum size of query syntax tree in number of nodes. Checked after parsing.", 0) \
|
||||
M(UInt64, max_expanded_ast_elements, 500000, "Maximum size of query syntax tree in number of nodes after expansion of aliases and the asterisk.", 0) \
|
||||
|
@ -26,8 +26,8 @@ IMPLEMENT_SETTING_ENUM(LoadBalancing, ErrorCodes::UNKNOWN_LOAD_BALANCING,
|
||||
|
||||
IMPLEMENT_SETTING_ENUM(JoinStrictness, ErrorCodes::UNKNOWN_JOIN,
|
||||
{{"", JoinStrictness::Unspecified},
|
||||
{"ALL", JoinStrictness::ALL},
|
||||
{"ANY", JoinStrictness::ANY}})
|
||||
{"ALL", JoinStrictness::All},
|
||||
{"ANY", JoinStrictness::Any}})
|
||||
|
||||
|
||||
IMPLEMENT_SETTING_MULTI_ENUM(JoinAlgorithm, ErrorCodes::UNKNOWN_JOIN,
|
||||
|
@ -1,12 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/SettingsFields.h>
|
||||
#include <Core/Joins.h>
|
||||
#include <QueryPipeline/SizeLimits.h>
|
||||
#include <Formats/FormatSettings.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
enum class LoadBalancing
|
||||
{
|
||||
/// among replicas with a minimum number of errors selected randomly
|
||||
@ -26,28 +28,8 @@ enum class LoadBalancing
|
||||
|
||||
DECLARE_SETTING_ENUM(LoadBalancing)
|
||||
|
||||
|
||||
enum class JoinStrictness
|
||||
{
|
||||
Unspecified = 0, /// Query JOIN without strictness will throw Exception.
|
||||
ALL, /// Query JOIN without strictness -> ALL JOIN ...
|
||||
ANY, /// Query JOIN without strictness -> ANY JOIN ...
|
||||
};
|
||||
|
||||
DECLARE_SETTING_ENUM(JoinStrictness)
|
||||
|
||||
enum class JoinAlgorithm
|
||||
{
|
||||
DEFAULT = 0,
|
||||
AUTO,
|
||||
HASH,
|
||||
PARTIAL_MERGE,
|
||||
PREFER_PARTIAL_MERGE,
|
||||
PARALLEL_HASH,
|
||||
DIRECT,
|
||||
FULL_SORTING_MERGE,
|
||||
};
|
||||
|
||||
DECLARE_SETTING_MULTI_ENUM(JoinAlgorithm)
|
||||
|
||||
|
||||
@ -200,4 +182,5 @@ DECLARE_SETTING_ENUM_WITH_RENAME(EnumComparingMode, FormatSettings::EnumComparin
|
||||
DECLARE_SETTING_ENUM_WITH_RENAME(EscapingRule, FormatSettings::EscapingRule)
|
||||
|
||||
DECLARE_SETTING_ENUM_WITH_RENAME(MsgPackUUIDRepresentation, FormatSettings::MsgPackUUIDRepresentation)
|
||||
|
||||
}
|
||||
|
@ -529,7 +529,12 @@ namespace JSONUtils
|
||||
writeObjectStart(out, 2);
|
||||
|
||||
writeTitle<true>("name", out, 3);
|
||||
writeDoubleQuoted(fields[i].name, out);
|
||||
|
||||
/// The field names are pre-escaped to be put into JSON string literal.
|
||||
writeChar('"', out);
|
||||
writeString(fields[i].name, out);
|
||||
writeChar('"', out);
|
||||
|
||||
writeFieldDelimiter(out);
|
||||
writeTitle<true>("type", out, 3);
|
||||
writeJSONString(fields[i].type->getName(), out, settings);
|
||||
|
@ -6,13 +6,14 @@ add_subdirectory(divide)
|
||||
include("${ClickHouse_SOURCE_DIR}/cmake/dbms_glob_sources.cmake")
|
||||
add_headers_and_sources(clickhouse_functions .)
|
||||
|
||||
list(REMOVE_ITEM clickhouse_functions_sources IFunction.cpp FunctionFactory.cpp FunctionHelpers.cpp)
|
||||
list(REMOVE_ITEM clickhouse_functions_headers IFunction.h FunctionFactory.h FunctionHelpers.h)
|
||||
list(REMOVE_ITEM clickhouse_functions_sources IFunction.cpp FunctionFactory.cpp FunctionHelpers.cpp extractTimeZoneFromFunctionArguments.cpp FunctionsLogical.cpp)
|
||||
list(REMOVE_ITEM clickhouse_functions_headers IFunction.h FunctionFactory.h FunctionHelpers.h extractTimeZoneFromFunctionArguments.h FunctionsLogical.h)
|
||||
|
||||
add_library(clickhouse_functions ${clickhouse_functions_sources})
|
||||
add_library(clickhouse_functions_obj OBJECT ${clickhouse_functions_sources})
|
||||
|
||||
target_link_libraries(clickhouse_functions
|
||||
PUBLIC
|
||||
list (APPEND OBJECT_LIBS $<TARGET_OBJECTS:clickhouse_functions_obj>)
|
||||
|
||||
list (APPEND PUBLIC_LIBS
|
||||
ch_contrib::wyhash
|
||||
ch_contrib::cityhash
|
||||
ch_contrib::farmhash
|
||||
@ -24,27 +25,28 @@ target_link_libraries(clickhouse_functions
|
||||
ch_contrib::metrohash
|
||||
ch_contrib::murmurhash
|
||||
ch_contrib::hashidsxx
|
||||
)
|
||||
|
||||
PRIVATE
|
||||
list (APPEND PRIVATE_LIBS
|
||||
ch_contrib::zlib
|
||||
boost::filesystem
|
||||
divide_impl
|
||||
)
|
||||
|
||||
if (TARGET OpenSSL::Crypto)
|
||||
target_link_libraries(clickhouse_functions PUBLIC OpenSSL::Crypto)
|
||||
list (APPEND PUBLIC_LIBS OpenSSL::Crypto)
|
||||
endif()
|
||||
|
||||
if (OMIT_HEAVY_DEBUG_SYMBOLS)
|
||||
target_compile_options(clickhouse_functions PRIVATE "-g0")
|
||||
target_compile_options(clickhouse_functions_obj PRIVATE "-g0")
|
||||
endif()
|
||||
|
||||
if (TARGET ch_contrib::icu)
|
||||
target_link_libraries (clickhouse_functions PRIVATE ch_contrib::icu)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::icu)
|
||||
endif ()
|
||||
|
||||
if (TARGET ch_contrib::fastops)
|
||||
target_link_libraries (clickhouse_functions PRIVATE ch_contrib::fastops)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::fastops)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_EXAMPLES)
|
||||
@ -52,45 +54,46 @@ if (ENABLE_EXAMPLES)
|
||||
endif ()
|
||||
|
||||
if (TARGET ch_contrib::llvm)
|
||||
target_link_libraries(clickhouse_functions PRIVATE ch_contrib::llvm)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::llvm)
|
||||
endif ()
|
||||
|
||||
if (TARGET ch_contrib::base64)
|
||||
target_link_libraries(clickhouse_functions PRIVATE ch_contrib::base64)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::base64)
|
||||
endif()
|
||||
|
||||
target_link_libraries(clickhouse_functions PRIVATE ch_contrib::lz4)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::lz4)
|
||||
|
||||
if (ENABLE_NLP)
|
||||
target_link_libraries(clickhouse_functions PRIVATE ch_contrib::cld2)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::cld2)
|
||||
endif()
|
||||
|
||||
if (TARGET ch_contrib::h3)
|
||||
target_link_libraries (clickhouse_functions PRIVATE ch_contrib::h3)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::h3)
|
||||
endif()
|
||||
|
||||
if (TARGET ch_contrib::vectorscan)
|
||||
target_link_libraries(clickhouse_functions PRIVATE ch_contrib::vectorscan)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::vectorscan)
|
||||
endif()
|
||||
|
||||
if (TARGET ch_contrib::simdjson)
|
||||
target_link_libraries(clickhouse_functions PRIVATE ch_contrib::simdjson)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::simdjson)
|
||||
endif()
|
||||
|
||||
if (TARGET ch_contrib::rapidjson)
|
||||
target_link_libraries(clickhouse_functions PRIVATE ch_contrib::rapidjson)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::rapidjson)
|
||||
endif()
|
||||
|
||||
add_subdirectory(GatherUtils)
|
||||
target_link_libraries(clickhouse_functions PRIVATE clickhouse_functions_gatherutils)
|
||||
list (APPEND PRIVATE_LIBS clickhouse_functions_gatherutils)
|
||||
|
||||
add_subdirectory(URL)
|
||||
target_link_libraries(clickhouse_functions PRIVATE clickhouse_functions_url)
|
||||
list (APPEND OBJECT_LIBS $<TARGET_OBJECTS:clickhouse_functions_url>)
|
||||
|
||||
add_subdirectory(array)
|
||||
target_link_libraries(clickhouse_functions PRIVATE clickhouse_functions_array)
|
||||
list (APPEND OBJECT_LIBS $<TARGET_OBJECTS:clickhouse_functions_array>)
|
||||
|
||||
add_subdirectory(JSONPath)
|
||||
list (APPEND PRIVATE_LIBS clickhouse_functions_jsonpath)
|
||||
|
||||
# Signed integer overflow on user-provided data inside boost::geometry - ignore.
|
||||
set_source_files_properties("pointInPolygon.cpp" PROPERTIES COMPILE_FLAGS -fno-sanitize=signed-integer-overflow)
|
||||
@ -98,3 +101,15 @@ set_source_files_properties("pointInPolygon.cpp" PROPERTIES COMPILE_FLAGS -fno-s
|
||||
if (ENABLE_FUZZING)
|
||||
add_compile_definitions(FUZZING_MODE=1)
|
||||
endif ()
|
||||
|
||||
target_link_libraries(clickhouse_functions_obj PUBLIC ${PUBLIC_LIBS} PRIVATE ${PRIVATE_LIBS})
|
||||
|
||||
if (USE_STATIC_LIBRARIES OR NOT SPLIT_SHARED_LIBRARIES)
|
||||
# Used to forward the linking information to the final binaries such as clickhouse / unit_tests_dbms,
|
||||
# since such information are lost after we convert to OBJECT target
|
||||
add_library(clickhouse_functions INTERFACE)
|
||||
target_link_libraries(clickhouse_functions INTERFACE ${OBJECT_LIBS} ${PUBLIC_LIBS} ${PRIVATE_LIBS})
|
||||
else()
|
||||
add_library(clickhouse_functions SHARED ${OBJECT_LIBS})
|
||||
target_link_libraries(clickhouse_functions PUBLIC ${PUBLIC_LIBS} PRIVATE ${PRIVATE_LIBS})
|
||||
endif ()
|
||||
|
@ -143,7 +143,7 @@ void registerFunctionCRCImpl(FunctionFactory & factory)
|
||||
factory.registerFunction<T>(T::name, FunctionFactory::CaseInsensitive);
|
||||
}
|
||||
|
||||
void registerFunctionCRC(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CRC)
|
||||
{
|
||||
registerFunctionCRCImpl<FunctionCRC32ZLIB>(factory);
|
||||
registerFunctionCRCImpl<FunctionCRC32IEEE>(factory);
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerCastOverloadResolvers(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CastOverloadResolvers)
|
||||
{
|
||||
factory.registerFunction<CastInternalOverloadResolver<CastType::nonAccurate>>(FunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction<CastInternalOverloadResolver<CastType::accurate>>();
|
||||
|
@ -113,7 +113,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
void registerFunctionChar(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Char)
|
||||
{
|
||||
factory.registerFunction<FunctionChar>(FunctionFactory::CaseInsensitive);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
void registerFunctionFQDN(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(FQDN)
|
||||
{
|
||||
factory.registerFunction<FunctionFQDN>(FunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction<FunctionFQDN>("fullHostName");
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Interpreters/Context_fwd.h>
|
||||
#include <Common/register_objects.h>
|
||||
#include <Common/IFactoryWithAliases.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Functions/IFunctionAdaptors.h>
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnConst.h>
|
||||
#include <Columns/IColumn.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <DataTypes/DataTypeString.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <IO/ReadBufferFromFile.h>
|
||||
#include <IO/WriteBufferFromVector.h>
|
||||
#include <IO/copyData.h>
|
||||
@ -19,6 +22,7 @@ namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
extern const int NOT_IMPLEMENTED;
|
||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||
extern const int DATABASE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@ -30,21 +34,41 @@ public:
|
||||
static FunctionPtr create(ContextPtr context_) { return std::make_shared<FunctionFile>(context_); }
|
||||
explicit FunctionFile(ContextPtr context_) : WithContext(context_) {}
|
||||
|
||||
bool isVariadic() const override { return true; }
|
||||
String getName() const override { return name; }
|
||||
size_t getNumberOfArguments() const override { return 1; }
|
||||
size_t getNumberOfArguments() const override { return 0; }
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
if (arguments.empty() || arguments.size() > 2)
|
||||
throw Exception(
|
||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
|
||||
"Number of arguments for function {} doesn't match: passed {}, should be 1 or 2",
|
||||
getName(), toString(arguments.size()));
|
||||
|
||||
if (!isString(arguments[0].type))
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "{} is only implemented for type String", getName());
|
||||
|
||||
if (arguments.size() == 2)
|
||||
{
|
||||
if (arguments[1].type->onlyNull())
|
||||
return makeNullable(std::make_shared<DataTypeString>());
|
||||
|
||||
if (!isString(arguments[1].type))
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "{} only accepts String or Null as second argument", getName());
|
||||
}
|
||||
|
||||
return std::make_shared<DataTypeString>();
|
||||
}
|
||||
|
||||
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
|
||||
|
||||
bool useDefaultImplementationForNulls() const override { return false; }
|
||||
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
|
||||
{
|
||||
const ColumnPtr column = arguments[0].column;
|
||||
const ColumnString * column_src = checkAndGetColumn<ColumnString>(column.get());
|
||||
@ -53,6 +77,31 @@ public:
|
||||
fmt::format("Illegal column {} of argument of function {}", arguments[0].column->getName(), getName()),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
|
||||
String default_result;
|
||||
|
||||
ColumnUInt8::MutablePtr col_null_map_to;
|
||||
ColumnUInt8::Container * vec_null_map_to [[maybe_unused]] = nullptr;
|
||||
|
||||
if (arguments.size() == 2)
|
||||
{
|
||||
if (result_type->isNullable())
|
||||
{
|
||||
col_null_map_to = ColumnUInt8::create(input_rows_count, false);
|
||||
vec_null_map_to = &col_null_map_to->getData();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto & default_column = arguments[1].column;
|
||||
const ColumnConst * default_col = checkAndGetColumn<ColumnConst>(default_column.get());
|
||||
|
||||
if (!default_col)
|
||||
throw Exception(
|
||||
"Illegal column " + arguments[1].column->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN);
|
||||
|
||||
default_result = default_col->getValue<String>();
|
||||
}
|
||||
}
|
||||
|
||||
auto result = ColumnString::create();
|
||||
auto & res_chars = result->getChars();
|
||||
auto & res_offsets = result->getOffsets();
|
||||
@ -77,24 +126,40 @@ public:
|
||||
/// Otherwise it will not allow to work with symlinks in `user_files_path` directory.
|
||||
file_path = fs::absolute(file_path).lexically_normal();
|
||||
|
||||
if (need_check && file_path.string().find(user_files_absolute_path_string) != 0)
|
||||
throw Exception(ErrorCodes::DATABASE_ACCESS_DENIED, "File is not inside {}", user_files_absolute_path.string());
|
||||
try
|
||||
{
|
||||
if (need_check && file_path.string().find(user_files_absolute_path_string) != 0)
|
||||
throw Exception(ErrorCodes::DATABASE_ACCESS_DENIED, "File is not inside {}", user_files_absolute_path.string());
|
||||
|
||||
ReadBufferFromFile in(file_path);
|
||||
WriteBufferFromVector out(res_chars, AppendModeTag{});
|
||||
copyData(in, out);
|
||||
out.finalize();
|
||||
ReadBufferFromFile in(file_path);
|
||||
WriteBufferFromVector out(res_chars, AppendModeTag{});
|
||||
copyData(in, out);
|
||||
out.finalize();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (arguments.size() == 1)
|
||||
throw;
|
||||
|
||||
if (vec_null_map_to)
|
||||
(*vec_null_map_to)[row] = true;
|
||||
else
|
||||
res_chars.insert(default_result.data(), default_result.data() + default_result.size());
|
||||
}
|
||||
|
||||
res_chars.push_back(0);
|
||||
res_offsets[row] = res_chars.size();
|
||||
}
|
||||
|
||||
if (vec_null_map_to)
|
||||
return ColumnNullable::create(std::move(result), std::move(col_null_map_to));
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void registerFunctionFile(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(File)
|
||||
{
|
||||
factory.registerFunction<FunctionFile>();
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionHashID(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(HashID)
|
||||
{
|
||||
factory.registerFunction<FunctionHashID>();
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ FunctionBasePtr JoinGetOverloadResolver<or_null>::buildImpl(const ColumnsWithTyp
|
||||
return std::make_unique<FunctionJoinGet<or_null>>(getContext(), table_lock, storage_join, attr_name, argument_types, return_type);
|
||||
}
|
||||
|
||||
void registerFunctionJoinGet(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(JoinGet)
|
||||
{
|
||||
// joinGet
|
||||
factory.registerFunction<JoinGetOverloadResolver<false>>();
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionsSQLJSON(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(SQLJSON)
|
||||
{
|
||||
factory.registerFunction<FunctionSQLJSON<NameJSONExists, JSONExistsImpl>>();
|
||||
factory.registerFunction<FunctionSQLJSON<NameJSONQuery, JSONQueryImpl>>();
|
||||
|
@ -4,7 +4,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionShowCertificate(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(ShowCertificate)
|
||||
{
|
||||
factory.registerFunction<FunctionShowCertificate>();
|
||||
}
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
namespace DB
|
||||
{
|
||||
void registerFunctionBase58Encode(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Base58Encode)
|
||||
{
|
||||
factory.registerFunction<FunctionBase58Conversion<Base58Encode>>();
|
||||
}
|
||||
|
||||
void registerFunctionBase58Decode(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Base58Decode)
|
||||
{
|
||||
factory.registerFunction<FunctionBase58Conversion<Base58Decode>>();
|
||||
}
|
||||
|
@ -621,7 +621,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void registerFunctionsBinaryRepr(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(BinaryRepr)
|
||||
{
|
||||
factory.registerFunction<EncodeToBinaryRepresentation<HexImpl>>(FunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction<DecodeFromBinaryRepresentation<UnhexImpl>>(FunctionFactory::CaseInsensitive);
|
||||
|
@ -329,7 +329,7 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionsBitToArray(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(BitToArray)
|
||||
{
|
||||
factory.registerFunction<FunctionBitPositionsToArray>();
|
||||
factory.registerFunction<FunctionBitmaskToArray>();
|
||||
|
@ -7,7 +7,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionsBitmap(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Bitmap)
|
||||
{
|
||||
factory.registerFunction<FunctionBitmapBuild>();
|
||||
factory.registerFunction<FunctionBitmapToArray>();
|
||||
|
@ -143,7 +143,7 @@ struct NameDetectLanguageUnknown
|
||||
using FunctionDetectCharset = FunctionTextClassificationString<CharsetClassificationImpl<false>, NameDetectCharset>;
|
||||
using FunctionDetectLanguageUnknown = FunctionTextClassificationString<CharsetClassificationImpl<true>, NameDetectLanguageUnknown>;
|
||||
|
||||
void registerFunctionDetectCharset(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(DetectCharset)
|
||||
{
|
||||
factory.registerFunction<FunctionDetectCharset>();
|
||||
factory.registerFunction<FunctionDetectLanguageUnknown>();
|
||||
|
@ -1128,7 +1128,7 @@ public:
|
||||
struct NameFunctionIPv4NumToString { static constexpr auto name = "IPv4NumToString"; };
|
||||
struct NameFunctionIPv4NumToStringClassC { static constexpr auto name = "IPv4NumToStringClassC"; };
|
||||
|
||||
void registerFunctionsCoding(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Coding)
|
||||
{
|
||||
factory.registerFunction<FunctionCutIPv6>();
|
||||
factory.registerFunction<FunctionIPv4ToIPv6>();
|
||||
|
@ -229,7 +229,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void registerFunctionsCodingUUID(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CodingUUID)
|
||||
{
|
||||
factory.registerFunction<FunctionUUIDNumToString>();
|
||||
factory.registerFunction<FunctionUUIDStringToNum>();
|
||||
|
@ -5,11 +5,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionFixedString(FunctionFactory & factory);
|
||||
|
||||
void registerCastOverloadResolvers(FunctionFactory & factory);
|
||||
|
||||
void registerFunctionsConversion(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Conversion)
|
||||
{
|
||||
factory.registerFunction<FunctionToUInt8>();
|
||||
factory.registerFunction<FunctionToUInt16>();
|
||||
@ -41,12 +37,8 @@ void registerFunctionsConversion(FunctionFactory & factory)
|
||||
factory.registerFunction<FunctionToUUID>();
|
||||
factory.registerFunction<FunctionToString>();
|
||||
|
||||
registerFunctionFixedString(factory);
|
||||
|
||||
factory.registerFunction<FunctionToUnixTimestamp>();
|
||||
|
||||
registerCastOverloadResolvers(factory);
|
||||
|
||||
factory.registerFunction<FunctionToUInt8OrZero>();
|
||||
factory.registerFunction<FunctionToUInt16OrZero>();
|
||||
factory.registerFunction<FunctionToUInt32OrZero>();
|
||||
|
@ -191,27 +191,29 @@ struct ConvertImpl
|
||||
vec_null_map_to = &col_null_map_to->getData();
|
||||
}
|
||||
|
||||
bool result_is_bool = isBool(result_type);
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
if constexpr (std::is_same_v<ToDataType, DataTypeUInt8>)
|
||||
{
|
||||
if constexpr (std::is_same_v<ToDataType, DataTypeUInt8>)
|
||||
if (isBool(result_type))
|
||||
{
|
||||
if (result_is_bool)
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
vec_to[i] = vec_from[i] != FromFieldType(0);
|
||||
continue;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<FromDataType, DataTypeUUID> != std::is_same_v<ToDataType, DataTypeUUID>)
|
||||
if constexpr (std::is_same_v<FromDataType, DataTypeUUID> != std::is_same_v<ToDataType, DataTypeUUID>)
|
||||
{
|
||||
throw Exception("Conversion between numeric types and UUID is not supported. Probably the passed UUID is unquoted", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (IsDataTypeDecimal<FromDataType> || IsDataTypeDecimal<ToDataType>)
|
||||
{
|
||||
throw Exception("Conversion between numeric types and UUID is not supported. Probably the passed UUID is unquoted", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (IsDataTypeDecimal<FromDataType> || IsDataTypeDecimal<ToDataType>)
|
||||
if constexpr (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>)
|
||||
{
|
||||
if constexpr (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>)
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
ToFieldType result;
|
||||
bool convert_result = false;
|
||||
@ -231,7 +233,10 @@ struct ConvertImpl
|
||||
(*vec_null_map_to)[i] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
if constexpr (IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>)
|
||||
vec_to[i] = convertDecimals<FromDataType, ToDataType>(vec_from[i], col_from->getScale(), col_to->getScale());
|
||||
@ -243,10 +248,13 @@ struct ConvertImpl
|
||||
throw Exception("Unsupported data type in conversion function", ErrorCodes::CANNOT_CONVERT_TYPE);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
/// If From Data is Nan or Inf and we convert to integer type, throw exception
|
||||
if constexpr (std::is_floating_point_v<FromFieldType> && !std::is_floating_point_v<ToFieldType>)
|
||||
{
|
||||
/// If From Data is Nan or Inf and we convert to integer type, throw exception
|
||||
if constexpr (std::is_floating_point_v<FromFieldType> && !std::is_floating_point_v<ToFieldType>)
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
if (!isFinite(vec_from[i]))
|
||||
{
|
||||
@ -254,15 +262,46 @@ struct ConvertImpl
|
||||
{
|
||||
vec_to[i] = 0;
|
||||
(*vec_null_map_to)[i] = true;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
throw Exception("Unexpected inf or nan to integer conversion", ErrorCodes::CANNOT_CONVERT_TYPE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>
|
||||
|| std::is_same_v<Additions, AccurateConvertStrategyAdditions>)
|
||||
{
|
||||
bool convert_result = accurate::convertNumeric(vec_from[i], vec_to[i]);
|
||||
|
||||
if constexpr (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>
|
||||
|| std::is_same_v<Additions, AccurateConvertStrategyAdditions>)
|
||||
if (!convert_result)
|
||||
{
|
||||
if (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>)
|
||||
{
|
||||
vec_to[i] = 0;
|
||||
(*vec_null_map_to)[i] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(
|
||||
"Value in column " + named_from.column->getName() + " cannot be safely converted into type "
|
||||
+ result_type->getName(),
|
||||
ErrorCodes::CANNOT_CONVERT_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vec_to[i] = static_cast<ToFieldType>(vec_from[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>
|
||||
|| std::is_same_v<Additions, AccurateConvertStrategyAdditions>)
|
||||
{
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
bool convert_result = accurate::convertNumeric(vec_from[i], vec_to[i]);
|
||||
|
||||
@ -282,14 +321,38 @@ struct ConvertImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (std::is_same_v<FromDataType, DataTypeUInt64> && std::is_same_v<ToDataType, DataTypeFloat32>)
|
||||
{
|
||||
/// Turns out that when ClickHouse is compiled with AVX1 or AVX2 instructions, Clang's autovectorizer produces
|
||||
/// code for UInt64-to-Float23 conversion which is only ~50% as fast as scalar code. Interestingly, scalar code
|
||||
/// is equally fast than code compiled for SSE4.2, so we might as well disable vectorization. This situation
|
||||
/// may change with AVX512 which has a dediated instruction for that usecase (_mm512_cvtepi64_ps).
|
||||
#if defined(__x86_64__)
|
||||
# ifdef __clang__
|
||||
# pragma clang loop vectorize(disable) interleave(disable)
|
||||
# endif
|
||||
#endif
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
vec_to[i] = static_cast<ToFieldType>(vec_from[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vec_to[i] = static_cast<ToFieldType>(vec_from[i]);
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
vec_to[i] = static_cast<ToFieldType>(vec_from[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if constexpr (std::is_same_v<Additions, AccurateOrNullConvertStrategyAdditions>)
|
||||
return ColumnNullable::create(std::move(col_to), std::move(col_null_map_to));
|
||||
else
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionsEmbeddedDictionaries(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(EmbeddedDictionaries)
|
||||
{
|
||||
factory.registerFunction<FunctionRegionToCity>();
|
||||
factory.registerFunction<FunctionRegionToArea>();
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionsExternalDictionaries(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(ExternalDictionaries)
|
||||
{
|
||||
factory.registerFunction<FunctionDictHas>();
|
||||
factory.registerFunction<FunctionDictGetUInt8>();
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionsHashing(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Hashing)
|
||||
{
|
||||
#if USE_SSL
|
||||
factory.registerFunction<FunctionMD4>();
|
||||
|
@ -1443,7 +1443,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void registerFunctionsJSON(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(JSON)
|
||||
{
|
||||
factory.registerFunction<JSONOverloadResolver<NameJSONHas, JSONHasImpl>>();
|
||||
factory.registerFunction<JSONOverloadResolver<NameIsValidJSON, IsValidJSONImpl>>();
|
||||
|
@ -221,7 +221,7 @@ struct NameDetectLanguage
|
||||
|
||||
using FunctionDetectLanguage = FunctionTextClassificationString<FunctionDetectLanguageImpl, NameDetectLanguage>;
|
||||
|
||||
void registerFunctionsDetectLanguage(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(DetectLanguage)
|
||||
{
|
||||
factory.registerFunction<FunctionDetectLanguage>();
|
||||
factory.registerFunction<FunctionDetectLanguageMixed>();
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionsLogical(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Logical)
|
||||
{
|
||||
factory.registerFunction<FunctionAnd>();
|
||||
factory.registerFunction<FunctionOr>();
|
||||
|
@ -112,7 +112,7 @@ struct NameDetectProgrammingLanguage
|
||||
|
||||
using FunctionDetectProgrammingLanguage = FunctionTextClassificationString<FunctionDetectProgrammingLanguageImpl, NameDetectProgrammingLanguage>;
|
||||
|
||||
void registerFunctionDetectProgrammingLanguage(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(DetectProgrammingLanguage)
|
||||
{
|
||||
factory.registerFunction<FunctionDetectProgrammingLanguage>();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void registerFunctionsRound(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Round)
|
||||
{
|
||||
factory.registerFunction<FunctionRound>("round", FunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction<FunctionRoundBankers>("roundBankers", FunctionFactory::CaseSensitive);
|
||||
|
@ -27,7 +27,7 @@ DataTypePtr FunctionArrayStringConcat::getReturnTypeImpl(const DataTypes & argum
|
||||
return std::make_shared<DataTypeString>();
|
||||
}
|
||||
|
||||
void registerFunctionsStringArray(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(StringArray)
|
||||
{
|
||||
factory.registerFunction<FunctionExtractAll>();
|
||||
factory.registerFunction<FunctionAlphaTokens>();
|
||||
|
@ -743,7 +743,7 @@ using FunctionWordShingleMinHashArgUTF8
|
||||
using FunctionWordShingleMinHashArgCaseInsensitiveUTF8
|
||||
= FunctionsStringHash<MinHashImpl<true, false, true>, NameWordShingleMinHashArgCaseInsensitiveUTF8, false, true>;
|
||||
|
||||
void registerFunctionsStringHash(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(StringHash)
|
||||
{
|
||||
factory.registerFunction<FunctionNgramSimHash>();
|
||||
factory.registerFunction<FunctionNgramSimHashCaseInsensitive>();
|
||||
|
@ -530,7 +530,7 @@ using FunctionNgramSearchUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, U
|
||||
using FunctionNgramSearchCaseInsensitiveUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, UInt32, true, true, false>, NameNgramSearchUTF8CaseInsensitive>;
|
||||
|
||||
|
||||
void registerFunctionsStringSimilarity(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(StringSimilarity)
|
||||
{
|
||||
factory.registerFunction<FunctionNgramDistance>();
|
||||
factory.registerFunction<FunctionNgramDistanceCaseInsensitive>();
|
||||
|
@ -684,7 +684,7 @@ ColumnPtr FunctionTimeWindow<type>::executeImpl(const ColumnsWithTypeAndName & a
|
||||
return TimeWindowImpl<type>::dispatchForColumns(arguments, name);
|
||||
}
|
||||
|
||||
void registerFunctionsTimeWindow(FunctionFactory& factory)
|
||||
REGISTER_FUNCTION(TimeWindow)
|
||||
{
|
||||
factory.registerFunction<FunctionTumble>();
|
||||
factory.registerFunction<FunctionHop>();
|
||||
|
@ -81,7 +81,7 @@ struct NameDetectTonality
|
||||
|
||||
using FunctionDetectTonality = FunctionTextClassificationFloat<FunctionDetectTonalityImpl, NameDetectTonality>;
|
||||
|
||||
void registerFunctionDetectTonality(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(DetectTonality)
|
||||
{
|
||||
factory.registerFunction<FunctionDetectTonality>();
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionsTransactionCounters(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(TransactionCounters)
|
||||
{
|
||||
factory.registerFunction<FunctionTransactionID>();
|
||||
factory.registerFunction<FunctionTransactionLatestSnapshot>();
|
||||
|
@ -6,7 +6,6 @@ add_library(clickhouse_functions_jsonpath ${clickhouse_functions_jsonpath_source
|
||||
|
||||
target_link_libraries(clickhouse_functions_jsonpath PRIVATE dbms)
|
||||
target_link_libraries(clickhouse_functions_jsonpath PRIVATE clickhouse_parsers)
|
||||
target_link_libraries(clickhouse_functions PRIVATE clickhouse_functions_jsonpath)
|
||||
|
||||
if (OMIT_HEAVY_DEBUG_SYMBOLS)
|
||||
target_compile_options(clickhouse_functions_jsonpath PRIVATE "-g0")
|
||||
|
@ -6,19 +6,19 @@ namespace DB
|
||||
{
|
||||
|
||||
using FunctionSubtractNanoseconds = FunctionDateOrDateTimeAddInterval<SubtractNanosecondsImpl>;
|
||||
void registerFunctionSubtractNanoseconds(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(SubtractNanoseconds)
|
||||
{
|
||||
factory.registerFunction<FunctionSubtractNanoseconds>();
|
||||
}
|
||||
|
||||
using FunctionSubtractMicroseconds = FunctionDateOrDateTimeAddInterval<SubtractMicrosecondsImpl>;
|
||||
void registerFunctionSubtractMicroseconds(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(SubtractMicroseconds)
|
||||
{
|
||||
factory.registerFunction<FunctionSubtractMicroseconds>();
|
||||
}
|
||||
|
||||
using FunctionSubtractMilliseconds = FunctionDateOrDateTimeAddInterval<SubtractMillisecondsImpl>;
|
||||
void registerFunctionSubtractMilliseconds(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(SubtractMilliseconds)
|
||||
{
|
||||
factory.registerFunction<FunctionSubtractMilliseconds>();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
include("${ClickHouse_SOURCE_DIR}/cmake/dbms_glob_sources.cmake")
|
||||
add_headers_and_sources(clickhouse_functions_url .)
|
||||
add_library(clickhouse_functions_url ${clickhouse_functions_url_sources} ${clickhouse_functions_url_headers})
|
||||
add_library(clickhouse_functions_url OBJECT ${clickhouse_functions_url_sources} ${clickhouse_functions_url_headers})
|
||||
target_link_libraries(clickhouse_functions_url PRIVATE dbms)
|
||||
|
||||
if (OMIT_HEAVY_DEBUG_SYMBOLS)
|
||||
@ -10,6 +10,7 @@ endif()
|
||||
# TODO: move Functions/Regexps.h to some lib and use here
|
||||
if (TARGET ch_contrib::vectorscan)
|
||||
target_link_libraries(clickhouse_functions_url PRIVATE ch_contrib::vectorscan)
|
||||
list (APPEND PRIVATE_LIBS ch_contrib::vectorscan PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if (USE_GPERF)
|
||||
|
@ -104,7 +104,7 @@ public:
|
||||
struct NameURLPathHierarchy { static constexpr auto name = "URLPathHierarchy"; };
|
||||
using FunctionURLPathHierarchy = FunctionTokens<URLPathHierarchyImpl>;
|
||||
|
||||
void registerFunctionURLPathHierarchy(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(URLPathHierarchy)
|
||||
{
|
||||
factory.registerFunction<FunctionURLPathHierarchy>();
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
struct NameURLHierarchy { static constexpr auto name = "URLHierarchy"; };
|
||||
using FunctionURLHierarchy = FunctionTokens<URLHierarchyImpl>;
|
||||
|
||||
void registerFunctionURLHierarchy(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(URLHierarchy)
|
||||
{
|
||||
factory.registerFunction<FunctionURLHierarchy>();
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ struct ExtractBasename
|
||||
struct NameBasename { static constexpr auto name = "basename"; };
|
||||
using FunctionBasename = FunctionStringToString<ExtractSubstringImpl<ExtractBasename>, NameBasename>;
|
||||
|
||||
void registerFunctionBasename(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Basename)
|
||||
{
|
||||
factory.registerFunction<FunctionBasename>();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
struct NameCutFragment { static constexpr auto name = "cutFragment"; };
|
||||
using FunctionCutFragment = FunctionStringToString<CutSubstringImpl<ExtractFragment<false>>, NameCutFragment>;
|
||||
|
||||
void registerFunctionCutFragment(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CutFragment)
|
||||
{
|
||||
factory.registerFunction<FunctionCutFragment>();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
struct NameCutQueryString { static constexpr auto name = "cutQueryString"; };
|
||||
using FunctionCutQueryString = FunctionStringToString<CutSubstringImpl<ExtractQueryString<false>>, NameCutQueryString>;
|
||||
|
||||
void registerFunctionCutQueryString(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CutQueryString)
|
||||
{
|
||||
factory.registerFunction<FunctionCutQueryString>();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
struct NameCutQueryStringAndFragment { static constexpr auto name = "cutQueryStringAndFragment"; };
|
||||
using FunctionCutQueryStringAndFragment = FunctionStringToString<CutSubstringImpl<ExtractQueryStringAndFragment<false>>, NameCutQueryStringAndFragment>;
|
||||
|
||||
void registerFunctionCutQueryStringAndFragment(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CutQueryStringAndFragment)
|
||||
{
|
||||
factory.registerFunction<FunctionCutQueryStringAndFragment>();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ using FunctionCutToFirstSignificantSubdomain = FunctionStringToString<ExtractSub
|
||||
struct NameCutToFirstSignificantSubdomainWithWWW { static constexpr auto name = "cutToFirstSignificantSubdomainWithWWW"; };
|
||||
using FunctionCutToFirstSignificantSubdomainWithWWW = FunctionStringToString<ExtractSubstringImpl<CutToFirstSignificantSubdomain<false>>, NameCutToFirstSignificantSubdomainWithWWW>;
|
||||
|
||||
void registerFunctionCutToFirstSignificantSubdomain(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CutToFirstSignificantSubdomain)
|
||||
{
|
||||
factory.registerFunction<FunctionCutToFirstSignificantSubdomain>();
|
||||
factory.registerFunction<FunctionCutToFirstSignificantSubdomainWithWWW>();
|
||||
|
@ -34,7 +34,7 @@ using FunctionCutToFirstSignificantSubdomainCustom = FunctionCutToFirstSignifica
|
||||
struct NameCutToFirstSignificantSubdomainCustomWithWWW { static constexpr auto name = "cutToFirstSignificantSubdomainCustomWithWWW"; };
|
||||
using FunctionCutToFirstSignificantSubdomainCustomWithWWW = FunctionCutToFirstSignificantSubdomainCustomImpl<CutToFirstSignificantSubdomainCustom<false>, NameCutToFirstSignificantSubdomainCustomWithWWW>;
|
||||
|
||||
void registerFunctionCutToFirstSignificantSubdomainCustom(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CutToFirstSignificantSubdomainCustom)
|
||||
{
|
||||
factory.registerFunction<FunctionCutToFirstSignificantSubdomainCustom>();
|
||||
factory.registerFunction<FunctionCutToFirstSignificantSubdomainCustomWithWWW>();
|
||||
|
@ -77,7 +77,7 @@ struct CutURLParameterImpl
|
||||
struct NameCutURLParameter { static constexpr auto name = "cutURLParameter"; };
|
||||
using FunctionCutURLParameter = FunctionsStringSearchToString<CutURLParameterImpl, NameCutURLParameter>;
|
||||
|
||||
void registerFunctionCutURLParameter(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CutURLParameter)
|
||||
{
|
||||
factory.registerFunction<FunctionCutURLParameter>();
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ struct ExtractWWW
|
||||
struct NameCutWWW { static constexpr auto name = "cutWWW"; };
|
||||
using FunctionCutWWW = FunctionStringToString<CutSubstringImpl<ExtractWWW>, NameCutWWW>;
|
||||
|
||||
void registerFunctionCutWWW(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(CutWWW)
|
||||
{
|
||||
factory.registerFunction<FunctionCutWWW>();
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ using FunctionEncodeURLComponent = FunctionStringToString<CodeURLComponentImpl<e
|
||||
using FunctionDecodeURLFormComponent = FunctionStringToString<CodeURLComponentImpl<decode, true>, NameDecodeURLFormComponent>;
|
||||
using FunctionEncodeURLFormComponent = FunctionStringToString<CodeURLComponentImpl<encode, true>, NameEncodeURLFormComponent>;
|
||||
|
||||
void registerFunctionEncodeAndDecodeURLComponent(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(EncodeAndDecodeURLComponent)
|
||||
{
|
||||
factory.registerFunction<FunctionDecodeURLComponent>();
|
||||
factory.registerFunction<FunctionEncodeURLComponent>();
|
||||
|
@ -10,7 +10,7 @@ struct NameDomain { static constexpr auto name = "domain"; };
|
||||
using FunctionDomain = FunctionStringToString<ExtractSubstringImpl<ExtractDomain<false>>, NameDomain>;
|
||||
|
||||
|
||||
void registerFunctionDomain(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Domain)
|
||||
{
|
||||
factory.registerFunction<FunctionDomain>();
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ struct NameDomainWithoutWWW { static constexpr auto name = "domainWithoutWWW"; }
|
||||
using FunctionDomainWithoutWWW = FunctionStringToString<ExtractSubstringImpl<ExtractDomain<true>>, NameDomainWithoutWWW>;
|
||||
|
||||
|
||||
void registerFunctionDomainWithoutWWW(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(DomainWithoutWWW)
|
||||
{
|
||||
factory.registerFunction<FunctionDomainWithoutWWW>();
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ struct ExtractURLParameterImpl
|
||||
struct NameExtractURLParameter { static constexpr auto name = "extractURLParameter"; };
|
||||
using FunctionExtractURLParameter = FunctionsStringSearchToString<ExtractURLParameterImpl, NameExtractURLParameter>;
|
||||
|
||||
void registerFunctionExtractURLParameter(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(ExtractURLParameter)
|
||||
{
|
||||
factory.registerFunction<FunctionExtractURLParameter>();
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
struct NameExtractURLParameterNames { static constexpr auto name = "extractURLParameterNames"; };
|
||||
using FunctionExtractURLParameterNames = FunctionTokens<ExtractURLParameterNamesImpl>;
|
||||
|
||||
void registerFunctionExtractURLParameterNames(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(ExtractURLParameterNames)
|
||||
{
|
||||
factory.registerFunction<FunctionExtractURLParameterNames>();
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public:
|
||||
struct NameExtractURLParameters { static constexpr auto name = "extractURLParameters"; };
|
||||
using FunctionExtractURLParameters = FunctionTokens<ExtractURLParametersImpl>;
|
||||
|
||||
void registerFunctionExtractURLParameters(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(ExtractURLParameters)
|
||||
{
|
||||
factory.registerFunction<FunctionExtractURLParameters>();
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ struct NameFirstSignificantSubdomain { static constexpr auto name = "firstSignif
|
||||
|
||||
using FunctionFirstSignificantSubdomain = FunctionStringToString<ExtractSubstringImpl<ExtractFirstSignificantSubdomain<true>>, NameFirstSignificantSubdomain>;
|
||||
|
||||
void registerFunctionFirstSignificantSubdomain(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(FirstSignificantSubdomain)
|
||||
{
|
||||
factory.registerFunction<FunctionFirstSignificantSubdomain>();
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ struct NameFirstSignificantSubdomainCustom { static constexpr auto name = "first
|
||||
|
||||
using FunctionFirstSignificantSubdomainCustom = FunctionCutToFirstSignificantSubdomainCustomImpl<ExtractFirstSignificantSubdomain<true>, NameFirstSignificantSubdomainCustom>;
|
||||
|
||||
void registerFunctionFirstSignificantSubdomainCustom(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(FirstSignificantSubdomainCustom)
|
||||
{
|
||||
factory.registerFunction<FunctionFirstSignificantSubdomainCustom>();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
struct NameFragment { static constexpr auto name = "fragment"; };
|
||||
using FunctionFragment = FunctionStringToString<ExtractSubstringImpl<ExtractFragment<true>>, NameFragment>;
|
||||
|
||||
void registerFunctionFragment(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Fragment)
|
||||
{
|
||||
factory.registerFunction<FunctionFragment>();
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ struct ExtractNetloc
|
||||
struct NameNetloc { static constexpr auto name = "netloc"; };
|
||||
using FunctionNetloc = FunctionStringToString<ExtractSubstringImpl<ExtractNetloc>, NameNetloc>;
|
||||
|
||||
void registerFunctionNetloc(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Netloc)
|
||||
{
|
||||
factory.registerFunction<FunctionNetloc>();
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace DB
|
||||
struct NamePath { static constexpr auto name = "path"; };
|
||||
using FunctionPath = FunctionStringToString<ExtractSubstringImpl<ExtractPath<false>>, NamePath>;
|
||||
|
||||
void registerFunctionPath(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Path)
|
||||
{
|
||||
factory.registerFunction<FunctionPath>();
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace DB
|
||||
struct NamePathFull { static constexpr auto name = "pathFull"; };
|
||||
using FunctionPathFull = FunctionStringToString<ExtractSubstringImpl<ExtractPath<true>>, NamePathFull>;
|
||||
|
||||
void registerFunctionPathFull(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(PathFull)
|
||||
{
|
||||
factory.registerFunction<FunctionPathFull>();
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
void registerFunctionPort(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Port)
|
||||
{
|
||||
factory.registerFunction<FunctionPort>();
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace DB
|
||||
struct NameProtocol { static constexpr auto name = "protocol"; };
|
||||
using FunctionProtocol = FunctionStringToString<ExtractSubstringImpl<ExtractProtocol>, NameProtocol>;
|
||||
|
||||
void registerFunctionProtocol(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Protocol)
|
||||
{
|
||||
factory.registerFunction<FunctionProtocol>();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
struct NameQueryString { static constexpr auto name = "queryString"; };
|
||||
using FunctionQueryString = FunctionStringToString<ExtractSubstringImpl<ExtractQueryString<true>>, NameQueryString>;
|
||||
|
||||
void registerFunctionQueryString(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(QueryString)
|
||||
{
|
||||
factory.registerFunction<FunctionQueryString>();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
struct NameQueryStringAndFragment { static constexpr auto name = "queryStringAndFragment"; };
|
||||
using FunctionQueryStringAndFragment = FunctionStringToString<ExtractSubstringImpl<ExtractQueryStringAndFragment<true>>, NameQueryStringAndFragment>;
|
||||
|
||||
void registerFunctionQueryStringAndFragment(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(QueryStringAndFragment)
|
||||
{
|
||||
factory.registerFunction<FunctionQueryStringAndFragment>();
|
||||
}
|
||||
|
@ -1,64 +0,0 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
class FunctionFactory;
|
||||
|
||||
void registerFunctionProtocol(FunctionFactory & factory);
|
||||
void registerFunctionDomain(FunctionFactory & factory);
|
||||
void registerFunctionDomainWithoutWWW(FunctionFactory & factory);
|
||||
void registerFunctionFirstSignificantSubdomain(FunctionFactory & factory);
|
||||
void registerFunctionFirstSignificantSubdomainCustom(FunctionFactory & factory);
|
||||
void registerFunctionTopLevelDomain(FunctionFactory & factory);
|
||||
void registerFunctionPort(FunctionFactory & factory);
|
||||
void registerFunctionPath(FunctionFactory & factory);
|
||||
void registerFunctionPathFull(FunctionFactory & factory);
|
||||
void registerFunctionQueryString(FunctionFactory & factory);
|
||||
void registerFunctionFragment(FunctionFactory & factory);
|
||||
void registerFunctionQueryStringAndFragment(FunctionFactory & factory);
|
||||
void registerFunctionExtractURLParameter(FunctionFactory & factory);
|
||||
void registerFunctionExtractURLParameters(FunctionFactory & factory);
|
||||
void registerFunctionExtractURLParameterNames(FunctionFactory & factory);
|
||||
void registerFunctionURLHierarchy(FunctionFactory & factory);
|
||||
void registerFunctionURLPathHierarchy(FunctionFactory & factory);
|
||||
void registerFunctionCutToFirstSignificantSubdomain(FunctionFactory & factory);
|
||||
void registerFunctionCutToFirstSignificantSubdomainCustom(FunctionFactory & factory);
|
||||
void registerFunctionCutWWW(FunctionFactory & factory);
|
||||
void registerFunctionCutQueryString(FunctionFactory & factory);
|
||||
void registerFunctionCutFragment(FunctionFactory & factory);
|
||||
void registerFunctionCutQueryStringAndFragment(FunctionFactory & factory);
|
||||
void registerFunctionCutURLParameter(FunctionFactory & factory);
|
||||
void registerFunctionEncodeAndDecodeURLComponent(FunctionFactory & factory);
|
||||
void registerFunctionNetloc(FunctionFactory & factory);
|
||||
|
||||
void registerFunctionsURL(FunctionFactory & factory)
|
||||
{
|
||||
registerFunctionProtocol(factory);
|
||||
registerFunctionDomain(factory);
|
||||
registerFunctionDomainWithoutWWW(factory);
|
||||
registerFunctionFirstSignificantSubdomain(factory);
|
||||
registerFunctionFirstSignificantSubdomainCustom(factory);
|
||||
registerFunctionTopLevelDomain(factory);
|
||||
registerFunctionPort(factory);
|
||||
registerFunctionPath(factory);
|
||||
registerFunctionPathFull(factory);
|
||||
registerFunctionQueryString(factory);
|
||||
registerFunctionFragment(factory);
|
||||
registerFunctionQueryStringAndFragment(factory);
|
||||
registerFunctionExtractURLParameter(factory);
|
||||
registerFunctionExtractURLParameters(factory);
|
||||
registerFunctionExtractURLParameterNames(factory);
|
||||
registerFunctionURLHierarchy(factory);
|
||||
registerFunctionURLPathHierarchy(factory);
|
||||
registerFunctionCutToFirstSignificantSubdomain(factory);
|
||||
registerFunctionCutToFirstSignificantSubdomainCustom(factory);
|
||||
registerFunctionCutWWW(factory);
|
||||
registerFunctionCutQueryString(factory);
|
||||
registerFunctionCutFragment(factory);
|
||||
registerFunctionCutQueryStringAndFragment(factory);
|
||||
registerFunctionCutURLParameter(factory);
|
||||
registerFunctionEncodeAndDecodeURLComponent(factory);
|
||||
registerFunctionNetloc(factory);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ struct ExtractTopLevelDomain
|
||||
struct NameTopLevelDomain { static constexpr auto name = "topLevelDomain"; };
|
||||
using FunctionTopLevelDomain = FunctionStringToString<ExtractSubstringImpl<ExtractTopLevelDomain>, NameTopLevelDomain>;
|
||||
|
||||
void registerFunctionTopLevelDomain(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(TopLevelDomain)
|
||||
{
|
||||
factory.registerFunction<FunctionTopLevelDomain>();
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ template <> struct FunctionUnaryArithmeticMonotonicity<NameAbs>
|
||||
}
|
||||
};
|
||||
|
||||
void registerFunctionAbs(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Abs)
|
||||
{
|
||||
factory.registerFunction<FunctionAbs>(FunctionFactory::CaseInsensitive);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ using FunctionAcos = FunctionMathUnary<UnaryFunctionVectorized<AcosName, acos>>;
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionAcos(FunctionFactory & factory)
|
||||
REGISTER_FUNCTION(Acos)
|
||||
{
|
||||
factory.registerFunction<FunctionAcos>(FunctionFactory::CaseInsensitive);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user