mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-15 20:24:07 +00:00
Merge branch 'master' into remove-sorting-from-stream-properties
This commit is contained in:
commit
9004bb6006
@ -28,7 +28,7 @@
|
||||
* Add `_etag` virtual column for S3 table engine. Fixes [#65312](https://github.com/ClickHouse/ClickHouse/issues/65312). [#65386](https://github.com/ClickHouse/ClickHouse/pull/65386) ([skyoct](https://github.com/skyoct)).
|
||||
* Added a tagging (namespace) mechanism for the query cache. The same queries with different tags are considered different by the query cache. Example: `SELECT 1 SETTINGS use_query_cache = 1, query_cache_tag = 'abc'` and `SELECT 1 SETTINGS use_query_cache = 1, query_cache_tag = 'def'` now create different query cache entries. [#68235](https://github.com/ClickHouse/ClickHouse/pull/68235) ([sakulali](https://github.com/sakulali)).
|
||||
* Support more variants of JOIN strictness (`LEFT/RIGHT SEMI/ANTI/ANY JOIN`) with inequality conditions which involve columns from both left and right table. e.g. `t1.y < t2.y` (see the setting `allow_experimental_join_condition`). [#64281](https://github.com/ClickHouse/ClickHouse/pull/64281) ([lgbo](https://github.com/lgbo-ustc)).
|
||||
* Intrpret Hive-style partitioning for different engines (`File`, `URL`, `S3`, `AzureBlobStorage`, `HDFS`). Hive-style partitioning organizes data into partitioned sub-directories, making it efficient to query and manage large datasets. Currently, it only creates virtual columns with the appropriate name and data. The follow-up PR will introduce the appropriate data filtering (performance speedup). [#65997](https://github.com/ClickHouse/ClickHouse/pull/65997) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
|
||||
* Interpret Hive-style partitioning for different engines (`File`, `URL`, `S3`, `AzureBlobStorage`, `HDFS`). Hive-style partitioning organizes data into partitioned sub-directories, making it efficient to query and manage large datasets. Currently, it only creates virtual columns with the appropriate name and data. The follow-up PR will introduce the appropriate data filtering (performance speedup). [#65997](https://github.com/ClickHouse/ClickHouse/pull/65997) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
|
||||
* Add function `printf` for Spark compatiability (but you can use the existing `format` function). [#66257](https://github.com/ClickHouse/ClickHouse/pull/66257) ([李扬](https://github.com/taiyang-li)).
|
||||
* Add options `restore_replace_external_engines_to_null` and `restore_replace_external_table_functions_to_null` to replace external engines and table_engines to `Null` engine that can be useful for testing. It should work for RESTORE and explicit table creation. [#66536](https://github.com/ClickHouse/ClickHouse/pull/66536) ([Ilya Yatsishin](https://github.com/qoega)).
|
||||
* Added support for reading `MULTILINESTRING` geometry in `WKT` format using function `readWKTLineString`. [#67647](https://github.com/ClickHouse/ClickHouse/pull/67647) ([Jacob Reckhard](https://github.com/jacobrec)).
|
||||
|
@ -42,8 +42,6 @@ Keep an eye out for upcoming meetups and events around the world. Somewhere else
|
||||
|
||||
Upcoming meetups
|
||||
|
||||
* [Bangalore Meetup](https://www.meetup.com/clickhouse-bangalore-user-group/events/303208274/) - September 18
|
||||
* [Tel Aviv Meetup](https://www.meetup.com/clickhouse-meetup-israel/events/303095121) - September 22
|
||||
* [Jakarta Meetup](https://www.meetup.com/clickhouse-indonesia-user-group/events/303191359/) - October 1
|
||||
* [Singapore Meetup](https://www.meetup.com/clickhouse-singapore-meetup-group/events/303212064/) - October 3
|
||||
* [Madrid Meetup](https://www.meetup.com/clickhouse-spain-user-group/events/303096564/) - October 22
|
||||
@ -67,6 +65,8 @@ Recently completed meetups
|
||||
* [Chicago Meetup (Jump Capital)](https://lu.ma/43tvmrfw) - September 12
|
||||
* [London Meetup](https://www.meetup.com/clickhouse-london-user-group/events/302977267) - September 17
|
||||
* [Austin Meetup](https://www.meetup.com/clickhouse-austin-user-group/events/302558689/) - September 17
|
||||
* [Bangalore Meetup](https://www.meetup.com/clickhouse-bangalore-user-group/events/303208274/) - September 18
|
||||
* [Tel Aviv Meetup](https://www.meetup.com/clickhouse-meetup-israel/events/303095121) - September 22
|
||||
|
||||
## Recent Recordings
|
||||
* **Recent Meetup Videos**: [Meetup Playlist](https://www.youtube.com/playlist?list=PL0Z2YDlm0b3iNDUzpY1S3L_iV4nARda_U) Whenever possible recordings of the ClickHouse Community Meetups are edited and presented as individual talks. Current featuring "Modern SQL in 2023", "Fast, Concurrent, and Consistent Asynchronous INSERTS in ClickHouse", and "Full-Text Indices: Design and Experiments"
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
# NOTE: VERSION_REVISION has nothing common with DBMS_TCP_PROTOCOL_VERSION,
|
||||
# only DBMS_TCP_PROTOCOL_VERSION should be incremented on protocol changes.
|
||||
SET(VERSION_REVISION 54490)
|
||||
SET(VERSION_REVISION 54491)
|
||||
SET(VERSION_MAJOR 24)
|
||||
SET(VERSION_MINOR 9)
|
||||
SET(VERSION_MINOR 10)
|
||||
SET(VERSION_PATCH 1)
|
||||
SET(VERSION_GITHASH e02b434d2fc0c4fbee29ca675deab7474d274608)
|
||||
SET(VERSION_DESCRIBE v24.9.1.1-testing)
|
||||
SET(VERSION_STRING 24.9.1.1)
|
||||
SET(VERSION_GITHASH b12a367741812f9e5fe754d19ebae600e2a2614c)
|
||||
SET(VERSION_DESCRIBE v24.10.1.1-testing)
|
||||
SET(VERSION_STRING 24.10.1.1)
|
||||
# end of autochange
|
||||
|
@ -1,4 +1,11 @@
|
||||
# docker build -t clickhouse/docs-builder .
|
||||
FROM golang:alpine AS htmltest-builder
|
||||
|
||||
ARG HTMLTEST_VERSION=0.17.0
|
||||
|
||||
RUN CGO_ENABLED=0 go install github.com/wjdp/htmltest@v${HTMLTEST_VERSION} \
|
||||
&& mv "${GOPATH}/bin/htmltest" /usr/bin/htmltest
|
||||
|
||||
# nodejs 17 prefers ipv6 and is broken in our environment
|
||||
FROM node:16-alpine
|
||||
|
||||
@ -17,6 +24,13 @@ RUN yarn config set registry https://registry.npmjs.org \
|
||||
&& yarn install \
|
||||
&& yarn cache clean
|
||||
|
||||
ENV HOME /opt/clickhouse-docs
|
||||
|
||||
RUN mkdir /output_path \
|
||||
&& chmod -R a+w . /output_path \
|
||||
&& git config --global --add safe.directory /opt/clickhouse-docs
|
||||
|
||||
COPY run.sh /run.sh
|
||||
COPY --from=htmltest-builder /usr/bin/htmltest /usr/bin/htmltest
|
||||
|
||||
ENTRYPOINT ["/run.sh"]
|
||||
|
9
docs/.htmltest.yml
Normal file
9
docs/.htmltest.yml
Normal file
@ -0,0 +1,9 @@
|
||||
DirectoryPath: /test
|
||||
IgnoreDirectoryMissingTrailingSlash: true
|
||||
CheckExternal: false
|
||||
CheckInternal: false
|
||||
CheckInternalHash: true
|
||||
CheckMailto: false
|
||||
IgnoreAltMissing: true
|
||||
IgnoreEmptyHref: true
|
||||
IgnoreInternalEmptyHash: true
|
@ -1,17 +1,20 @@
|
||||
---
|
||||
slug: /en/engines/table-engines/integrations/postgresql
|
||||
title: PostgreSQL Table Engine
|
||||
sidebar_position: 160
|
||||
sidebar_label: PostgreSQL
|
||||
---
|
||||
|
||||
# PostgreSQL
|
||||
|
||||
The PostgreSQL engine allows to perform `SELECT` and `INSERT` queries on data that is stored on a remote PostgreSQL server.
|
||||
The PostgreSQL engine allows `SELECT` and `INSERT` queries on data stored on a remote PostgreSQL server.
|
||||
|
||||
:::note
|
||||
Currently, only PostgreSQL versions 12 and up are supported.
|
||||
:::
|
||||
|
||||
:::note Replicating or migrating Postgres data with with PeerDB
|
||||
> In addition to the Postgres table engine, you can use [PeerDB](https://docs.peerdb.io/introduction) by ClickHouse to set up a continuous data pipeline from Postgres to ClickHouse. PeerDB is a tool designed specifically to replicate data from Postgres to ClickHouse using change data capture (CDC).
|
||||
:::
|
||||
|
||||
## Creating a Table {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
|
@ -79,7 +79,7 @@ All of the parameters excepting `config_section` have the same meaning as in `Me
|
||||
|
||||
## Rollup Configuration {#rollup-configuration}
|
||||
|
||||
The settings for rollup are defined by the [graphite_rollup](../../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-graphite) parameter in the server configuration. The name of the parameter could be any. You can create several configurations and use them for different tables.
|
||||
The settings for rollup are defined by the [graphite_rollup](../../../operations/server-configuration-parameters/settings.md#graphite) parameter in the server configuration. The name of the parameter could be any. You can create several configurations and use them for different tables.
|
||||
|
||||
Rollup configuration structure:
|
||||
|
||||
|
@ -710,7 +710,7 @@ Data part is the minimum movable unit for `MergeTree`-engine tables. The data be
|
||||
### Terms {#terms}
|
||||
|
||||
- Disk — Block device mounted to the filesystem.
|
||||
- Default disk — Disk that stores the path specified in the [path](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-path) server setting.
|
||||
- Default disk — Disk that stores the path specified in the [path](/docs/en/operations/server-configuration-parameters/settings.md/#path) server setting.
|
||||
- Volume — Ordered set of equal disks (similar to [JBOD](https://en.wikipedia.org/wiki/Non-RAID_drive_architectures)).
|
||||
- Storage policy — Set of volumes and the rules for moving data between them.
|
||||
|
||||
|
@ -127,7 +127,7 @@ By default, an INSERT query waits for confirmation of writing the data from only
|
||||
|
||||
Each block of data is written atomically. The INSERT query is divided into blocks up to `max_insert_block_size = 1048576` rows. In other words, if the `INSERT` query has less than 1048576 rows, it is made atomically.
|
||||
|
||||
Data blocks are deduplicated. For multiple writes of the same data block (data blocks of the same size containing the same rows in the same order), the block is only written once. The reason for this is in case of network failures when the client application does not know if the data was written to the DB, so the `INSERT` query can simply be repeated. It does not matter which replica INSERTs were sent to with identical data. `INSERTs` are idempotent. Deduplication parameters are controlled by [merge_tree](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-merge_tree) server settings.
|
||||
Data blocks are deduplicated. For multiple writes of the same data block (data blocks of the same size containing the same rows in the same order), the block is only written once. The reason for this is in case of network failures when the client application does not know if the data was written to the DB, so the `INSERT` query can simply be repeated. It does not matter which replica INSERTs were sent to with identical data. `INSERTs` are idempotent. Deduplication parameters are controlled by [merge_tree](/docs/en/operations/server-configuration-parameters/settings.md/#merge_tree) server settings.
|
||||
|
||||
During replication, only the source data to insert is transferred over the network. Further data transformation (merging) is coordinated and performed on all the replicas in the same way. This minimizes network usage, which means that replication works well when replicas reside in different datacenters. (Note that duplicating data in different datacenters is the main goal of replication.)
|
||||
|
||||
|
@ -1,35 +1,39 @@
|
||||
---
|
||||
slug: /en/getting-started/example-datasets/star-schema
|
||||
sidebar_label: Star Schema Benchmark
|
||||
description: "Dataset based on the TPC-H dbgen source. The coding style and architecture
|
||||
follows the TPCH dbgen."
|
||||
description: "Dataset based on the TPC-H dbgen source. The coding style and architecture follows the TPCH dbgen."
|
||||
---
|
||||
|
||||
# Star Schema Benchmark
|
||||
# Star Schema Benchmark (SSB, 2009)
|
||||
|
||||
The Star Schema Benchmark is roughly based on the TPC-H tables and queries but unlike TPC-H, it uses a star schema layout.
|
||||
The bulk of the data sits in a gigantic fact table which is surrounded by multiple small dimension tables.
|
||||
The queries joined the fact table with one or more dimension tables to apply filter criteria, e.g. `MONTH = 'JANUARY'`.
|
||||
|
||||
References:
|
||||
[Star Schema Benchmark](https://cs.umb.edu/~poneil/StarSchemaB.pdf) (O'Neil et. al), 2009
|
||||
[Variations of the Star Schema Benchmark to Test the Effects of Data Skew on Query Performance](https://doi.org/10.1145/2479871.2479927) (Rabl. et. al.), 2013
|
||||
|
||||
|
||||
Compiling dbgen:
|
||||
|
||||
First, checkout the star schema benchmark repository and compile the data generator:
|
||||
``` bash
|
||||
$ git clone git@github.com:vadimtk/ssb-dbgen.git
|
||||
$ git clone https://github.com/vadimtk/ssb-dbgen.git
|
||||
$ cd ssb-dbgen
|
||||
$ make
|
||||
```
|
||||
|
||||
Generating data:
|
||||
|
||||
:::note
|
||||
With `-s 100` dbgen generates 600 million rows (67 GB), while while `-s 1000` it generates 6 billion rows (which takes a lot of time)
|
||||
:::
|
||||
Then, generate the data. Parameter `-s` specifies the scale factor. For example, with `-s 100`, 600 million rows (67 GB) are generated.
|
||||
|
||||
``` bash
|
||||
$ ./dbgen -s 1000 -T c
|
||||
$ ./dbgen -s 1000 -T l
|
||||
$ ./dbgen -s 1000 -T p
|
||||
$ ./dbgen -s 1000 -T s
|
||||
$ ./dbgen -s 1000 -T d
|
||||
```
|
||||
|
||||
Creating tables in ClickHouse:
|
||||
Now create tables in ClickHouse:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE customer
|
||||
@ -92,18 +96,42 @@ CREATE TABLE supplier
|
||||
S_PHONE String
|
||||
)
|
||||
ENGINE = MergeTree ORDER BY S_SUPPKEY;
|
||||
|
||||
CREATE TABLE date
|
||||
(
|
||||
D_DATEKEY Date,
|
||||
D_DATE FixedString(18),
|
||||
D_DAYOFWEEK LowCardinality(String),
|
||||
D_MONTH LowCardinality(String),
|
||||
D_YEAR UInt16,
|
||||
D_YEARMONTHNUM UInt32,
|
||||
D_YEARMONTH LowCardinality(FixedString(7)),
|
||||
D_DAYNUMINWEEK UInt8,
|
||||
D_DAYNUMINMONTH UInt8,
|
||||
D_DAYNUMINYEAR UInt16,
|
||||
D_MONTHNUMINYEAR UInt8,
|
||||
D_WEEKNUMINYEAR UInt8,
|
||||
D_SELLINGSEASON String,
|
||||
D_LASTDAYINWEEKFL UInt8,
|
||||
D_LASTDAYINMONTHFL UInt8,
|
||||
D_HOLIDAYFL UInt8,
|
||||
D_WEEKDAYFL UInt8
|
||||
)
|
||||
ENGINE = MergeTree ORDER BY D_DATEKEY;
|
||||
```
|
||||
|
||||
Inserting data:
|
||||
The data can be imported as follows:
|
||||
|
||||
``` bash
|
||||
$ clickhouse-client --query "INSERT INTO customer FORMAT CSV" < customer.tbl
|
||||
$ clickhouse-client --query "INSERT INTO part FORMAT CSV" < part.tbl
|
||||
$ clickhouse-client --query "INSERT INTO supplier FORMAT CSV" < supplier.tbl
|
||||
$ clickhouse-client --query "INSERT INTO lineorder FORMAT CSV" < lineorder.tbl
|
||||
$ clickhouse-client --query "INSERT INTO date FORMAT CSV" < date.tbl
|
||||
```
|
||||
|
||||
Converting “star schema” to denormalized “flat schema”:
|
||||
In many use cases of ClickHouse, multiple tables are converted into a single denormalized flat table.
|
||||
This step is optional, below queries are listed in their original form and in a format rewritten for the denormalized table.
|
||||
|
||||
``` sql
|
||||
SET max_memory_usage = 20000000000;
|
||||
@ -159,38 +187,127 @@ Running the queries:
|
||||
|
||||
Q1.1
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS REVENUE
|
||||
FROM
|
||||
lineorder,
|
||||
date
|
||||
WHERE
|
||||
LO_ORDERDATE = D_DATEKEY
|
||||
AND D_YEAR = 1993
|
||||
AND LO_DISCOUNT BETWEEN 1 AND 3
|
||||
AND LO_QUANTITY < 25;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
``` sql
|
||||
SELECT sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS revenue
|
||||
FROM lineorder_flat
|
||||
WHERE toYear(LO_ORDERDATE) = 1993 AND LO_DISCOUNT BETWEEN 1 AND 3 AND LO_QUANTITY < 25;
|
||||
SELECT
|
||||
sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS revenue
|
||||
FROM
|
||||
lineorder_flat
|
||||
WHERE
|
||||
toYear(LO_ORDERDATE) = 1993
|
||||
AND LO_DISCOUNT BETWEEN 1 AND 3
|
||||
AND LO_QUANTITY < 25;
|
||||
```
|
||||
|
||||
Q1.2
|
||||
|
||||
``` sql
|
||||
SELECT sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS revenue
|
||||
FROM lineorder_flat
|
||||
WHERE toYYYYMM(LO_ORDERDATE) = 199401 AND LO_DISCOUNT BETWEEN 4 AND 6 AND LO_QUANTITY BETWEEN 26 AND 35;
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS REVENUE
|
||||
FROM
|
||||
lineorder,
|
||||
date
|
||||
WHERE
|
||||
LO_ORDERDATE = D_DATEKEY
|
||||
AND D_YEARMONTHNUM = 199401
|
||||
AND LO_DISCOUNT BETWEEN 4 AND 6
|
||||
AND LO_QUANTITY BETWEEN 26 AND 35;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS revenue
|
||||
FROM
|
||||
lineorder_flat
|
||||
WHERE
|
||||
toYYYYMM(LO_ORDERDATE) = 199401
|
||||
AND LO_DISCOUNT BETWEEN 4 AND 6
|
||||
AND LO_QUANTITY BETWEEN 26 AND 35;
|
||||
```
|
||||
|
||||
Q1.3
|
||||
|
||||
``` sql
|
||||
SELECT sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS revenue
|
||||
FROM lineorder_flat
|
||||
WHERE toISOWeek(LO_ORDERDATE) = 6 AND toYear(LO_ORDERDATE) = 1994
|
||||
AND LO_DISCOUNT BETWEEN 5 AND 7 AND LO_QUANTITY BETWEEN 26 AND 35;
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_EXTENDEDPRICE*LO_DISCOUNT) AS REVENUE
|
||||
FROM
|
||||
lineorder,
|
||||
date
|
||||
WHERE
|
||||
LO_ORDERDATE = D_DATEKEY
|
||||
AND D_WEEKNUMINYEAR = 6
|
||||
AND D_YEAR = 1994
|
||||
AND LO_DISCOUNT BETWEEN 5 AND 7
|
||||
AND LO_QUANTITY BETWEEN 26 AND 35;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_EXTENDEDPRICE * LO_DISCOUNT) AS revenue
|
||||
FROM
|
||||
lineorder_flat
|
||||
WHERE
|
||||
toISOWeek(LO_ORDERDATE) = 6
|
||||
AND toYear(LO_ORDERDATE) = 1994
|
||||
AND LO_DISCOUNT BETWEEN 5 AND 7
|
||||
AND LO_QUANTITY BETWEEN 26 AND 35;
|
||||
```
|
||||
|
||||
Q2.1
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_REVENUE),
|
||||
D_YEAR,
|
||||
P_BRAND
|
||||
FROM
|
||||
lineorder,
|
||||
date,
|
||||
part,
|
||||
supplier
|
||||
WHERE
|
||||
LO_ORDERDATE = D_DATEKEY
|
||||
AND LO_PARTKEY = P_PARTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND P_CATEGORY = 'MFGR#12'
|
||||
AND S_REGION = 'AMERICA'
|
||||
GROUP BY
|
||||
D_YEAR,
|
||||
P_BRAND
|
||||
ORDER BY
|
||||
D_YEAR,
|
||||
P_BRAND;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_REVENUE),
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
P_BRAND
|
||||
FROM lineorder_flat
|
||||
WHERE P_CATEGORY = 'MFGR#12' AND S_REGION = 'AMERICA'
|
||||
WHERE
|
||||
P_CATEGORY = 'MFGR#12'
|
||||
AND S_REGION = 'AMERICA'
|
||||
GROUP BY
|
||||
year,
|
||||
P_BRAND
|
||||
@ -201,7 +318,34 @@ ORDER BY
|
||||
|
||||
Q2.2
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_REVENUE),
|
||||
D_YEAR,
|
||||
P_BRAND
|
||||
FROM
|
||||
lineorder,
|
||||
date,
|
||||
part,
|
||||
supplier
|
||||
WHERE
|
||||
LO_ORDERDATE = D_DATEKEY
|
||||
AND LO_PARTKEY = P_PARTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND P_BRAND BETWEEN
|
||||
'MFGR#2221' AND 'MFGR#2228'
|
||||
AND S_REGION = 'ASIA'
|
||||
GROUP BY
|
||||
D_YEAR,
|
||||
P_BRAND
|
||||
ORDER BY
|
||||
D_YEAR,
|
||||
P_BRAND;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_REVENUE),
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
@ -218,7 +362,33 @@ ORDER BY
|
||||
|
||||
Q2.3
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_REVENUE),
|
||||
D_YEAR,
|
||||
P_BRAND
|
||||
FROM
|
||||
lineorder,
|
||||
date,
|
||||
part,
|
||||
supplier
|
||||
WHERE
|
||||
LO_ORDERDATE = D_DATEKEY
|
||||
AND LO_PARTKEY = P_PARTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND P_BRAND = 'MFGR#2221'
|
||||
AND S_REGION = 'EUROPE'
|
||||
GROUP BY
|
||||
D_YEAR,
|
||||
P_BRAND
|
||||
ORDER BY
|
||||
D_YEAR,
|
||||
P_BRAND;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
sum(LO_REVENUE),
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
@ -235,14 +405,46 @@ ORDER BY
|
||||
|
||||
Q3.1
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
C_NATION,
|
||||
S_NATION,
|
||||
D_YEAR,
|
||||
sum(LO_REVENUE) AS REVENUE
|
||||
FROM
|
||||
customer,
|
||||
lineorder,
|
||||
supplier,
|
||||
date
|
||||
WHERE
|
||||
LO_CUSTKEY = C_CUSTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND LO_ORDERDATE = D_DATEKEY
|
||||
AND C_REGION = 'ASIA' AND S_REGION = 'ASIA'
|
||||
AND D_YEAR >= 1992 AND D_YEAR <= 1997
|
||||
GROUP BY
|
||||
C_NATION,
|
||||
S_NATION,
|
||||
D_YEAR
|
||||
ORDER BY
|
||||
D_YEAR ASC,
|
||||
REVENUE DESC;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
C_NATION,
|
||||
S_NATION,
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
sum(LO_REVENUE) AS revenue
|
||||
FROM lineorder_flat
|
||||
WHERE C_REGION = 'ASIA' AND S_REGION = 'ASIA' AND year >= 1992 AND year <= 1997
|
||||
WHERE
|
||||
C_REGION = 'ASIA'
|
||||
AND S_REGION = 'ASIA'
|
||||
AND year >= 1992
|
||||
AND year <= 1997
|
||||
GROUP BY
|
||||
C_NATION,
|
||||
S_NATION,
|
||||
@ -254,14 +456,47 @@ ORDER BY
|
||||
|
||||
Q3.2
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
D_YEAR,
|
||||
sum(LO_REVENUE) AS REVENUE
|
||||
FROM
|
||||
customer,
|
||||
lineorder,
|
||||
supplier,
|
||||
date
|
||||
WHERE
|
||||
LO_CUSTKEY = C_CUSTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND LO_ORDERDATE = D_DATEKEY
|
||||
AND C_NATION = 'UNITED STATES'
|
||||
AND S_NATION = 'UNITED STATES'
|
||||
AND D_YEAR >= 1992 AND D_YEAR <= 1997
|
||||
GROUP BY
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
D_YEAR
|
||||
ORDER BY
|
||||
D_YEAR ASC,
|
||||
REVENUE DESC;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
sum(LO_REVENUE) AS revenue
|
||||
FROM lineorder_flat
|
||||
WHERE C_NATION = 'UNITED STATES' AND S_NATION = 'UNITED STATES' AND year >= 1992 AND year <= 1997
|
||||
WHERE
|
||||
C_NATION = 'UNITED STATES'
|
||||
AND S_NATION = 'UNITED STATES'
|
||||
AND year >= 1992
|
||||
AND year <= 1997
|
||||
GROUP BY
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
@ -273,14 +508,48 @@ ORDER BY
|
||||
|
||||
Q3.3
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
D_YEAR,
|
||||
sum(LO_REVENUE) AS revenue
|
||||
FROM
|
||||
customer,
|
||||
lineorder,
|
||||
supplier,
|
||||
date
|
||||
WHERE
|
||||
LO_CUSTKEY = C_CUSTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND LO_ORDERDATE = D_DATEKEY
|
||||
AND (C_CITY = 'UNITED KI1' OR C_CITY = 'UNITED KI5')
|
||||
AND (S_CITY = 'UNITED KI1' OR S_CITY = 'UNITED KI5')
|
||||
AND D_YEAR >= 1992
|
||||
AND D_YEAR <= 1997
|
||||
GROUP BY
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
D_YEAR
|
||||
ORDER BY
|
||||
D_YEAR ASC,
|
||||
revenue DESC;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
sum(LO_REVENUE) AS revenue
|
||||
FROM lineorder_flat
|
||||
WHERE (C_CITY = 'UNITED KI1' OR C_CITY = 'UNITED KI5') AND (S_CITY = 'UNITED KI1' OR S_CITY = 'UNITED KI5') AND year >= 1992 AND year <= 1997
|
||||
WHERE
|
||||
(C_CITY = 'UNITED KI1' OR C_CITY = 'UNITED KI5')
|
||||
AND (S_CITY = 'UNITED KI1' OR S_CITY = 'UNITED KI5')
|
||||
AND year >= 1992
|
||||
AND year <= 1997
|
||||
GROUP BY
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
@ -292,14 +561,46 @@ ORDER BY
|
||||
|
||||
Q3.4
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
D_YEAR,
|
||||
sum(LO_REVENUE) AS revenue
|
||||
FROM
|
||||
customer,
|
||||
lineorder,
|
||||
supplier,
|
||||
date
|
||||
WHERE
|
||||
LO_CUSTKEY = C_CUSTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND LO_ORDERDATE = D_DATEKEY
|
||||
AND (C_CITY='UNITED KI1' OR C_CITY='UNITED KI5')
|
||||
AND (S_CITY='UNITED KI1' OR S_CITY='UNITED KI5')
|
||||
AND D_YEARMONTH = 'Dec1997'
|
||||
GROUP BY
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
D_YEAR
|
||||
ORDER BY
|
||||
D_YEAR ASC,
|
||||
revenue DESC;
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
sum(LO_REVENUE) AS revenue
|
||||
FROM lineorder_flat
|
||||
WHERE (C_CITY = 'UNITED KI1' OR C_CITY = 'UNITED KI5') AND (S_CITY = 'UNITED KI1' OR S_CITY = 'UNITED KI5') AND toYYYYMM(LO_ORDERDATE) = 199712
|
||||
WHERE
|
||||
(C_CITY = 'UNITED KI1' OR C_CITY = 'UNITED KI5')
|
||||
AND (S_CITY = 'UNITED KI1' OR S_CITY = 'UNITED KI5')
|
||||
AND toYYYYMM(LO_ORDERDATE) = 199712
|
||||
GROUP BY
|
||||
C_CITY,
|
||||
S_CITY,
|
||||
@ -311,7 +612,36 @@ ORDER BY
|
||||
|
||||
Q4.1
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
D_YEAR,
|
||||
C_NATION,
|
||||
sum(LO_REVENUE - LO_SUPPLYCOST) AS PROFIT
|
||||
FROM
|
||||
date,
|
||||
customer,
|
||||
supplier,
|
||||
part,
|
||||
lineorder
|
||||
WHERE
|
||||
LO_CUSTKEY = C_CUSTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND LO_PARTKEY = P_PARTKEY
|
||||
AND LO_ORDERDATE = D_DATEKEY
|
||||
AND C_REGION = 'AMERICA'
|
||||
AND S_REGION = 'AMERICA'
|
||||
AND (P_MFGR = 'MFGR#1' OR P_MFGR = 'MFGR#2')
|
||||
GROUP BY
|
||||
D_YEAR,
|
||||
C_NATION
|
||||
ORDER BY
|
||||
D_YEAR,
|
||||
C_NATION
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
C_NATION,
|
||||
@ -328,14 +658,51 @@ ORDER BY
|
||||
|
||||
Q4.2
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
D_YEAR,
|
||||
S_NATION,
|
||||
P_CATEGORY,
|
||||
sum(LO_REVENUE - LO_SUPPLYCOST) AS profit
|
||||
FROM
|
||||
date,
|
||||
customer,
|
||||
supplier,
|
||||
part,
|
||||
lineorder
|
||||
WHERE
|
||||
LO_CUSTKEY = C_CUSTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND LO_PARTKEY = P_PARTKEY
|
||||
AND LO_ORDERDATE = D_DATEKEY
|
||||
AND C_REGION = 'AMERICA'
|
||||
AND S_REGION = 'AMERICA'
|
||||
AND (D_YEAR = 1997 OR D_YEAR = 1998)
|
||||
AND (P_MFGR = 'MFGR#1' OR P_MFGR = 'MFGR#2')
|
||||
GROUP BY
|
||||
D_YEAR,
|
||||
S_NATION,
|
||||
P_CATEGORY
|
||||
ORDER BY
|
||||
D_YEAR,
|
||||
S_NATION,
|
||||
P_CATEGORY
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
S_NATION,
|
||||
P_CATEGORY,
|
||||
sum(LO_REVENUE - LO_SUPPLYCOST) AS profit
|
||||
FROM lineorder_flat
|
||||
WHERE C_REGION = 'AMERICA' AND S_REGION = 'AMERICA' AND (year = 1997 OR year = 1998) AND (P_MFGR = 'MFGR#1' OR P_MFGR = 'MFGR#2')
|
||||
WHERE
|
||||
C_REGION = 'AMERICA'
|
||||
AND S_REGION = 'AMERICA'
|
||||
AND (year = 1997 OR year = 1998)
|
||||
AND (P_MFGR = 'MFGR#1' OR P_MFGR = 'MFGR#2')
|
||||
GROUP BY
|
||||
year,
|
||||
S_NATION,
|
||||
@ -348,14 +715,51 @@ ORDER BY
|
||||
|
||||
Q4.3
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT
|
||||
D_YEAR,
|
||||
S_CITY,
|
||||
P_BRAND,
|
||||
sum(LO_REVENUE - LO_SUPPLYCOST) AS profit
|
||||
FROM
|
||||
date,
|
||||
customer,
|
||||
supplier,
|
||||
part,
|
||||
lineorder
|
||||
WHERE
|
||||
LO_CUSTKEY = C_CUSTKEY
|
||||
AND LO_SUPPKEY = S_SUPPKEY
|
||||
AND LO_PARTKEY = P_PARTKEY
|
||||
AND LO_ORDERDATE = D_DATEKEY
|
||||
AND C_REGION = 'AMERICA'
|
||||
AND S_NATION = 'UNITED STATES'
|
||||
AND (D_YEAR = 1997 OR D_YEAR = 1998)
|
||||
AND P_CATEGORY = 'MFGR#14'
|
||||
GROUP BY
|
||||
D_YEAR,
|
||||
S_CITY,
|
||||
P_BRAND
|
||||
ORDER BY
|
||||
D_YEAR,
|
||||
S_CITY,
|
||||
P_BRAND
|
||||
```
|
||||
|
||||
Denormalized table:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
toYear(LO_ORDERDATE) AS year,
|
||||
S_CITY,
|
||||
P_BRAND,
|
||||
sum(LO_REVENUE - LO_SUPPLYCOST) AS profit
|
||||
FROM lineorder_flat
|
||||
WHERE S_NATION = 'UNITED STATES' AND (year = 1997 OR year = 1998) AND P_CATEGORY = 'MFGR#14'
|
||||
FROM
|
||||
lineorder_flat
|
||||
WHERE
|
||||
S_NATION = 'UNITED STATES'
|
||||
AND (year = 1997 OR year = 1998)
|
||||
AND P_CATEGORY = 'MFGR#14'
|
||||
GROUP BY
|
||||
year,
|
||||
S_CITY,
|
||||
@ -365,3 +769,4 @@ ORDER BY
|
||||
S_CITY ASC,
|
||||
P_BRAND ASC;
|
||||
```
|
||||
|
||||
|
@ -155,7 +155,7 @@ Format a query as usual, then place the values that you want to pass from the ap
|
||||
|
||||
``` bash
|
||||
$ clickhouse-client --param_tuple_in_tuple="(10, ('dt', 10))" -q "SELECT * FROM table WHERE val = {tuple_in_tuple:Tuple(UInt8, Tuple(String, UInt8))}"
|
||||
$ clickhouse-client --param_tbl="numbers" --param_db="system" --param_col="number" --query "SELECT {col:Identifier} FROM {db:Identifier}.{tbl:Identifier} LIMIT 10"
|
||||
$ clickhouse-client --param_tbl="numbers" --param_db="system" --param_col="number" --param_alias="top_ten" --query "SELECT {col:Identifier} as {alias:Identifier} FROM {db:Identifier}.{tbl:Identifier} LIMIT 10"
|
||||
```
|
||||
|
||||
## Configuring {#interfaces_cli_configuration}
|
||||
@ -188,7 +188,7 @@ You can pass parameters to `clickhouse-client` (all parameters have a default va
|
||||
- `--memory-usage` – If specified, print memory usage to ‘stderr’ in non-interactive mode]. Possible values: 'none' - do not print memory usage, 'default' - print number of bytes, 'readable' - print memory usage in human-readable format.
|
||||
- `--stacktrace` – If specified, also print the stack trace if an exception occurs.
|
||||
- `--config-file` – The name of the configuration file.
|
||||
- `--secure` – If specified, will connect to server over secure connection (TLS). You might need to configure your CA certificates in the [configuration file](#configuration_files). The available configuration settings are the same as for [server-side TLS configuration](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-openssl).
|
||||
- `--secure` – If specified, will connect to server over secure connection (TLS). You might need to configure your CA certificates in the [configuration file](#configuration_files). The available configuration settings are the same as for [server-side TLS configuration](../operations/server-configuration-parameters/settings.md#openssl).
|
||||
- `--history_file` — Path to a file containing command history.
|
||||
- `--param_<name>` — Value for a [query with parameters](#cli-queries-with-parameters).
|
||||
- `--hardware-utilization` — Print hardware utilization information in progress bar.
|
||||
|
@ -2059,7 +2059,7 @@ In this case autogenerated Protobuf schema will be saved in file `path/to/schema
|
||||
|
||||
### Drop Protobuf cache
|
||||
|
||||
To reload Protobuf schema loaded from [format_schema_path](../operations/server-configuration-parameters/settings.md/#server_configuration_parameters-format_schema_path) use [SYSTEM DROP ... FORMAT CACHE](../sql-reference/statements/system.md/#system-drop-schema-format) statement.
|
||||
To reload Protobuf schema loaded from [format_schema_path](../operations/server-configuration-parameters/settings.md/#format_schema_path) use [SYSTEM DROP ... FORMAT CACHE](../sql-reference/statements/system.md/#system-drop-schema-format) statement.
|
||||
|
||||
```sql
|
||||
SYSTEM DROP FORMAT SCHEMA CACHE FOR Protobuf
|
||||
@ -2622,7 +2622,7 @@ Result:
|
||||
|
||||
## Npy {#data-format-npy}
|
||||
|
||||
This function is designed to load a NumPy array from a .npy file into ClickHouse. The NumPy file format is a binary format used for efficiently storing arrays of numerical data. During import, ClickHouse treats top level dimension as an array of rows with single column. Supported Npy data types and their corresponding type in ClickHouse:
|
||||
This function is designed to load a NumPy array from a .npy file into ClickHouse. The NumPy file format is a binary format used for efficiently storing arrays of numerical data. During import, ClickHouse treats top level dimension as an array of rows with single column. Supported Npy data types and their corresponding type in ClickHouse:
|
||||
|
||||
| Npy data type (`INSERT`) | ClickHouse data type | Npy data type (`SELECT`) |
|
||||
|--------------------------|-----------------------------------------------------------------|--------------------------|
|
||||
@ -2774,7 +2774,7 @@ can contain an absolute path or a path relative to the current directory on the
|
||||
If you use the client in the [batch mode](/docs/en/interfaces/cli.md/#cli_usage), the path to the schema must be relative due to security reasons.
|
||||
|
||||
If you input or output data via the [HTTP interface](/docs/en/interfaces/http.md) the file name specified in the format schema
|
||||
should be located in the directory specified in [format_schema_path](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-format_schema_path)
|
||||
should be located in the directory specified in [format_schema_path](/docs/en/operations/server-configuration-parameters/settings.md/#format_schema_path)
|
||||
in the server configuration.
|
||||
|
||||
## Skipping Errors {#skippingerrors}
|
||||
|
@ -11,7 +11,7 @@ The HTTP interface lets you use ClickHouse on any platform from any programming
|
||||
By default, `clickhouse-server` listens for HTTP on port 8123 (this can be changed in the config).
|
||||
HTTPS can be enabled as well with port 8443 by default.
|
||||
|
||||
If you make a `GET /` request without parameters, it returns 200 response code and the string which defined in [http_server_default_response](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-http_server_default_response) default value “Ok.” (with a line feed at the end)
|
||||
If you make a `GET /` request without parameters, it returns 200 response code and the string which defined in [http_server_default_response](../operations/server-configuration-parameters/settings.md#http_server_default_response) default value “Ok.” (with a line feed at the end)
|
||||
|
||||
``` bash
|
||||
$ curl 'http://localhost:8123/'
|
||||
@ -791,7 +791,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
|
||||
* Connection #0 to host localhost left intact
|
||||
```
|
||||
|
||||
## Valid JSON/XML response on exception during HTTP streaming {valid-output-on-exception-http-streaming}
|
||||
## Valid JSON/XML response on exception during HTTP streaming {valid-output-on-exception-http-streaming}
|
||||
|
||||
While query execution over HTTP an exception can happen when part of the data has already been sent. Usually an exception is sent to the client in plain text
|
||||
even if some specific data format was used to output data and the output may become invalid in terms of specified data format.
|
||||
|
@ -96,7 +96,7 @@ In this case, ensure that the username follows the `mysql4<subdomain>_<username>
|
||||
|
||||
## Enabling the MySQL Interface On Self-managed ClickHouse
|
||||
|
||||
Add the [mysql_port](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-mysql_port) setting to your server's configuration file. For example, you could define the port in a new XML file in your `config.d/` [folder](../operations/configuration-files):
|
||||
Add the [mysql_port](../operations/server-configuration-parameters/settings.md#mysql_port) setting to your server's configuration file. For example, you could define the port in a new XML file in your `config.d/` [folder](../operations/configuration-files):
|
||||
|
||||
``` xml
|
||||
<clickhouse>
|
||||
|
@ -8,7 +8,7 @@ sidebar_label: PostgreSQL Interface
|
||||
|
||||
ClickHouse supports the PostgreSQL wire protocol, which allows you to use Postgres clients to connect to ClickHouse. In a sense, ClickHouse can pretend to be a PostgreSQL instance - allowing you to connect a PostgreSQL client application to ClickHouse that is not already directly supported by ClickHouse (for example, Amazon Redshift).
|
||||
|
||||
To enable the PostgreSQL wire protocol, add the [postgresql_port](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-postgresql_port) setting to your server's configuration file. For example, you could define the port in a new XML file in your `config.d` folder:
|
||||
To enable the PostgreSQL wire protocol, add the [postgresql_port](../operations/server-configuration-parameters/settings.md#postgresql_port) setting to your server's configuration file. For example, you could define the port in a new XML file in your `config.d` folder:
|
||||
|
||||
```xml
|
||||
<clickhouse>
|
||||
|
@ -151,7 +151,7 @@ Check:
|
||||
|
||||
- Endpoint settings.
|
||||
|
||||
Check [listen_host](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-listen_host) and [tcp_port](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-tcp_port) settings.
|
||||
Check [listen_host](../operations/server-configuration-parameters/settings.md#listen_host) and [tcp_port](../operations/server-configuration-parameters/settings.md#tcp_port) settings.
|
||||
|
||||
ClickHouse server accepts localhost connections only by default.
|
||||
|
||||
@ -163,8 +163,8 @@ Check:
|
||||
|
||||
Check:
|
||||
|
||||
- The [tcp_port_secure](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-tcp_port_secure) setting.
|
||||
- Settings for [SSL certificates](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-openssl).
|
||||
- The [tcp_port_secure](../operations/server-configuration-parameters/settings.md#tcp_port_secure) setting.
|
||||
- Settings for [SSL certificates](../operations/server-configuration-parameters/settings.md#openssl).
|
||||
|
||||
Use proper parameters while connecting. For example, use the `port_secure` parameter with `clickhouse_client`.
|
||||
|
||||
|
@ -7,7 +7,7 @@ sidebar_label: Configuration Files
|
||||
# Configuration Files
|
||||
|
||||
The ClickHouse server can be configured with configuration files in XML or YAML syntax. In most installation types, the ClickHouse server runs with `/etc/clickhouse-server/config.xml` as default configuration file, but it is also possible to specify the location of the configuration file manually at server startup using command line option `--config-file=` or `-C`. Additional configuration files may be placed into directory `config.d/` relative to the main configuration file, for example into directory `/etc/clickhouse-server/config.d/`. Files in this directory and the main configuration are merged in a preprocessing step before the configuration is applied in ClickHouse server. Configuration files are merged in alphabetical order. To simplify updates and improve modularization, it is best practice to keep the default `config.xml` file unmodified and place additional customization into `config.d/`.
|
||||
(The ClickHouse keeper configuration lives in `/etc/clickhouse-keeper/keeper_config.xml` and thus the additional files need to be placed in `/etc/clickhouse-keeper/keeper_config.d/` )
|
||||
(The ClickHouse keeper configuration lives in `/etc/clickhouse-keeper/keeper_config.xml` and thus the additional files need to be placed in `/etc/clickhouse-keeper/keeper_config.d/` )
|
||||
|
||||
|
||||
It is possible to mix XML and YAML configuration files, for example you could have a main configuration file `config.xml` and additional configuration files `config.d/network.xml`, `config.d/timezone.yaml` and `config.d/keeper.yaml`. Mixing XML and YAML within a single configuration file is not supported. XML configuration files should use `<clickhouse>...</clickhouse>` as top-level tag. In YAML configuration files, `clickhouse:` is optional, the parser inserts it implicitly if absent.
|
||||
@ -154,7 +154,7 @@ will take the default value
|
||||
|
||||
The config can define substitutions. There are two types of substitutions:
|
||||
|
||||
- If an element has the `incl` attribute, the corresponding substitution from the file will be used as the value. By default, the path to the file with substitutions is `/etc/metrika.xml`. This can be changed in the [include_from](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-include_from) element in the server config. The substitution values are specified in `/clickhouse/substitution_name` elements in this file. If a substitution specified in `incl` does not exist, it is recorded in the log. To prevent ClickHouse from logging missing substitutions, specify the `optional="true"` attribute (for example, settings for [macros](../operations/server-configuration-parameters/settings.md#macros)).
|
||||
- If an element has the `incl` attribute, the corresponding substitution from the file will be used as the value. By default, the path to the file with substitutions is `/etc/metrika.xml`. This can be changed in the [include_from](../operations/server-configuration-parameters/settings.md#include_from) element in the server config. The substitution values are specified in `/clickhouse/substitution_name` elements in this file. If a substitution specified in `incl` does not exist, it is recorded in the log. To prevent ClickHouse from logging missing substitutions, specify the `optional="true"` attribute (for example, settings for [macros](../operations/server-configuration-parameters/settings.md#macros)).
|
||||
|
||||
- If you want to replace an entire element with a substitution, use `include` as the element name. Substitutions can also be performed from ZooKeeper by specifying attribute `from_zk = "/path/to/node"`. In this case, the element value is replaced with the contents of the Zookeeper node at `/path/to/node`. This also works with you store an entire XML subtree as a Zookeeper node, it will be fully inserted into the source element.
|
||||
|
||||
|
@ -6,7 +6,7 @@ import SelfManaged from '@site/docs/en/_snippets/_self_managed_only_no_roadmap.m
|
||||
|
||||
<SelfManaged />
|
||||
|
||||
[SSL 'strict' option](../server-configuration-parameters/settings.md#server_configuration_parameters-openssl) enables mandatory certificate validation for the incoming connections. In this case, only connections with trusted certificates can be established. Connections with untrusted certificates will be rejected. Thus, certificate validation allows to uniquely authenticate an incoming connection. `Common Name` or `subjectAltName extension` field of the certificate is used to identify the connected user. `subjectAltName extension` supports the usage of one wildcard '*' in the server configuration. This allows to associate multiple certificates with the same user. Additionally, reissuing and revoking of the certificates does not affect the ClickHouse configuration.
|
||||
[SSL 'strict' option](../server-configuration-parameters/settings.md#openssl) enables mandatory certificate validation for the incoming connections. In this case, only connections with trusted certificates can be established. Connections with untrusted certificates will be rejected. Thus, certificate validation allows to uniquely authenticate an incoming connection. `Common Name` or `subjectAltName extension` field of the certificate is used to identify the connected user. `subjectAltName extension` supports the usage of one wildcard '*' in the server configuration. This allows to associate multiple certificates with the same user. Additionally, reissuing and revoking of the certificates does not affect the ClickHouse configuration.
|
||||
|
||||
To enable SSL certificate authentication, a list of `Common Name`'s or `Subject Alt Name`'s for each ClickHouse user must be specified in the settings file `users.xml `:
|
||||
|
||||
@ -40,4 +40,4 @@ To enable SSL certificate authentication, a list of `Common Name`'s or `Subject
|
||||
</clickhouse>
|
||||
```
|
||||
|
||||
For the SSL [`chain of trust`](https://en.wikipedia.org/wiki/Chain_of_trust) to work correctly, it is also important to make sure that the [`caConfig`](../server-configuration-parameters/settings.md#server_configuration_parameters-openssl) parameter is configured properly.
|
||||
For the SSL [`chain of trust`](https://en.wikipedia.org/wiki/Chain_of_trust) to work correctly, it is also important to make sure that the [`caConfig`](../server-configuration-parameters/settings.md#openssl) parameter is configured properly.
|
||||
|
@ -50,7 +50,7 @@ This data is collected in the `system.asynchronous_metric_log` table.
|
||||
|
||||
ClickHouse server has embedded instruments for self-state monitoring.
|
||||
|
||||
To track server events use server logs. See the [logger](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-logger) section of the configuration file.
|
||||
To track server events use server logs. See the [logger](../operations/server-configuration-parameters/settings.md#logger) section of the configuration file.
|
||||
|
||||
ClickHouse collects:
|
||||
|
||||
@ -59,9 +59,9 @@ ClickHouse collects:
|
||||
|
||||
You can find metrics in the [system.metrics](../operations/system-tables/metrics.md#system_tables-metrics), [system.events](../operations/system-tables/events.md#system_tables-events), and [system.asynchronous_metrics](../operations/system-tables/asynchronous_metrics.md#system_tables-asynchronous_metrics) tables.
|
||||
|
||||
You can configure ClickHouse to export metrics to [Graphite](https://github.com/graphite-project). See the [Graphite section](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-graphite) in the ClickHouse server configuration file. Before configuring export of metrics, you should set up Graphite by following their official [guide](https://graphite.readthedocs.io/en/latest/install.html).
|
||||
You can configure ClickHouse to export metrics to [Graphite](https://github.com/graphite-project). See the [Graphite section](../operations/server-configuration-parameters/settings.md#graphite) in the ClickHouse server configuration file. Before configuring export of metrics, you should set up Graphite by following their official [guide](https://graphite.readthedocs.io/en/latest/install.html).
|
||||
|
||||
You can configure ClickHouse to export metrics to [Prometheus](https://prometheus.io). See the [Prometheus section](../operations/server-configuration-parameters/settings.md#server_configuration_parameters-prometheus) in the ClickHouse server configuration file. Before configuring export of metrics, you should set up Prometheus by following their official [guide](https://prometheus.io/docs/prometheus/latest/installation/).
|
||||
You can configure ClickHouse to export metrics to [Prometheus](https://prometheus.io). See the [Prometheus section](../operations/server-configuration-parameters/settings.md#prometheus) in the ClickHouse server configuration file. Before configuring export of metrics, you should set up Prometheus by following their official [guide](https://prometheus.io/docs/prometheus/latest/installation/).
|
||||
|
||||
Additionally, you can monitor server availability through the HTTP API. Send the `HTTP GET` request to `/ping`. If the server is available, it responds with `200 OK`.
|
||||
|
||||
|
@ -28,7 +28,7 @@ SETTINGS allow_introspection_functions = 1
|
||||
|
||||
In self-managed deployments, to use query profiler:
|
||||
|
||||
- Setup the [trace_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-trace_log) section of the server configuration.
|
||||
- Setup the [trace_log](../../operations/server-configuration-parameters/settings.md#trace_log) section of the server configuration.
|
||||
|
||||
This section configures the [trace_log](../../operations/system-tables/trace_log.md#system_tables-trace_log) system table containing the results of the profiler functioning. It is configured by default. Remember that data in this table is valid only for a running server. After the server restart, ClickHouse does not clean up the table and all the stored virtual memory address may become invalid.
|
||||
|
||||
|
@ -933,7 +933,7 @@ Default value: `1`.
|
||||
|
||||
Setting up query logging.
|
||||
|
||||
Queries sent to ClickHouse with this setup are logged according to the rules in the [query_log](../../operations/server-configuration-parameters/settings.md/#server_configuration_parameters-query-log) server configuration parameter.
|
||||
Queries sent to ClickHouse with this setup are logged according to the rules in the [query_log](../../operations/server-configuration-parameters/settings.md/#query-log) server configuration parameter.
|
||||
|
||||
Example:
|
||||
|
||||
@ -978,7 +978,7 @@ log_queries_min_type='EXCEPTION_WHILE_PROCESSING'
|
||||
|
||||
Setting up query threads logging.
|
||||
|
||||
Query threads log into the [system.query_thread_log](../../operations/system-tables/query_thread_log.md) table. This setting has effect only when [log_queries](#log-queries) is true. Queries’ threads run by ClickHouse with this setup are logged according to the rules in the [query_thread_log](../../operations/server-configuration-parameters/settings.md/#server_configuration_parameters-query_thread_log) server configuration parameter.
|
||||
Query threads log into the [system.query_thread_log](../../operations/system-tables/query_thread_log.md) table. This setting has effect only when [log_queries](#log-queries) is true. Queries’ threads run by ClickHouse with this setup are logged according to the rules in the [query_thread_log](../../operations/server-configuration-parameters/settings.md/#query_thread_log) server configuration parameter.
|
||||
|
||||
Possible values:
|
||||
|
||||
@ -997,7 +997,7 @@ log_query_threads=1
|
||||
|
||||
Setting up query views logging.
|
||||
|
||||
When a query run by ClickHouse with this setting enabled has associated views (materialized or live views), they are logged in the [query_views_log](../../operations/server-configuration-parameters/settings.md/#server_configuration_parameters-query_views_log) server configuration parameter.
|
||||
When a query run by ClickHouse with this setting enabled has associated views (materialized or live views), they are logged in the [query_views_log](../../operations/server-configuration-parameters/settings.md/#query_views_log) server configuration parameter.
|
||||
|
||||
Example:
|
||||
|
||||
@ -4773,7 +4773,7 @@ Use this setting only for backward compatibility if your use cases depend on old
|
||||
Sets the implicit time zone of the current session or query.
|
||||
The implicit time zone is the time zone applied to values of type DateTime/DateTime64 which have no explicitly specified time zone.
|
||||
The setting takes precedence over the globally configured (server-level) implicit time zone.
|
||||
A value of '' (empty string) means that the implicit time zone of the current session or query is equal to the [server time zone](../server-configuration-parameters/settings.md#server_configuration_parameters-timezone).
|
||||
A value of '' (empty string) means that the implicit time zone of the current session or query is equal to the [server time zone](../server-configuration-parameters/settings.md#timezone).
|
||||
|
||||
You can use functions `timeZone()` and `serverTimeZone()` to get the session time zone and server time zone.
|
||||
|
||||
@ -4829,7 +4829,7 @@ This happens due to different parsing pipelines:
|
||||
|
||||
**See also**
|
||||
|
||||
- [timezone](../server-configuration-parameters/settings.md#server_configuration_parameters-timezone)
|
||||
- [timezone](../server-configuration-parameters/settings.md#timezone)
|
||||
|
||||
## final {#final}
|
||||
|
||||
|
@ -5,9 +5,9 @@ slug: /en/operations/system-tables/asynchronous_insert_log
|
||||
|
||||
Contains information about async inserts. Each entry represents an insert query buffered into an async insert query.
|
||||
|
||||
To start logging configure parameters in the [asynchronous_insert_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-asynchronous_insert_log) section.
|
||||
To start logging configure parameters in the [asynchronous_insert_log](../../operations/server-configuration-parameters/settings.md#asynchronous_insert_log) section.
|
||||
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [asynchronous_insert_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-asynchronous_insert_log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [asynchronous_insert_log](../../operations/server-configuration-parameters/settings.md#asynchronous_insert_log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
|
||||
ClickHouse does not delete data from the table automatically. See [Introduction](../../operations/system-tables/index.md#system-tables-introduction) for more details.
|
||||
|
||||
|
@ -3,7 +3,7 @@ slug: /en/operations/system-tables/graphite_retentions
|
||||
---
|
||||
# graphite_retentions
|
||||
|
||||
Contains information about parameters [graphite_rollup](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-graphite) which are used in tables with [\*GraphiteMergeTree](../../engines/table-engines/mergetree-family/graphitemergetree.md) engines.
|
||||
Contains information about parameters [graphite_rollup](../../operations/server-configuration-parameters/settings.md#graphite) which are used in tables with [\*GraphiteMergeTree](../../engines/table-engines/mergetree-family/graphitemergetree.md) engines.
|
||||
|
||||
Columns:
|
||||
|
||||
|
@ -3,7 +3,7 @@ slug: /en/operations/system-tables/part_log
|
||||
---
|
||||
# part_log
|
||||
|
||||
The `system.part_log` table is created only if the [part_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-part-log) server setting is specified.
|
||||
The `system.part_log` table is created only if the [part_log](../../operations/server-configuration-parameters/settings.md#part-log) server setting is specified.
|
||||
|
||||
This table contains information about events that occurred with [data parts](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) in the [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) family tables, such as adding or merging data.
|
||||
|
||||
|
@ -9,11 +9,11 @@ Contains information about executed queries, for example, start time, duration o
|
||||
This table does not contain the ingested data for `INSERT` queries.
|
||||
:::
|
||||
|
||||
You can change settings of queries logging in the [query_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-query-log) section of the server configuration.
|
||||
You can change settings of queries logging in the [query_log](../../operations/server-configuration-parameters/settings.md#query-log) section of the server configuration.
|
||||
|
||||
You can disable queries logging by setting [log_queries = 0](../../operations/settings/settings.md#log-queries). We do not recommend to turn off logging because information in this table is important for solving issues.
|
||||
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [query_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-query-log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [query_log](../../operations/server-configuration-parameters/settings.md#query-log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
|
||||
ClickHouse does not delete data from the table automatically. See [Introduction](../../operations/system-tables/index.md#system-tables-introduction) for more details.
|
||||
|
||||
|
@ -7,10 +7,10 @@ Contains information about threads that execute queries, for example, thread nam
|
||||
|
||||
To start logging:
|
||||
|
||||
1. Configure parameters in the [query_thread_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-query_thread_log) section.
|
||||
1. Configure parameters in the [query_thread_log](../../operations/server-configuration-parameters/settings.md#query_thread_log) section.
|
||||
2. Set [log_query_threads](../../operations/settings/settings.md#log-query-threads) to 1.
|
||||
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [query_thread_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-query_thread_log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [query_thread_log](../../operations/server-configuration-parameters/settings.md#query_thread_log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
|
||||
ClickHouse does not delete data from the table automatically. See [Introduction](../../operations/system-tables/index.md#system-tables-introduction) for more details.
|
||||
|
||||
|
@ -7,10 +7,10 @@ Contains information about the dependent views executed when running a query, fo
|
||||
|
||||
To start logging:
|
||||
|
||||
1. Configure parameters in the [query_views_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-query_views_log) section.
|
||||
1. Configure parameters in the [query_views_log](../../operations/server-configuration-parameters/settings.md#query_views_log) section.
|
||||
2. Set [log_query_views](../../operations/settings/settings.md#log-query-views) to 1.
|
||||
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [query_views_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-query_views_log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
The flushing period of data is set in `flush_interval_milliseconds` parameter of the [query_views_log](../../operations/server-configuration-parameters/settings.md#query_views_log) server settings section. To force flushing, use the [SYSTEM FLUSH LOGS](../../sql-reference/statements/system.md#query_language-system-flush_logs) query.
|
||||
|
||||
ClickHouse does not delete data from the table automatically. See [Introduction](../../operations/system-tables/index.md#system-tables-introduction) for more details.
|
||||
|
||||
|
@ -4,7 +4,7 @@ slug: /en/operations/system-tables/server_settings
|
||||
# server_settings
|
||||
|
||||
Contains information about global settings for the server, which were specified in `config.xml`.
|
||||
Currently, the table shows only settings from the first layer of `config.xml` and doesn't support nested configs (e.g. [logger](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-logger)).
|
||||
Currently, the table shows only settings from the first layer of `config.xml` and doesn't support nested configs (e.g. [logger](../../operations/server-configuration-parameters/settings.md#logger)).
|
||||
|
||||
Columns:
|
||||
|
||||
@ -50,7 +50,7 @@ WHERE name LIKE '%thread_pool%'
|
||||
|
||||
```
|
||||
|
||||
Using of `WHERE changed` can be useful, for example, when you want to check
|
||||
Using of `WHERE changed` can be useful, for example, when you want to check
|
||||
whether settings in configuration files are loaded correctly and are in use.
|
||||
|
||||
<!-- -->
|
||||
|
@ -5,7 +5,7 @@ slug: /en/operations/system-tables/trace_log
|
||||
|
||||
Contains stack traces collected by the [sampling query profiler](../../operations/optimizing-performance/sampling-query-profiler.md).
|
||||
|
||||
ClickHouse creates this table when the [trace_log](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-trace_log) server configuration section is set. Also see settings: [query_profiler_real_time_period_ns](../../operations/settings/settings.md#query_profiler_real_time_period_ns), [query_profiler_cpu_time_period_ns](../../operations/settings/settings.md#query_profiler_cpu_time_period_ns), [memory_profiler_step](../../operations/settings/settings.md#memory_profiler_step),
|
||||
ClickHouse creates this table when the [trace_log](../../operations/server-configuration-parameters/settings.md#trace_log) server configuration section is set. Also see settings: [query_profiler_real_time_period_ns](../../operations/settings/settings.md#query_profiler_real_time_period_ns), [query_profiler_cpu_time_period_ns](../../operations/settings/settings.md#query_profiler_cpu_time_period_ns), [memory_profiler_step](../../operations/settings/settings.md#memory_profiler_step),
|
||||
[memory_profiler_sample_probability](../../operations/settings/settings.md#memory_profiler_sample_probability), [trace_profile_events](../../operations/settings/settings.md#trace_profile_events).
|
||||
|
||||
To analyze logs, use the `addressToLine`, `addressToLineWithInlines`, `addressToSymbol` and `demangle` introspection functions.
|
||||
|
@ -12,7 +12,7 @@ A utility providing filesystem-like operations for ClickHouse disks. It can work
|
||||
|
||||
* `--config-file, -C` -- path to ClickHouse config, defaults to `/etc/clickhouse-server/config.xml`.
|
||||
* `--save-logs` -- Log progress of invoked commands to `/var/log/clickhouse-server/clickhouse-disks.log`.
|
||||
* `--log-level` -- What [type](../server-configuration-parameters/settings#server_configuration_parameters-logger) of events to log, defaults to `none`.
|
||||
* `--log-level` -- What [type](../server-configuration-parameters/settings#logger) of events to log, defaults to `none`.
|
||||
* `--disk` -- what disk to use for `mkdir, move, read, write, remove` commands. Defaults to `default`.
|
||||
* `--query, -q` -- single query that can be executed without launching interactive mode
|
||||
* `--help, -h` -- print all the options and commands with description
|
||||
@ -23,7 +23,7 @@ After the launch two disks are initialized. The first one is a disk `local` that
|
||||
## Clickhouse-disks state
|
||||
For each disk that was added the utility stores current directory (as in a usual filesystem). User can change current directory and switch between disks.
|
||||
|
||||
State is reflected in a prompt "`disk_name`:`path_name`"
|
||||
State is reflected in a prompt "`disk_name`:`path_name`"
|
||||
|
||||
## Commands
|
||||
|
||||
@ -35,7 +35,7 @@ In these documentation file all mandatory positional arguments are referred as `
|
||||
Recursively copy data from `path-from` at disk `disk_1` (default value is a current disk (parameter `disk` in a non-interactive mode))
|
||||
to `path-to` at disk `disk_2` (default value is a current disk (parameter `disk` in a non-interactive mode)).
|
||||
* `current_disk_with_path (current, current_disk, current_path)`
|
||||
Print current state in format:
|
||||
Print current state in format:
|
||||
`Disk: "current_disk" Path: "current path on current disk"`
|
||||
* `help [<command>]`
|
||||
Print help message about command `command`. If `command` is not specified print information about all commands.
|
||||
@ -54,6 +54,6 @@ In these documentation file all mandatory positional arguments are referred as `
|
||||
* `read (r) <path-from> [--path-to path]`
|
||||
Read a file from `path-from` to `path` (`stdout` if not supplied).
|
||||
* `switch-disk [--path path] <disk>`
|
||||
Switch to disk `disk` on path `path` (if `path` is not specified default value is a previous path on disk `disk`).
|
||||
Switch to disk `disk` on path `path` (if `path` is not specified default value is a previous path on disk `disk`).
|
||||
* `write (w) [--path-from path] <path-to>`.
|
||||
Write a file from `path` (`stdin` if `path` is not supplied, input must finish by Ctrl+D) to `path-to`.
|
||||
|
@ -32,7 +32,7 @@ Timezone agnostic Unix timestamp is stored in tables, and the timezone is used t
|
||||
|
||||
A list of supported time zones can be found in the [IANA Time Zone Database](https://www.iana.org/time-zones) and also can be queried by `SELECT * FROM system.time_zones`. [The list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) is also available at Wikipedia.
|
||||
|
||||
You can explicitly set a time zone for `DateTime`-type columns when creating a table. Example: `DateTime('UTC')`. If the time zone isn’t set, ClickHouse uses the value of the [timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) parameter in the server settings or the operating system settings at the moment of the ClickHouse server start.
|
||||
You can explicitly set a time zone for `DateTime`-type columns when creating a table. Example: `DateTime('UTC')`. If the time zone isn’t set, ClickHouse uses the value of the [timezone](../../operations/server-configuration-parameters/settings.md#timezone) parameter in the server settings or the operating system settings at the moment of the ClickHouse server start.
|
||||
|
||||
The [clickhouse-client](../../interfaces/cli.md) applies the server time zone by default if a time zone isn’t explicitly set when initializing the data type. To use the client time zone, run `clickhouse-client` with the `--use_client_time_zone` parameter.
|
||||
|
||||
@ -149,7 +149,7 @@ Time shifts for multiple days. Some pacific islands changed their timezone offse
|
||||
- [Functions for working with arrays](../../sql-reference/functions/array-functions.md)
|
||||
- [The `date_time_input_format` setting](../../operations/settings/settings-formats.md#date_time_input_format)
|
||||
- [The `date_time_output_format` setting](../../operations/settings/settings-formats.md#date_time_output_format)
|
||||
- [The `timezone` server configuration parameter](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone)
|
||||
- [The `timezone` server configuration parameter](../../operations/server-configuration-parameters/settings.md#timezone)
|
||||
- [The `session_timezone` setting](../../operations/settings/settings.md#session_timezone)
|
||||
- [Operators for working with dates and times](../../sql-reference/operators/index.md#operators-datetime)
|
||||
- [The `Date` data type](../../sql-reference/data-types/date.md)
|
||||
|
@ -119,7 +119,7 @@ FROM dt64;
|
||||
- [Functions for working with dates and times](../../sql-reference/functions/date-time-functions.md)
|
||||
- [The `date_time_input_format` setting](../../operations/settings/settings-formats.md#date_time_input_format)
|
||||
- [The `date_time_output_format` setting](../../operations/settings/settings-formats.md#date_time_output_format)
|
||||
- [The `timezone` server configuration parameter](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone)
|
||||
- [The `timezone` server configuration parameter](../../operations/server-configuration-parameters/settings.md#timezone)
|
||||
- [The `session_timezone` setting](../../operations/settings/settings.md#session_timezone)
|
||||
- [Operators for working with dates and times](../../sql-reference/operators/index.md#operators-for-working-with-dates-and-times)
|
||||
- [`Date` data type](../../sql-reference/data-types/date.md)
|
||||
|
@ -31,9 +31,9 @@ ClickHouse:
|
||||
- Periodically updates dictionaries and dynamically loads missing values. In other words, dictionaries can be loaded dynamically.
|
||||
- Allows creating dictionaries with xml files or [DDL queries](../../sql-reference/statements/create/dictionary.md).
|
||||
|
||||
The configuration of dictionaries can be located in one or more xml-files. The path to the configuration is specified in the [dictionaries_config](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-dictionaries_config) parameter.
|
||||
The configuration of dictionaries can be located in one or more xml-files. The path to the configuration is specified in the [dictionaries_config](../../operations/server-configuration-parameters/settings.md#dictionaries_config) parameter.
|
||||
|
||||
Dictionaries can be loaded at server startup or at first use, depending on the [dictionaries_lazy_load](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-dictionaries_lazy_load) setting.
|
||||
Dictionaries can be loaded at server startup or at first use, depending on the [dictionaries_lazy_load](../../operations/server-configuration-parameters/settings.md#dictionaries_lazy_load) setting.
|
||||
|
||||
The [dictionaries](../../operations/system-tables/dictionaries.md#system_tables-dictionaries) system table contains information about dictionaries configured at server. For each dictionary you can find there:
|
||||
|
||||
@ -1156,7 +1156,7 @@ Setting fields:
|
||||
- `command_read_timeout` - Timeout for reading data from command stdout in milliseconds. Default value 10000. Optional parameter.
|
||||
- `command_write_timeout` - Timeout for writing data to command stdin in milliseconds. Default value 10000. Optional parameter.
|
||||
- `implicit_key` — The executable source file can return only values, and the correspondence to the requested keys is determined implicitly — by the order of rows in the result. Default value is false.
|
||||
- `execute_direct` - If `execute_direct` = `1`, then `command` will be searched inside user_scripts folder specified by [user_scripts_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_scripts_path). Additional script arguments can be specified using a whitespace separator. Example: `script_name arg1 arg2`. If `execute_direct` = `0`, `command` is passed as argument for `bin/sh -c`. Default value is `0`. Optional parameter.
|
||||
- `execute_direct` - If `execute_direct` = `1`, then `command` will be searched inside user_scripts folder specified by [user_scripts_path](../../operations/server-configuration-parameters/settings.md#user_scripts_path). Additional script arguments can be specified using a whitespace separator. Example: `script_name arg1 arg2`. If `execute_direct` = `0`, `command` is passed as argument for `bin/sh -c`. Default value is `0`. Optional parameter.
|
||||
- `send_chunk_header` - controls whether to send row count before sending a chunk of data to process. Optional. Default value is `false`.
|
||||
|
||||
That dictionary source can be configured only via XML configuration. Creating dictionaries with executable source via DDL is disabled; otherwise, the DB user would be able to execute arbitrary binaries on the ClickHouse node.
|
||||
@ -1191,7 +1191,7 @@ Setting fields:
|
||||
- `command_read_timeout` - timeout for reading data from command stdout in milliseconds. Default value 10000. Optional parameter.
|
||||
- `command_write_timeout` - timeout for writing data to command stdin in milliseconds. Default value 10000. Optional parameter.
|
||||
- `implicit_key` — The executable source file can return only values, and the correspondence to the requested keys is determined implicitly — by the order of rows in the result. Default value is false. Optional parameter.
|
||||
- `execute_direct` - If `execute_direct` = `1`, then `command` will be searched inside user_scripts folder specified by [user_scripts_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_scripts_path). Additional script arguments can be specified using whitespace separator. Example: `script_name arg1 arg2`. If `execute_direct` = `0`, `command` is passed as argument for `bin/sh -c`. Default value is `1`. Optional parameter.
|
||||
- `execute_direct` - If `execute_direct` = `1`, then `command` will be searched inside user_scripts folder specified by [user_scripts_path](../../operations/server-configuration-parameters/settings.md#user_scripts_path). Additional script arguments can be specified using whitespace separator. Example: `script_name arg1 arg2`. If `execute_direct` = `0`, `command` is passed as argument for `bin/sh -c`. Default value is `1`. Optional parameter.
|
||||
- `send_chunk_header` - controls whether to send row count before sending a chunk of data to process. Optional. Default value is `false`.
|
||||
|
||||
That dictionary source can be configured only via XML configuration. Creating dictionaries with executable source via DDL is disabled, otherwise, the DB user would be able to execute arbitrary binary on ClickHouse node.
|
||||
@ -1232,7 +1232,7 @@ SOURCE(HTTP(
|
||||
))
|
||||
```
|
||||
|
||||
In order for ClickHouse to access an HTTPS resource, you must [configure openSSL](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-openssl) in the server configuration.
|
||||
In order for ClickHouse to access an HTTPS resource, you must [configure openSSL](../../operations/server-configuration-parameters/settings.md#openssl) in the server configuration.
|
||||
|
||||
Setting fields:
|
||||
|
||||
|
@ -1717,6 +1717,24 @@ Result:
|
||||
[[1,1,2,3],[1,2,3,4]]
|
||||
```
|
||||
|
||||
## arrayUnion(arr)
|
||||
|
||||
Takes multiple arrays, returns an array that contains all elements that are present in any of the source arrays.
|
||||
|
||||
Example:
|
||||
```sql
|
||||
SELECT
|
||||
arrayUnion([-2, 1], [10, 1], [-2], []) as num_example,
|
||||
arrayUnion(['hi'], [], ['hello', 'hi']) as str_example,
|
||||
arrayUnion([1, 3, NULL], [2, 3, NULL]) as null_example
|
||||
```
|
||||
|
||||
```text
|
||||
┌─num_example─┬─str_example────┬─null_example─┐
|
||||
│ [10,-2,1] │ ['hello','hi'] │ [3,2,1,NULL] │
|
||||
└─────────────┴────────────────┴──────────────┘
|
||||
```
|
||||
|
||||
## arrayIntersect(arr)
|
||||
|
||||
Takes multiple arrays, returns an array with elements that are present in all source arrays.
|
||||
|
@ -83,7 +83,7 @@ Result:
|
||||
```
|
||||
## makeDate32
|
||||
|
||||
Creates a date of type [Date32](../../sql-reference/data-types/date32.md) from a year, month, day (or optionally a year and a day).
|
||||
Creates a date of type [Date32](../../sql-reference/data-types/date32.md) from a year, month, day (or optionally a year and a day).
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -153,7 +153,7 @@ makeDateTime(year, month, day, hour, minute, second[, timezone])
|
||||
- `hour` — Hour. [Integer](../data-types/int-uint.md), [Float](../data-types/float.md) or [Decimal](../data-types/decimal.md).
|
||||
- `minute` — Minute. [Integer](../data-types/int-uint.md), [Float](../data-types/float.md) or [Decimal](../data-types/decimal.md).
|
||||
- `second` — Second. [Integer](../data-types/int-uint.md), [Float](../data-types/float.md) or [Decimal](../data-types/decimal.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -186,11 +186,11 @@ makeDateTime64(year, month, day, hour, minute, second[, precision])
|
||||
**Arguments**
|
||||
|
||||
- `year` — Year (0-9999). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `month` — Month (1-12). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `month` — Month (1-12). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `day` — Day (1-31). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `hour` — Hour (0-23). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `minute` — Minute (0-59). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `second` — Second (0-59). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `minute` — Minute (0-59). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `second` — Second (0-59). [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `precision` — Optional precision of the sub-second component (0-9). [Integer](../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Returned value**
|
||||
@ -294,7 +294,7 @@ Result:
|
||||
|
||||
## serverTimeZone
|
||||
|
||||
Returns the timezone of the server, i.e. the value of setting [timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone).
|
||||
Returns the timezone of the server, i.e. the value of setting [timezone](../../operations/server-configuration-parameters/settings.md#timezone).
|
||||
If the function is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise, it produces a constant value.
|
||||
|
||||
**Syntax**
|
||||
@ -1269,7 +1269,7 @@ toStartOfSecond(value, [timezone])
|
||||
**Arguments**
|
||||
|
||||
- `value` — Date and time. [DateTime64](../data-types/datetime64.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -1309,7 +1309,7 @@ Result:
|
||||
|
||||
**See also**
|
||||
|
||||
- [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) server configuration parameter.
|
||||
- [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) server configuration parameter.
|
||||
|
||||
## toStartOfMillisecond
|
||||
|
||||
@ -1324,7 +1324,7 @@ toStartOfMillisecond(value, [timezone])
|
||||
**Arguments**
|
||||
|
||||
- `value` — Date and time. [DateTime64](../../sql-reference/data-types/datetime64.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../../sql-reference/data-types/string.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -1376,7 +1376,7 @@ toStartOfMicrosecond(value, [timezone])
|
||||
**Arguments**
|
||||
|
||||
- `value` — Date and time. [DateTime64](../../sql-reference/data-types/datetime64.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../../sql-reference/data-types/string.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -1416,7 +1416,7 @@ Result:
|
||||
|
||||
**See also**
|
||||
|
||||
- [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) server configuration parameter.
|
||||
- [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) server configuration parameter.
|
||||
|
||||
## toStartOfNanosecond
|
||||
|
||||
@ -1431,7 +1431,7 @@ toStartOfNanosecond(value, [timezone])
|
||||
**Arguments**
|
||||
|
||||
- `value` — Date and time. [DateTime64](../../sql-reference/data-types/datetime64.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../../sql-reference/data-types/string.md).
|
||||
- `timezone` — [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -1471,7 +1471,7 @@ Result:
|
||||
|
||||
**See also**
|
||||
|
||||
- [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) server configuration parameter.
|
||||
- [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) server configuration parameter.
|
||||
|
||||
## toStartOfFiveMinutes
|
||||
|
||||
@ -1674,7 +1674,7 @@ Result:
|
||||
|
||||
## toRelativeYearNum
|
||||
|
||||
Converts a date, or date with time, to the number of years elapsed since a certain fixed point in the past.
|
||||
Converts a date, or date with time, to the number of years elapsed since a certain fixed point in the past.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -2178,7 +2178,7 @@ age('unit', startdate, enddate, [timezone])
|
||||
|
||||
- `enddate` — The second time value to subtract from (the minuend). [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md).
|
||||
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional). If specified, it is applied to both `startdate` and `enddate`. If not specified, timezones of `startdate` and `enddate` are used. If they are not the same, the result is unspecified. [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional). If specified, it is applied to both `startdate` and `enddate`. If not specified, timezones of `startdate` and `enddate` are used. If they are not the same, the result is unspecified. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -2254,7 +2254,7 @@ Aliases: `dateDiff`, `DATE_DIFF`, `timestampDiff`, `timestamp_diff`, `TIMESTAMP_
|
||||
|
||||
- `enddate` — The second time value to subtract from (the minuend). [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md).
|
||||
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional). If specified, it is applied to both `startdate` and `enddate`. If not specified, timezones of `startdate` and `enddate` are used. If they are not the same, the result is unspecified. [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional). If specified, it is applied to both `startdate` and `enddate`. If not specified, timezones of `startdate` and `enddate` are used. If they are not the same, the result is unspecified. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -2323,7 +2323,7 @@ Alias: `dateTrunc`.
|
||||
`unit` argument is case-insensitive.
|
||||
|
||||
- `value` — Date and time. [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -2703,7 +2703,7 @@ now([timezone])
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -2752,7 +2752,7 @@ now64([scale], [timezone])
|
||||
**Arguments**
|
||||
|
||||
- `scale` - Tick size (precision): 10<sup>-precision</sup> seconds. Valid range: [ 0 : 9 ]. Typically, are used - 3 (default) (milliseconds), 6 (microseconds), 9 (nanoseconds).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -2786,7 +2786,7 @@ nowInBlock([timezone])
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -2975,7 +2975,7 @@ YYYYMMDDhhmmssToDateTime(yyyymmddhhmmss[, timezone]);
|
||||
**Arguments**
|
||||
|
||||
- `yyyymmddhhmmss` - A number representing the year, month and day. [Integer](../data-types/int-uint.md), [Float](../data-types/float.md) or [Decimal](../data-types/decimal.md).
|
||||
- `timezone` - [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional).
|
||||
- `timezone` - [Timezone](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -3631,7 +3631,7 @@ addInterval(interval_1, interval_2)
|
||||
- Returns a tuple of intervals. [tuple](../data-types/tuple.md)([interval](../data-types/special-data-types/interval.md)).
|
||||
|
||||
:::note
|
||||
Intervals of the same type will be combined into a single interval. For instance if `toIntervalDay(1)` and `toIntervalDay(2)` are passed then the result will be `(3)` rather than `(1,1)`.
|
||||
Intervals of the same type will be combined into a single interval. For instance if `toIntervalDay(1)` and `toIntervalDay(2)` are passed then the result will be `(3)` rather than `(1,1)`.
|
||||
:::
|
||||
|
||||
**Example**
|
||||
@ -3682,7 +3682,7 @@ addTupleOfIntervals(interval_1, interval_2)
|
||||
Query:
|
||||
|
||||
```sql
|
||||
WITH toDate('2018-01-01') AS date
|
||||
WITH toDate('2018-01-01') AS date
|
||||
SELECT addTupleOfIntervals(date, (INTERVAL 1 DAY, INTERVAL 1 MONTH, INTERVAL 1 YEAR))
|
||||
```
|
||||
|
||||
@ -4802,4 +4802,3 @@ timeDiff(toDateTime64('1927-01-01 00:00:00', 3), toDate32('1927-01-02'));
|
||||
## Related content
|
||||
|
||||
- Blog: [Working with time series data in ClickHouse](https://clickhouse.com/blog/working-with-time-series-data-and-functions-ClickHouse)
|
||||
|
||||
|
@ -18,7 +18,7 @@ file(path[, default])
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `path` — The path of the file relative to [user_files_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_files_path). Supports wildcards `*`, `**`, `?`, `{abc,def}` and `{N..M}` where `N`, `M` are numbers and `'abc', 'def'` are strings.
|
||||
- `path` — The path of the file relative to [user_files_path](../../operations/server-configuration-parameters/settings.md#user_files_path). Supports wildcards `*`, `**`, `?`, `{abc,def}` and `{N..M}` where `N`, `M` are numbers and `'abc', 'def'` are strings.
|
||||
- `default` — The value returned if the file does not exist or cannot be accessed. Supported data types: [String](../data-types/string.md) and [NULL](../../sql-reference/syntax.md#null-literal).
|
||||
|
||||
**Example**
|
||||
|
@ -86,11 +86,11 @@ Returns the fully qualified domain name of the ClickHouse server.
|
||||
fqdn();
|
||||
```
|
||||
|
||||
Aliases: `fullHostName`, `FQDN`.
|
||||
Aliases: `fullHostName`, `FQDN`.
|
||||
|
||||
**Returned value**
|
||||
|
||||
- String with the fully qualified domain name. [String](../data-types/string.md).
|
||||
- String with the fully qualified domain name. [String](../data-types/string.md).
|
||||
|
||||
**Example**
|
||||
|
||||
@ -245,7 +245,7 @@ Result:
|
||||
3. │ 5 │
|
||||
4. │ 5 │
|
||||
5. │ 5 │
|
||||
└─────────────┘
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
## byteSize
|
||||
@ -347,7 +347,7 @@ Result:
|
||||
|
||||
Turns a constant into a full column containing a single value.
|
||||
Full columns and constants are represented differently in memory.
|
||||
Functions usually execute different code for normal and constant arguments, although the result should typically be the same.
|
||||
Functions usually execute different code for normal and constant arguments, although the result should typically be the same.
|
||||
This function can be used to debug this behavior.
|
||||
|
||||
**Syntax**
|
||||
@ -366,8 +366,8 @@ materialize(x)
|
||||
|
||||
**Example**
|
||||
|
||||
In the example below the `countMatches` function expects a constant second argument.
|
||||
This behaviour can be debugged by using the `materialize` function to turn a constant into a full column,
|
||||
In the example below the `countMatches` function expects a constant second argument.
|
||||
This behaviour can be debugged by using the `materialize` function to turn a constant into a full column,
|
||||
verifying that the function throws an error for a non-constant argument.
|
||||
|
||||
Query:
|
||||
@ -1837,7 +1837,7 @@ Returns the default value for the given data type.
|
||||
|
||||
Does not include default values for custom columns set by the user.
|
||||
|
||||
**Syntax**
|
||||
**Syntax**
|
||||
|
||||
```sql
|
||||
defaultValueOfArgumentType(expression)
|
||||
@ -2164,7 +2164,7 @@ Result:
|
||||
|
||||
## filesystemCapacity
|
||||
|
||||
Returns the capacity of the filesystem in bytes. Needs the [path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-path) to the data directory to be configured.
|
||||
Returns the capacity of the filesystem in bytes. Needs the [path](../../operations/server-configuration-parameters/settings.md#path) to the data directory to be configured.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -2592,7 +2592,7 @@ joinGetOrNull(join_storage_table_name, `value_column`, join_keys)
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `join_storage_table_name` — an [identifier](../../sql-reference/syntax.md#syntax-identifiers) indicating where the search is performed.
|
||||
- `join_storage_table_name` — an [identifier](../../sql-reference/syntax.md#syntax-identifiers) indicating where the search is performed.
|
||||
- `value_column` — name of the column of the table that contains required data.
|
||||
- `join_keys` — list of keys.
|
||||
|
||||
@ -2917,7 +2917,7 @@ Result:
|
||||
|
||||
**See Also**
|
||||
|
||||
- [tcp_port](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-tcp_port)
|
||||
- [tcp_port](../../operations/server-configuration-parameters/settings.md#tcp_port)
|
||||
|
||||
## currentProfiles
|
||||
|
||||
@ -4031,7 +4031,7 @@ displayName()
|
||||
|
||||
**Example**
|
||||
|
||||
The `display_name` can be set in `config.xml`. Taking for example a server with `display_name` configured to 'production':
|
||||
The `display_name` can be set in `config.xml`. Taking for example a server with `display_name` configured to 'production':
|
||||
|
||||
```xml
|
||||
<!-- It is the name that will be shown in the clickhouse-client.
|
||||
@ -4279,4 +4279,3 @@ Result:
|
||||
1. │ ['{ArraySizes}','{ArrayElements, TupleElement(keys), Regular}','{ArrayElements, TupleElement(values), Regular}'] │
|
||||
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
|
@ -10,7 +10,7 @@ Time window functions return the inclusive lower and exclusive upper bound of th
|
||||
|
||||
## tumble
|
||||
|
||||
A tumbling time window assigns records to non-overlapping, continuous windows with a fixed duration (`interval`).
|
||||
A tumbling time window assigns records to non-overlapping, continuous windows with a fixed duration (`interval`).
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -21,7 +21,7 @@ tumble(time_attr, interval [, timezone])
|
||||
**Arguments**
|
||||
- `time_attr` — Date and time. [DateTime](../data-types/datetime.md).
|
||||
- `interval` — Window interval in [Interval](../data-types/special-data-types/interval.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional).
|
||||
|
||||
**Returned values**
|
||||
|
||||
@ -57,7 +57,7 @@ tumbleStart(time_attr, interval [, timezone]);
|
||||
|
||||
- `time_attr` — Date and time. [DateTime](../data-types/datetime.md).
|
||||
- `interval` — Window interval in [Interval](../data-types/special-data-types/interval.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional).
|
||||
|
||||
The parameters above can also be passed to the function as a [tuple](../data-types/tuple.md).
|
||||
|
||||
@ -95,7 +95,7 @@ tumbleEnd(time_attr, interval [, timezone]);
|
||||
|
||||
- `time_attr` — Date and time. [DateTime](../data-types/datetime.md).
|
||||
- `interval` — Window interval in [Interval](../data-types/special-data-types/interval.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional).
|
||||
|
||||
The parameters above can also be passed to the function as a [tuple](../data-types/tuple.md).
|
||||
|
||||
@ -132,7 +132,7 @@ hop(time_attr, hop_interval, window_interval [, timezone])
|
||||
- `time_attr` — Date and time. [DateTime](../data-types/datetime.md).
|
||||
- `hop_interval` — Positive Hop interval. [Interval](../data-types/special-data-types/interval.md).
|
||||
- `window_interval` — Positive Window interval. [Interval](../data-types/special-data-types/interval.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional).
|
||||
|
||||
**Returned values**
|
||||
|
||||
@ -172,7 +172,7 @@ hopStart(time_attr, hop_interval, window_interval [, timezone]);
|
||||
- `time_attr` — Date and time. [DateTime](../data-types/datetime.md).
|
||||
- `hop_interval` — Positive Hop interval. [Interval](../data-types/special-data-types/interval.md).
|
||||
- `window_interval` — Positive Window interval. [Interval](../data-types/special-data-types/interval.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional).
|
||||
|
||||
The parameters above can also be passed to the function as a [tuple](../data-types/tuple.md).
|
||||
|
||||
@ -212,9 +212,9 @@ hopEnd(time_attr, hop_interval, window_interval [, timezone]);
|
||||
**Arguments**
|
||||
|
||||
- `time_attr` — Date and time. [DateTime](../data-types/datetime.md).
|
||||
- `hop_interval` — Positive Hop interval. [Interval](../data-types/special-data-types/interval.md).
|
||||
- `hop_interval` — Positive Hop interval. [Interval](../data-types/special-data-types/interval.md).
|
||||
- `window_interval` — Positive Window interval. [Interval](../data-types/special-data-types/interval.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) (optional).
|
||||
|
||||
The parameters above can also be passed to the function as a [tuple](../data-types/tuple.md).
|
||||
|
||||
|
@ -121,7 +121,7 @@ Unsupported arguments:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt8('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int8](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int8](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
For example: `SELECT toInt8(128) == -128;`.
|
||||
:::
|
||||
@ -193,7 +193,7 @@ This is not considered an error.
|
||||
- 8-bit integer value if successful, otherwise `0`. [Int8](../data-types/int-uint.md).
|
||||
|
||||
:::note
|
||||
The function uses [rounding towards zero](https://en.wikipedia.org/wiki/Rounding#Rounding_towards_zero), meaning it truncates fractional digits of numbers.
|
||||
The function uses [rounding towards zero](https://en.wikipedia.org/wiki/Rounding#Rounding_towards_zero), meaning it truncates fractional digits of numbers.
|
||||
:::
|
||||
|
||||
**Example**
|
||||
@ -492,7 +492,7 @@ Unsupported arguments (return `\N`)
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt16OrNull('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int16](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int16](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -555,7 +555,7 @@ Arguments for which the default value is returned:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt16OrDefault('0xc0fe', CAST('-1', 'Int16'));`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int16](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int16](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -617,7 +617,7 @@ Unsupported arguments:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt32('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), the result over or under flows.
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), the result over or under flows.
|
||||
This is not considered an error.
|
||||
For example: `SELECT toInt32(2147483648) == -2147483648;`
|
||||
:::
|
||||
@ -680,7 +680,7 @@ Unsupported arguments (return `0`):
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt32OrZero('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -739,7 +739,7 @@ Unsupported arguments (return `\N`)
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt32OrNull('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -802,7 +802,7 @@ Arguments for which the default value is returned:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt32OrDefault('0xc0fe', CAST('-1', 'Int32'));`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int32](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -864,7 +864,7 @@ Unsupported types:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt64('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int64](../data-types/int-uint.md), the result over or under flows.
|
||||
If the input value cannot be represented within the bounds of [Int64](../data-types/int-uint.md), the result over or under flows.
|
||||
This is not considered an error.
|
||||
For example: `SELECT toInt64(9223372036854775808) == -9223372036854775808;`
|
||||
:::
|
||||
@ -927,7 +927,7 @@ Unsupported arguments (return `0`):
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt64OrZero('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int64](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int64](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -987,7 +987,7 @@ Unsupported arguments (return `\N`)
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt64OrNull('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int64](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int64](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -1112,7 +1112,7 @@ Unsupported arguments:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt128('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int128](../data-types/int-uint.md), the result over or under flows.
|
||||
If the input value cannot be represented within the bounds of [Int128](../data-types/int-uint.md), the result over or under flows.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -1234,7 +1234,7 @@ Unsupported arguments (return `\N`)
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt128OrNull('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int128](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int128](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -1298,7 +1298,7 @@ Arguments for which the default value is returned:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt128OrDefault('0xc0fe', CAST('-1', 'Int128'));`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int128](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int128](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -1360,7 +1360,7 @@ Unsupported arguments:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt256('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int256](../data-types/int-uint.md), the result over or under flows.
|
||||
If the input value cannot be represented within the bounds of [Int256](../data-types/int-uint.md), the result over or under flows.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -1422,7 +1422,7 @@ Unsupported arguments (return `0`):
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt256OrZero('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int256](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int256](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -1482,7 +1482,7 @@ Unsupported arguments (return `\N`)
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toInt256OrNull('0xc0fe');`.
|
||||
|
||||
:::note
|
||||
If the input value cannot be represented within the bounds of [Int256](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
If the input value cannot be represented within the bounds of [Int256](../data-types/int-uint.md), overflow or underflow of the result occurs.
|
||||
This is not considered an error.
|
||||
:::
|
||||
|
||||
@ -4063,7 +4063,7 @@ Result:
|
||||
|
||||
## toDateTime64OrDefault
|
||||
|
||||
Like [toDateTime64](#todatetime64), this function converts an input value to a value of type [DateTime64](../data-types/datetime64.md),
|
||||
Like [toDateTime64](#todatetime64), this function converts an input value to a value of type [DateTime64](../data-types/datetime64.md),
|
||||
but returns either the default value of [DateTime64](../data-types/datetime64.md)
|
||||
or the provided default if an invalid argument is received.
|
||||
|
||||
@ -4132,8 +4132,8 @@ Unsupported arguments:
|
||||
- String representations of binary and hexadecimal values, e.g. `SELECT toDecimal32('0xc0fe', 1);`.
|
||||
|
||||
:::note
|
||||
An overflow can occur if the value of `expr` exceeds the bounds of `Decimal32`: `( -1 * 10^(9 - S), 1 * 10^(9 - S) )`.
|
||||
Excessive digits in a fraction are discarded (not rounded).
|
||||
An overflow can occur if the value of `expr` exceeds the bounds of `Decimal32`: `( -1 * 10^(9 - S), 1 * 10^(9 - S) )`.
|
||||
Excessive digits in a fraction are discarded (not rounded).
|
||||
Excessive digits in the integer part will lead to an exception.
|
||||
:::
|
||||
|
||||
@ -5261,7 +5261,7 @@ Result:
|
||||
|
||||
## reinterpretAsUInt8
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt8. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt8. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5299,7 +5299,7 @@ Result:
|
||||
|
||||
## reinterpretAsUInt16
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt16. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt16. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5375,7 +5375,7 @@ Result:
|
||||
|
||||
## reinterpretAsUInt64
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt64. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt64. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5413,7 +5413,7 @@ Result:
|
||||
|
||||
## reinterpretAsUInt128
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt128. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type UInt128. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5489,7 +5489,7 @@ Result:
|
||||
|
||||
## reinterpretAsInt8
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int8. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int8. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5565,7 +5565,7 @@ Result:
|
||||
|
||||
## reinterpretAsInt32
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int32. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int32. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5603,7 +5603,7 @@ Result:
|
||||
|
||||
## reinterpretAsInt64
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int64. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int64. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5641,7 +5641,7 @@ Result:
|
||||
|
||||
## reinterpretAsInt128
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int128. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int128. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5679,7 +5679,7 @@ Result:
|
||||
|
||||
## reinterpretAsInt256
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int256. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type Int256. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5717,7 +5717,7 @@ Result:
|
||||
|
||||
## reinterpretAsFloat32
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type Float32. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type Float32. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5751,7 +5751,7 @@ Result:
|
||||
|
||||
## reinterpretAsFloat64
|
||||
|
||||
Performs byte reinterpretation by treating the input value as a value of type Float64. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
Performs byte reinterpretation by treating the input value as a value of type Float64. Unlike [`CAST`](#cast), the function does not attempt to preserve the original value - if the target type is not able to represent the input type, the output is meaningless.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -5804,7 +5804,7 @@ reinterpretAsDate(x)
|
||||
**Implementation details**
|
||||
|
||||
:::note
|
||||
If the provided string isn’t long enough, the function works as if the string is padded with the necessary number of null bytes. If the string is longer than needed, the extra bytes are ignored.
|
||||
If the provided string isn’t long enough, the function works as if the string is padded with the necessary number of null bytes. If the string is longer than needed, the extra bytes are ignored.
|
||||
:::
|
||||
|
||||
**Example**
|
||||
@ -5844,7 +5844,7 @@ reinterpretAsDateTime(x)
|
||||
**Implementation details**
|
||||
|
||||
:::note
|
||||
If the provided string isn’t long enough, the function works as if the string is padded with the necessary number of null bytes. If the string is longer than needed, the extra bytes are ignored.
|
||||
If the provided string isn’t long enough, the function works as if the string is padded with the necessary number of null bytes. If the string is longer than needed, the extra bytes are ignored.
|
||||
:::
|
||||
|
||||
**Example**
|
||||
@ -5886,8 +5886,8 @@ reinterpretAsString(x)
|
||||
Query:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
reinterpretAsString(toDateTime('1970-01-01 01:01:05')),
|
||||
SELECT
|
||||
reinterpretAsString(toDateTime('1970-01-01 01:01:05')),
|
||||
reinterpretAsString(toDate('1970-03-07'));
|
||||
```
|
||||
|
||||
@ -5922,8 +5922,8 @@ reinterpretAsFixedString(x)
|
||||
Query:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
reinterpretAsFixedString(toDateTime('1970-01-01 01:01:05')),
|
||||
SELECT
|
||||
reinterpretAsFixedString(toDateTime('1970-01-01 01:01:05')),
|
||||
reinterpretAsFixedString(toDate('1970-03-07'));
|
||||
```
|
||||
|
||||
@ -6702,7 +6702,7 @@ parseDateTime(str[, format[, timezone]])
|
||||
|
||||
- `str` — The String to be parsed
|
||||
- `format` — The format string. Optional. `%Y-%m-%d %H:%i:%s` if not specified.
|
||||
- `timezone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-timezone). Optional.
|
||||
- `timezone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md#timezone). Optional.
|
||||
|
||||
**Returned value(s)**
|
||||
|
||||
@ -6751,7 +6751,7 @@ parseDateTimeInJodaSyntax(str[, format[, timezone]])
|
||||
|
||||
- `str` — The String to be parsed
|
||||
- `format` — The format string. Optional. `yyyy-MM-dd HH:mm:ss` if not specified.
|
||||
- `timezone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-timezone). Optional.
|
||||
- `timezone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md#timezone). Optional.
|
||||
|
||||
**Returned value(s)**
|
||||
|
||||
@ -6958,7 +6958,7 @@ parseDateTime64BestEffort(time_string [, precision [, time_zone]])
|
||||
|
||||
- `time_string` — String containing a date or date with time to convert. [String](../data-types/string.md).
|
||||
- `precision` — Required precision. `3` — for milliseconds, `6` — for microseconds. Default — `3`. Optional. [UInt8](../data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md#timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -7028,7 +7028,7 @@ toLowCardinality(expr)
|
||||
|
||||
**Returned values**
|
||||
|
||||
- Result of `expr`. [LowCardinality](../data-types/lowcardinality.md) of the type of `expr`.
|
||||
- Result of `expr`. [LowCardinality](../data-types/lowcardinality.md) of the type of `expr`.
|
||||
|
||||
**Example**
|
||||
|
||||
@ -7249,7 +7249,7 @@ Result:
|
||||
|
||||
## fromUnixTimestamp64Nano
|
||||
|
||||
Converts an `Int64` to a `DateTime64` value with fixed nanosecond precision and optional timezone. The input value is scaled up or down appropriately depending on its precision.
|
||||
Converts an `Int64` to a `DateTime64` value with fixed nanosecond precision and optional timezone. The input value is scaled up or down appropriately depending on its precision.
|
||||
|
||||
:::note
|
||||
Please note that input value is treated as a UTC timestamp, not timestamp at the given (or implicit) timezone.
|
||||
|
@ -10,7 +10,7 @@ sidebar_label: UDF
|
||||
## Executable User Defined Functions
|
||||
ClickHouse can call any external executable program or script to process data.
|
||||
|
||||
The configuration of executable user defined functions can be located in one or more xml-files. The path to the configuration is specified in the [user_defined_executable_functions_config](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_defined_executable_functions_config) parameter.
|
||||
The configuration of executable user defined functions can be located in one or more xml-files. The path to the configuration is specified in the [user_defined_executable_functions_config](../../operations/server-configuration-parameters/settings.md#user_defined_executable_functions_config) parameter.
|
||||
|
||||
A function configuration contains the following settings:
|
||||
|
||||
@ -27,7 +27,7 @@ A function configuration contains the following settings:
|
||||
- `command_write_timeout` - timeout for writing data to command stdin in milliseconds. Default value 10000. Optional parameter.
|
||||
- `pool_size` - the size of a command pool. Optional. Default value is `16`.
|
||||
- `send_chunk_header` - controls whether to send row count before sending a chunk of data to process. Optional. Default value is `false`.
|
||||
- `execute_direct` - If `execute_direct` = `1`, then `command` will be searched inside user_scripts folder specified by [user_scripts_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_scripts_path). Additional script arguments can be specified using whitespace separator. Example: `script_name arg1 arg2`. If `execute_direct` = `0`, `command` is passed as argument for `bin/sh -c`. Default value is `1`. Optional parameter.
|
||||
- `execute_direct` - If `execute_direct` = `1`, then `command` will be searched inside user_scripts folder specified by [user_scripts_path](../../operations/server-configuration-parameters/settings.md#user_scripts_path). Additional script arguments can be specified using whitespace separator. Example: `script_name arg1 arg2`. If `execute_direct` = `0`, `command` is passed as argument for `bin/sh -c`. Default value is `1`. Optional parameter.
|
||||
- `lifetime` - the reload interval of a function in seconds. If it is set to `0` then the function is not reloaded. Default value is `0`. Optional parameter.
|
||||
|
||||
The command must read arguments from `STDIN` and must output the result to `STDOUT`. The command must process arguments iteratively. That is after processing a chunk of arguments it must wait for the next chunk.
|
||||
|
@ -61,7 +61,7 @@ ULIDStringToDateTime(ulid[, timezone])
|
||||
**Arguments**
|
||||
|
||||
- `ulid` — Input ULID. [String](../data-types/string.md) or [FixedString(26)](../data-types/fixedstring.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
|
@ -493,7 +493,7 @@ UUIDv7ToDateTime(uuid[, timezone])
|
||||
**Arguments**
|
||||
|
||||
- `uuid` — [UUID](../data-types/uuid.md) of version 7.
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#timezone) for the returned value (optional). [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -637,7 +637,7 @@ snowflakeToDateTime(value[, time_zone])
|
||||
**Arguments**
|
||||
|
||||
- `value` — Snowflake ID. [Int64](../data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md#timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -678,7 +678,7 @@ snowflakeToDateTime64(value[, time_zone])
|
||||
**Arguments**
|
||||
|
||||
- `value` — Snowflake ID. [Int64](../data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md#timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -793,7 +793,7 @@ snowflakeIDToDateTime(value[, epoch[, time_zone]])
|
||||
|
||||
- `value` — Snowflake ID. [UInt64](../data-types/int-uint.md).
|
||||
- `epoch` - Epoch of the Snowflake ID in milliseconds since 1970-01-01. Defaults to 0 (1970-01-01). For the Twitter/X epoch (2015-01-01), provide 1288834974657. Optional. [UInt*](../data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md#timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -829,7 +829,7 @@ snowflakeIDToDateTime64(value[, epoch[, time_zone]])
|
||||
|
||||
- `value` — Snowflake ID. [UInt64](../data-types/int-uint.md).
|
||||
- `epoch` - Epoch of the Snowflake ID in milliseconds since 1970-01-01. Defaults to 0 (1970-01-01). For the Twitter/X epoch (2015-01-01), provide 1288834974657. Optional. [UInt*](../data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md/#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
- `time_zone` — [Timezone](/docs/en/operations/server-configuration-parameters/settings.md#timezone). The function parses `time_string` according to the timezone. Optional. [String](../data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
|
@ -6,7 +6,7 @@ sidebar_label: VIEW
|
||||
|
||||
# CREATE VIEW
|
||||
|
||||
Creates a new view. Views can be [normal](#normal-view), [materialized](#materialized-view), [live](#live-view-deprecated), and [window](#window-view-experimental) (live view and window view are experimental features).
|
||||
Creates a new view. Views can be [normal](#normal-view), [materialized](#materialized-view), [refreshable materialized](#refreshable-materialized-view), and [window](#window-view-experimental) (refreshable materialized view and window view are experimental features).
|
||||
|
||||
## Normal View
|
||||
|
||||
|
@ -15,7 +15,7 @@ Always returns `Ok.` regardless of the result of the internal dictionary update.
|
||||
## RELOAD DICTIONARIES
|
||||
|
||||
Reloads all dictionaries that have been successfully loaded before.
|
||||
By default, dictionaries are loaded lazily (see [dictionaries_lazy_load](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-dictionaries_lazy_load)), so instead of being loaded automatically at startup, they are initialized on first access through dictGet function or SELECT from tables with ENGINE = Dictionary. The `SYSTEM RELOAD DICTIONARIES` query reloads such dictionaries (LOADED).
|
||||
By default, dictionaries are loaded lazily (see [dictionaries_lazy_load](../../operations/server-configuration-parameters/settings.md#dictionaries_lazy_load)), so instead of being loaded automatically at startup, they are initialized on first access through dictGet function or SELECT from tables with ENGINE = Dictionary. The `SYSTEM RELOAD DICTIONARIES` query reloads such dictionaries (LOADED).
|
||||
Always returns `Ok.` regardless of the result of the dictionary update.
|
||||
|
||||
**Syntax**
|
||||
@ -146,7 +146,7 @@ If a tag is specified, only query cache entries with the specified tag are delet
|
||||
|
||||
## DROP FORMAT SCHEMA CACHE {#system-drop-schema-format}
|
||||
|
||||
Clears cache for schemas loaded from [format_schema_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-format_schema_path).
|
||||
Clears cache for schemas loaded from [format_schema_path](../../operations/server-configuration-parameters/settings.md#format_schema_path).
|
||||
|
||||
Supported formats:
|
||||
|
||||
|
@ -18,7 +18,7 @@ file([path_to_archive ::] path [,format] [,structure] [,compression])
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `path` — The relative path to the file from [user_files_path](/docs/en/operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_files_path). Supports in read-only mode the following [globs](#globs-in-path): `*`, `?`, `{abc,def}` (with `'abc'` and `'def'` being strings) and `{N..M}` (with `N` and `M` being numbers).
|
||||
- `path` — The relative path to the file from [user_files_path](/docs/en/operations/server-configuration-parameters/settings.md#user_files_path). Supports in read-only mode the following [globs](#globs-in-path): `*`, `?`, `{abc,def}` (with `'abc'` and `'def'` being strings) and `{N..M}` (with `N` and `M` being numbers).
|
||||
- `path_to_archive` - The relative path to a zip/tar/7z archive. Supports the same globs as `path`.
|
||||
- `format` — The [format](/docs/en/interfaces/formats.md#formats) of the file.
|
||||
- `structure` — Structure of the table. Format: `'column1_name column1_type, column2_name column2_type, ...'`.
|
||||
@ -128,7 +128,7 @@ Reading data from `table.csv`, located in `archive1.zip` or/and `archive2.zip`:
|
||||
SELECT * FROM file('user_files/archives/archive{1..2}.zip :: table.csv');
|
||||
```
|
||||
|
||||
## Globs in path
|
||||
## Globs in path
|
||||
|
||||
Paths may use globbing. Files must match the whole path pattern, not only the suffix or prefix. There is one exception that if the path refers to an existing
|
||||
directory and does not use globs, a `*` will be implicitly added to the path so
|
||||
|
@ -22,7 +22,7 @@ fileCluster(cluster_name, path[, format, structure, compression_method])
|
||||
**Arguments**
|
||||
|
||||
- `cluster_name` — Name of a cluster that is used to build a set of addresses and connection parameters to remote and local servers.
|
||||
- `path` — The relative path to the file from [user_files_path](/docs/en/operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_files_path). Path to file also supports [globs](#globs-in-path).
|
||||
- `path` — The relative path to the file from [user_files_path](/docs/en/operations/server-configuration-parameters/settings.md#user_files_path). Path to file also supports [globs](#globs-in-path).
|
||||
- `format` — [Format](../../interfaces/formats.md#formats) of the files. Type: [String](../../sql-reference/data-types/string.md).
|
||||
- `structure` — Table structure in `'UserID UInt64, Name String'` format. Determines column names and types. Type: [String](../../sql-reference/data-types/string.md).
|
||||
- `compression_method` — Compression method. Supported compression types are `gz`, `br`, `xz`, `zst`, `lz4`, and `bz2`.
|
||||
|
@ -151,3 +151,7 @@ CREATE TABLE pg_table_schema_with_dots (a UInt32)
|
||||
|
||||
- Blog: [ClickHouse and PostgreSQL - a match made in data heaven - part 1](https://clickhouse.com/blog/migrating-data-between-clickhouse-postgres)
|
||||
- Blog: [ClickHouse and PostgreSQL - a Match Made in Data Heaven - part 2](https://clickhouse.com/blog/migrating-data-between-clickhouse-postgres-part-2)
|
||||
|
||||
### Replicating or migrating Postgres data with with PeerDB
|
||||
|
||||
> In addition to table functions, you can always use [PeerDB](https://docs.peerdb.io/introduction) by ClickHouse to set up a continuous data pipeline from Postgres to ClickHouse. PeerDB is a tool designed specifically to replicate data from Postgres to ClickHouse using change data capture (CDC).
|
||||
|
@ -27,7 +27,7 @@ remoteSecure(named_collection[, option=value [,..]])
|
||||
|
||||
The `host` can be specified as a server name, or as a IPv4 or IPv6 address. An IPv6 address must be specified in square brackets.
|
||||
|
||||
The `port` is the TCP port on the remote server. If the port is omitted, it uses [tcp_port](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-tcp_port) from the server config file for table function `remote` (by default, 9000) and [tcp_port_secure](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-tcp_port_secure) for table function `remoteSecure` (by default, 9440).
|
||||
The `port` is the TCP port on the remote server. If the port is omitted, it uses [tcp_port](../../operations/server-configuration-parameters/settings.md#tcp_port) from the server config file for table function `remote` (by default, 9000) and [tcp_port_secure](../../operations/server-configuration-parameters/settings.md#tcp_port_secure) for table function `remoteSecure` (by default, 9440).
|
||||
|
||||
For IPv6 addresses, a port is required.
|
||||
|
||||
|
@ -58,11 +58,11 @@ Count the total amount of rows in all files in the cluster `cluster_simple`:
|
||||
If your listing of files contains number ranges with leading zeros, use the construction with braces for each digit separately or use `?`.
|
||||
:::
|
||||
|
||||
For production use cases it is recommended to use [named collections](/docs/en/operations/named-collections.md). Here is the example:
|
||||
For production use cases, it is recommended to use [named collections](/docs/en/operations/named-collections.md). Here is the example:
|
||||
``` sql
|
||||
|
||||
CREATE NAMED COLLECTION creds AS
|
||||
access_key_id = 'minio'
|
||||
access_key_id = 'minio',
|
||||
secret_access_key = 'minio123';
|
||||
SELECT count(*) FROM s3Cluster(
|
||||
'cluster_simple', creds, url='https://s3-object-url.csv',
|
||||
|
@ -6,7 +6,7 @@ sidebar_label: Date32
|
||||
|
||||
# Date32 {#data_type-datetime32}
|
||||
|
||||
Дата. Поддерживается такой же диапазон дат, как для типа [DateTime64](../../sql-reference/data-types/datetime64.md). Значение хранится в четырех байтах и соответствует числу дней с 1900-01-01 по 2299-12-31.
|
||||
Дата. Поддерживается такой же диапазон дат, как для типа [DateTime64](../../sql-reference/data-types/datetime64.md). Значение хранится в четырех байтах, представляющим дни с 1970-01-01 (0 представляет 1970-01-01, а отрицательные значения представляют дни до 1970).
|
||||
|
||||
**Пример**
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
---
|
||||
slug: /ru/sql-reference/distributed-ddl
|
||||
sidebar_position: 32
|
||||
sidebar_label: "Распределенные DDL запросы"
|
||||
sidebar_label: "Распределенные DDL-запросы"
|
||||
---
|
||||
|
||||
# Распределенные DDL запросы (секция ON CLUSTER) {#raspredelennye-ddl-zaprosy-sektsiia-on-cluster}
|
||||
# Распределенные DDL-запросы (секция ON CLUSTER) {#raspredelennye-ddl-zaprosy-sektsiia-on-cluster}
|
||||
|
||||
Запросы `CREATE`, `DROP`, `ALTER`, `RENAME` поддерживают возможность распределенного выполнения на кластере.
|
||||
Запросы `CREATE`, `DROP`, `ALTER`, `RENAME` поддерживают возможность распределённого выполнения на кластере.
|
||||
Например, следующий запрос создает распределенную (Distributed) таблицу `all_hits` на каждом хосте в `cluster`:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE IF NOT EXISTS all_hits ON CLUSTER cluster (p Date, i Int32) ENGINE = Distributed(cluster, default, hits)
|
||||
```
|
||||
|
||||
Для корректного выполнения таких запросов необходимо на каждом хосте иметь одинаковое определение кластера (для упрощения синхронизации конфигов можете использовать подстановки из ZooKeeper). Также необходимо подключение к ZooKeeper серверам.
|
||||
Локальная версия запроса в конечном итоге будет выполнена на каждом хосте кластера, даже если некоторые хосты в данный момент не доступны. Гарантируется упорядоченность выполнения запросов в рамках одного хоста.
|
||||
Для корректного выполнения таких запросов необходимо на каждом хосте иметь одинаковое определение кластера (для упрощения синхронизации конфигураций можете использовать подстановки из ZooKeeper). Также необходимо подключение к ZooKeeper-серверам.
|
||||
Локальная версия запроса в конечном итоге будет выполнена на каждом хосте кластера, даже если некоторые хосты в данный момент недоступны. Гарантируется упорядоченность выполнения запросов в рамках одного хоста.
|
||||
|
@ -219,8 +219,8 @@ FROM system.numbers LIMIT 5 FORMAT TabSeparated;
|
||||
``` text
|
||||
(0,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(1,'2019-05-20') 1 First First ('First','First')
|
||||
(2,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(3,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
(2,'2019-05-20') 1 Second \N ('Second',NULL)
|
||||
(3,'2019-05-20') 1 Third Third ('Third','Third')
|
||||
(4,'2019-05-20') 0 \N \N (NULL,NULL)
|
||||
```
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <Client/ConnectionEstablisher.h>
|
||||
#include <Common/quoteString.h>
|
||||
#include <Common/ProfileEvents.h>
|
||||
#include <Common/FailPoint.h>
|
||||
#include <Core/Settings.h>
|
||||
|
||||
namespace ProfileEvents
|
||||
@ -27,6 +28,11 @@ namespace ErrorCodes
|
||||
extern const int SOCKET_TIMEOUT;
|
||||
}
|
||||
|
||||
namespace FailPoints
|
||||
{
|
||||
extern const char replicated_merge_tree_all_replicas_stale[];
|
||||
}
|
||||
|
||||
ConnectionEstablisher::ConnectionEstablisher(
|
||||
ConnectionPoolPtr pool_,
|
||||
const ConnectionTimeouts * timeouts_,
|
||||
@ -91,7 +97,15 @@ void ConnectionEstablisher::run(ConnectionEstablisher::TryResult & result, std::
|
||||
|
||||
const UInt32 delay = table_status_it->second.absolute_delay;
|
||||
if (delay < max_allowed_delay)
|
||||
{
|
||||
result.is_up_to_date = true;
|
||||
|
||||
fiu_do_on(FailPoints::replicated_merge_tree_all_replicas_stale,
|
||||
{
|
||||
result.delay = 1;
|
||||
result.is_up_to_date = false;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
result.is_up_to_date = false;
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
/// Temporarily blocks corresponding actions (while the returned object is alive)
|
||||
friend class ActionLock;
|
||||
ActionLock cancel() { return ActionLock(*this); }
|
||||
[[nodiscard]] ActionLock cancel() { return ActionLock(*this); }
|
||||
|
||||
/// Cancel the actions forever.
|
||||
void cancelForever() { ++(*counter); }
|
||||
|
@ -65,6 +65,7 @@ static struct InitFiu
|
||||
PAUSEABLE(infinite_sleep) \
|
||||
PAUSEABLE(stop_moving_part_before_swap_with_active) \
|
||||
REGULAR(slowdown_index_analysis) \
|
||||
REGULAR(replicated_merge_tree_all_replicas_stale) \
|
||||
|
||||
|
||||
namespace FailPoints
|
||||
|
@ -47,6 +47,4 @@ TEST(EventNotifier, SimpleTest)
|
||||
handler13.reset();
|
||||
EventNotifier::instance().notify(Coordination::Error::ZSESSIONEXPIRED);
|
||||
ASSERT_EQ(result, 1);
|
||||
|
||||
EventNotifier::shutdown();
|
||||
}
|
||||
|
@ -173,7 +173,8 @@ namespace DB
|
||||
M(Double, gwp_asan_force_sample_probability, 0.0003, "Probability that an allocation from specific places will be sampled by GWP Asan (i.e. PODArray allocations)", 0) \
|
||||
M(UInt64, config_reload_interval_ms, 2000, "How often clickhouse will reload config and check for new changes", 0) \
|
||||
M(UInt64, memory_worker_period_ms, 0, "Tick period of background memory worker which corrects memory tracker memory usages and cleans up unused pages during higher memory usage. If set to 0, default value will be used depending on the memory usage source", 0) \
|
||||
M(Bool, disable_insertion_and_mutation, false, "Disable all insert/alter/delete queries. This setting will be enabled if someone needs read-only nodes to prevent insertion and mutation affect reading performance.", 0)
|
||||
M(Bool, disable_insertion_and_mutation, false, "Disable all insert/alter/delete queries. This setting will be enabled if someone needs read-only nodes to prevent insertion and mutation affect reading performance.", 0) \
|
||||
M(UInt64, keeper_multiread_batch_size, 10'000, "Maximum size of batch for MultiRead request to [Zoo]Keeper that support batching. If set to 0, batching is disabled. Available only in ClickHouse Cloud.", 0) \
|
||||
|
||||
/// If you add a setting which can be updated at runtime, please update 'changeable_settings' map in StorageSystemServerSettings.cpp
|
||||
|
||||
|
@ -36,14 +36,14 @@ namespace ErrorCodes
|
||||
/** List of settings: type, name, default value, description, flags
|
||||
*
|
||||
* This looks rather inconvenient. It is done that way to avoid repeating settings in different places.
|
||||
* Note: as an alternative, we could implement settings to be completely dynamic in form of map: String -> Field,
|
||||
* but we are not going to do it, because settings is used everywhere as static struct fields.
|
||||
* Note: as an alternative, we could implement settings to be completely dynamic in the form of the map: String -> Field,
|
||||
* but we are not going to do it, because settings are used everywhere as static struct fields.
|
||||
*
|
||||
* `flags` can be either 0 or IMPORTANT.
|
||||
* A setting is "IMPORTANT" if it affects the results of queries and can't be ignored by older versions.
|
||||
*
|
||||
* When adding new or changing existing settings add them to settings changes history in SettingsChangesHistory.h
|
||||
* for tracking settings changes in different versions and for special `compatibility` setting to work correctly.
|
||||
* When adding new or changing existing settings add them to the settings changes history in SettingsChangesHistory.h
|
||||
* for tracking settings changes in different versions and for special `compatibility` settings to work correctly.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
@ -54,18 +54,18 @@ namespace ErrorCodes
|
||||
#else
|
||||
#define COMMON_SETTINGS(M, ALIAS) \
|
||||
M(Dialect, dialect, Dialect::clickhouse, "Which dialect will be used to parse query", 0)\
|
||||
M(UInt64, min_compress_block_size, 65536, "The actual size of the block to compress, if the uncompressed data less than max_compress_block_size is no less than this value and no less than the volume of data for one mark.", 0) \
|
||||
M(UInt64, min_compress_block_size, 65536, "The actual size of the block to compress, if the uncompressed data is less than max_compress_block_size, is no less than this value and no less than the volume of data for one mark.", 0) \
|
||||
M(UInt64, max_compress_block_size, 1048576, "The maximum size of blocks of uncompressed data before compressing for writing to a table.", 0) \
|
||||
M(UInt64, max_block_size, DEFAULT_BLOCK_SIZE, "Maximum block size in rows for reading", 0) \
|
||||
M(UInt64, max_insert_block_size, DEFAULT_INSERT_BLOCK_SIZE, "The maximum block size for insertion, if we control the creation of blocks for insertion.", 0) \
|
||||
M(UInt64, min_insert_block_size_rows, DEFAULT_INSERT_BLOCK_SIZE, "Squash blocks passed to INSERT query to specified size in rows, if blocks are not big enough.", 0) \
|
||||
M(UInt64, min_insert_block_size_bytes, (DEFAULT_INSERT_BLOCK_SIZE * 256), "Squash blocks passed to INSERT query to specified size in bytes, if blocks are not big enough.", 0) \
|
||||
M(UInt64, min_insert_block_size_bytes, (DEFAULT_INSERT_BLOCK_SIZE * 256), "Squash blocks passed to INSERT query to a specified size in bytes if blocks are not big enough.", 0) \
|
||||
M(UInt64, min_insert_block_size_rows_for_materialized_views, 0, "Like min_insert_block_size_rows, but applied only during pushing to MATERIALIZED VIEW (default: min_insert_block_size_rows)", 0) \
|
||||
M(UInt64, min_insert_block_size_bytes_for_materialized_views, 0, "Like min_insert_block_size_bytes, but applied only during pushing to MATERIALIZED VIEW (default: min_insert_block_size_bytes)", 0) \
|
||||
M(UInt64, min_external_table_block_size_rows, DEFAULT_INSERT_BLOCK_SIZE, "Squash blocks passed to external table to specified size in rows, if blocks are not big enough.", 0) \
|
||||
M(UInt64, min_external_table_block_size_bytes, (DEFAULT_INSERT_BLOCK_SIZE * 256), "Squash blocks passed to external table to specified size in bytes, if blocks are not big enough.", 0) \
|
||||
M(UInt64, min_external_table_block_size_bytes, (DEFAULT_INSERT_BLOCK_SIZE * 256), "Squash blocks passed to the external table to a specified size in bytes, if blocks are not big enough.", 0) \
|
||||
M(UInt64, max_joined_block_size_rows, DEFAULT_BLOCK_SIZE, "Maximum block size for JOIN result (if join algorithm supports it). 0 means unlimited.", 0) \
|
||||
M(UInt64, max_insert_threads, 0, "The maximum number of threads to execute the INSERT SELECT query. Values 0 or 1 means that INSERT SELECT is not run in parallel. Higher values will lead to higher memory usage. Parallel INSERT SELECT has effect only if the SELECT part is run on parallel, see 'max_threads' setting.", 0) \
|
||||
M(UInt64, max_insert_threads, 0, "The maximum number of threads to execute the INSERT SELECT query. Values 0 or 1 mean that INSERT SELECT is not run in parallel. Higher values will lead to higher memory usage. Parallel INSERT SELECT has effect only if the SELECT part is run on parallel, see 'max_threads' setting.", 0) \
|
||||
M(UInt64, max_insert_delayed_streams_for_parallel_write, 0, "The maximum number of streams (columns) to delay final part flush. Default - auto (1000 in case of underlying storage supports parallel write, for example S3 and disabled otherwise)", 0) \
|
||||
M(MaxThreads, max_final_threads, 0, "The maximum number of threads to read from table with FINAL.", 0) \
|
||||
M(UInt64, max_threads_for_indexes, 0, "The maximum number of threads process indices.", 0) \
|
||||
@ -84,8 +84,8 @@ namespace ErrorCodes
|
||||
M(Milliseconds, handshake_timeout_ms, 10000, "Timeout for receiving HELLO packet from replicas.", 0) \
|
||||
M(Milliseconds, connect_timeout_with_failover_ms, 1000, "Connection timeout for selecting first healthy replica.", 0) \
|
||||
M(Milliseconds, connect_timeout_with_failover_secure_ms, 1000, "Connection timeout for selecting first healthy replica (for secure connections).", 0) \
|
||||
M(Seconds, receive_timeout, DBMS_DEFAULT_RECEIVE_TIMEOUT_SEC, "Timeout for receiving data from network, in seconds. If no bytes were received in this interval, exception is thrown. If you set this setting on client, the 'send_timeout' for the socket will be also set on the corresponding connection end on the server.", 0) \
|
||||
M(Seconds, send_timeout, DBMS_DEFAULT_SEND_TIMEOUT_SEC, "Timeout for sending data to network, in seconds. If client needs to sent some data, but it did not able to send any bytes in this interval, exception is thrown. If you set this setting on client, the 'receive_timeout' for the socket will be also set on the corresponding connection end on the server.", 0) \
|
||||
M(Seconds, receive_timeout, DBMS_DEFAULT_RECEIVE_TIMEOUT_SEC, "Timeout for receiving data from the network, in seconds. If no bytes were received in this interval, the exception is thrown. If you set this setting on the client, the 'send_timeout' for the socket will also be set on the corresponding connection end on the server.", 0) \
|
||||
M(Seconds, send_timeout, DBMS_DEFAULT_SEND_TIMEOUT_SEC, "Timeout for sending data to the network, in seconds. If a client needs to send some data but is not able to send any bytes in this interval, the exception is thrown. If you set this setting on the client, the 'receive_timeout' for the socket will also be set on the corresponding connection end on the server.", 0) \
|
||||
M(Seconds, tcp_keep_alive_timeout, DEFAULT_TCP_KEEP_ALIVE_TIMEOUT /* less than DBMS_DEFAULT_RECEIVE_TIMEOUT_SEC */, "The time in seconds the connection needs to remain idle before TCP starts sending keepalive probes", 0) \
|
||||
M(Milliseconds, hedged_connection_timeout_ms, 50, "Connection timeout for establishing connection with replica for Hedged requests", 0) \
|
||||
M(Milliseconds, receive_data_timeout_ms, 2000, "Connection timeout for receiving first packet of data or packet with positive progress from replica", 0) \
|
||||
@ -161,7 +161,7 @@ namespace ErrorCodes
|
||||
M(Bool, hdfs_create_new_file_on_insert, false, "Enables or disables creating a new file on each insert in hdfs engine tables", 0) \
|
||||
M(Bool, hdfs_skip_empty_files, false, "Allow to skip empty files in hdfs table engine", 0) \
|
||||
M(Bool, azure_skip_empty_files, false, "Allow to skip empty files in azure table engine", 0) \
|
||||
M(UInt64, hsts_max_age, 0, "Expired time for hsts. 0 means disable HSTS.", 0) \
|
||||
M(UInt64, hsts_max_age, 0, "Expired time for HSTS. 0 means disable HSTS.", 0) \
|
||||
M(Bool, extremes, false, "Calculate minimums and maximums of the result columns. They can be output in JSON-formats.", IMPORTANT) \
|
||||
M(Bool, use_uncompressed_cache, false, "Whether to use the cache of uncompressed blocks.", 0) \
|
||||
M(Bool, replace_running_query, false, "Whether the running request should be canceled with the same id as the new one.", 0) \
|
||||
@ -170,10 +170,10 @@ namespace ErrorCodes
|
||||
M(UInt64, max_local_read_bandwidth, 0, "The maximum speed of local reads in bytes per second.", 0) \
|
||||
M(UInt64, max_local_write_bandwidth, 0, "The maximum speed of local writes in bytes per second.", 0) \
|
||||
M(Bool, stream_like_engine_allow_direct_select, false, "Allow direct SELECT query for Kafka, RabbitMQ, FileLog, Redis Streams, and NATS engines. In case there are attached materialized views, SELECT query is not allowed even if this setting is enabled.", 0) \
|
||||
M(String, stream_like_engine_insert_queue, "", "When stream like engine reads from multiple queues, user will need to select one queue to insert into when writing. Used by Redis Streams and NATS.", 0) \
|
||||
M(String, stream_like_engine_insert_queue, "", "When stream-like engine reads from multiple queues, the user will need to select one queue to insert into when writing. Used by Redis Streams and NATS.", 0) \
|
||||
M(Bool, dictionary_validate_primary_key_type, false, "Validate primary key type for dictionaries. By default id type for simple layouts will be implicitly converted to UInt64.", 0) \
|
||||
M(Bool, distributed_insert_skip_read_only_replicas, false, "If true, INSERT into Distributed will skip read-only replicas.", 0) \
|
||||
M(Bool, distributed_foreground_insert, false, "If setting is enabled, insert query into distributed waits until data are sent to all nodes in a cluster. \n\nEnables or disables synchronous data insertion into a `Distributed` table.\n\nBy default, when inserting data into a Distributed table, the ClickHouse server sends data to cluster nodes in the background. When `distributed_foreground_insert` = 1, the data is processed synchronously, and the `INSERT` operation succeeds only after all the data is saved on all shards (at least one replica for each shard if `internal_replication` is true).", 0) ALIAS(insert_distributed_sync) \
|
||||
M(Bool, distributed_foreground_insert, false, "If the setting is enabled, insert query into distributed waits until data are sent to all nodes in a cluster. \n\nEnables or disables synchronous data insertion into a `Distributed` table.\n\nBy default, when inserting data into a Distributed table, the ClickHouse server sends data to cluster nodes in the background. When `distributed_foreground_insert` = 1, the data is processed synchronously, and the `INSERT` operation succeeds only after all the data is saved on all shards (at least one replica for each shard if `internal_replication` is true).", 0) ALIAS(insert_distributed_sync) \
|
||||
M(UInt64, distributed_background_insert_timeout, 0, "Timeout for insert query into distributed. Setting is used only with insert_distributed_sync enabled. Zero value means no timeout.", 0) ALIAS(insert_distributed_timeout) \
|
||||
M(Milliseconds, distributed_background_insert_sleep_time_ms, 100, "Sleep time for background INSERTs into Distributed, in case of any errors delay grows exponentially.", 0) ALIAS(distributed_directory_monitor_sleep_time_ms) \
|
||||
M(Milliseconds, distributed_background_insert_max_sleep_time_ms, 30000, "Maximum sleep time for background INSERTs into Distributed, it limits exponential growth too.", 0) ALIAS(distributed_directory_monitor_max_sleep_time_ms) \
|
||||
@ -182,7 +182,7 @@ namespace ErrorCodes
|
||||
M(Bool, distributed_background_insert_split_batch_on_failure, false, "Should batches of the background INSERT into Distributed be split into smaller batches in case of failures.", 0) ALIAS(distributed_directory_monitor_split_batch_on_failure) \
|
||||
\
|
||||
M(Bool, optimize_move_to_prewhere, true, "Allows disabling WHERE to PREWHERE optimization in SELECT queries from MergeTree.", 0) \
|
||||
M(Bool, optimize_move_to_prewhere_if_final, false, "If query has `FINAL`, the optimization `move_to_prewhere` is not always correct and it is enabled only if both settings `optimize_move_to_prewhere` and `optimize_move_to_prewhere_if_final` are turned on", 0) \
|
||||
M(Bool, optimize_move_to_prewhere_if_final, false, "If the query has `FINAL`, the optimization `move_to_prewhere` is not always correct and it is enabled only if both settings `optimize_move_to_prewhere` and `optimize_move_to_prewhere_if_final` are turned on", 0) \
|
||||
M(Bool, move_all_conditions_to_prewhere, true, "Move all viable conditions from WHERE to PREWHERE", 0) \
|
||||
M(Bool, enable_multiple_prewhere_read_steps, true, "Move more conditions from WHERE to PREWHERE and do reads from disk and filtering in multiple steps if there are multiple conditions combined with AND", 0) \
|
||||
M(Bool, move_primary_key_columns_to_end_of_prewhere, true, "Move PREWHERE conditions containing primary key columns to the end of AND chain. It is likely that these conditions are taken into account during primary key analysis and thus will not contribute a lot to PREWHERE filtering.", 0) \
|
||||
@ -198,7 +198,7 @@ namespace ErrorCodes
|
||||
M(Float, totals_auto_threshold, 0.5, "The threshold for totals_mode = 'auto'.", 0) \
|
||||
\
|
||||
M(Bool, allow_suspicious_low_cardinality_types, false, "In CREATE TABLE statement allows specifying LowCardinality modifier for types of small fixed size (8 or less). Enabling this may increase merge times and memory consumption.", 0) \
|
||||
M(Bool, allow_suspicious_fixed_string_types, false, "In CREATE TABLE statement allows creating columns of type FixedString(n) with n > 256. FixedString with length >= 256 is suspicious and most likely indicates misuse", 0) \
|
||||
M(Bool, allow_suspicious_fixed_string_types, false, "In CREATE TABLE statement allows creating columns of type FixedString(n) with n > 256. FixedString with length >= 256 is suspicious and most likely indicates a misuse", 0) \
|
||||
M(Bool, allow_suspicious_indices, false, "Reject primary/secondary indexes and sorting keys with identical expressions", 0) \
|
||||
M(Bool, allow_suspicious_ttl_expressions, false, "Reject TTL expressions that don't depend on any of table's columns. It indicates a user error most of the time.", 0) \
|
||||
M(Bool, allow_suspicious_variant_types, false, "In CREATE TABLE statement allows specifying Variant type with similar variant types (for example, with different numeric or date types). Enabling this setting may introduce some ambiguity when working with values with similar types.", 0) \
|
||||
@ -263,7 +263,7 @@ namespace ErrorCodes
|
||||
\
|
||||
M(UInt64, min_bytes_to_use_direct_io, 0, "The minimum number of bytes for reading the data with O_DIRECT option during SELECT queries execution. 0 - disabled.", 0) \
|
||||
M(UInt64, min_bytes_to_use_mmap_io, 0, "The minimum number of bytes for reading the data with mmap option during SELECT queries execution. 0 - disabled.", 0) \
|
||||
M(Bool, checksum_on_read, true, "Validate checksums on reading. It is enabled by default and should be always enabled in production. Please do not expect any benefits in disabling this setting. It may only be used for experiments and benchmarks. The setting only applicable for tables of MergeTree family. Checksums are always validated for other table engines and when receiving data over network.", 0) \
|
||||
M(Bool, checksum_on_read, true, "Validate checksums on reading. It is enabled by default and should be always enabled in production. Please do not expect any benefits in disabling this setting. It may only be used for experiments and benchmarks. The setting is only applicable for tables of MergeTree family. Checksums are always validated for other table engines and when receiving data over the network.", 0) \
|
||||
\
|
||||
M(Bool, force_index_by_date, false, "Throw an exception if there is a partition key in a table, and it is not used.", 0) \
|
||||
M(Bool, force_primary_key, false, "Throw an exception if there is primary key in a table, and it is not used.", 0) \
|
||||
@ -275,8 +275,8 @@ namespace ErrorCodes
|
||||
\
|
||||
M(String, force_data_skipping_indices, "", "Comma separated list of strings or literals with the name of the data skipping indices that should be used during query execution, otherwise an exception will be thrown.", 0) \
|
||||
\
|
||||
M(Float, max_streams_to_max_threads_ratio, 1, "Allows you to use more sources than the number of threads - to more evenly distribute work across threads. It is assumed that this is a temporary solution, since it will be possible in the future to make the number of sources equal to the number of threads, but for each source to dynamically select available work for itself.", 0) \
|
||||
M(Float, max_streams_multiplier_for_merge_tables, 5, "Ask more streams when reading from Merge table. Streams will be spread across tables that Merge table will use. This allows more even distribution of work across threads and especially helpful when merged tables differ in size.", 0) \
|
||||
M(Float, max_streams_to_max_threads_ratio, 1, "Allows you to use more sources than the number of threads - to more evenly distribute work across threads. It is assumed that this is a temporary solution since it will be possible in the future to make the number of sources equal to the number of threads, but for each source to dynamically select available work for itself.", 0) \
|
||||
M(Float, max_streams_multiplier_for_merge_tables, 5, "Ask more streams when reading from Merge table. Streams will be spread across tables that Merge table will use. This allows more even distribution of work across threads and is especially helpful when merged tables differ in size.", 0) \
|
||||
\
|
||||
M(String, network_compression_method, "LZ4", "Allows you to select the method of data compression when writing.", 0) \
|
||||
\
|
||||
@ -291,7 +291,7 @@ namespace ErrorCodes
|
||||
M(Bool, log_formatted_queries, false, "Log formatted queries and write the log to the system table.", 0) \
|
||||
M(LogQueriesType, log_queries_min_type, QueryLogElementType::QUERY_START, "Minimal type in query_log to log, possible values (from low to high): QUERY_START, QUERY_FINISH, EXCEPTION_BEFORE_START, EXCEPTION_WHILE_PROCESSING.", 0) \
|
||||
M(Milliseconds, log_queries_min_query_duration_ms, 0, "Minimal time for the query to run, to get to the query_log/query_thread_log/query_views_log.", 0) \
|
||||
M(UInt64, log_queries_cut_to_length, 100000, "If query length is greater than specified threshold (in bytes), then cut query when writing to query log. Also limit length of printed query in ordinary text log.", 0) \
|
||||
M(UInt64, log_queries_cut_to_length, 100000, "If query length is greater than a specified threshold (in bytes), then cut query when writing to query log. Also limit the length of printed query in ordinary text log.", 0) \
|
||||
M(Float, log_queries_probability, 1., "Log queries with the specified probability.", 0) \
|
||||
\
|
||||
M(Bool, log_processors_profiles, true, "Log Processors profile events.", 0) \
|
||||
@ -304,7 +304,7 @@ namespace ErrorCodes
|
||||
M(Bool, async_insert_deduplicate, false, "For async INSERT queries in the replicated table, specifies that deduplication of inserting blocks should be performed", 0) \
|
||||
\
|
||||
M(UInt64Auto, insert_quorum, 0, "For INSERT queries in the replicated table, wait writing for the specified number of replicas and linearize the addition of the data. 0 - disabled, 'auto' - use majority", 0) \
|
||||
M(Milliseconds, insert_quorum_timeout, 600000, "If the quorum of replicas did not meet in specified time (in milliseconds), exception will be thrown and insertion is aborted.", 0) \
|
||||
M(Milliseconds, insert_quorum_timeout, 600000, "If the quorum of replicas did not meet in a specified time (in milliseconds), an exception will be thrown and insertion is aborted.", 0) \
|
||||
M(Bool, insert_quorum_parallel, true, "For quorum INSERT queries - enable to make parallel inserts without linearizability", 0) \
|
||||
M(UInt64, select_sequential_consistency, 0, "For SELECT queries from the replicated table, throw an exception if the replica does not have a chunk written with the quorum; do not read the parts that have not yet been written with the quorum.", 0) \
|
||||
M(UInt64, table_function_remote_max_addresses, 1000, "The maximum number of different shards and the maximum number of replicas of one shard in the `remote` function.", 0) \
|
||||
@ -323,11 +323,11 @@ namespace ErrorCodes
|
||||
\
|
||||
M(Bool, http_native_compression_disable_checksumming_on_decompress, false, "If you uncompress the POST data from the client compressed by the native format, do not check the checksum.", 0) \
|
||||
\
|
||||
M(String, count_distinct_implementation, "uniqExact", "What aggregate function to use for implementation of count(DISTINCT ...)", 0) \
|
||||
M(String, count_distinct_implementation, "uniqExact", "What aggregate function to use for the implementation of count(DISTINCT ...)", 0) \
|
||||
\
|
||||
M(Bool, add_http_cors_header, false, "Write add http CORS header.", 0) \
|
||||
\
|
||||
M(UInt64, max_http_get_redirects, 0, "Max number of http GET redirects hops allowed. Ensures additional security measures are in place to prevent a malicious server to redirect your requests to unexpected services.\n\nIt is the case when an external server redirects to another address, but that address appears to be internal to the company's infrastructure, and by sending an HTTP request to an internal server, you could request an internal API from the internal network, bypassing the auth, or even query other services, such as Redis or Memcached. When you don't have an internal infrastructure (including something running on your localhost), or you trust the server, it is safe to allow redirects. Although keep in mind, that if the URL uses HTTP instead of HTTPS, and you will have to trust not only the remote server but also your ISP and every network in the middle.", 0) \
|
||||
M(UInt64, max_http_get_redirects, 0, "Max number of HTTP GET redirects hops allowed. Ensures additional security measures are in place to prevent a malicious server from redirecting your requests to unexpected services.\n\nIt is the case when an external server redirects to another address, but that address appears to be internal to the company's infrastructure, and by sending an HTTP request to an internal server, you could request an internal API from the internal network, bypassing the auth, or even query other services, such as Redis or Memcached. When you don't have an internal infrastructure (including something running on your localhost), or you trust the server, it is safe to allow redirects. Although keep in mind, that if the URL uses HTTP instead of HTTPS, and you will have to trust not only the remote server but also your ISP and every network in the middle.", 0) \
|
||||
\
|
||||
M(Bool, use_client_time_zone, false, "Use client timezone for interpreting DateTime string values, instead of adopting server timezone.", 0) \
|
||||
\
|
||||
@ -338,16 +338,16 @@ namespace ErrorCodes
|
||||
M(Bool, http_write_exception_in_output_format, true, "Write exception in output format to produce valid output. Works with JSON and XML formats.", 0) \
|
||||
M(UInt64, http_response_buffer_size, 0, "The number of bytes to buffer in the server memory before sending a HTTP response to the client or flushing to disk (when http_wait_end_of_query is enabled).", 0) \
|
||||
\
|
||||
M(Bool, fsync_metadata, true, "Do fsync after changing metadata for tables and databases (.sql files). Could be disabled in case of poor latency on server with high load of DDL queries and high load of disk subsystem.", 0) \
|
||||
M(Bool, fsync_metadata, true, "Do fsync after changing the metadata for tables and databases (.sql files). Could be disabled in case of poor latency on a server with high load of DDL queries and high load of the disk subsystem.", 0) \
|
||||
\
|
||||
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(Int32, join_output_by_rowlist_perkey_rows_threshold, 5, "The lower limit of per-key average rows in the right table to determine whether to output by row list in hash join.", 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(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 an 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(Bool, single_join_prefer_left_table, true, "For single JOIN in case of identifier ambiguity prefer left table", IMPORTANT) \
|
||||
\
|
||||
M(UInt64, preferred_block_size_bytes, 1000000, "This setting adjusts the data block size for query processing and represents additional fine tune to the more rough 'max_block_size' setting. If the columns are large and with 'max_block_size' rows the block size is likely to be larger than the specified amount of bytes, its size will be lowered for better CPU cache locality.", 0) \
|
||||
M(UInt64, preferred_block_size_bytes, 1000000, "This setting adjusts the data block size for query processing and represents additional fine-tuning to the more rough 'max_block_size' setting. If the columns are large and with 'max_block_size' rows the block size is likely to be larger than the specified amount of bytes, its size will be lowered for better CPU cache locality.", 0) \
|
||||
\
|
||||
M(UInt64, max_replica_delay_for_distributed_queries, 300, "If set, distributed queries of Replicated tables will choose servers with replication delay in seconds less than the specified value (not inclusive). Zero means do not take delay into account.", 0) \
|
||||
M(Bool, fallback_to_stale_replicas_for_distributed_queries, true, "Suppose max_replica_delay_for_distributed_queries is set and all replicas for the queried table are stale. If this setting is enabled, the query will be performed anyway, otherwise the error will be reported.", 0) \
|
||||
@ -357,11 +357,11 @@ namespace ErrorCodes
|
||||
M(UInt64, parts_to_throw_insert, 0, "If more than this number active parts in a single partition of the destination table, throw 'Too many parts ...' exception.", 0) \
|
||||
M(UInt64, number_of_mutations_to_delay, 0, "If the mutated table contains at least that many unfinished mutations, artificially slow down mutations of table. 0 - disabled", 0) \
|
||||
M(UInt64, number_of_mutations_to_throw, 0, "If the mutated table contains at least that many unfinished mutations, throw 'Too many mutations ...' exception. 0 - disabled", 0) \
|
||||
M(Int64, distributed_ddl_task_timeout, 180, "Timeout for DDL query responses from all hosts in cluster. If a ddl request has not been performed on all hosts, a response will contain a timeout error and a request will be executed in an async mode. Negative value means infinite. Zero means async mode.", 0) \
|
||||
M(Int64, distributed_ddl_task_timeout, 180, "Timeout for DDL query responses from all hosts in the cluster. If a ddl request has not been performed on all hosts, a response will contain a timeout error and a request will be executed in an async mode. A negative value means infinite. Zero means async mode.", 0) \
|
||||
M(Milliseconds, stream_flush_interval_ms, 7500, "Timeout for flushing data from streaming storages.", 0) \
|
||||
M(Milliseconds, stream_poll_timeout_ms, 500, "Timeout for polling data from/to streaming storages.", 0) \
|
||||
\
|
||||
M(Bool, final, false, "Query with the FINAL modifier by default. If the engine does not support final, it does not have any effect. On queries with multiple tables final is applied only on those that support it. It also works on distributed tables", 0) \
|
||||
M(Bool, final, false, "Query with the FINAL modifier by default. If the engine does not support the FINAL, it does not have any effect. On queries with multiple tables, FINAL is applied only to those that support it. It also works on distributed tables", 0) \
|
||||
\
|
||||
M(Bool, partial_result_on_first_cancel, false, "Allows query to return a partial result after cancel.", 0) \
|
||||
\
|
||||
@ -386,7 +386,7 @@ namespace ErrorCodes
|
||||
M(Bool, http_make_head_request, true, "Allows the execution of a `HEAD` request while reading data from HTTP to retrieve information about the file to be read, such as its size", 0) \
|
||||
M(Bool, optimize_throw_if_noop, false, "If setting is enabled and OPTIMIZE query didn't actually assign a merge then an explanatory exception is thrown", 0) \
|
||||
M(Bool, use_index_for_in_with_subqueries, true, "Try using an index if there is a subquery or a table expression on the right side of the IN operator.", 0) \
|
||||
M(UInt64, use_index_for_in_with_subqueries_max_values, 0, "The maximum size of set in the right hand side of the IN operator to use table index for filtering. It allows to avoid performance degradation and higher memory usage due to preparation of additional data structures for large queries. Zero means no limit.", 0) \
|
||||
M(UInt64, use_index_for_in_with_subqueries_max_values, 0, "The maximum size of the set in the right-hand side of the IN operator to use table index for filtering. It allows to avoid performance degradation and higher memory usage due to the preparation of additional data structures for large queries. Zero means no limit.", 0) \
|
||||
M(Bool, analyze_index_with_space_filling_curves, true, "If a table has a space-filling curve in its index, e.g. `ORDER BY mortonEncode(x, y)`, and the query has conditions on its arguments, e.g. `x >= 10 AND x <= 20 AND y >= 20 AND y <= 30`, use the space-filling curve for index analysis.", 0) \
|
||||
M(Bool, joined_subquery_requires_alias, true, "Force joined subqueries and table functions to have aliases for correct name qualification.", 0) \
|
||||
M(Bool, empty_result_for_aggregation_by_empty_set, false, "Return empty result when aggregating without keys on empty set.", 0) \
|
||||
@ -395,8 +395,8 @@ namespace ErrorCodes
|
||||
M(Bool, allow_suspicious_codecs, false, "If it is set to true, allow to specify meaningless compression codecs.", 0) \
|
||||
M(Bool, enable_deflate_qpl_codec, false, "Enable/disable the DEFLATE_QPL codec.", 0) \
|
||||
M(Bool, enable_zstd_qat_codec, false, "Enable/disable the ZSTD_QAT codec.", 0) \
|
||||
M(UInt64, query_profiler_real_time_period_ns, QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off the real clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \
|
||||
M(UInt64, query_profiler_cpu_time_period_ns, QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off the CPU clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \
|
||||
M(UInt64, query_profiler_real_time_period_ns, QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off the real clock query profiler. The recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \
|
||||
M(UInt64, query_profiler_cpu_time_period_ns, QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off the CPU clock query profiler. The recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \
|
||||
M(Bool, metrics_perf_events_enabled, false, "If enabled, some of the perf events will be measured throughout queries' execution.", 0) \
|
||||
M(String, metrics_perf_events_list, "", "Comma separated list of perf metrics that will be measured throughout queries' execution. Empty means all events. See PerfEventInfo in sources for the available events.", 0) \
|
||||
M(Float, opentelemetry_start_trace_probability, 0., "Probability to start an OpenTelemetry trace for an incoming query.", 0) \
|
||||
@ -424,13 +424,13 @@ namespace ErrorCodes
|
||||
\
|
||||
M(UInt64, max_rows_to_group_by, 0, "If aggregation during GROUP BY is generating more than the specified number of rows (unique GROUP BY keys), the behavior will be determined by the 'group_by_overflow_mode' which by default is - throw an exception, but can be also switched to an approximate GROUP BY mode.", 0) \
|
||||
M(OverflowModeGroupBy, group_by_overflow_mode, OverflowMode::THROW, "What to do when the limit is exceeded.", 0) \
|
||||
M(UInt64, max_bytes_before_external_group_by, 0, "If memory usage during GROUP BY operation is exceeding this threshold in bytes, activate the 'external aggregation' mode (spill data to disk). Recommended value is half of available system memory.", 0) \
|
||||
M(UInt64, max_bytes_before_external_group_by, 0, "If memory usage during GROUP BY operation is exceeding this threshold in bytes, activate the 'external aggregation' mode (spill data to disk). Recommended value is half of the available system memory.", 0) \
|
||||
\
|
||||
M(UInt64, max_rows_to_sort, 0, "If more than the specified amount of records have to be processed for ORDER BY operation, the behavior will be determined by the 'sort_overflow_mode' which by default is - throw an exception", 0) \
|
||||
M(UInt64, max_bytes_to_sort, 0, "If more than the specified amount of (uncompressed) bytes have to be processed for ORDER BY operation, the behavior will be determined by the 'sort_overflow_mode' which by default is - throw an exception", 0) \
|
||||
M(OverflowMode, sort_overflow_mode, OverflowMode::THROW, "What to do when the limit is exceeded.", 0) \
|
||||
M(UInt64, prefer_external_sort_block_bytes, DEFAULT_BLOCK_SIZE * 256, "Prefer maximum block bytes for external sort, reduce the memory usage during merging.", 0) \
|
||||
M(UInt64, max_bytes_before_external_sort, 0, "If memory usage during ORDER BY operation is exceeding this threshold in bytes, activate the 'external sorting' mode (spill data to disk). Recommended value is half of available system memory.", 0) \
|
||||
M(UInt64, max_bytes_before_external_sort, 0, "If memory usage during ORDER BY operation is exceeding this threshold in bytes, activate the 'external sorting' mode (spill data to disk). Recommended value is half of the available system memory.", 0) \
|
||||
M(UInt64, max_bytes_before_remerge_sort, 1000000000, "In case of ORDER BY with LIMIT, when memory usage is higher than specified threshold, perform additional steps of merging blocks before final merge to keep just top LIMIT rows.", 0) \
|
||||
M(Float, remerge_sort_lowered_memory_bytes_ratio, 2., "If memory usage after remerge does not reduced by this ratio, remerge will be disabled.", 0) \
|
||||
\
|
||||
@ -439,7 +439,7 @@ namespace ErrorCodes
|
||||
M(OverflowMode, result_overflow_mode, OverflowMode::THROW, "What to do when the limit is exceeded.", 0) \
|
||||
\
|
||||
/* TODO: Check also when merging and finalizing aggregate functions. */ \
|
||||
M(Seconds, max_execution_time, 0, "If query runtime exceeds the specified number of seconds, the behavior will be determined by the 'timeout_overflow_mode', which by default is - throw an exception. Note that the timeout is checked and query can stop only in designated places during data processing. It currently cannot stop during merging of aggregation states or during query analysis, and the actual run time will be higher than the value of this setting.", 0) \
|
||||
M(Seconds, max_execution_time, 0, "If query runtime exceeds the specified number of seconds, the behavior will be determined by the 'timeout_overflow_mode', which by default is - throw an exception. Note that the timeout is checked and the query can stop only in designated places during data processing. It currently cannot stop during merging of aggregation states or during query analysis, and the actual run time will be higher than the value of this setting.", 0) \
|
||||
M(OverflowMode, timeout_overflow_mode, OverflowMode::THROW, "What to do when the limit is exceeded.", 0) \
|
||||
M(Seconds, max_execution_time_leaf, 0, "Similar semantic to max_execution_time but only apply on leaf node for distributed queries, the time out behavior will be determined by 'timeout_overflow_mode_leaf' which by default is - throw an exception", 0) \
|
||||
M(OverflowMode, timeout_overflow_mode_leaf, OverflowMode::THROW, "What to do when the leaf limit is exceeded.", 0) \
|
||||
@ -452,8 +452,8 @@ namespace ErrorCodes
|
||||
M(Seconds, max_estimated_execution_time, 0, "Maximum query estimate execution time in seconds.", 0) \
|
||||
\
|
||||
M(UInt64, max_columns_to_read, 0, "If a query requires reading more than specified number of columns, exception is thrown. Zero value means unlimited. This setting is useful to prevent too complex queries.", 0) \
|
||||
M(UInt64, max_temporary_columns, 0, "If a query generates more than the specified number of temporary columns in memory as a result of intermediate calculation, exception is thrown. Zero value means unlimited. This setting is useful to prevent too complex queries.", 0) \
|
||||
M(UInt64, max_temporary_non_const_columns, 0, "Similar to the 'max_temporary_columns' setting but applies only to non-constant columns. This makes sense, because constant columns are cheap and it is reasonable to allow more of them.", 0) \
|
||||
M(UInt64, max_temporary_columns, 0, "If a query generates more than the specified number of temporary columns in memory as a result of intermediate calculation, the exception is thrown. Zero value means unlimited. This setting is useful to prevent too complex queries.", 0) \
|
||||
M(UInt64, max_temporary_non_const_columns, 0, "Similar to the 'max_temporary_columns' setting but applies only to non-constant columns. This makes sense because constant columns are cheap and it is reasonable to allow more of them.", 0) \
|
||||
\
|
||||
M(UInt64, max_sessions_for_user, 0, "Maximum number of simultaneous sessions for a user.", 0) \
|
||||
\
|
||||
@ -491,18 +491,18 @@ namespace ErrorCodes
|
||||
M(OverflowMode, transfer_overflow_mode, OverflowMode::THROW, "What to do when the limit is exceeded.", 0) \
|
||||
\
|
||||
M(UInt64, max_rows_in_distinct, 0, "Maximum number of elements during execution of DISTINCT.", 0) \
|
||||
M(UInt64, max_bytes_in_distinct, 0, "Maximum total size of state (in uncompressed bytes) in memory for the execution of DISTINCT.", 0) \
|
||||
M(UInt64, max_bytes_in_distinct, 0, "Maximum total size of the state (in uncompressed bytes) in memory for the execution of DISTINCT.", 0) \
|
||||
M(OverflowMode, distinct_overflow_mode, OverflowMode::THROW, "What to do when the limit is exceeded.", 0) \
|
||||
\
|
||||
M(UInt64, max_memory_usage, 0, "Maximum memory usage for processing of single query. Zero means unlimited.", 0) \
|
||||
M(UInt64, memory_overcommit_ratio_denominator, 1_GiB, "It represents soft memory limit on the user level. This value is used to compute query overcommit ratio.", 0) \
|
||||
M(UInt64, max_memory_usage_for_user, 0, "Maximum memory usage for processing all concurrently running queries for the user. Zero means unlimited.", 0) \
|
||||
M(UInt64, memory_overcommit_ratio_denominator_for_user, 1_GiB, "It represents soft memory limit on the global level. This value is used to compute query overcommit ratio.", 0) \
|
||||
M(UInt64, max_untracked_memory, (4 * 1024 * 1024), "Small allocations and deallocations are grouped in thread local variable and tracked or profiled only when amount (in absolute value) becomes larger than specified value. If the value is higher than 'memory_profiler_step' it will be effectively lowered to 'memory_profiler_step'.", 0) \
|
||||
M(UInt64, memory_profiler_step, (4 * 1024 * 1024), "Whenever query memory usage becomes larger than every next step in number of bytes the memory profiler will collect the allocating stack trace. Zero means disabled memory profiler. Values lower than a few megabytes will slow down query processing.", 0) \
|
||||
M(Float, memory_profiler_sample_probability, 0., "Collect random allocations and deallocations and write them into system.trace_log with 'MemorySample' trace_type. The probability is for every alloc/free regardless to the size of the allocation (can be changed with `memory_profiler_sample_min_allocation_size` and `memory_profiler_sample_max_allocation_size`). Note that sampling happens only when the amount of untracked memory exceeds 'max_untracked_memory'. You may want to set 'max_untracked_memory' to 0 for extra fine grained sampling.", 0) \
|
||||
M(UInt64, memory_profiler_sample_min_allocation_size, 0, "Collect random allocations of size greater or equal than specified value with probability equal to `memory_profiler_sample_probability`. 0 means disabled. You may want to set 'max_untracked_memory' to 0 to make this threshold to work as expected.", 0) \
|
||||
M(UInt64, memory_profiler_sample_max_allocation_size, 0, "Collect random allocations of size less or equal than specified value with probability equal to `memory_profiler_sample_probability`. 0 means disabled. You may want to set 'max_untracked_memory' to 0 to make this threshold to work as expected.", 0) \
|
||||
M(UInt64, max_untracked_memory, (4 * 1024 * 1024), "Small allocations and deallocations are grouped in thread local variable and tracked or profiled only when an amount (in absolute value) becomes larger than the specified value. If the value is higher than 'memory_profiler_step' it will be effectively lowered to 'memory_profiler_step'.", 0) \
|
||||
M(UInt64, memory_profiler_step, (4 * 1024 * 1024), "Whenever query memory usage becomes larger than every next step in a number of bytes the memory profiler will collect the allocating stack trace. Zero means disabled memory profiler. Values lower than a few megabytes will slow down query processing.", 0) \
|
||||
M(Float, memory_profiler_sample_probability, 0., "Collect random allocations and deallocations and write them into system.trace_log with 'MemorySample' trace_type. The probability is for every alloc/free regardless of the size of the allocation (can be changed with `memory_profiler_sample_min_allocation_size` and `memory_profiler_sample_max_allocation_size`). Note that sampling happens only when the amount of untracked memory exceeds 'max_untracked_memory'. You may want to set 'max_untracked_memory' to 0 for extra fine-grained sampling.", 0) \
|
||||
M(UInt64, memory_profiler_sample_min_allocation_size, 0, "Collect random allocations of size greater or equal than the specified value with probability equal to `memory_profiler_sample_probability`. 0 means disabled. You may want to set 'max_untracked_memory' to 0 to make this threshold work as expected.", 0) \
|
||||
M(UInt64, memory_profiler_sample_max_allocation_size, 0, "Collect random allocations of size less or equal than the specified value with probability equal to `memory_profiler_sample_probability`. 0 means disabled. You may want to set 'max_untracked_memory' to 0 to make this threshold work as expected.", 0) \
|
||||
M(Bool, trace_profile_events, false, "Send to system.trace_log profile event and value of increment on each increment with 'ProfileEvent' trace_type", 0) \
|
||||
\
|
||||
M(UInt64, memory_usage_overcommit_max_wait_microseconds, 5'000'000, "Maximum time thread will wait for memory to be freed in the case of memory overcommit. If timeout is reached and memory is not freed, exception is thrown.", 0) \
|
||||
@ -530,7 +530,7 @@ namespace ErrorCodes
|
||||
M(Bool, log_query_settings, true, "Log query settings into the query_log.", 0) \
|
||||
M(Bool, log_query_threads, false, "Log query threads into system.query_thread_log table. This setting have effect only when 'log_queries' is true.", 0) \
|
||||
M(Bool, log_query_views, true, "Log query dependent views into system.query_views_log table. This setting have effect only when 'log_queries' is true.", 0) \
|
||||
M(String, log_comment, "", "Log comment into system.query_log table and server log. It can be set to arbitrary string no longer than max_query_size.", 0) \
|
||||
M(String, log_comment, "", "Log comment into the system.query_log table and server log. It can be set to arbitrary string no longer than max_query_size.", 0) \
|
||||
M(LogsLevel, send_logs_level, LogsLevel::fatal, "Send server text logs with specified minimum level to client. Valid values: 'trace', 'debug', 'information', 'warning', 'error', 'fatal', 'none'", 0) \
|
||||
M(String, send_logs_source_regexp, "", "Send server text logs with specified regexp to match log source name. Empty means all sources.", 0) \
|
||||
M(Bool, enable_optimize_predicate_expression, true, "If it is set to true, optimize predicates to subqueries.", 0) \
|
||||
@ -542,10 +542,10 @@ namespace ErrorCodes
|
||||
M(Bool, decimal_check_overflow, true, "Check overflow of decimal arithmetic/comparison operations", 0) \
|
||||
M(Bool, allow_custom_error_code_in_throwif, false, "Enable custom error code in function throwIf(). If true, thrown exceptions may have unexpected error codes.", 0) \
|
||||
\
|
||||
M(Bool, prefer_localhost_replica, true, "If it's true then queries will be always sent to local replica (if it exists). If it's false then replica to send a query will be chosen between local and remote ones according to load_balancing", 0) \
|
||||
M(Bool, prefer_localhost_replica, true, "If it's true then queries will be always sent to the local replica (if it exists). If it's false then the replica to send a query will be chosen between local and remote ones according to load_balancing", 0) \
|
||||
M(UInt64, max_fetch_partition_retries_count, 5, "Amount of retries while fetching partition from another host.", 0) \
|
||||
M(UInt64, http_max_multipart_form_data_size, 1024 * 1024 * 1024, "Limit on size of multipart/form-data content. This setting cannot be parsed from URL parameters and should be set in user profile. Note that content is parsed and external tables are created in memory before start of query execution. And this is the only limit that has effect on that stage (limits on max memory usage and max execution time have no effect while reading HTTP form data).", 0) \
|
||||
M(Bool, calculate_text_stack_trace, true, "Calculate text stack trace in case of exceptions during query execution. This is the default. It requires symbol lookups that may slow down fuzzing tests when huge amount of wrong queries are executed. In normal cases you should not disable this option.", 0) \
|
||||
M(UInt64, http_max_multipart_form_data_size, 1024 * 1024 * 1024, "Limit on size of multipart/form-data content. This setting cannot be parsed from URL parameters and should be set in a user profile. Note that content is parsed and external tables are created in memory before the start of query execution. And this is the only limit that has an effect on that stage (limits on max memory usage and max execution time have no effect while reading HTTP form data).", 0) \
|
||||
M(Bool, calculate_text_stack_trace, true, "Calculate text stack trace in case of exceptions during query execution. This is the default. It requires symbol lookups that may slow down fuzzing tests when a huge amount of wrong queries are executed. In normal cases, you should not disable this option.", 0) \
|
||||
M(Bool, enable_job_stack_trace, false, "Output stack trace of a job creator when job results in exception", 0) \
|
||||
M(Bool, allow_ddl, true, "If it is set to true, then a user is allowed to executed DDL queries.", 0) \
|
||||
M(Bool, parallel_view_processing, false, "Enables pushing to attached views concurrently instead of sequentially.", 0) \
|
||||
@ -558,7 +558,7 @@ namespace ErrorCodes
|
||||
M(UInt64, read_in_order_two_level_merge_threshold, 100, "Minimal number of parts to read to run preliminary merge step during multithread reading in order of primary key.", 0) \
|
||||
M(Bool, low_cardinality_allow_in_native_format, true, "Use LowCardinality type in Native format. Otherwise, convert LowCardinality columns to ordinary for select query, and convert ordinary columns to required LowCardinality for insert query.", 0) \
|
||||
M(Bool, cancel_http_readonly_queries_on_client_close, false, "Cancel HTTP readonly queries when a client closes the connection without waiting for response.", 0) \
|
||||
M(Bool, external_table_functions_use_nulls, true, "If it is set to true, external table functions will implicitly use Nullable type if needed. Otherwise NULLs will be substituted with default values. Currently supported only by 'mysql', 'postgresql' and 'odbc' table functions.", 0) \
|
||||
M(Bool, external_table_functions_use_nulls, true, "If it is set to true, external table functions will implicitly use Nullable type if needed. Otherwise, NULLs will be substituted with default values. Currently supported only by 'mysql', 'postgresql' and 'odbc' table functions.", 0) \
|
||||
M(Bool, external_table_strict_query, false, "If it is set to true, transforming expression to local filter is forbidden for queries to external tables.", 0) \
|
||||
\
|
||||
M(Bool, allow_hyperscan, true, "Allow functions that use Hyperscan library. Disable to avoid potentially long compilation times and excessive resource usage.", 0) \
|
||||
@ -567,7 +567,7 @@ namespace ErrorCodes
|
||||
M(Bool, reject_expensive_hyperscan_regexps, true, "Reject patterns which will likely be expensive to evaluate with hyperscan (due to NFA state explosion)", 0) \
|
||||
M(Bool, allow_simdjson, true, "Allow using simdjson library in 'JSON*' functions if AVX2 instructions are available. If disabled rapidjson will be used.", 0) \
|
||||
M(Bool, allow_introspection_functions, false, "Allow functions for introspection of ELF and DWARF for query profiling. These functions are slow and may impose security considerations.", 0) \
|
||||
M(Bool, splitby_max_substrings_includes_remaining_string, false, "Functions 'splitBy*()' with 'max_substrings' argument > 0 include the remaining string as last element in the result", 0) \
|
||||
M(Bool, splitby_max_substrings_includes_remaining_string, false, "Functions 'splitBy*()' with 'max_substrings' argument > 0 include the remaining string as the last element in the result", 0) \
|
||||
\
|
||||
M(Bool, allow_execute_multiif_columnar, true, "Allow execute multiIf function columnar", 0) \
|
||||
M(Bool, formatdatetime_f_prints_single_zero, false, "Formatter '%f' in function 'formatDateTime()' prints a single zero instead of six zeros if the formatted value has no fractional seconds.", 0) \
|
||||
@ -575,12 +575,12 @@ namespace ErrorCodes
|
||||
M(Bool, parsedatetime_parse_without_leading_zeros, true, "Formatters '%c', '%l' and '%k' in function 'parseDateTime()' parse months and hours without leading zeros.", 0) \
|
||||
M(Bool, formatdatetime_format_without_leading_zeros, false, "Formatters '%c', '%l' and '%k' in function 'formatDateTime()' print months and hours without leading zeros.", 0) \
|
||||
\
|
||||
M(UInt64, max_partitions_per_insert_block, 100, "Limit maximum number of partitions in single INSERTed block. Zero means unlimited. Throw exception if the block contains too many partitions. This setting is a safety threshold, because using large number of partitions is a common misconception.", 0) \
|
||||
M(UInt64, max_partitions_per_insert_block, 100, "Limit maximum number of partitions in the single INSERTed block. Zero means unlimited. Throw an exception if the block contains too many partitions. This setting is a safety threshold because using a large number of partitions is a common misconception.", 0) \
|
||||
M(Bool, throw_on_max_partitions_per_insert_block, true, "Used with max_partitions_per_insert_block. If true (default), an exception will be thrown when max_partitions_per_insert_block is reached. If false, details of the insert query reaching this limit with the number of partitions will be logged. This can be useful if you're trying to understand the impact on users when changing max_partitions_per_insert_block.", 0) \
|
||||
M(Int64, max_partitions_to_read, -1, "Limit the max number of partitions that can be accessed in one query. <= 0 means unlimited.", 0) \
|
||||
M(Bool, check_query_single_value_result, true, "Return check query result as single 1/0 value", 0) \
|
||||
M(Bool, allow_drop_detached, false, "Allow ALTER TABLE ... DROP DETACHED PART[ITION] ... queries", 0) \
|
||||
M(UInt64, max_table_size_to_drop, 50000000000lu, "If size of a table is greater than this value (in bytes) than table could not be dropped with any DROP query.", 0) \
|
||||
M(UInt64, max_table_size_to_drop, 50000000000lu, "If the size of a table is greater than this value (in bytes) then the table could not be dropped with any DROP query.", 0) \
|
||||
M(UInt64, max_partition_size_to_drop, 50000000000lu, "Same as max_table_size_to_drop, but for the partitions.", 0) \
|
||||
\
|
||||
M(UInt64, postgresql_connection_pool_size, 16, "Connection pool size for PostgreSQL table engine and database engine.", 0) \
|
||||
@ -608,9 +608,9 @@ namespace ErrorCodes
|
||||
M(Bool, optimize_count_from_files, true, "Optimize counting rows from files in supported input formats", 0) \
|
||||
M(Bool, use_cache_for_count_from_files, true, "Use cache to count the number of rows in files", 0) \
|
||||
M(Bool, optimize_respect_aliases, true, "If it is set to true, it will respect aliases in WHERE/GROUP BY/ORDER BY, that will help with partition pruning/secondary indexes/optimize_aggregation_in_order/optimize_read_in_order/optimize_trivial_count", 0) \
|
||||
M(UInt64, mutations_sync, 0, "Wait for synchronous execution of ALTER TABLE UPDATE/DELETE queries (mutations). 0 - execute asynchronously. 1 - wait current server. 2 - wait all replicas if they exist.", 0) \
|
||||
M(UInt64, mutations_sync, 0, "Wait for synchronous execution of ALTER TABLE UPDATE/DELETE queries (mutations). 0 - execute asynchronously. 1 - wait for the current server. 2 - wait for all replicas if they exist.", 0) \
|
||||
M(Bool, enable_lightweight_delete, true, "Enable lightweight DELETE mutations for mergetree tables.", 0) ALIAS(allow_experimental_lightweight_delete) \
|
||||
M(UInt64, lightweight_deletes_sync, 2, "The same as 'mutation_sync', but controls only execution of lightweight deletes", 0) \
|
||||
M(UInt64, lightweight_deletes_sync, 2, "The same as 'mutations_sync', but controls only execution of lightweight deletes", 0) \
|
||||
M(Bool, apply_deleted_mask, true, "Enables filtering out rows deleted with lightweight DELETE. If disabled, a query will be able to read those rows. This is useful for debugging and \"undelete\" scenarios", 0) \
|
||||
M(Bool, optimize_normalize_count_variants, true, "Rewrite aggregate functions that semantically equals to count() as count().", 0) \
|
||||
M(Bool, optimize_injective_functions_inside_uniq, true, "Delete injective functions of one argument inside uniq*() functions.", 0) \
|
||||
|
@ -566,7 +566,6 @@ static void deserializeTextImpl(
|
||||
const auto & variant_info = dynamic_column.getVariantInfo();
|
||||
const auto & variant_types = assert_cast<const DataTypeVariant &>(*variant_info.variant_type).getVariants();
|
||||
String field = read_field(istr);
|
||||
auto field_buf = std::make_unique<ReadBufferFromString>(field);
|
||||
JSONInferenceInfo json_info;
|
||||
auto variant_type = tryInferDataTypeByEscapingRule(field, settings, escaping_rule, &json_info);
|
||||
if (escaping_rule == FormatSettings::EscapingRule::JSON)
|
||||
@ -580,7 +579,7 @@ static void deserializeTextImpl(
|
||||
size_t shared_variant_discr = dynamic_column.getSharedVariantDiscriminator();
|
||||
for (size_t i = 0; i != variant_types.size(); ++i)
|
||||
{
|
||||
field_buf = std::make_unique<ReadBufferFromString>(field);
|
||||
auto field_buf = std::make_unique<ReadBufferFromString>(field);
|
||||
if (i != shared_variant_discr
|
||||
&& deserializeVariant<bool>(
|
||||
variant_column,
|
||||
@ -591,21 +590,24 @@ static void deserializeTextImpl(
|
||||
return;
|
||||
}
|
||||
|
||||
/// We cannot insert value with incomplete type, insert it as String.
|
||||
variant_type = std::make_shared<DataTypeString>();
|
||||
/// To be able to deserialize field as String with Quoted escaping rule, it should be quoted.
|
||||
if (escaping_rule == FormatSettings::EscapingRule::Quoted && (field.size() < 2 || field.front() != '\'' || field.back() != '\''))
|
||||
field = "'" + field + "'";
|
||||
}
|
||||
else if (dynamic_column.addNewVariant(variant_type, variant_type->getName()))
|
||||
|
||||
if (dynamic_column.addNewVariant(variant_type, variant_type->getName()))
|
||||
{
|
||||
auto field_buf = std::make_unique<ReadBufferFromString>(field);
|
||||
auto discr = variant_info.variant_name_to_discriminator.at(variant_type->getName());
|
||||
deserializeVariant(dynamic_column.getVariantColumn(), dynamic_column.getVariantSerialization(variant_type), discr, *field_buf, deserialize_variant);
|
||||
return;
|
||||
}
|
||||
|
||||
/// We couldn't infer type or add new variant. Insert it into shared variant.
|
||||
/// We couldn't add new variant. Insert it into shared variant.
|
||||
auto tmp_variant_column = variant_type->createColumn();
|
||||
field_buf = std::make_unique<ReadBufferFromString>(field);
|
||||
auto field_buf = std::make_unique<ReadBufferFromString>(field);
|
||||
auto variant_type_name = variant_type->getName();
|
||||
deserialize_variant(*dynamic_column.getVariantSerialization(variant_type, variant_type_name), *tmp_variant_column, *field_buf);
|
||||
dynamic_column.insertValueIntoSharedVariant(*tmp_variant_column, variant_type, variant_type_name, 0);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <Interpreters/Cache/FileSegment.h>
|
||||
#include <Interpreters/FilesystemCacheLog.h>
|
||||
#include <IO/SwapHelper.h>
|
||||
#include <IO/NullWriteBuffer.h>
|
||||
|
||||
|
||||
namespace ProfileEvents
|
||||
@ -20,6 +21,7 @@ namespace DB
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int LOGICAL_ERROR;
|
||||
extern const int NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
FileSegmentRangeWriter::FileSegmentRangeWriter(
|
||||
@ -149,7 +151,7 @@ FileSegment & FileSegmentRangeWriter::allocateFileSegment(size_t offset, FileSeg
|
||||
* File segment capacity will equal `max_file_segment_size`, but actual size is 0.
|
||||
*/
|
||||
|
||||
CreateFileSegmentSettings create_settings(segment_kind, false);
|
||||
CreateFileSegmentSettings create_settings(segment_kind);
|
||||
|
||||
/// We set max_file_segment_size to be downloaded,
|
||||
/// if we have less size to write, file segment will be resized in complete() method.
|
||||
@ -198,6 +200,22 @@ void FileSegmentRangeWriter::completeFileSegment()
|
||||
appendFilesystemCacheLog(file_segment);
|
||||
}
|
||||
|
||||
void FileSegmentRangeWriter::jumpToPosition(size_t position)
|
||||
{
|
||||
if (!file_segments->empty())
|
||||
{
|
||||
auto & file_segment = file_segments->front();
|
||||
|
||||
const auto current_write_offset = file_segment.getCurrentWriteOffset();
|
||||
if (position < current_write_offset)
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot jump backwards: {} < {}", position, current_write_offset);
|
||||
|
||||
file_segment.complete();
|
||||
file_segments.reset();
|
||||
}
|
||||
expected_write_offset = position;
|
||||
}
|
||||
|
||||
CachedOnDiskWriteBufferFromFile::CachedOnDiskWriteBufferFromFile(
|
||||
std::unique_ptr<WriteBuffer> impl_,
|
||||
FileCachePtr cache_,
|
||||
@ -206,7 +224,8 @@ CachedOnDiskWriteBufferFromFile::CachedOnDiskWriteBufferFromFile(
|
||||
const String & query_id_,
|
||||
const WriteSettings & settings_,
|
||||
const FileCacheUserInfo & user_,
|
||||
std::shared_ptr<FilesystemCacheLog> cache_log_)
|
||||
std::shared_ptr<FilesystemCacheLog> cache_log_,
|
||||
FileSegmentKind file_segment_kind_)
|
||||
: WriteBufferFromFileDecorator(std::move(impl_))
|
||||
, log(getLogger("CachedOnDiskWriteBufferFromFile"))
|
||||
, cache(cache_)
|
||||
@ -216,6 +235,7 @@ CachedOnDiskWriteBufferFromFile::CachedOnDiskWriteBufferFromFile(
|
||||
, user(user_)
|
||||
, reserve_space_lock_wait_timeout_milliseconds(settings_.filesystem_cache_reserve_space_wait_lock_timeout_milliseconds)
|
||||
, throw_on_error_from_cache(settings_.throw_on_error_from_cache)
|
||||
, file_segment_kind(file_segment_kind_)
|
||||
, cache_log(!query_id_.empty() && settings_.enable_filesystem_cache_log ? cache_log_ : nullptr)
|
||||
{
|
||||
}
|
||||
@ -265,7 +285,7 @@ void CachedOnDiskWriteBufferFromFile::cacheData(char * data, size_t size, bool t
|
||||
|
||||
try
|
||||
{
|
||||
if (!cache_writer->write(data, size, current_download_offset, FileSegmentKind::Regular))
|
||||
if (!cache_writer->write(data, size, current_download_offset, file_segment_kind))
|
||||
{
|
||||
LOG_INFO(log, "Write-through cache is stopped as cache limit is reached and nothing can be evicted");
|
||||
return;
|
||||
@ -332,4 +352,16 @@ void CachedOnDiskWriteBufferFromFile::finalizeImpl()
|
||||
}
|
||||
}
|
||||
|
||||
void CachedOnDiskWriteBufferFromFile::jumpToPosition(size_t position)
|
||||
{
|
||||
if (!dynamic_cast<const NullWriteBuffer *>(impl.get()))
|
||||
{
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED,
|
||||
"Jumping to position in CachedOnDiskWriteBufferFromFile "
|
||||
"is allowed only for NullWriteBuffer");
|
||||
}
|
||||
|
||||
cache_writer->jumpToPosition(position);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,6 +45,10 @@ public:
|
||||
|
||||
~FileSegmentRangeWriter();
|
||||
|
||||
const FileSegmentsHolder * getFileSegments() const { return file_segments.get(); }
|
||||
|
||||
void jumpToPosition(size_t position);
|
||||
|
||||
private:
|
||||
FileSegment & allocateFileSegment(size_t offset, FileSegmentKind segment_kind);
|
||||
|
||||
@ -69,11 +73,22 @@ private:
|
||||
bool finalized = false;
|
||||
};
|
||||
|
||||
class IFilesystemCacheWriteBuffer
|
||||
{
|
||||
public:
|
||||
virtual bool cachingStopped() const = 0;
|
||||
virtual const FileSegmentsHolder * getFileSegments() const = 0;
|
||||
virtual void jumpToPosition(size_t position) = 0;
|
||||
|
||||
virtual WriteBuffer & getImpl() = 0;
|
||||
|
||||
virtual ~IFilesystemCacheWriteBuffer() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write buffer for filesystem caching on write operations.
|
||||
*/
|
||||
class CachedOnDiskWriteBufferFromFile final : public WriteBufferFromFileDecorator
|
||||
class CachedOnDiskWriteBufferFromFile final : public WriteBufferFromFileDecorator, public IFilesystemCacheWriteBuffer
|
||||
{
|
||||
public:
|
||||
CachedOnDiskWriteBufferFromFile(
|
||||
@ -84,13 +99,20 @@ public:
|
||||
const String & query_id_,
|
||||
const WriteSettings & settings_,
|
||||
const FileCacheUserInfo & user_,
|
||||
std::shared_ptr<FilesystemCacheLog> cache_log_);
|
||||
std::shared_ptr<FilesystemCacheLog> cache_log_,
|
||||
FileSegmentKind file_segment_kind_ = FileSegmentKind::Regular);
|
||||
|
||||
void nextImpl() override;
|
||||
|
||||
void finalizeImpl() override;
|
||||
|
||||
bool cachingStopped() const { return cache_in_error_state_or_disabled; }
|
||||
bool cachingStopped() const override { return cache_in_error_state_or_disabled; }
|
||||
|
||||
const FileSegmentsHolder * getFileSegments() const override { return cache_writer ? cache_writer->getFileSegments() : nullptr; }
|
||||
|
||||
void jumpToPosition(size_t position) override;
|
||||
|
||||
WriteBuffer & getImpl() override { return *this; }
|
||||
|
||||
private:
|
||||
void cacheData(char * data, size_t size, bool throw_on_error);
|
||||
@ -109,6 +131,8 @@ private:
|
||||
size_t current_download_offset = 0;
|
||||
bool cache_in_error_state_or_disabled = false;
|
||||
|
||||
FileSegmentKind file_segment_kind;
|
||||
|
||||
std::unique_ptr<FileSegmentRangeWriter> cache_writer;
|
||||
std::shared_ptr<FilesystemCacheLog> cache_log;
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <type_traits>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/FunctionHelpers.h>
|
||||
@ -12,6 +13,7 @@
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/getMostSubtype.h>
|
||||
#include <DataTypes/getLeastSupertype.h>
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnFixedString.h>
|
||||
@ -35,10 +37,21 @@ namespace ErrorCodes
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
}
|
||||
|
||||
struct ArrayModeIntersect
|
||||
{
|
||||
static constexpr auto name = "arrayIntersect";
|
||||
};
|
||||
|
||||
struct ArrayModeUnion
|
||||
{
|
||||
static constexpr auto name = "arrayUnion";
|
||||
};
|
||||
|
||||
template <typename Mode>
|
||||
class FunctionArrayIntersect : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "arrayIntersect";
|
||||
static constexpr auto name = Mode::name;
|
||||
static FunctionPtr create(ContextPtr context) { return std::make_shared<FunctionArrayIntersect>(context); }
|
||||
explicit FunctionArrayIntersect(ContextPtr context_) : context(context_) {}
|
||||
|
||||
@ -97,6 +110,9 @@ private:
|
||||
template <typename Map, typename ColumnType, bool is_numeric_column>
|
||||
static ColumnPtr execute(const UnpackedArrays & arrays, MutableColumnPtr result_data);
|
||||
|
||||
template <typename Map, typename ColumnType, bool is_numeric_column>
|
||||
static void insertElement(typename Map::LookupResult & pair, size_t & result_offset, ColumnType & result_data, NullMap & null_map, const bool & use_null_map);
|
||||
|
||||
struct NumberExecutor
|
||||
{
|
||||
const UnpackedArrays & arrays;
|
||||
@ -124,13 +140,15 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
DataTypePtr FunctionArrayIntersect::getReturnTypeImpl(const DataTypes & arguments) const
|
||||
template <typename Mode>
|
||||
DataTypePtr FunctionArrayIntersect<Mode>::getReturnTypeImpl(const DataTypes & arguments) const
|
||||
{
|
||||
DataTypes nested_types;
|
||||
nested_types.reserve(arguments.size());
|
||||
|
||||
bool has_nothing = false;
|
||||
DataTypePtr has_decimal_type = nullptr;
|
||||
DataTypePtr has_non_decimal_type = nullptr;
|
||||
|
||||
if (arguments.empty())
|
||||
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "Function {} requires at least one argument.", getName());
|
||||
@ -146,23 +164,49 @@ DataTypePtr FunctionArrayIntersect::getReturnTypeImpl(const DataTypes & argument
|
||||
const auto & nested_type = array_type->getNestedType();
|
||||
|
||||
if (typeid_cast<const DataTypeNothing *>(nested_type.get()))
|
||||
has_nothing = true;
|
||||
{
|
||||
if constexpr (std::is_same_v<Mode, ArrayModeIntersect>)
|
||||
{
|
||||
has_nothing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nested_types.push_back(nested_type);
|
||||
|
||||
/// Throw exception if have a decimal and another type (e.g int/date type)
|
||||
/// This is the same behavior as the arrayIntersect and notEquals functions
|
||||
/// This case is not covered by getLeastSupertype() and results in crashing the program if left out
|
||||
if constexpr (std::is_same_v<Mode, ArrayModeUnion>)
|
||||
{
|
||||
if (WhichDataType(nested_type).isDecimal())
|
||||
has_decimal_type = nested_type;
|
||||
else
|
||||
has_non_decimal_type = nested_type;
|
||||
|
||||
if (has_non_decimal_type && has_decimal_type)
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal types of arguments for function {}: {} and {}.",
|
||||
getName(), has_non_decimal_type->getName(), has_decimal_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DataTypePtr result_type;
|
||||
|
||||
if (!nested_types.empty())
|
||||
result_type = getMostSubtype(nested_types, true);
|
||||
|
||||
if (has_nothing)
|
||||
// If any DataTypeNothing in ArrayModeIntersect or all arrays in ArrayModeUnion are DataTypeNothing
|
||||
if (has_nothing || nested_types.empty())
|
||||
result_type = std::make_shared<DataTypeNothing>();
|
||||
else if constexpr (std::is_same_v<Mode, ArrayModeIntersect>)
|
||||
result_type = getMostSubtype(nested_types, true);
|
||||
else
|
||||
result_type = getLeastSupertype(nested_types);
|
||||
|
||||
return std::make_shared<DataTypeArray>(result_type);
|
||||
}
|
||||
|
||||
ColumnPtr FunctionArrayIntersect::castRemoveNullable(const ColumnPtr & column, const DataTypePtr & data_type) const
|
||||
template <typename Mode>
|
||||
ColumnPtr FunctionArrayIntersect<Mode>::castRemoveNullable(const ColumnPtr & column, const DataTypePtr & data_type) const
|
||||
{
|
||||
if (const auto * column_nullable = checkAndGetColumn<ColumnNullable>(column.get()))
|
||||
{
|
||||
@ -208,7 +252,8 @@ ColumnPtr FunctionArrayIntersect::castRemoveNullable(const ColumnPtr & column, c
|
||||
return column;
|
||||
}
|
||||
|
||||
FunctionArrayIntersect::CastArgumentsResult FunctionArrayIntersect::castColumns(
|
||||
template <typename Mode>
|
||||
FunctionArrayIntersect<Mode>::CastArgumentsResult FunctionArrayIntersect<Mode>::castColumns(
|
||||
const ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type, const DataTypePtr & return_type_with_nulls)
|
||||
{
|
||||
size_t num_args = arguments.size();
|
||||
@ -294,7 +339,8 @@ static ColumnPtr callFunctionNotEquals(ColumnWithTypeAndName first, ColumnWithTy
|
||||
return eq_func->execute(args, eq_func->getResultType(), args.front().column->size());
|
||||
}
|
||||
|
||||
FunctionArrayIntersect::UnpackedArrays FunctionArrayIntersect::prepareArrays(
|
||||
template <typename Mode>
|
||||
FunctionArrayIntersect<Mode>::UnpackedArrays FunctionArrayIntersect<Mode>::prepareArrays(
|
||||
const ColumnsWithTypeAndName & columns, ColumnsWithTypeAndName & initial_columns) const
|
||||
{
|
||||
UnpackedArrays arrays;
|
||||
@ -384,7 +430,8 @@ FunctionArrayIntersect::UnpackedArrays FunctionArrayIntersect::prepareArrays(
|
||||
return arrays;
|
||||
}
|
||||
|
||||
ColumnPtr FunctionArrayIntersect::executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
|
||||
template <typename Mode>
|
||||
ColumnPtr FunctionArrayIntersect<Mode>::executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
|
||||
{
|
||||
const auto * return_type_array = checkAndGetDataType<DataTypeArray>(result_type.get());
|
||||
|
||||
@ -402,7 +449,12 @@ ColumnPtr FunctionArrayIntersect::executeImpl(const ColumnsWithTypeAndName & arg
|
||||
for (size_t i = 0; i < num_args; ++i)
|
||||
data_types.push_back(arguments[i].type);
|
||||
|
||||
auto return_type_with_nulls = getMostSubtype(data_types, true, true);
|
||||
DataTypePtr return_type_with_nulls;
|
||||
if constexpr (std::is_same_v<Mode, ArrayModeIntersect>)
|
||||
return_type_with_nulls = getMostSubtype(data_types, true, true);
|
||||
else
|
||||
return_type_with_nulls = getLeastSupertype(data_types);
|
||||
|
||||
auto casted_columns = castColumns(arguments, result_type, return_type_with_nulls);
|
||||
|
||||
UnpackedArrays arrays = prepareArrays(casted_columns.casted, casted_columns.initial);
|
||||
@ -450,8 +502,9 @@ ColumnPtr FunctionArrayIntersect::executeImpl(const ColumnsWithTypeAndName & arg
|
||||
return result_column;
|
||||
}
|
||||
|
||||
template <typename Mode>
|
||||
template <class T>
|
||||
void FunctionArrayIntersect::NumberExecutor::operator()(TypeList<T>)
|
||||
void FunctionArrayIntersect<Mode>::NumberExecutor::operator()(TypeList<T>)
|
||||
{
|
||||
using Container = ClearableHashMapWithStackMemory<T, size_t, DefaultHash<T>,
|
||||
INITIAL_SIZE_DEGREE>;
|
||||
@ -460,8 +513,9 @@ void FunctionArrayIntersect::NumberExecutor::operator()(TypeList<T>)
|
||||
result = execute<Container, ColumnVector<T>, true>(arrays, ColumnVector<T>::create());
|
||||
}
|
||||
|
||||
template <typename Mode>
|
||||
template <class T>
|
||||
void FunctionArrayIntersect::DecimalExecutor::operator()(TypeList<T>)
|
||||
void FunctionArrayIntersect<Mode>::DecimalExecutor::operator()(TypeList<T>)
|
||||
{
|
||||
using Container = ClearableHashMapWithStackMemory<T, size_t, DefaultHash<T>,
|
||||
INITIAL_SIZE_DEGREE>;
|
||||
@ -471,13 +525,15 @@ void FunctionArrayIntersect::DecimalExecutor::operator()(TypeList<T>)
|
||||
result = execute<Container, ColumnDecimal<T>, true>(arrays, ColumnDecimal<T>::create(0, decimal->getScale()));
|
||||
}
|
||||
|
||||
template <typename Mode>
|
||||
template <typename Map, typename ColumnType, bool is_numeric_column>
|
||||
ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, MutableColumnPtr result_data_ptr)
|
||||
ColumnPtr FunctionArrayIntersect<Mode>::execute(const UnpackedArrays & arrays, MutableColumnPtr result_data_ptr)
|
||||
{
|
||||
auto args = arrays.args.size();
|
||||
auto rows = arrays.base_rows;
|
||||
|
||||
bool all_nullable = true;
|
||||
bool has_nullable = false;
|
||||
|
||||
std::vector<const ColumnType *> columns;
|
||||
columns.reserve(args);
|
||||
@ -493,6 +549,8 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
||||
|
||||
if (!arg.null_map)
|
||||
all_nullable = false;
|
||||
else
|
||||
has_nullable = true;
|
||||
}
|
||||
|
||||
auto & result_data = static_cast<ColumnType &>(*result_data_ptr);
|
||||
@ -511,6 +569,7 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
||||
map.clear();
|
||||
|
||||
bool all_has_nullable = all_nullable;
|
||||
bool has_a_null = false;
|
||||
bool current_has_nullable = false;
|
||||
|
||||
for (size_t arg_num = 0; arg_num < args; ++arg_num)
|
||||
@ -546,7 +605,7 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
||||
}
|
||||
|
||||
/// Here we count the number of element appearances, but no more than once per array.
|
||||
if (*value == arg_num)
|
||||
if (*value <= arg_num)
|
||||
++(*value);
|
||||
}
|
||||
}
|
||||
@ -561,77 +620,90 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
||||
}
|
||||
if (!current_has_nullable)
|
||||
all_has_nullable = false;
|
||||
else
|
||||
has_a_null = true;
|
||||
}
|
||||
|
||||
// We have NULL in output only once if it should be there
|
||||
bool null_added = false;
|
||||
const auto & arg = arrays.args[0];
|
||||
size_t off;
|
||||
// const array has only one row
|
||||
if (arg.is_const)
|
||||
off = (*arg.offsets)[0];
|
||||
else
|
||||
off = (*arg.offsets)[row];
|
||||
bool use_null_map;
|
||||
|
||||
for (auto i : collections::range(prev_off[0], off))
|
||||
if constexpr (std::is_same_v<Mode, ArrayModeUnion>)
|
||||
{
|
||||
all_has_nullable = all_nullable;
|
||||
typename Map::LookupResult pair = nullptr;
|
||||
|
||||
if (arg.null_map && (*arg.null_map)[i])
|
||||
use_null_map = has_nullable;
|
||||
for (auto & p : map)
|
||||
{
|
||||
current_has_nullable = true;
|
||||
if (all_has_nullable && !null_added)
|
||||
typename Map::LookupResult pair = map.find(p.getKey());
|
||||
if (pair && pair->getMapped() >= 1)
|
||||
{
|
||||
++result_offset;
|
||||
result_data.insertDefault();
|
||||
null_map.push_back(1);
|
||||
null_added = true;
|
||||
insertElement<Map, ColumnType, is_numeric_column>(pair, result_offset, result_data, null_map, use_null_map);
|
||||
}
|
||||
if (null_added)
|
||||
continue;
|
||||
}
|
||||
else if constexpr (is_numeric_column)
|
||||
if (has_a_null && !null_added)
|
||||
{
|
||||
pair = map.find(columns[0]->getElement(i));
|
||||
}
|
||||
else if constexpr (std::is_same_v<ColumnType, ColumnString> || std::is_same_v<ColumnType, ColumnFixedString>)
|
||||
pair = map.find(columns[0]->getDataAt(i));
|
||||
else
|
||||
{
|
||||
const char * data = nullptr;
|
||||
pair = map.find(columns[0]->serializeValueIntoArena(i, arena, data));
|
||||
}
|
||||
prev_off[0] = off;
|
||||
if (arg.is_const)
|
||||
prev_off[0] = 0;
|
||||
|
||||
if (!current_has_nullable)
|
||||
all_has_nullable = false;
|
||||
|
||||
if (pair && pair->getMapped() == args)
|
||||
{
|
||||
// We increase pair->getMapped() here to not skip duplicate values from the first array.
|
||||
++pair->getMapped();
|
||||
++result_offset;
|
||||
if constexpr (is_numeric_column)
|
||||
{
|
||||
result_data.insertValue(pair->getKey());
|
||||
}
|
||||
else if constexpr (std::is_same_v<ColumnType, ColumnString> || std::is_same_v<ColumnType, ColumnFixedString>)
|
||||
{
|
||||
result_data.insertData(pair->getKey().data, pair->getKey().size);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ignore = result_data.deserializeAndInsertFromArena(pair->getKey().data);
|
||||
}
|
||||
if (all_nullable)
|
||||
null_map.push_back(0);
|
||||
result_data.insertDefault();
|
||||
null_map.push_back(1);
|
||||
null_added = true;
|
||||
}
|
||||
}
|
||||
result_offsets.getElement(row) = result_offset;
|
||||
else if constexpr (std::is_same_v<Mode, ArrayModeIntersect>)
|
||||
{
|
||||
use_null_map = all_nullable;
|
||||
const auto & arg = arrays.args[0];
|
||||
size_t off;
|
||||
// const array has only one row
|
||||
if (arg.is_const)
|
||||
off = (*arg.offsets)[0];
|
||||
else
|
||||
off = (*arg.offsets)[row];
|
||||
|
||||
for (auto i : collections::range(prev_off[0], off))
|
||||
{
|
||||
all_has_nullable = all_nullable;
|
||||
typename Map::LookupResult pair = nullptr;
|
||||
|
||||
if (arg.null_map && (*arg.null_map)[i])
|
||||
{
|
||||
current_has_nullable = true;
|
||||
if (all_has_nullable && !null_added)
|
||||
{
|
||||
++result_offset;
|
||||
result_data.insertDefault();
|
||||
null_map.push_back(1);
|
||||
null_added = true;
|
||||
}
|
||||
if (null_added)
|
||||
continue;
|
||||
}
|
||||
else if constexpr (is_numeric_column)
|
||||
{
|
||||
pair = map.find(columns[0]->getElement(i));
|
||||
}
|
||||
else if constexpr (std::is_same_v<ColumnType, ColumnString> || std::is_same_v<ColumnType, ColumnFixedString>)
|
||||
pair = map.find(columns[0]->getDataAt(i));
|
||||
else
|
||||
{
|
||||
const char * data = nullptr;
|
||||
pair = map.find(columns[0]->serializeValueIntoArena(i, arena, data));
|
||||
}
|
||||
prev_off[0] = off;
|
||||
if (arg.is_const)
|
||||
prev_off[0] = 0;
|
||||
|
||||
if (!current_has_nullable)
|
||||
all_has_nullable = false;
|
||||
|
||||
// Add the value if all arrays have the value for intersect
|
||||
// or if there was at least one occurrence in all of the arrays for union
|
||||
if (pair && pair->getMapped() == args)
|
||||
{
|
||||
insertElement<Map, ColumnType, is_numeric_column>(pair, result_offset, result_data, null_map, use_null_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result_offsets.getElement(row) = result_offset;
|
||||
}
|
||||
ColumnPtr result_column = std::move(result_data_ptr);
|
||||
if (all_nullable)
|
||||
@ -640,10 +712,36 @@ ColumnPtr FunctionArrayIntersect::execute(const UnpackedArrays & arrays, Mutable
|
||||
|
||||
}
|
||||
|
||||
template <typename Mode>
|
||||
template <typename Map, typename ColumnType, bool is_numeric_column>
|
||||
void FunctionArrayIntersect<Mode>::insertElement(typename Map::LookupResult & pair, size_t & result_offset, ColumnType & result_data, NullMap & null_map, const bool & use_null_map)
|
||||
{
|
||||
pair->getMapped() = -1;
|
||||
++result_offset;
|
||||
if constexpr (is_numeric_column)
|
||||
{
|
||||
result_data.insertValue(pair->getKey());
|
||||
}
|
||||
else if constexpr (std::is_same_v<ColumnType, ColumnString> || std::is_same_v<ColumnType, ColumnFixedString>)
|
||||
{
|
||||
result_data.insertData(pair->getKey().data, pair->getKey().size);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ignore = result_data.deserializeAndInsertFromArena(pair->getKey().data);
|
||||
}
|
||||
if (use_null_map)
|
||||
null_map.push_back(0);
|
||||
}
|
||||
|
||||
|
||||
using ArrayIntersect = FunctionArrayIntersect<ArrayModeIntersect>;
|
||||
using ArrayUnion = FunctionArrayIntersect<ArrayModeUnion>;
|
||||
|
||||
REGISTER_FUNCTION(ArrayIntersect)
|
||||
{
|
||||
factory.registerFunction<FunctionArrayIntersect>();
|
||||
factory.registerFunction<ArrayIntersect>();
|
||||
factory.registerFunction<ArrayUnion>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ public:
|
||||
size_t getNumberOfArguments() const override { return 2; }
|
||||
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||
bool useDefaultImplementationForNulls() const override { return false; }
|
||||
bool useDefaultImplementationForNulls() const override { return true; }
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
bool useDefaultImplementationForLowCardinalityColumns() const override { return false; }
|
||||
|
||||
|
@ -184,6 +184,18 @@ void FileCacheFactory::updateSettingsFromConfig(const Poco::Util::AbstractConfig
|
||||
}
|
||||
}
|
||||
|
||||
void FileCacheFactory::remove(FileCachePtr cache)
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
for (auto it = caches_by_name.begin(); it != caches_by_name.end();)
|
||||
{
|
||||
if (it->second->cache == cache)
|
||||
it = caches_by_name.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void FileCacheFactory::clear()
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
FileCacheDataPtr getByName(const std::string & cache_name);
|
||||
|
||||
void updateSettingsFromConfig(const Poco::Util::AbstractConfiguration & config);
|
||||
|
||||
void remove(FileCachePtr cache);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
@ -20,6 +20,5 @@ class FileCache;
|
||||
using FileCachePtr = std::shared_ptr<FileCache>;
|
||||
|
||||
struct FileCacheSettings;
|
||||
struct CreateFileSegmentSettings;
|
||||
|
||||
}
|
||||
|
@ -669,7 +669,7 @@ void FileSegment::complete()
|
||||
resetDownloaderUnlocked(segment_lock);
|
||||
}
|
||||
|
||||
if (segment_kind == FileSegmentKind::Temporary && is_last_holder)
|
||||
if (segment_kind == FileSegmentKind::Ephemeral && is_last_holder)
|
||||
{
|
||||
LOG_TEST(log, "Removing temporary file segment: {}", getInfoForLogUnlocked(segment_lock));
|
||||
locked_key->removeFileSegment(offset(), segment_lock);
|
||||
@ -988,13 +988,26 @@ FileSegmentsHolder::FileSegmentsHolder(FileSegments && file_segments_)
|
||||
ProfileEvents::increment(ProfileEvents::FilesystemCacheHoldFileSegments, file_segments.size());
|
||||
}
|
||||
|
||||
FileSegmentsHolder::~FileSegmentsHolder()
|
||||
FileSegmentPtr FileSegmentsHolder::getSingleFileSegment() const
|
||||
{
|
||||
if (file_segments.size() != 1)
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Expected single file segment, got: {} in holder {}", file_segments.size(), toString());
|
||||
return file_segments.front();
|
||||
}
|
||||
|
||||
void FileSegmentsHolder::reset()
|
||||
{
|
||||
ProfileEventTimeIncrement<Microseconds> watch(ProfileEvents::FileSegmentHolderCompleteMicroseconds);
|
||||
|
||||
ProfileEvents::increment(ProfileEvents::FilesystemCacheUnusedHoldFileSegments, file_segments.size());
|
||||
for (auto file_segment_it = file_segments.begin(); file_segment_it != file_segments.end();)
|
||||
file_segment_it = completeAndPopFrontImpl();
|
||||
file_segments.clear();
|
||||
}
|
||||
|
||||
FileSegmentsHolder::~FileSegmentsHolder()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
FileSegments::iterator FileSegmentsHolder::completeAndPopFrontImpl()
|
||||
@ -1012,7 +1025,7 @@ FileSegment & FileSegmentsHolder::add(FileSegmentPtr && file_segment)
|
||||
return *file_segments.back();
|
||||
}
|
||||
|
||||
String FileSegmentsHolder::toString(bool with_state)
|
||||
String FileSegmentsHolder::toString(bool with_state) const
|
||||
{
|
||||
return DB::toString(file_segments, with_state);
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ struct CreateFileSegmentSettings
|
||||
|
||||
CreateFileSegmentSettings() = default;
|
||||
|
||||
explicit CreateFileSegmentSettings(FileSegmentKind kind_, bool unbounded_ = false)
|
||||
: kind(kind_), unbounded(unbounded_) {}
|
||||
explicit CreateFileSegmentSettings(FileSegmentKind kind_)
|
||||
: kind(kind_), unbounded(kind == FileSegmentKind::Ephemeral) {}
|
||||
};
|
||||
|
||||
class FileSegment : private boost::noncopyable
|
||||
@ -283,7 +283,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct FileSegmentsHolder : private boost::noncopyable
|
||||
struct FileSegmentsHolder final : private boost::noncopyable
|
||||
{
|
||||
FileSegmentsHolder() = default;
|
||||
|
||||
@ -295,7 +295,7 @@ struct FileSegmentsHolder : private boost::noncopyable
|
||||
|
||||
size_t size() const { return file_segments.size(); }
|
||||
|
||||
String toString(bool with_state = false);
|
||||
String toString(bool with_state = false) const;
|
||||
|
||||
void popFront() { completeAndPopFrontImpl(); }
|
||||
|
||||
@ -312,6 +312,9 @@ struct FileSegmentsHolder : private boost::noncopyable
|
||||
|
||||
FileSegments::const_iterator begin() const { return file_segments.begin(); }
|
||||
FileSegments::const_iterator end() const { return file_segments.end(); }
|
||||
FileSegmentPtr getSingleFileSegment() const;
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
FileSegments file_segments{};
|
||||
|
@ -41,16 +41,18 @@ namespace DB
|
||||
enum class FileSegmentKind : uint8_t
|
||||
{
|
||||
/**
|
||||
* `Regular` file segment is still in cache after usage, and can be evicted
|
||||
* (unless there're some holders).
|
||||
* Represents data cached from S3 or other backing storage.
|
||||
* It is kept in the cache after usage and can be evicted on demand, unless there are some holders.
|
||||
*/
|
||||
Regular,
|
||||
|
||||
/**
|
||||
* Temporary` file segment is removed right after releasing.
|
||||
* Also corresponding files are removed during cache loading (if any).
|
||||
* Represents temporary data without backing storage, but written to the cache from outside.
|
||||
* Ephemeral file segments are kept while they are in use, but then can be removed immediately after releasing.
|
||||
* Also, corresponding files are removed during cache loading.
|
||||
* Ephemeral file segments have no bound, and a single segment can have an arbitrary size.
|
||||
*/
|
||||
Temporary,
|
||||
Ephemeral,
|
||||
};
|
||||
|
||||
enum class FileCacheQueueEntryType : uint8_t
|
||||
|
@ -178,7 +178,7 @@ String CacheMetadata::getFileNameForFileSegment(size_t offset, FileSegmentKind s
|
||||
String file_suffix;
|
||||
switch (segment_kind)
|
||||
{
|
||||
case FileSegmentKind::Temporary:
|
||||
case FileSegmentKind::Ephemeral:
|
||||
file_suffix = "_temporary";
|
||||
break;
|
||||
case FileSegmentKind::Regular:
|
||||
@ -198,13 +198,13 @@ String CacheMetadata::getFileSegmentPath(
|
||||
|
||||
String CacheMetadata::getKeyPath(const Key & key, const UserInfo & user) const
|
||||
{
|
||||
const auto key_str = key.toString();
|
||||
if (write_cache_per_user_directory)
|
||||
{
|
||||
return fs::path(path) / fmt::format("{}.{}", user.user_id, user.weight.value()) / key.toString();
|
||||
return fs::path(path) / fmt::format("{}.{}", user.user_id, user.weight.value()) / key_str.substr(0, 3) / key_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto key_str = key.toString();
|
||||
return fs::path(path) / key_str.substr(0, 3) / key_str;
|
||||
}
|
||||
}
|
||||
@ -423,6 +423,8 @@ CacheMetadata::removeEmptyKey(
|
||||
fs::remove(key_prefix_directory);
|
||||
LOG_TEST(log, "Prefix directory ({}) for key {} removed", key_prefix_directory.string(), key);
|
||||
}
|
||||
|
||||
/// TODO: Remove empty user directories.
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ void WriteBufferToFileSegment::nextImpl()
|
||||
|
||||
throw Exception(ErrorCodes::NOT_ENOUGH_SPACE, "Failed to reserve {} bytes for {}: reason {}, {}(segment info: {})",
|
||||
bytes_to_write,
|
||||
file_segment->getKind() == FileSegmentKind::Temporary ? "temporary file" : "the file in cache",
|
||||
file_segment->getKind() == FileSegmentKind::Ephemeral ? "temporary file" : "the file in cache",
|
||||
failure_reason,
|
||||
reserve_stat_msg,
|
||||
file_segment->getInfoForLog()
|
||||
|
@ -3,13 +3,19 @@
|
||||
#include <IO/WriteBufferFromFileDecorator.h>
|
||||
#include <Interpreters/Cache/FileSegment.h>
|
||||
#include <IO/IReadableWriteBuffer.h>
|
||||
#include <Disks/IO/CachedOnDiskWriteBufferFromFile.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
class FileSegment;
|
||||
|
||||
class WriteBufferToFileSegment : public WriteBufferFromFileBase, public IReadableWriteBuffer
|
||||
class WriteBufferToFileSegment : public WriteBufferFromFileBase, public IReadableWriteBuffer, public IFilesystemCacheWriteBuffer
|
||||
{
|
||||
public:
|
||||
explicit WriteBufferToFileSegment(FileSegment * file_segment_);
|
||||
@ -21,6 +27,12 @@ public:
|
||||
|
||||
void sync() override;
|
||||
|
||||
WriteBuffer & getImpl() override { return *this; }
|
||||
|
||||
bool cachingStopped() const override { return false; }
|
||||
const FileSegmentsHolder * getFileSegments() const override { return segment_holder.get(); }
|
||||
void jumpToPosition(size_t) override { throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Method jumpToPosition is not implemented for WriteBufferToFileSegment"); }
|
||||
|
||||
protected:
|
||||
void finalizeImpl() override;
|
||||
|
||||
|
@ -1045,7 +1045,7 @@ void DDLWorker::createStatusDirs(const std::string & node_path, const ZooKeeperP
|
||||
if (is_currently_deleting)
|
||||
{
|
||||
cleanup_event->set();
|
||||
throw Exception(ErrorCodes::UNFINISHED, "Cannot create status dirs for {}, "
|
||||
throw Exception(ErrorCodes::UNFINISHED, "Cannot create znodes (status) for {} in [Zoo]Keeper, "
|
||||
"most likely because someone is deleting it concurrently", node_path);
|
||||
}
|
||||
|
||||
|
@ -863,7 +863,10 @@ void MutationsInterpreter::prepare(bool dry_run)
|
||||
else if (command.type == MutationCommand::MATERIALIZE_TTL)
|
||||
{
|
||||
mutation_kind.set(MutationKind::MUTATE_OTHER);
|
||||
if (materialize_ttl_recalculate_only)
|
||||
bool suitable_for_ttl_optimization = source.getMergeTreeData()->getSettings()->ttl_only_drop_parts
|
||||
&& metadata_snapshot->hasOnlyRowsTTL();
|
||||
|
||||
if (materialize_ttl_recalculate_only || suitable_for_ttl_optimization)
|
||||
{
|
||||
// just recalculate ttl_infos without remove expired data
|
||||
auto all_columns_vec = all_columns.getNames();
|
||||
|
@ -33,6 +33,7 @@ namespace ErrorCodes
|
||||
void ReplaceQueryParameterVisitor::visit(ASTPtr & ast)
|
||||
{
|
||||
checkStackSize();
|
||||
resolveParametrizedAlias(ast);
|
||||
|
||||
if (ast->as<ASTQueryParameter>())
|
||||
visitQueryParameter(ast);
|
||||
@ -156,4 +157,13 @@ void ReplaceQueryParameterVisitor::visitIdentifier(ASTPtr & ast)
|
||||
ast_identifier->children.clear();
|
||||
}
|
||||
|
||||
void ReplaceQueryParameterVisitor::resolveParametrizedAlias(ASTPtr & ast)
|
||||
{
|
||||
auto ast_with_alias = std::dynamic_pointer_cast<ASTWithAlias>(ast);
|
||||
if (!ast_with_alias)
|
||||
return;
|
||||
|
||||
if (ast_with_alias->parametrised_alias)
|
||||
setAlias(ast, getParamValue((*ast_with_alias->parametrised_alias)->name));
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ private:
|
||||
size_t num_replaced_parameters = 0;
|
||||
|
||||
const String & getParamValue(const String & name);
|
||||
void resolveParametrizedAlias(ASTPtr & ast);
|
||||
void visitIdentifier(ASTPtr & ast);
|
||||
void visitQueryParameter(ASTPtr & ast);
|
||||
void visitChildren(ASTPtr & ast);
|
||||
|
@ -110,7 +110,7 @@ FileSegmentsHolderPtr TemporaryDataOnDisk::createCacheFile(size_t max_file_size)
|
||||
const auto key = FileSegment::Key::random();
|
||||
auto holder = file_cache->set(
|
||||
key, 0, std::max(10_MiB, max_file_size),
|
||||
CreateFileSegmentSettings(FileSegmentKind::Temporary, /* unbounded */ true), FileCache::getCommonUser());
|
||||
CreateFileSegmentSettings(FileSegmentKind::Ephemeral), FileCache::getCommonUser());
|
||||
|
||||
chassert(holder->size() == 1);
|
||||
holder->back().getKeyMetadata()->createBaseDirectory(/* throw_if_failed */true);
|
||||
|
@ -830,7 +830,7 @@ TEST_F(FileCacheTest, writeBuffer)
|
||||
auto write_to_cache = [&, this](const String & key, const Strings & data, bool flush, ReadBufferPtr * out_read_buffer = nullptr)
|
||||
{
|
||||
CreateFileSegmentSettings segment_settings;
|
||||
segment_settings.kind = FileSegmentKind::Temporary;
|
||||
segment_settings.kind = FileSegmentKind::Ephemeral;
|
||||
segment_settings.unbounded = true;
|
||||
|
||||
auto cache_key = FileCache::createKeyForPath(key);
|
||||
|
@ -6,6 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
class ASTQueryParameter;
|
||||
|
||||
/** Base class for AST, which can contain an alias (identifiers, literals, functions).
|
||||
*/
|
||||
@ -17,6 +18,9 @@ public:
|
||||
/// If is true, getColumnName returns alias. Uses for aliases in former WITH section of SELECT query.
|
||||
/// Example: 'WITH pow(2, 2) as a SELECT pow(a, 2)' returns 'pow(a, 2)' instead of 'pow(pow(2, 2), 2)'
|
||||
bool prefer_alias_to_column_name = false;
|
||||
// An alias can be defined as a query parameter,
|
||||
// in which case we can only resolve it during query execution.
|
||||
std::optional<std::shared_ptr<ASTQueryParameter>> parametrised_alias;
|
||||
|
||||
using IAST::IAST;
|
||||
|
||||
|
@ -1607,7 +1607,7 @@ const char * ParserAlias::restricted_keywords[] =
|
||||
bool ParserAlias::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
ParserKeyword s_as(Keyword::AS);
|
||||
ParserIdentifier id_p(false, Highlight::alias);
|
||||
ParserIdentifier id_p{true, Highlight::alias};
|
||||
|
||||
bool has_as_word = s_as.ignore(pos, expected);
|
||||
if (!allow_alias_without_as_keyword && !has_as_word)
|
||||
@ -2154,6 +2154,10 @@ bool ParserWithOptionalAlias::parseImpl(Pos & pos, ASTPtr & node, Expected & exp
|
||||
if (auto * ast_with_alias = dynamic_cast<ASTWithAlias *>(node.get()))
|
||||
{
|
||||
tryGetIdentifierNameInto(alias_node, ast_with_alias->alias);
|
||||
|
||||
// the alias is parametrised and will be resolved later when the query context is known
|
||||
if (!alias_node->children.empty() && alias_node->children.front()->as<ASTQueryParameter>())
|
||||
ast_with_alias->parametrised_alias = std::dynamic_pointer_cast<ASTQueryParameter>(alias_node->children.front());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -59,6 +59,16 @@ std::string DataPartStorageOnDiskBase::getRelativePath() const
|
||||
return fs::path(root_path) / part_dir / "";
|
||||
}
|
||||
|
||||
std::string DataPartStorageOnDiskBase::getParentDirectory() const
|
||||
{
|
||||
/// Cut last "/" if it exists (it shouldn't). Otherwise fs::path behave differently.
|
||||
fs::path part_dir_without_slash = part_dir.ends_with("/") ? part_dir.substr(0, part_dir.size() - 1) : part_dir;
|
||||
|
||||
if (part_dir_without_slash.has_parent_path())
|
||||
return part_dir_without_slash.parent_path();
|
||||
return "";
|
||||
}
|
||||
|
||||
std::optional<String> DataPartStorageOnDiskBase::getRelativePathForPrefix(LoggerPtr log, const String & prefix, bool detached, bool broken) const
|
||||
{
|
||||
assert(!broken || detached);
|
||||
@ -699,9 +709,9 @@ void DataPartStorageOnDiskBase::remove(
|
||||
|
||||
if (!has_delete_prefix)
|
||||
{
|
||||
if (part_dir_without_slash.has_parent_path())
|
||||
auto parent_path = getParentDirectory();
|
||||
if (!parent_path.empty())
|
||||
{
|
||||
auto parent_path = part_dir_without_slash.parent_path();
|
||||
if (parent_path == MergeTreeData::DETACHED_DIR_NAME)
|
||||
throw Exception(
|
||||
ErrorCodes::LOGICAL_ERROR,
|
||||
@ -709,7 +719,7 @@ void DataPartStorageOnDiskBase::remove(
|
||||
part_dir,
|
||||
root_path);
|
||||
|
||||
part_dir_without_slash = parent_path / ("delete_tmp_" + std::string{part_dir_without_slash.filename()});
|
||||
part_dir_without_slash = fs::path(parent_path) / ("delete_tmp_" + std::string{part_dir_without_slash.filename()});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -20,6 +20,7 @@ public:
|
||||
std::string getRelativePath() const override;
|
||||
std::string getPartDirectory() const override;
|
||||
std::string getFullRootPath() const override;
|
||||
std::string getParentDirectory() const override;
|
||||
|
||||
Poco::Timestamp getLastModified() const override;
|
||||
UInt64 calculateTotalSizeOnDisk() const override;
|
||||
|
@ -96,11 +96,12 @@ public:
|
||||
virtual MergeTreeDataPartStorageType getType() const = 0;
|
||||
|
||||
/// Methods to get path components of a data part.
|
||||
virtual std::string getFullPath() const = 0; /// '/var/lib/clickhouse/data/database/table/moving/all_1_5_1'
|
||||
virtual std::string getRelativePath() const = 0; /// 'database/table/moving/all_1_5_1'
|
||||
virtual std::string getPartDirectory() const = 0; /// 'all_1_5_1'
|
||||
virtual std::string getFullRootPath() const = 0; /// '/var/lib/clickhouse/data/database/table/moving'
|
||||
/// Can add it if needed /// 'database/table/moving'
|
||||
virtual std::string getFullPath() const = 0; /// '/var/lib/clickhouse/data/database/table/moving/all_1_5_1'
|
||||
virtual std::string getRelativePath() const = 0; /// 'database/table/moving/all_1_5_1'
|
||||
virtual std::string getPartDirectory() const = 0; /// 'all_1_5_1'
|
||||
virtual std::string getFullRootPath() const = 0; /// '/var/lib/clickhouse/data/database/table/moving'
|
||||
virtual std::string getParentDirectory() const = 0; /// '' (or 'detached' for 'detached/all_1_5_1')
|
||||
/// Can add it if needed /// 'database/table/moving'
|
||||
/// virtual std::string getRelativeRootPath() const = 0;
|
||||
|
||||
/// Get a storage for projection.
|
||||
|
@ -742,7 +742,9 @@ void IMergeTreeDataPart::loadColumnsChecksumsIndexes(bool require_columns_checks
|
||||
/// Don't scare people with broken part error if it's retryable.
|
||||
if (!isRetryableException(std::current_exception()))
|
||||
{
|
||||
LOG_ERROR(storage.log, "Part {} is broken and needs manual correction", getDataPartStorage().getFullPath());
|
||||
auto message = getCurrentExceptionMessage(true);
|
||||
LOG_ERROR(storage.log, "Part {} is broken and needs manual correction. Reason: {}",
|
||||
getDataPartStorage().getFullPath(), message);
|
||||
|
||||
if (Exception * e = exception_cast<Exception *>(std::current_exception()))
|
||||
{
|
||||
|
@ -3959,7 +3959,7 @@ void MergeTreeData::checkPartDynamicColumns(MutableDataPartPtr & part, DataParts
|
||||
}
|
||||
}
|
||||
|
||||
void MergeTreeData::preparePartForCommit(MutableDataPartPtr & part, Transaction & out_transaction, bool need_rename)
|
||||
void MergeTreeData::preparePartForCommit(MutableDataPartPtr & part, Transaction & out_transaction, bool need_rename, bool rename_in_transaction)
|
||||
{
|
||||
part->is_temp = false;
|
||||
part->setState(DataPartState::PreActive);
|
||||
@ -3970,13 +3970,17 @@ void MergeTreeData::preparePartForCommit(MutableDataPartPtr & part, Transaction
|
||||
bool may_be_cleaned_up = dir_name.starts_with("tmp_") || dir_name.starts_with("tmp-fetch_");
|
||||
return !may_be_cleaned_up || temporary_parts.contains(dir_name);
|
||||
}());
|
||||
assert(!(!need_rename && rename_in_transaction));
|
||||
|
||||
if (need_rename)
|
||||
if (need_rename && !rename_in_transaction)
|
||||
part->renameTo(part->name, true);
|
||||
|
||||
LOG_TEST(log, "preparePartForCommit: inserting {} into data_parts_indexes", part->getNameWithState());
|
||||
data_parts_indexes.insert(part);
|
||||
out_transaction.addPart(part);
|
||||
if (rename_in_transaction)
|
||||
out_transaction.addPart(part, need_rename);
|
||||
else
|
||||
out_transaction.addPart(part, /* need_rename= */ false);
|
||||
}
|
||||
|
||||
bool MergeTreeData::addTempPart(
|
||||
@ -4025,7 +4029,8 @@ bool MergeTreeData::renameTempPartAndReplaceImpl(
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & out_transaction,
|
||||
DataPartsLock & lock,
|
||||
DataPartsVector * out_covered_parts)
|
||||
DataPartsVector * out_covered_parts,
|
||||
bool rename_in_transaction)
|
||||
{
|
||||
LOG_TRACE(log, "Renaming temporary part {} to {} with tid {}.", part->getDataPartStorage().getPartDirectory(), part->name, out_transaction.getTID());
|
||||
|
||||
@ -4064,7 +4069,7 @@ bool MergeTreeData::renameTempPartAndReplaceImpl(
|
||||
|
||||
/// All checks are passed. Now we can rename the part on disk.
|
||||
/// So, we maintain invariant: if a non-temporary part in filesystem then it is in data_parts
|
||||
preparePartForCommit(part, out_transaction, /* need_rename */ true);
|
||||
preparePartForCommit(part, out_transaction, /* need_rename= */ true, rename_in_transaction);
|
||||
|
||||
if (out_covered_parts)
|
||||
{
|
||||
@ -4079,29 +4084,31 @@ bool MergeTreeData::renameTempPartAndReplaceUnlocked(
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & out_transaction,
|
||||
DataPartsLock & lock,
|
||||
DataPartsVector * out_covered_parts)
|
||||
bool rename_in_transaction)
|
||||
{
|
||||
return renameTempPartAndReplaceImpl(part, out_transaction, lock, out_covered_parts);
|
||||
return renameTempPartAndReplaceImpl(part, out_transaction, lock, /*out_covered_parts=*/ nullptr, rename_in_transaction);
|
||||
}
|
||||
|
||||
MergeTreeData::DataPartsVector MergeTreeData::renameTempPartAndReplace(
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & out_transaction)
|
||||
Transaction & out_transaction,
|
||||
bool rename_in_transaction)
|
||||
{
|
||||
auto part_lock = lockParts();
|
||||
DataPartsVector covered_parts;
|
||||
renameTempPartAndReplaceImpl(part, out_transaction, part_lock, &covered_parts);
|
||||
renameTempPartAndReplaceImpl(part, out_transaction, part_lock, &covered_parts, rename_in_transaction);
|
||||
return covered_parts;
|
||||
}
|
||||
|
||||
bool MergeTreeData::renameTempPartAndAdd(
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & out_transaction,
|
||||
DataPartsLock & lock)
|
||||
DataPartsLock & lock,
|
||||
bool rename_in_transaction)
|
||||
{
|
||||
DataPartsVector covered_parts;
|
||||
|
||||
if (!renameTempPartAndReplaceImpl(part, out_transaction, lock, &covered_parts))
|
||||
if (!renameTempPartAndReplaceImpl(part, out_transaction, lock, &covered_parts, rename_in_transaction))
|
||||
return false;
|
||||
|
||||
if (!covered_parts.empty())
|
||||
@ -4142,9 +4149,9 @@ void MergeTreeData::removePartsFromWorkingSet(MergeTreeTransaction * txn, const
|
||||
resetObjectColumnsFromActiveParts(acquired_lock);
|
||||
}
|
||||
|
||||
void MergeTreeData::removePartsFromWorkingSetImmediatelyAndSetTemporaryState(const DataPartsVector & remove)
|
||||
void MergeTreeData::removePartsFromWorkingSetImmediatelyAndSetTemporaryState(const DataPartsVector & remove, DataPartsLock * acquired_lock)
|
||||
{
|
||||
auto lock = lockParts();
|
||||
auto lock = (acquired_lock) ? DataPartsLock() : lockParts();
|
||||
|
||||
for (const auto & part : remove)
|
||||
{
|
||||
@ -4310,7 +4317,7 @@ MergeTreeData::PartsToRemoveFromZooKeeper MergeTreeData::removePartsInRangeFromW
|
||||
auto [new_data_part, tmp_dir_holder] = createEmptyPart(empty_info, partition, empty_part_name, NO_TRANSACTION_PTR);
|
||||
|
||||
MergeTreeData::Transaction transaction(*this, NO_TRANSACTION_RAW);
|
||||
renameTempPartAndAdd(new_data_part, transaction, lock); /// All covered parts must be already removed
|
||||
renameTempPartAndAdd(new_data_part, transaction, lock, /*rename_in_transaction=*/ false); /// All covered parts must be already removed
|
||||
|
||||
/// It will add the empty part to the set of Outdated parts without making it Active (exactly what we need)
|
||||
transaction.rollback(&lock);
|
||||
@ -6709,25 +6716,54 @@ TransactionID MergeTreeData::Transaction::getTID() const
|
||||
return Tx::PrehistoricTID;
|
||||
}
|
||||
|
||||
void MergeTreeData::Transaction::addPart(MutableDataPartPtr & part)
|
||||
void MergeTreeData::Transaction::addPart(MutableDataPartPtr & part, bool need_rename)
|
||||
{
|
||||
precommitted_parts.insert(part);
|
||||
if (need_rename)
|
||||
precommitted_parts_need_rename.insert(part);
|
||||
}
|
||||
|
||||
void MergeTreeData::Transaction::rollback(DataPartsLock * lock)
|
||||
{
|
||||
if (!isEmpty())
|
||||
{
|
||||
WriteBufferFromOwnString buf;
|
||||
buf << "Removing parts:";
|
||||
for (const auto & part : precommitted_parts)
|
||||
buf << " " << part->getDataPartStorage().getPartDirectory();
|
||||
buf << ".";
|
||||
LOG_DEBUG(data.log, "Undoing transaction {}. {}", getTID(), buf.str());
|
||||
|
||||
for (const auto & part : precommitted_parts)
|
||||
part->version.creation_csn.store(Tx::RolledBackCSN);
|
||||
|
||||
auto non_detached_precommitted_parts = precommitted_parts;
|
||||
|
||||
/// Remove detached parts from working set.
|
||||
///
|
||||
/// It is possible to have detached parts here, only when rename (in
|
||||
/// commit()) of detached parts had been broken (i.e. during ATTACH),
|
||||
/// i.e. the part itself is broken.
|
||||
DataPartsVector detached_precommitted_parts;
|
||||
for (auto it = non_detached_precommitted_parts.begin(); it != non_detached_precommitted_parts.end();)
|
||||
{
|
||||
const auto & part = *it;
|
||||
if (part->getDataPartStorage().getParentDirectory() == DETACHED_DIR_NAME)
|
||||
{
|
||||
detached_precommitted_parts.push_back(part);
|
||||
it = non_detached_precommitted_parts.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
WriteBufferFromOwnString buf;
|
||||
buf << "Removing parts:";
|
||||
for (const auto & part : non_detached_precommitted_parts)
|
||||
buf << " " << part->getDataPartStorage().getPartDirectory();
|
||||
buf << ".";
|
||||
if (!detached_precommitted_parts.empty())
|
||||
{
|
||||
buf << " Rollbacking parts state to temporary and removing from working set:";
|
||||
for (const auto & part : detached_precommitted_parts)
|
||||
buf << " " << part->getDataPartStorage().getPartDirectory();
|
||||
buf << ".";
|
||||
}
|
||||
LOG_DEBUG(data.log, "Undoing transaction {}. {}", getTID(), buf.str());
|
||||
|
||||
/// It would be much better with TSA...
|
||||
auto our_lock = (lock) ? DataPartsLock() : data.lockParts();
|
||||
|
||||
@ -6737,7 +6773,7 @@ void MergeTreeData::Transaction::rollback(DataPartsLock * lock)
|
||||
if (!data.all_data_dropped)
|
||||
{
|
||||
Strings part_names;
|
||||
for (const auto & part : precommitted_parts)
|
||||
for (const auto & part : non_detached_precommitted_parts)
|
||||
part_names.emplace_back(part->name);
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "There are some PreActive parts ({}) to rollback, "
|
||||
"but data parts set is empty and table {} was not dropped. It's a bug",
|
||||
@ -6746,8 +6782,12 @@ void MergeTreeData::Transaction::rollback(DataPartsLock * lock)
|
||||
}
|
||||
else
|
||||
{
|
||||
data.removePartsFromWorkingSetImmediatelyAndSetTemporaryState(
|
||||
detached_precommitted_parts,
|
||||
&our_lock);
|
||||
|
||||
data.removePartsFromWorkingSet(txn,
|
||||
DataPartsVector(precommitted_parts.begin(), precommitted_parts.end()),
|
||||
DataPartsVector(non_detached_precommitted_parts.begin(), non_detached_precommitted_parts.end()),
|
||||
/* clear_without_timeout = */ true, &our_lock);
|
||||
}
|
||||
}
|
||||
@ -6757,7 +6797,19 @@ void MergeTreeData::Transaction::rollback(DataPartsLock * lock)
|
||||
|
||||
void MergeTreeData::Transaction::clear()
|
||||
{
|
||||
chassert(precommitted_parts.size() >= precommitted_parts_need_rename.size());
|
||||
precommitted_parts.clear();
|
||||
precommitted_parts_need_rename.clear();
|
||||
}
|
||||
|
||||
void MergeTreeData::Transaction::renameParts()
|
||||
{
|
||||
for (const auto & part_need_rename : precommitted_parts_need_rename)
|
||||
{
|
||||
LOG_TEST(data.log, "Renaming part to {}", part_need_rename->name);
|
||||
part_need_rename->renameTo(part_need_rename->name, true);
|
||||
}
|
||||
precommitted_parts_need_rename.clear();
|
||||
}
|
||||
|
||||
MergeTreeData::DataPartsVector MergeTreeData::Transaction::commit(DataPartsLock * acquired_parts_lock)
|
||||
@ -6766,6 +6818,9 @@ MergeTreeData::DataPartsVector MergeTreeData::Transaction::commit(DataPartsLock
|
||||
|
||||
if (!isEmpty())
|
||||
{
|
||||
if (!precommitted_parts_need_rename.empty())
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Parts had not been renamed");
|
||||
|
||||
auto settings = data.getSettings();
|
||||
auto parts_lock = acquired_parts_lock ? DataPartsLock() : data.lockParts();
|
||||
auto * owing_parts_lock = acquired_parts_lock ? acquired_parts_lock : &parts_lock;
|
||||
|
@ -255,7 +255,12 @@ public:
|
||||
|
||||
DataPartsVector commit(DataPartsLock * acquired_parts_lock = nullptr);
|
||||
|
||||
void addPart(MutableDataPartPtr & part);
|
||||
/// Rename should be done explicitly, before calling commit(), to
|
||||
/// guarantee that no lock held during rename (since rename is IO
|
||||
/// bound, while data parts lock is the bottleneck)
|
||||
void renameParts();
|
||||
|
||||
void addPart(MutableDataPartPtr & part, bool need_rename);
|
||||
|
||||
void rollback(DataPartsLock * lock = nullptr);
|
||||
|
||||
@ -286,9 +291,9 @@ public:
|
||||
|
||||
MergeTreeData & data;
|
||||
MergeTreeTransaction * txn;
|
||||
MutableDataParts precommitted_parts;
|
||||
MutableDataParts locked_parts;
|
||||
|
||||
MutableDataParts precommitted_parts;
|
||||
MutableDataParts precommitted_parts_need_rename;
|
||||
};
|
||||
|
||||
using TransactionUniquePtr = std::unique_ptr<Transaction>;
|
||||
@ -627,25 +632,27 @@ public:
|
||||
bool renameTempPartAndAdd(
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & transaction,
|
||||
DataPartsLock & lock);
|
||||
DataPartsLock & lock,
|
||||
bool rename_in_transaction);
|
||||
|
||||
/// The same as renameTempPartAndAdd but the block range of the part can contain existing parts.
|
||||
/// Returns all parts covered by the added part (in ascending order).
|
||||
DataPartsVector renameTempPartAndReplace(
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & out_transaction);
|
||||
Transaction & out_transaction,
|
||||
bool rename_in_transaction);
|
||||
|
||||
/// Unlocked version of previous one. Useful when added multiple parts with a single lock.
|
||||
bool renameTempPartAndReplaceUnlocked(
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & out_transaction,
|
||||
DataPartsLock & lock,
|
||||
DataPartsVector * out_covered_parts = nullptr);
|
||||
bool rename_in_transaction);
|
||||
|
||||
/// Remove parts from working set immediately (without wait for background
|
||||
/// process). Transfer part state to temporary. Have very limited usage only
|
||||
/// for new parts which aren't already present in table.
|
||||
void removePartsFromWorkingSetImmediatelyAndSetTemporaryState(const DataPartsVector & remove);
|
||||
void removePartsFromWorkingSetImmediatelyAndSetTemporaryState(const DataPartsVector & remove, DataPartsLock * acquired_lock = nullptr);
|
||||
|
||||
/// Removes parts from the working set parts.
|
||||
/// Parts in add must already be in data_parts with PreActive, Active, or Outdated states.
|
||||
@ -1646,7 +1653,10 @@ private:
|
||||
|
||||
/// Preparing itself to be committed in memory: fill some fields inside part, add it to data_parts_indexes
|
||||
/// in precommitted state and to transaction
|
||||
void preparePartForCommit(MutableDataPartPtr & part, Transaction & out_transaction, bool need_rename);
|
||||
///
|
||||
/// @param need_rename - rename the part
|
||||
/// @param rename_in_transaction - if set, the rename will be done as part of transaction (without holding DataPartsLock), otherwise inplace (when it does not make sense).
|
||||
void preparePartForCommit(MutableDataPartPtr & part, Transaction & out_transaction, bool need_rename, bool rename_in_transaction = false);
|
||||
|
||||
/// Low-level method for preparing parts for commit (in-memory).
|
||||
/// FIXME Merge MergeTreeTransaction and Transaction
|
||||
@ -1654,7 +1664,8 @@ private:
|
||||
MutableDataPartPtr & part,
|
||||
Transaction & out_transaction,
|
||||
DataPartsLock & lock,
|
||||
DataPartsVector * out_covered_parts);
|
||||
DataPartsVector * out_covered_parts,
|
||||
bool rename_in_transaction);
|
||||
|
||||
/// RAII Wrapper for atomic work with currently moving parts
|
||||
/// Acquire them in constructor and remove them in destructor
|
||||
|
@ -750,7 +750,10 @@ MergeTreeData::DataPartPtr MergeTreeDataMergerMutator::renameMergedTemporaryPart
|
||||
"but transactions were enabled for this table");
|
||||
|
||||
/// Rename new part, add to the set and remove original parts.
|
||||
auto replaced_parts = data.renameTempPartAndReplace(new_data_part, out_transaction);
|
||||
auto replaced_parts = data.renameTempPartAndReplace(new_data_part, out_transaction, /*rename_in_transaction=*/ true);
|
||||
|
||||
/// Explicitly rename part while still holding the lock for tmp folder to avoid cleanup
|
||||
out_transaction.renameParts();
|
||||
|
||||
/// Let's check that all original parts have been deleted and only them.
|
||||
if (replaced_parts.size() != parts.size())
|
||||
@ -780,7 +783,14 @@ MergeTreeData::DataPartPtr MergeTreeDataMergerMutator::renameMergedTemporaryPart
|
||||
* (NOTE: Merging with part that is not in ZK is not possible, see checks in 'createLogEntryToMergeParts'.)
|
||||
* - and after merge, this part will be removed in addition to parts that was merged.
|
||||
*/
|
||||
LOG_WARNING(log, "Unexpected number of parts removed when adding {}: {} instead of {}", new_data_part->name, replaced_parts.size(), parts.size());
|
||||
LOG_WARNING(log, "Unexpected number of parts removed when adding {}: {} instead of {}\n"
|
||||
"Replaced parts:\n{}\n"
|
||||
"Parts:\n{}\n",
|
||||
new_data_part->name,
|
||||
replaced_parts.size(),
|
||||
parts.size(),
|
||||
fmt::join(getPartsNames(replaced_parts), "\n"),
|
||||
fmt::join(getPartsNames(parts), "\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -226,7 +226,17 @@ void MergeTreeSink::finishDelayedChunk()
|
||||
}
|
||||
}
|
||||
|
||||
added = storage.renameTempPartAndAdd(part, transaction, lock);
|
||||
/// FIXME: renames for MergeTree should be done under the same lock
|
||||
/// to avoid removing extra covered parts after merge.
|
||||
///
|
||||
/// Image the following:
|
||||
/// - T1: all_2_2_0 is in renameParts()
|
||||
/// - T2: merge assigned for [all_1_1_0, all_3_3_0]
|
||||
/// - T1: renameParts() finished, part had been added as Active
|
||||
/// - T2: merge finished, covered parts removed, and it will include all_2_2_0!
|
||||
///
|
||||
/// Hence, for now rename_in_transaction is false.
|
||||
added = storage.renameTempPartAndAdd(part, transaction, lock, /*rename_in_transaction=*/ false);
|
||||
transaction.commit(&lock);
|
||||
}
|
||||
|
||||
|
@ -237,10 +237,11 @@ bool MutateFromLogEntryTask::finalize(ReplicatedMergeMutateTaskBase::PartLogWrit
|
||||
if (data_part_storage.hasActiveTransaction())
|
||||
data_part_storage.precommitTransaction();
|
||||
|
||||
storage.renameTempPartAndReplace(new_part, *transaction_ptr);
|
||||
storage.renameTempPartAndReplace(new_part, *transaction_ptr, /*rename_in_transaction=*/ true);
|
||||
|
||||
try
|
||||
{
|
||||
transaction_ptr->renameParts();
|
||||
storage.checkPartChecksumsAndCommit(*transaction_ptr, new_part, mutate_task->getHardlinkedFiles());
|
||||
}
|
||||
catch (const Exception & e)
|
||||
|
@ -102,7 +102,8 @@ bool MutatePlainMergeTreeTask::executeStep()
|
||||
|
||||
MergeTreeData::Transaction transaction(storage, merge_mutate_entry->txn.get());
|
||||
/// FIXME Transactions: it's too optimistic, better to lock parts before starting transaction
|
||||
storage.renameTempPartAndReplace(new_part, transaction);
|
||||
storage.renameTempPartAndReplace(new_part, transaction, /*rename_in_transaction=*/ true);
|
||||
transaction.renameParts();
|
||||
transaction.commit();
|
||||
|
||||
storage.updateMutationEntriesErrors(future_part, true, "");
|
||||
|
@ -124,6 +124,7 @@ static void splitAndModifyMutationCommands(
|
||||
const MutationCommands & commands,
|
||||
MutationCommands & for_interpreter,
|
||||
MutationCommands & for_file_renames,
|
||||
bool suitable_for_ttl_optimization,
|
||||
LoggerPtr log)
|
||||
{
|
||||
auto part_columns = part->getColumnsDescription();
|
||||
@ -133,6 +134,7 @@ static void splitAndModifyMutationCommands(
|
||||
{
|
||||
NameSet mutated_columns;
|
||||
NameSet dropped_columns;
|
||||
NameSet ignored_columns;
|
||||
|
||||
for (const auto & command : commands)
|
||||
{
|
||||
@ -158,6 +160,15 @@ static void splitAndModifyMutationCommands(
|
||||
for_interpreter.push_back(command);
|
||||
for (const auto & [column_name, expr] : command.column_to_update_expression)
|
||||
mutated_columns.emplace(column_name);
|
||||
|
||||
if (command.type == MutationCommand::Type::MATERIALIZE_TTL && suitable_for_ttl_optimization)
|
||||
{
|
||||
for (const auto & col : part_columns)
|
||||
{
|
||||
if (!mutated_columns.contains(col.name))
|
||||
ignored_columns.emplace(col.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (command.type == MutationCommand::Type::DROP_INDEX
|
||||
|| command.type == MutationCommand::Type::DROP_PROJECTION
|
||||
@ -218,7 +229,7 @@ static void splitAndModifyMutationCommands(
|
||||
/// from disk we just don't read dropped columns
|
||||
for (const auto & column : part_columns)
|
||||
{
|
||||
if (!mutated_columns.contains(column.name))
|
||||
if (!mutated_columns.contains(column.name) && !ignored_columns.contains(column.name))
|
||||
{
|
||||
if (!metadata_snapshot->getColumns().has(column.name) && !part->storage.getVirtualsPtr()->has(column.name))
|
||||
{
|
||||
@ -1889,6 +1900,82 @@ private:
|
||||
std::unique_ptr<PartMergerWriter> part_merger_writer_task{nullptr};
|
||||
};
|
||||
|
||||
/*
|
||||
* Decorator that'll drop expired parts by replacing them with empty ones.
|
||||
* Main use case (only use case for now) is to decorate `MutateSomePartColumnsTask`,
|
||||
* which is used to recalculate TTL. If the part is expired, this class will replace it with
|
||||
* an empty one.
|
||||
*
|
||||
* Triggered when `ttl_only_drop_parts` is set and the only TTL is rows TTL.
|
||||
* */
|
||||
class ExecutableTaskDropTTLExpiredPartsDecorator : public IExecutableTask
|
||||
{
|
||||
public:
|
||||
explicit ExecutableTaskDropTTLExpiredPartsDecorator(
|
||||
std::unique_ptr<IExecutableTask> executable_task_,
|
||||
MutationContextPtr ctx_
|
||||
)
|
||||
: executable_task(std::move(executable_task_)), ctx(ctx_) {}
|
||||
|
||||
void onCompleted() override { throw Exception(ErrorCodes::LOGICAL_ERROR, "Not implemented"); }
|
||||
StorageID getStorageID() const override { throw Exception(ErrorCodes::LOGICAL_ERROR, "Not implemented"); }
|
||||
Priority getPriority() const override { throw Exception(ErrorCodes::LOGICAL_ERROR, "Not implemented"); }
|
||||
String getQueryId() const override { throw Exception(ErrorCodes::LOGICAL_ERROR, "Not implemented"); }
|
||||
|
||||
bool executeStep() override
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case State::NEED_EXECUTE:
|
||||
{
|
||||
if (executable_task->executeStep())
|
||||
return true;
|
||||
|
||||
if (isRowsMaxTTLExpired())
|
||||
replacePartWithEmpty();
|
||||
|
||||
state = State::SUCCESS;
|
||||
return true;
|
||||
}
|
||||
case State::SUCCESS:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class State
|
||||
{
|
||||
NEED_EXECUTE,
|
||||
|
||||
SUCCESS
|
||||
};
|
||||
|
||||
State state{State::NEED_EXECUTE};
|
||||
|
||||
std::unique_ptr<IExecutableTask> executable_task;
|
||||
MutationContextPtr ctx;
|
||||
|
||||
bool isRowsMaxTTLExpired() const
|
||||
{
|
||||
const auto ttl = ctx->new_data_part->ttl_infos.table_ttl;
|
||||
return ttl.max && ttl.max <= ctx->time_of_mutation;
|
||||
}
|
||||
|
||||
void replacePartWithEmpty()
|
||||
{
|
||||
MergeTreePartInfo part_info = ctx->new_data_part->info;
|
||||
part_info.level += 1;
|
||||
|
||||
MergeTreePartition partition = ctx->new_data_part->partition;
|
||||
std::string part_name = ctx->new_data_part->getNewName(part_info);
|
||||
|
||||
auto [mutable_empty_part, _] = ctx->data->createEmptyPart(part_info, partition, part_name, ctx->txn);
|
||||
ctx->new_data_part = std::move(mutable_empty_part);
|
||||
}
|
||||
};
|
||||
|
||||
MutateTask::MutateTask(
|
||||
FutureMergedMutatedPartPtr future_part_,
|
||||
@ -2127,6 +2214,7 @@ bool MutateTask::prepare()
|
||||
context_for_reading->setSetting("max_streams_for_merge_tree_reading", Field(0));
|
||||
context_for_reading->setSetting("read_from_filesystem_cache_if_exists_otherwise_bypass_cache", 1);
|
||||
|
||||
bool suitable_for_ttl_optimization = ctx->metadata_snapshot->hasOnlyRowsTTL() && ctx->data->getSettings()->ttl_only_drop_parts;
|
||||
MutationHelpers::splitAndModifyMutationCommands(
|
||||
ctx->source_part,
|
||||
ctx->metadata_snapshot,
|
||||
@ -2134,6 +2222,7 @@ bool MutateTask::prepare()
|
||||
ctx->commands_for_part,
|
||||
ctx->for_interpreter,
|
||||
ctx->for_file_renames,
|
||||
suitable_for_ttl_optimization,
|
||||
ctx->log);
|
||||
|
||||
ctx->stage_progress = std::make_unique<MergeStageProgress>(1.0);
|
||||
@ -2240,7 +2329,12 @@ bool MutateTask::prepare()
|
||||
/// The blobs have to be removed along with the part, this temporary part owns them and does not share them yet.
|
||||
ctx->new_data_part->remove_tmp_policy = IMergeTreeDataPart::BlobsRemovalPolicyForTemporaryParts::REMOVE_BLOBS;
|
||||
|
||||
task = std::make_unique<MutateAllPartColumnsTask>(ctx);
|
||||
bool drop_expired_parts = suitable_for_ttl_optimization && !ctx->data->getSettings()->materialize_ttl_recalculate_only;
|
||||
if (drop_expired_parts)
|
||||
task = std::make_unique<ExecutableTaskDropTTLExpiredPartsDecorator>(std::make_unique<MutateAllPartColumnsTask>(ctx), ctx);
|
||||
else
|
||||
task = std::make_unique<MutateAllPartColumnsTask>(ctx);
|
||||
|
||||
ProfileEvents::increment(ProfileEvents::MutationAllPartColumns);
|
||||
}
|
||||
else /// TODO: check that we modify only non-key columns in this case.
|
||||
@ -2300,7 +2394,12 @@ bool MutateTask::prepare()
|
||||
/// Keeper has to be asked with unlock request to release the references to the blobs
|
||||
ctx->new_data_part->remove_tmp_policy = IMergeTreeDataPart::BlobsRemovalPolicyForTemporaryParts::ASK_KEEPER;
|
||||
|
||||
task = std::make_unique<MutateSomePartColumnsTask>(ctx);
|
||||
bool drop_expired_parts = suitable_for_ttl_optimization && !ctx->data->getSettings()->materialize_ttl_recalculate_only;
|
||||
if (drop_expired_parts)
|
||||
task = std::make_unique<ExecutableTaskDropTTLExpiredPartsDecorator>(std::make_unique<MutateSomePartColumnsTask>(ctx), ctx);
|
||||
else
|
||||
task = std::make_unique<MutateSomePartColumnsTask>(ctx);
|
||||
|
||||
ProfileEvents::increment(ProfileEvents::MutationSomePartColumns);
|
||||
}
|
||||
|
||||
|
@ -917,7 +917,7 @@ std::pair<std::vector<String>, bool> ReplicatedMergeTreeSinkImpl<async_insert>::
|
||||
try
|
||||
{
|
||||
auto lock = storage.lockParts();
|
||||
storage.renameTempPartAndAdd(part, transaction, lock);
|
||||
storage.renameTempPartAndAdd(part, transaction, lock, /*rename_in_transaction=*/ true);
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
@ -932,6 +932,9 @@ std::pair<std::vector<String>, bool> ReplicatedMergeTreeSinkImpl<async_insert>::
|
||||
throw;
|
||||
}
|
||||
|
||||
/// Rename parts before committing to ZooKeeper without holding DataPartsLock.
|
||||
transaction.renameParts();
|
||||
|
||||
ThreadFuzzer::maybeInjectSleep();
|
||||
|
||||
fiu_do_on(FailPoints::replicated_merge_tree_commit_zk_fail_after_op, { zookeeper->forceFailureAfterOperation(); });
|
||||
|
@ -1295,13 +1295,15 @@ void StorageDistributed::initializeFromDisk()
|
||||
|
||||
void StorageDistributed::shutdown(bool)
|
||||
{
|
||||
async_insert_blocker.cancelForever();
|
||||
auto holder = async_insert_blocker.cancel();
|
||||
|
||||
std::lock_guard lock(cluster_nodes_mutex);
|
||||
|
||||
LOG_DEBUG(log, "Joining background threads for async INSERT");
|
||||
cluster_nodes_data.clear();
|
||||
LOG_DEBUG(log, "Background threads for async INSERT joined");
|
||||
|
||||
async_insert_blocker.cancelForever();
|
||||
}
|
||||
|
||||
void StorageDistributed::drop()
|
||||
|
@ -260,6 +260,12 @@ bool StorageInMemoryMetadata::hasAnyTableTTL() const
|
||||
return hasAnyMoveTTL() || hasRowsTTL() || hasAnyRecompressionTTL() || hasAnyGroupByTTL() || hasAnyRowsWhereTTL();
|
||||
}
|
||||
|
||||
bool StorageInMemoryMetadata::hasOnlyRowsTTL() const
|
||||
{
|
||||
bool has_any_other_ttl = hasAnyMoveTTL() || hasAnyRecompressionTTL() || hasAnyGroupByTTL() || hasAnyRowsWhereTTL() || hasAnyColumnTTL();
|
||||
return hasRowsTTL() && !has_any_other_ttl;
|
||||
}
|
||||
|
||||
TTLColumnsDescription StorageInMemoryMetadata::getColumnTTLs() const
|
||||
{
|
||||
return column_ttls_by_name;
|
||||
|
@ -144,6 +144,9 @@ struct StorageInMemoryMetadata
|
||||
/// Returns true if there is set table TTL, any column TTL or any move TTL.
|
||||
bool hasAnyTTL() const { return hasAnyColumnTTL() || hasAnyTableTTL(); }
|
||||
|
||||
/// Returns true if only rows TTL is set, not even rows where.
|
||||
bool hasOnlyRowsTTL() const;
|
||||
|
||||
/// Common tables TTLs (for rows and moves).
|
||||
TTLTableDescription getTableTTLs() const;
|
||||
bool hasAnyTableTTL() const;
|
||||
|
@ -1795,7 +1795,7 @@ void StorageMergeTree::renameAndCommitEmptyParts(MutableDataPartsVector & new_pa
|
||||
|
||||
for (auto & part: new_parts)
|
||||
{
|
||||
DataPartsVector covered_parts_by_one_part = renameTempPartAndReplace(part, transaction);
|
||||
DataPartsVector covered_parts_by_one_part = renameTempPartAndReplace(part, transaction, /*rename_in_transaction=*/ true);
|
||||
|
||||
if (covered_parts_by_one_part.size() > 1)
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR,
|
||||
@ -1805,10 +1805,10 @@ void StorageMergeTree::renameAndCommitEmptyParts(MutableDataPartsVector & new_pa
|
||||
|
||||
std::move(covered_parts_by_one_part.begin(), covered_parts_by_one_part.end(), std::back_inserter(covered_parts));
|
||||
}
|
||||
|
||||
LOG_INFO(log, "Remove {} parts by covering them with empty {} parts. With txn {}.",
|
||||
covered_parts.size(), new_parts.size(), transaction.getTID());
|
||||
|
||||
transaction.renameParts();
|
||||
transaction.commit();
|
||||
|
||||
/// Remove covered parts without waiting for old_parts_lifetime seconds.
|
||||
@ -2071,7 +2071,7 @@ PartitionCommandsResultInfo StorageMergeTree::attachPartition(
|
||||
{
|
||||
auto lock = lockParts();
|
||||
fillNewPartNameAndResetLevel(loaded_parts[i], lock);
|
||||
renameTempPartAndAdd(loaded_parts[i], transaction, lock);
|
||||
renameTempPartAndAdd(loaded_parts[i], transaction, lock, /*rename_in_transaction=*/ false);
|
||||
transaction.commit(&lock);
|
||||
}
|
||||
|
||||
@ -2203,7 +2203,7 @@ void StorageMergeTree::replacePartitionFrom(const StoragePtr & source_table, con
|
||||
for (auto part : dst_parts)
|
||||
{
|
||||
fillNewPartName(part, data_parts_lock);
|
||||
renameTempPartAndReplaceUnlocked(part, transaction, data_parts_lock);
|
||||
renameTempPartAndReplaceUnlocked(part, transaction, data_parts_lock, /*rename_in_transaction=*/ false);
|
||||
}
|
||||
/// Populate transaction
|
||||
transaction.commit(&data_parts_lock);
|
||||
@ -2307,10 +2307,9 @@ void StorageMergeTree::movePartitionToTable(const StoragePtr & dest_table, const
|
||||
for (auto & part : dst_parts)
|
||||
{
|
||||
dest_table_storage->fillNewPartName(part, dest_data_parts_lock);
|
||||
dest_table_storage->renameTempPartAndReplaceUnlocked(part, transaction, dest_data_parts_lock);
|
||||
dest_table_storage->renameTempPartAndReplaceUnlocked(part, transaction, dest_data_parts_lock, /*rename_in_transaction=*/ false);
|
||||
}
|
||||
|
||||
|
||||
removePartsFromWorkingSet(local_context->getCurrentTransaction().get(), src_parts, true, src_data_parts_lock);
|
||||
transaction.commit(&src_data_parts_lock);
|
||||
}
|
||||
@ -2470,7 +2469,7 @@ void StorageMergeTree::attachRestoredParts(MutableDataPartsVector && parts)
|
||||
{
|
||||
auto lock = lockParts();
|
||||
fillNewPartName(part, lock);
|
||||
renameTempPartAndAdd(part, transaction, lock);
|
||||
renameTempPartAndAdd(part, transaction, lock, /*rename_in_transaction=*/ false);
|
||||
transaction.commit(&lock);
|
||||
}
|
||||
}
|
||||
|
@ -2125,7 +2125,8 @@ bool StorageReplicatedMergeTree::executeLogEntry(LogEntry & entry)
|
||||
Transaction transaction(*this, NO_TRANSACTION_RAW);
|
||||
|
||||
part->version.setCreationTID(Tx::PrehistoricTID, nullptr);
|
||||
renameTempPartAndReplace(part, transaction);
|
||||
renameTempPartAndReplace(part, transaction, /*rename_in_transaction=*/ true);
|
||||
transaction.renameParts();
|
||||
checkPartChecksumsAndCommit(transaction, part);
|
||||
|
||||
writePartLog(PartLogElement::Type::NEW_PART, {}, 0 /** log entry is fake so we don't measure the time */,
|
||||
@ -2914,11 +2915,11 @@ bool StorageReplicatedMergeTree::executeReplaceRange(LogEntry & entry)
|
||||
Coordination::Requests ops;
|
||||
for (PartDescriptionPtr & part_desc : final_parts)
|
||||
{
|
||||
renameTempPartAndReplace(part_desc->res_part, transaction);
|
||||
renameTempPartAndReplace(part_desc->res_part, transaction, /*rename_in_transaction=*/ true);
|
||||
getCommitPartOps(ops, part_desc->res_part);
|
||||
|
||||
lockSharedData(*part_desc->res_part, /* replace_existing_lock */ true, part_desc->hardlinked_files);
|
||||
lockSharedData(*part_desc->res_part, /*replace_existing_lock=*/ true, part_desc->hardlinked_files);
|
||||
}
|
||||
transaction.renameParts();
|
||||
|
||||
|
||||
if (!ops.empty())
|
||||
@ -4990,7 +4991,8 @@ bool StorageReplicatedMergeTree::fetchPart(
|
||||
if (!to_detached)
|
||||
{
|
||||
Transaction transaction(*this, NO_TRANSACTION_RAW);
|
||||
renameTempPartAndReplace(part, transaction);
|
||||
renameTempPartAndReplace(part, transaction, /*rename_in_transaction=*/ true);
|
||||
transaction.renameParts();
|
||||
|
||||
chassert(!part_to_clone || !is_zero_copy_part(part));
|
||||
replaced_parts = checkPartChecksumsAndCommit(transaction, part, /*hardlinked_files*/ {}, /*replace_zero_copy_lock*/ true);
|
||||
@ -8324,8 +8326,9 @@ std::unique_ptr<ReplicatedMergeTreeLogEntryData> StorageReplicatedMergeTree::rep
|
||||
{
|
||||
auto data_parts_lock = lockParts();
|
||||
for (auto & part : dst_parts)
|
||||
renameTempPartAndReplaceUnlocked(part, transaction, data_parts_lock);
|
||||
renameTempPartAndReplaceUnlocked(part, transaction, data_parts_lock, /*rename_in_transaction=*/ true);
|
||||
}
|
||||
transaction.renameParts();
|
||||
|
||||
for (const auto & dst_part : dst_parts)
|
||||
lockSharedData(*dst_part, false, /*hardlinked_files*/ {});
|
||||
@ -8594,7 +8597,7 @@ void StorageReplicatedMergeTree::movePartitionToTable(const StoragePtr & dest_ta
|
||||
auto dest_data_parts_lock = dest_table_storage->lockParts();
|
||||
|
||||
for (auto & part : dst_parts)
|
||||
dest_table_storage->renameTempPartAndReplaceUnlocked(part, transaction, dest_data_parts_lock);
|
||||
dest_table_storage->renameTempPartAndReplaceUnlocked(part, transaction, dest_data_parts_lock, /*rename_in_transaction=*/ false);
|
||||
|
||||
for (const auto & dst_part : dst_parts)
|
||||
dest_table_storage->lockSharedData(*dst_part, false, /*hardlinked_files*/ {});
|
||||
@ -10225,7 +10228,8 @@ bool StorageReplicatedMergeTree::createEmptyPartInsteadOfLost(zkutil::ZooKeeperP
|
||||
try
|
||||
{
|
||||
MergeTreeData::Transaction transaction(*this, NO_TRANSACTION_RAW);
|
||||
auto replaced_parts = renameTempPartAndReplace(new_data_part, transaction);
|
||||
auto replaced_parts = renameTempPartAndReplace(new_data_part, transaction, /*rename_in_transaction=*/ true);
|
||||
transaction.renameParts();
|
||||
|
||||
if (!replaced_parts.empty())
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ const char * auto_contributors[] {
|
||||
"0xflotus",
|
||||
"13DaGGeR",
|
||||
"1lann",
|
||||
"1on",
|
||||
"20018712",
|
||||
"243f6a88 85a308d3",
|
||||
"243f6a8885a308d313198a2e037",
|
||||
@ -102,12 +103,14 @@ const char * auto_contributors[] {
|
||||
"Alexey Katsman",
|
||||
"Alexey Korepanov",
|
||||
"Alexey Milovidov",
|
||||
"Alexey Olshanskiy",
|
||||
"Alexey Perevyshin",
|
||||
"Alexey Petrunyaka",
|
||||
"Alexey Tronov",
|
||||
"Alexey Vasiliev",
|
||||
"Alexey Zatelepin",
|
||||
"AlexeyGrezz",
|
||||
"Alexis Arnaud",
|
||||
"Alexsey Shestakov",
|
||||
"AlfVII",
|
||||
"Alfonso Martinez",
|
||||
@ -214,6 +217,7 @@ const char * auto_contributors[] {
|
||||
"Ash Vardanian",
|
||||
"AsiaKorushkina",
|
||||
"Atri Sharma",
|
||||
"Austin Bruch",
|
||||
"Austin Kothig",
|
||||
"Avery Fischer",
|
||||
"Avogar",
|
||||
@ -323,12 +327,14 @@ const char * auto_contributors[] {
|
||||
"Davit Vardanyan",
|
||||
"Denis Burlaka",
|
||||
"Denis Glazachev",
|
||||
"Denis Hananein",
|
||||
"Denis Krivak",
|
||||
"Denis Zhuravlev",
|
||||
"Denny Crane",
|
||||
"Denys Golotiuk",
|
||||
"Derek Chia",
|
||||
"Derek Perkins",
|
||||
"Dergousov",
|
||||
"Diego Nieto",
|
||||
"Diego Nieto (lesandie)",
|
||||
"DimaAmega",
|
||||
@ -440,6 +446,7 @@ const char * auto_contributors[] {
|
||||
"Gabriel",
|
||||
"Gabriel Archer",
|
||||
"Gabriel Martinez",
|
||||
"Gabriel Mendes",
|
||||
"Gagan Arneja",
|
||||
"Gagan Goel",
|
||||
"Gao Qiang",
|
||||
@ -639,6 +646,7 @@ const char * auto_contributors[] {
|
||||
"Konstantin Morozov",
|
||||
"Konstantin Podshumok",
|
||||
"Konstantin Rudenskii",
|
||||
"Konstantin Smirnov",
|
||||
"Korenevskiy Denis",
|
||||
"Korviakov Andrey",
|
||||
"Kostiantyn Storozhuk",
|
||||
@ -646,6 +654,7 @@ const char * auto_contributors[] {
|
||||
"KrJin",
|
||||
"Kris Buytaert",
|
||||
"Krisztián Szűcs",
|
||||
"Kruglov Kirill",
|
||||
"Kruglov Pavel",
|
||||
"Krzysztof Góralski",
|
||||
"Kseniia Sumarokova",
|
||||
@ -714,6 +723,7 @@ const char * auto_contributors[] {
|
||||
"Manuel de la Peña",
|
||||
"Marat IDRISOV",
|
||||
"Marcelo Rodriguez",
|
||||
"Marco Vilas Boas",
|
||||
"Marek Vavrusa",
|
||||
"Marek Vavruša",
|
||||
"Marek Vavruša",
|
||||
@ -732,6 +742,7 @@ const char * auto_contributors[] {
|
||||
"Marvin Taschenberger",
|
||||
"Masha",
|
||||
"Mathieu Rey",
|
||||
"Matt Woenker",
|
||||
"Matthew Peveler",
|
||||
"Mattias Naarttijärvi",
|
||||
"Matwey V. Kornilov",
|
||||
@ -747,6 +758,7 @@ const char * auto_contributors[] {
|
||||
"Maxim Akhmedov",
|
||||
"Maxim Alexeev",
|
||||
"Maxim Babenko",
|
||||
"Maxim Dergousov",
|
||||
"Maxim Fedotov",
|
||||
"Maxim Fridental",
|
||||
"Maxim Khrisanfov",
|
||||
@ -777,6 +789,7 @@ const char * auto_contributors[] {
|
||||
"Michael Stetsyuk",
|
||||
"Michail Safronov",
|
||||
"Michal Lisowski",
|
||||
"Michal Tabaszewski",
|
||||
"MicrochipQ",
|
||||
"Miel Donkers",
|
||||
"Miguel Fernández",
|
||||
@ -808,6 +821,7 @@ const char * auto_contributors[] {
|
||||
"Mingliang Pan",
|
||||
"Misko Lee",
|
||||
"Misz606",
|
||||
"Miсhael Stetsyuk",
|
||||
"MochiXu",
|
||||
"Mohamad Fadhil",
|
||||
"Mohammad Arab Anvari",
|
||||
@ -842,6 +856,7 @@ const char * auto_contributors[] {
|
||||
"Nicolae Vartolomei",
|
||||
"Niek",
|
||||
"Nik",
|
||||
"NikBarykin",
|
||||
"Nikhil Nadig",
|
||||
"Nikhil Raman",
|
||||
"Nikifor Seriakov",
|
||||
@ -883,6 +898,7 @@ const char * auto_contributors[] {
|
||||
"Oleg Strokachuk",
|
||||
"Oleg Taizov",
|
||||
"Oleg V. Kozlyuk",
|
||||
"Oleksandr",
|
||||
"Olga Khvostikova",
|
||||
"Olga Revyakina",
|
||||
"OmarBazaraa",
|
||||
@ -918,6 +934,7 @@ const char * auto_contributors[] {
|
||||
"Pawel Rog",
|
||||
"Paweł Kudzia",
|
||||
"Pazitiff9",
|
||||
"Pedro Ferreira",
|
||||
"Peignon Melvyn",
|
||||
"Peng Jian",
|
||||
"Peng Liu",
|
||||
@ -965,6 +982,7 @@ const char * auto_contributors[] {
|
||||
"Robert Hodges",
|
||||
"Robert Schulze",
|
||||
"Rodolphe Dugé de Bernonville",
|
||||
"Rodrigo Garcia",
|
||||
"RogerYK",
|
||||
"Rohit Agarwal",
|
||||
"Romain Neutron",
|
||||
@ -1006,6 +1024,7 @@ const char * auto_contributors[] {
|
||||
"Sami Kerola",
|
||||
"Samuel Chou",
|
||||
"Samuel Colvin",
|
||||
"Samuel Warfield",
|
||||
"Samuele Guerrini",
|
||||
"San",
|
||||
"Sanjam Panda",
|
||||
@ -1025,6 +1044,7 @@ const char * auto_contributors[] {
|
||||
"Sergei Solomatov",
|
||||
"Sergei Trifonov",
|
||||
"Sergei Tsetlin (rekub)",
|
||||
"Sergey (Finn) Gnezdilov",
|
||||
"Sergey Demurin",
|
||||
"Sergey Elantsev",
|
||||
"Sergey Fedorov",
|
||||
@ -1139,6 +1159,7 @@ const char * auto_contributors[] {
|
||||
"Tristan",
|
||||
"Tsarkova Anastasia",
|
||||
"TszkitLo40",
|
||||
"Tuan Pham Anh",
|
||||
"Tyler Hannan",
|
||||
"Ubuntu",
|
||||
"Ubus",
|
||||
@ -1282,6 +1303,7 @@ const char * auto_contributors[] {
|
||||
"ZhiYong Wang",
|
||||
"Zhichang Yu",
|
||||
"Zhichun Wu",
|
||||
"Zhigao Hong",
|
||||
"Zhiguo Zhou",
|
||||
"Zhipeng",
|
||||
"Zhukova, Maria",
|
||||
@ -1351,6 +1373,7 @@ const char * auto_contributors[] {
|
||||
"awakeljw",
|
||||
"awesomeleo",
|
||||
"bakam412",
|
||||
"baolin.hbl",
|
||||
"bbkas",
|
||||
"beetelbrox",
|
||||
"benamazing",
|
||||
@ -1490,6 +1513,7 @@ const char * auto_contributors[] {
|
||||
"fyu",
|
||||
"g-arslan",
|
||||
"gabrielmcg44",
|
||||
"gao chuan",
|
||||
"ggerogery",
|
||||
"giordyb",
|
||||
"glockbender",
|
||||
@ -1508,6 +1532,7 @@ const char * auto_contributors[] {
|
||||
"hanqf-git",
|
||||
"hao.he",
|
||||
"haohang",
|
||||
"haozelong",
|
||||
"hardstep33",
|
||||
"hchen9",
|
||||
"hcz",
|
||||
@ -1538,6 +1563,7 @@ const char * auto_contributors[] {
|
||||
"igor.lapko",
|
||||
"ikarishinjieva",
|
||||
"ikopylov",
|
||||
"imddba",
|
||||
"imgbot[bot]",
|
||||
"ip",
|
||||
"irenjj",
|
||||
@ -1595,6 +1621,7 @@ const char * auto_contributors[] {
|
||||
"koshachy",
|
||||
"kothiga",
|
||||
"kreuzerkrieg",
|
||||
"kruglov",
|
||||
"ks1322",
|
||||
"kshvakov",
|
||||
"kssenii",
|
||||
@ -1608,6 +1635,7 @@ const char * auto_contributors[] {
|
||||
"laurieliyang",
|
||||
"lcjh",
|
||||
"lehasm",
|
||||
"leonkozlowski",
|
||||
"leosunli",
|
||||
"leozhang",
|
||||
"levie",
|
||||
@ -1657,12 +1685,14 @@ const char * auto_contributors[] {
|
||||
"luocongkai",
|
||||
"lzydmxy",
|
||||
"m-ves",
|
||||
"m4xxx1m",
|
||||
"madianjun",
|
||||
"maiha",
|
||||
"maks-buren630501",
|
||||
"malkfilipp",
|
||||
"manmitya",
|
||||
"maqroll",
|
||||
"marco-vb",
|
||||
"martincholuj",
|
||||
"mastertheknife",
|
||||
"mateng0915",
|
||||
@ -1675,6 +1705,7 @@ const char * auto_contributors[] {
|
||||
"maxulan",
|
||||
"maxvostrikov",
|
||||
"mayamika",
|
||||
"megao",
|
||||
"mehanizm",
|
||||
"melin",
|
||||
"melvynator",
|
||||
@ -1695,6 +1726,7 @@ const char * auto_contributors[] {
|
||||
"millb",
|
||||
"minhthucdao",
|
||||
"mlkui",
|
||||
"mmav",
|
||||
"mnkonkova",
|
||||
"mo-avatar",
|
||||
"mochi",
|
||||
@ -1719,6 +1751,7 @@ const char * auto_contributors[] {
|
||||
"nellicus",
|
||||
"nemonlou",
|
||||
"neng.liu",
|
||||
"neoman36",
|
||||
"never lee",
|
||||
"ni1l",
|
||||
"nicelulu",
|
||||
@ -1732,6 +1765,7 @@ const char * auto_contributors[] {
|
||||
"objatie_groba",
|
||||
"ocadaruma",
|
||||
"ogorbacheva",
|
||||
"okunev",
|
||||
"olegkv",
|
||||
"olevino",
|
||||
"olevino999",
|
||||
@ -1824,6 +1858,7 @@ const char * auto_contributors[] {
|
||||
"sichenzhao",
|
||||
"simon-says",
|
||||
"simpleton",
|
||||
"siyuan",
|
||||
"skyoct",
|
||||
"slu",
|
||||
"slvrtrn",
|
||||
|
@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import logging
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from docker_images_helper import get_docker_image, pull_image
|
||||
from env_helper import REPO_COPY, TEMP_PATH
|
||||
from pr_info import PRInfo
|
||||
from report import FAILURE, SUCCESS, JobReport, TestResult, TestResults
|
||||
from report import FAIL, FAILURE, OK, SUCCESS, JobReport, TestResult, TestResults
|
||||
from stopwatch import Stopwatch
|
||||
from tee_popen import TeePopen
|
||||
|
||||
@ -28,6 +28,14 @@ def parse_args() -> argparse.Namespace:
|
||||
action="store_true",
|
||||
help="check the docs even if there no changes",
|
||||
)
|
||||
parser.add_argument("--pull-image", default=True, help=argparse.SUPPRESS)
|
||||
parser.add_argument(
|
||||
"--no-pull-image",
|
||||
dest="pull_image",
|
||||
action="store_false",
|
||||
default=argparse.SUPPRESS,
|
||||
help="do not pull docker image, use existing",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
@ -61,13 +69,16 @@ def main():
|
||||
elif args.force:
|
||||
logging.info("Check the docs because of force flag")
|
||||
|
||||
docker_image = pull_image(get_docker_image("clickhouse/docs-builder"))
|
||||
docker_image = get_docker_image("clickhouse/docs-builder")
|
||||
if args.pull_image:
|
||||
docker_image = pull_image(docker_image)
|
||||
|
||||
test_output = temp_path / "docs_check_log"
|
||||
test_output = temp_path / "docs_check"
|
||||
test_output.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
cmd = (
|
||||
f"docker run --cap-add=SYS_PTRACE -e GIT_DOCS_BRANCH={args.docs_branch} "
|
||||
f"docker run --cap-add=SYS_PTRACE --user={os.geteuid()}:{os.getegid()} "
|
||||
f"-e GIT_DOCS_BRANCH={args.docs_branch} "
|
||||
f"--volume={repo_path}:/ClickHouse --volume={test_output}:/output_path "
|
||||
f"{docker_image}"
|
||||
)
|
||||
@ -75,49 +86,67 @@ def main():
|
||||
run_log_path = test_output / "run.log"
|
||||
logging.info("Running command: '%s'", cmd)
|
||||
|
||||
with TeePopen(cmd, run_log_path) as process:
|
||||
test_results = [] # type: TestResults
|
||||
|
||||
test_sw = Stopwatch()
|
||||
with TeePopen(f"{cmd} --out-dir /output_path/build", run_log_path) as process:
|
||||
retcode = process.wait()
|
||||
if retcode == 0:
|
||||
logging.info("Run successfully")
|
||||
status = SUCCESS
|
||||
job_status = SUCCESS
|
||||
build_status = OK
|
||||
description = "Docs check passed"
|
||||
else:
|
||||
description = "Docs check failed (non zero exit code)"
|
||||
status = FAILURE
|
||||
job_status = FAILURE
|
||||
build_status = FAIL
|
||||
logging.info("Run failed")
|
||||
|
||||
subprocess.check_call(f"sudo chown -R ubuntu:ubuntu {temp_path}", shell=True)
|
||||
test_results = [] # type: TestResults
|
||||
additional_files = []
|
||||
if not any(test_output.iterdir()):
|
||||
logging.error("No output files after docs check")
|
||||
description = "No output files after docs check"
|
||||
status = FAILURE
|
||||
else:
|
||||
for p in test_output.iterdir():
|
||||
additional_files.append(p)
|
||||
with open(p, "r", encoding="utf-8") as check_file:
|
||||
for line in check_file:
|
||||
if "ERROR" in line:
|
||||
test_results.append(TestResult(line.split(":")[-1], "FAIL"))
|
||||
if test_results:
|
||||
status = FAILURE
|
||||
description = "Found errors in docs"
|
||||
elif status != FAILURE:
|
||||
test_results.append(TestResult("No errors found", "OK"))
|
||||
if build_status == OK:
|
||||
with open(run_log_path, "r", encoding="utf-8") as lfd:
|
||||
for line in lfd:
|
||||
if "ERROR" in line:
|
||||
build_status = FAIL
|
||||
job_status = FAIL
|
||||
break
|
||||
|
||||
test_results.append(
|
||||
TestResult("Docs build", build_status, test_sw.duration_seconds, [run_log_path])
|
||||
)
|
||||
|
||||
htmltest_log = test_output / "htmltest.log"
|
||||
|
||||
# FIXME: after all issues in htmltest will be fixed, consider the failure as a
|
||||
# failed job
|
||||
test_sw.reset()
|
||||
with TeePopen(
|
||||
f"{cmd} htmltest -c /ClickHouse/docs/.htmltest.yml /output_path/build",
|
||||
htmltest_log,
|
||||
) as process:
|
||||
retcode = process.wait()
|
||||
if retcode == 0:
|
||||
logging.info("Run successfully")
|
||||
test_results.append(
|
||||
TestResult("htmltest", OK, test_sw.duration_seconds, [htmltest_log])
|
||||
)
|
||||
else:
|
||||
test_results.append(TestResult("Non zero exit code", "FAIL"))
|
||||
logging.info("Run failed")
|
||||
test_results.append(
|
||||
TestResult(
|
||||
"htmltest", "FLAKY", test_sw.duration_seconds, [htmltest_log]
|
||||
)
|
||||
)
|
||||
|
||||
JobReport(
|
||||
description=description,
|
||||
test_results=test_results,
|
||||
status=status,
|
||||
status=job_status,
|
||||
start_time=stopwatch.start_time_str,
|
||||
duration=stopwatch.duration_seconds,
|
||||
additional_files=additional_files,
|
||||
additional_files=[],
|
||||
).dump()
|
||||
|
||||
if status == FAILURE:
|
||||
if job_status == FAILURE:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
@ -99,6 +99,7 @@ class TeePopen:
|
||||
for line in self.process.stdout:
|
||||
sys.stdout.write(line)
|
||||
self.log_file.write(line)
|
||||
self.log_file.flush()
|
||||
|
||||
return self.process.wait()
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user