mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
Merge branch 'master' into build-libcxx-and-libcxxabi-from-llvm-project
This commit is contained in:
commit
54e27d4230
@ -17,5 +17,7 @@ ClickHouse® is an open-source column-oriented database management system that a
|
||||
|
||||
## Upcoming events
|
||||
* [**v22.11 Release Webinar**](https://clickhouse.com/company/events/v22-11-release-webinar) Original creator, co-founder, and CTO of ClickHouse Alexey Milovidov will walk us through the highlights of the release, provide live demos, and share vision into what is coming in the roadmap.
|
||||
* [**ClickHouse Meetup at the Deutsche Bank office in Berlin**](https://www.meetup.com/clickhouse-berlin-user-group/events/289311596/) Hear from Deutsche Bank on why they chose ClickHouse for big sensitive data in a regulated environment. The ClickHouse team will then present how ClickHouse is used for real time financial data analytics, including tick data, trade analytics and risk management.
|
||||
* [**AWS re:Invent**](https://clickhouse.com/company/events/aws-reinvent) Core members of the ClickHouse team -- including 2 of our founders -- will be at re:Invent from November 29 to December 3. We are available on the show floor, but are also determining interest in holding an event during the time there.
|
||||
* [**ClickHosue Meetup at the RELEX Solutions office in Stockholm**](https://www.meetup.com/clickhouse-stockholm-user-group/events/289492084/) - Dec 1 - Formulate by RELEX is a Swedish promotion planning and analytics company. They will share why they chose ClickHouse for their real time analytics and forecasting solution. The ClickHouse team will then present how ClickHouse is used for real time financial data analytics, including tick data, trade analytics and risk management.
|
||||
* [**ClickHouse Meetup at the Deutsche Bank office in Berlin**](https://www.meetup.com/clickhouse-berlin-user-group/events/289311596/) - Dec 5 - Hear from Deutsche Bank on why they chose ClickHouse for big sensitive data in a regulated environment. The ClickHouse team will then present how ClickHouse is used for real time financial data analytics, including tick data, trade analytics and risk management.
|
||||
* [**ClickHouse Meetup at the Rokt offices in Manhattan**](https://www.meetup.com/clickhouse-new-york-user-group/events/289403909/) - Dec 6 - We are very excited to be holding our next in-person ClickHouse meetup at the Rokt offices in Manhattan. Featuring talks from Bloomberg, Disney Streaming, Prequel, Rokt, and ClickHouse
|
||||
|
||||
|
2
contrib/poco
vendored
2
contrib/poco
vendored
@ -1 +1 @@
|
||||
Subproject commit 76746b35d0e254eaaba71dc3b79e46cba8cbb144
|
||||
Subproject commit 799234226187c0ae0b8c90f23465b25ed7956e56
|
@ -496,6 +496,7 @@ else
|
||||
-e "Code: 269. DB::Exception: Destination table is myself" \
|
||||
-e "Coordination::Exception: Connection loss" \
|
||||
-e "MutateFromLogEntryTask" \
|
||||
-e "No connection to ZooKeeper, cannot get shared table ID" \
|
||||
/var/log/clickhouse-server/clickhouse-server.backward.clean.log | zgrep -Fa "<Error>" > /test_output/bc_check_error_messages.txt \
|
||||
&& echo -e 'Backward compatibility check: Error message in clickhouse-server.log (see bc_check_error_messages.txt)\tFAIL' >> /test_output/test_results.tsv \
|
||||
|| echo -e 'Backward compatibility check: No Error messages in clickhouse-server.log\tOK' >> /test_output/test_results.tsv
|
||||
|
@ -41,26 +41,27 @@ Approximate Nearest Neighbor Search Indexes (`ANNIndexes`) are similar to skip i
|
||||
|
||||
In these queries, `DistanceFunction` is selected from [distance functions](../../../sql-reference/functions/distance-functions). `Point` is a known vector (something like `(0.1, 0.1, ... )`). To avoid writing large vectors, use [client parameters](../../../interfaces/cli.md#queries-with-parameters-cli-queries-with-parameters). `Value` - a float value that will bound the neighbourhood.
|
||||
|
||||
!!! note "Note"
|
||||
ANN index can't speed up query that satisfies both types(`where + order by`, only one of them). All queries must have the limit, as algorithms are used to find nearest neighbors and need a specific number of them.
|
||||
:::note
|
||||
ANN index can't speed up query that satisfies both types (`where + order by`, only one of them). All queries must have the limit, as algorithms are used to find nearest neighbors and need a specific number of them.
|
||||
:::
|
||||
|
||||
!!! note "Note"
|
||||
Indexes are applied only to queries with a limit less than the `max_limit_for_ann_queries` setting. This helps to avoid memory overflows in queries with a large limit. `max_limit_for_ann_queries` setting can be changed if you know you can provide enough memory. The default value is `1000000`.
|
||||
:::note
|
||||
Indexes are applied only to queries with a limit less than the `max_limit_for_ann_queries` setting. This helps to avoid memory overflows in queries with a large limit. `max_limit_for_ann_queries` setting can be changed if you know you can provide enough memory. The default value is `1000000`.
|
||||
:::
|
||||
|
||||
Both types of queries are handled the same way. The indexes get `n` neighbors (where `n` is taken from the `LIMIT` clause) and work with them. In `ORDER BY` query they remember the numbers of all parts of the granule that have at least one of neighbor. In `WHERE` query they remember only those parts that satisfy the requirements.
|
||||
|
||||
|
||||
|
||||
## Create table with ANNIndex
|
||||
|
||||
This feature is disabled by default. To enable it, set `allow_experimental_annoy_index` to 1. Also, this feature is disabled for arm, due to likely problems with the algorithm.
|
||||
This feature is disabled by default. To enable it, set `allow_experimental_annoy_index` to 1. Also, this feature is disabled on ARM, due to likely problems with the algorithm.
|
||||
|
||||
```sql
|
||||
CREATE TABLE t
|
||||
(
|
||||
`id` Int64,
|
||||
`number` Tuple(Float32, Float32, Float32),
|
||||
INDEX x number TYPE index_name(parameters) GRANULARITY N
|
||||
`data` Tuple(Float32, Float32, Float32),
|
||||
INDEX ann_index_name data TYPE ann_index_type(ann_index_parameters) GRANULARITY N
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY id;
|
||||
@ -70,8 +71,8 @@ ORDER BY id;
|
||||
CREATE TABLE t
|
||||
(
|
||||
`id` Int64,
|
||||
`number` Array(Float32),
|
||||
INDEX x number TYPE index_name(parameters) GRANULARITY N
|
||||
`data` Array(Float32),
|
||||
INDEX ann_index_name data TYPE ann_index_type(ann_index_parameters) GRANULARITY N
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY id;
|
||||
@ -80,7 +81,7 @@ ORDER BY id;
|
||||
With greater `GRANULARITY` indexes remember the data structure better. The `GRANULARITY` indicates how many granules will be used to construct the index. The more data is provided for the index, the more of it can be handled by one index and the more chances that with the right hyperparameters the index will remember the data structure better. But some indexes can't be built if they don't have enough data, so this granule will always participate in the query. For more information, see the description of indexes.
|
||||
|
||||
As the indexes are built only during insertions into table, `INSERT` and `OPTIMIZE` queries are slower than for ordinary table. At this stage indexes remember all the information about the given data. ANNIndexes should be used if you have immutable or rarely changed data and many read requests.
|
||||
|
||||
|
||||
You can create your table with index which uses certain algorithm. Now only indices based on the following algorithms are supported:
|
||||
|
||||
# Index list
|
||||
@ -98,8 +99,8 @@ __Examples__:
|
||||
CREATE TABLE t
|
||||
(
|
||||
id Int64,
|
||||
number Tuple(Float32, Float32, Float32),
|
||||
INDEX x number TYPE annoy(Trees, DistanceName) GRANULARITY N
|
||||
data Tuple(Float32, Float32, Float32),
|
||||
INDEX ann_index_name data TYPE annoy(NumTrees, DistanceName) GRANULARITY N
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY id;
|
||||
@ -109,22 +110,24 @@ ORDER BY id;
|
||||
CREATE TABLE t
|
||||
(
|
||||
id Int64,
|
||||
number Array(Float32),
|
||||
INDEX x number TYPE annoy(Trees, DistanceName) GRANULARITY N
|
||||
data Array(Float32),
|
||||
INDEX ann_index_name data TYPE annoy(NumTrees, DistanceName) GRANULARITY N
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY id;
|
||||
```
|
||||
!!! note "Note"
|
||||
Table with array field will work faster, but all arrays **must** have same length. Use [CONSTRAINT](../../../sql-reference/statements/create/table.md#constraints) to avoid errors. For example, `CONSTRAINT constraint_name_1 CHECK length(number) = 256`.
|
||||
|
||||
Parameter `Trees` is the number of trees which algorithm will create. The bigger it is, the slower (approximately linear) it works (in both `CREATE` and `SELECT` requests), but the better accuracy you get (adjusted for randomness). By default it is set to `100`. Parameter `DistanceName` is name of distance function. By default it is set to `L2Distance`. It can be set without changing first parameter, for example
|
||||
:::note
|
||||
Table with array field will work faster, but all arrays **must** have same length. Use [CONSTRAINT](../../../sql-reference/statements/create/table.md#constraints) to avoid errors. For example, `CONSTRAINT constraint_name_1 CHECK length(data) = 256`.
|
||||
:::
|
||||
|
||||
Parameter `NumTrees` is the number of trees which the algorithm will create. The bigger it is, the slower (approximately linear) it works (in both `CREATE` and `SELECT` requests), but the better accuracy you get (adjusted for randomness). By default it is set to `100`. Parameter `DistanceName` is name of distance function. By default it is set to `L2Distance`. It can be set without changing first parameter, for example
|
||||
```sql
|
||||
CREATE TABLE t
|
||||
(
|
||||
id Int64,
|
||||
number Array(Float32),
|
||||
INDEX x number TYPE annoy('cosineDistance') GRANULARITY N
|
||||
data Array(Float32),
|
||||
INDEX ann_index_name data TYPE annoy('cosineDistance') GRANULARITY N
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY id;
|
||||
|
@ -151,7 +151,7 @@ Perform the query:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
dictGet('ext-dict-mult', ('c1','c2'), number) AS val,
|
||||
dictGet('ext-dict-mult', ('c1','c2'), number + 1) AS val,
|
||||
toTypeName(val) AS type
|
||||
FROM system.numbers
|
||||
LIMIT 3;
|
||||
|
@ -59,6 +59,28 @@ If the table already exists and `IF NOT EXISTS` is specified, the query won’t
|
||||
|
||||
There can be other clauses after the `ENGINE` clause in the query. See detailed documentation on how to create tables in the descriptions of [table engines](../../../engines/table-engines/index.md#table_engines).
|
||||
|
||||
:::tip
|
||||
In ClickHouse Cloud please split this into two steps:
|
||||
1. Create the table structure
|
||||
|
||||
```sql
|
||||
CREATE TABLE t1
|
||||
ENGINE = MergeTree
|
||||
ORDER BY ...
|
||||
# highlight-next-line
|
||||
EMPTY AS
|
||||
SELECT ...
|
||||
```
|
||||
|
||||
2. Populate the table
|
||||
|
||||
```sql
|
||||
INSERT INTO t1
|
||||
SELECT ...
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
@ -159,7 +181,7 @@ ENGINE = engine
|
||||
PRIMARY KEY(expr1[, expr2,...]);
|
||||
```
|
||||
|
||||
:::warning
|
||||
:::warning
|
||||
You can't combine both ways in one query.
|
||||
:::
|
||||
|
||||
@ -215,7 +237,7 @@ ALTER TABLE codec_example MODIFY COLUMN float_value CODEC(Default);
|
||||
|
||||
Codecs can be combined in a pipeline, for example, `CODEC(Delta, Default)`.
|
||||
|
||||
:::warning
|
||||
:::warning
|
||||
You can’t decompress ClickHouse database files with external utilities like `lz4`. Instead, use the special [clickhouse-compressor](https://github.com/ClickHouse/ClickHouse/tree/master/programs/compressor) utility.
|
||||
:::
|
||||
|
||||
@ -301,44 +323,44 @@ Encryption codecs:
|
||||
|
||||
#### AES_128_GCM_SIV
|
||||
|
||||
`CODEC('AES-128-GCM-SIV')` — Encrypts data with AES-128 in [RFC 8452](https://tools.ietf.org/html/rfc8452) GCM-SIV mode.
|
||||
`CODEC('AES-128-GCM-SIV')` — Encrypts data with AES-128 in [RFC 8452](https://tools.ietf.org/html/rfc8452) GCM-SIV mode.
|
||||
|
||||
|
||||
#### AES-256-GCM-SIV
|
||||
|
||||
`CODEC('AES-256-GCM-SIV')` — Encrypts data with AES-256 in GCM-SIV mode.
|
||||
`CODEC('AES-256-GCM-SIV')` — Encrypts data with AES-256 in GCM-SIV mode.
|
||||
|
||||
These codecs use a fixed nonce and encryption is therefore deterministic. This makes it compatible with deduplicating engines such as [ReplicatedMergeTree](../../../engines/table-engines/mergetree-family/replication.md) but has a weakness: when the same data block is encrypted twice, the resulting ciphertext will be exactly the same so an adversary who can read the disk can see this equivalence (although only the equivalence, without getting its content).
|
||||
|
||||
:::warning
|
||||
:::warning
|
||||
Most engines including the "\*MergeTree" family create index files on disk without applying codecs. This means plaintext will appear on disk if an encrypted column is indexed.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
:::warning
|
||||
If you perform a SELECT query mentioning a specific value in an encrypted column (such as in its WHERE clause), the value may appear in [system.query_log](../../../operations/system-tables/query_log.md). You may want to disable the logging.
|
||||
:::
|
||||
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
CREATE TABLE mytable
|
||||
CREATE TABLE mytable
|
||||
(
|
||||
x String Codec(AES_128_GCM_SIV)
|
||||
)
|
||||
)
|
||||
ENGINE = MergeTree ORDER BY x;
|
||||
```
|
||||
|
||||
:::note
|
||||
:::note
|
||||
If compression needs to be applied, it must be explicitly specified. Otherwise, only encryption will be applied to data.
|
||||
:::
|
||||
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
CREATE TABLE mytable
|
||||
CREATE TABLE mytable
|
||||
(
|
||||
x String Codec(Delta, LZ4, AES_128_GCM_SIV)
|
||||
)
|
||||
)
|
||||
ENGINE = MergeTree ORDER BY x;
|
||||
```
|
||||
|
||||
@ -372,7 +394,7 @@ It’s possible to use tables with [ENGINE = Memory](../../../engines/table-engi
|
||||
|
||||
'REPLACE' query allows you to update the table atomically.
|
||||
|
||||
:::note
|
||||
:::note
|
||||
This query is supported only for [Atomic](../../../engines/database-engines/atomic.md) database engine.
|
||||
:::
|
||||
|
||||
@ -388,7 +410,7 @@ RENAME TABLE myNewTable TO myOldTable;
|
||||
Instead of above, you can use the following:
|
||||
|
||||
```sql
|
||||
REPLACE TABLE myOldTable SELECT * FROM myOldTable WHERE CounterID <12345;
|
||||
REPLACE TABLE myOldTable ENGINE = MergeTree() ORDER BY CounterID AS SELECT * FROM myOldTable WHERE CounterID <12345;
|
||||
```
|
||||
|
||||
### Syntax
|
||||
@ -448,7 +470,7 @@ SELECT * FROM base.t1;
|
||||
|
||||
You can add a comment to the table when you creating it.
|
||||
|
||||
:::note
|
||||
:::note
|
||||
The comment is supported for all table engines except [Kafka](../../../engines/table-engines/integrations/kafka.md), [RabbitMQ](../../../engines/table-engines/integrations/rabbitmq.md) and [EmbeddedRocksDB](../../../engines/table-engines/integrations/embedded-rocksdb.md).
|
||||
:::
|
||||
|
||||
|
@ -151,7 +151,7 @@ LIMIT 3;
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
dictGet('ext-dict-mult', ('c1','c2'), number) AS val,
|
||||
dictGet('ext-dict-mult', ('c1','c2'), number + 1) AS val,
|
||||
toTypeName(val) AS type
|
||||
FROM system.numbers
|
||||
LIMIT 3;
|
||||
|
@ -5,17 +5,17 @@ sidebar_label: LIMIT BY
|
||||
|
||||
# LIMIT BY子句 {#limit-by-clause}
|
||||
|
||||
与查询 `LIMIT n BY expressions` 子句选择第一个 `n` 每个不同值的行 `expressions`. `LIMIT BY` 可以包含任意数量的 [表达式](../../../sql-reference/syntax.md#syntax-expressions).
|
||||
一个使用`LIMIT n BY expressions`从句的查询会以去重后的`expressions`结果分组,每一分组选择前`n`行。`LIMIT BY`指定的值可以是任意数量的[表达式](../../../sql-reference/syntax.md#syntax-expressions)。
|
||||
|
||||
ClickHouse支持以下语法变体:
|
||||
|
||||
- `LIMIT [offset_value, ]n BY expressions`
|
||||
- `LIMIT n OFFSET offset_value BY expressions`
|
||||
|
||||
在进行查询处理时,ClickHouse选择按排序键排序的数据。排序键设置显式地使用一个[ORDER BY](order-by.md#select-order-by)条款或隐式属性表的引擎(行顺序只是保证在使用[ORDER BY](order-by.md#select-order-by),否则不会命令行块由于多线程)。然后ClickHouse应用`LIMIT n BY 表达式`,并为每个不同的`表达式`组合返回前n行。如果指定了`OFFSET`,那么对于每个属于不同`表达式`组合的数据块,ClickHouse将跳过`offset_value`从块开始的行数,并最终返回最多`n`行的结果。如果`offset_value`大于数据块中的行数,则ClickHouse从数据块中返回零行。
|
||||
处理查询时,ClickHouse首先选择经由排序键排序过后的数据。排序键可以显式地使用[ORDER BY](order-by.md#select-order-by)从句指定,或隐式地使用表引擎使用的排序键(数据的顺序仅在使用[ORDER BY](order-by.md#select-order-by)时才可以保证,否则由于多线程处理,数据顺序会随机化)。然后ClickHouse执行`LIMIT n BY expressions`从句,将每一行按 `expressions` 的值进行分组,并对每一分组返回前`n`行。如果指定了`OFFSET`,那么对于每一分组,ClickHouse会跳过前`offset_value`行,接着返回前`n`行。如果`offset_value`大于某一分组的行数,ClickHouse会从分组返回0行。
|
||||
|
||||
!!! note "注"
|
||||
`LIMIT BY` 是不相关的 [LIMIT](../../../sql-reference/statements/select/limit.md). 它们都可以在同一个查询中使用。
|
||||
`LIMIT BY`与[LIMIT](../../../sql-reference/statements/select/limit.md)没有关系。它们可以在同一个查询中使用。
|
||||
|
||||
## 例 {#examples}
|
||||
|
||||
@ -53,9 +53,9 @@ SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id
|
||||
└────┴─────┘
|
||||
```
|
||||
|
||||
该 `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` 查询返回相同的结果。
|
||||
与 `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` 返回相同的结果。
|
||||
|
||||
以下查询返回每个引用的前5个引用 `domain, device_type` 最多可与100行配对 (`LIMIT n BY + LIMIT`).
|
||||
以下查询返回每个`domain,device_type`组合的前5个refferrer,总计返回至多100行(`LIMIT n BY + LIMIT`)。
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
|
@ -18,28 +18,28 @@ require (
|
||||
github.com/spf13/cobra v1.3.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.10.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/testcontainers/testcontainers-go v0.12.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/testcontainers/testcontainers-go v0.15.0
|
||||
github.com/yargevad/filepathx v1.0.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 // indirect
|
||||
github.com/Microsoft/hcsshim v0.8.16 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.4 // indirect
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68 // indirect
|
||||
github.com/containerd/containerd v1.5.0-beta.4 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/containerd/cgroups v1.0.4 // indirect
|
||||
github.com/containerd/containerd v1.6.8 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||
github.com/docker/docker v20.10.11+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/docker/docker v20.10.17+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dsnet/compress v0.0.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
@ -52,18 +52,18 @@ require (
|
||||
github.com/jaypipes/pcidb v0.6.0 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/moby/sys/mount v0.2.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.5.0 // indirect
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
|
||||
github.com/moby/sys/mount v0.3.3 // indirect
|
||||
github.com/moby/sys/mountinfo v0.6.2 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opencontainers/runc v1.0.2 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
|
||||
github.com/opencontainers/runc v1.1.3 // indirect
|
||||
github.com/paulmach/orb v0.4.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.14 // indirect
|
||||
@ -79,12 +79,12 @@ require (
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.opentelemetry.io/otel v1.4.1 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.4.1 // indirect
|
||||
golang.org/x/net v0.0.0-20211108170745-6635138e15ea // indirect
|
||||
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||
golang.org/x/text v0.3.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
|
||||
google.golang.org/grpc v1.43.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad // indirect
|
||||
google.golang.org/grpc v1.47.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
|
||||
|
@ -51,8 +51,9 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
@ -71,8 +72,6 @@ github.com/ClickHouse/clickhouse-go/v2 v2.0.12/go.mod h1:u4RoNQLLM2W6hNSPYrIESLJ
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/Flaque/filet v0.0.0-20201012163910-45f684403088 h1:PnnQln5IGbhLeJOi6hVs+lCeF+B1dRfFKPGXUAez0Ww=
|
||||
github.com/Flaque/filet v0.0.0-20201012163910-45f684403088/go.mod h1:TK+jB3mBs+8ZMWhU5BqZKnZWJ1MrLo8etNVg51ueTBo=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
@ -80,21 +79,28 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 h1:mw6pDQqv38/WGF1cO/jF5t/jyAJ2yi7CmtFLLO5tGFI=
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
||||
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
||||
github.com/Microsoft/hcsshim v0.8.16 h1:8/auA4LFIZFTGrqfKhGBSXwM6/4X1fHa/xniyEHu8ac=
|
||||
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
|
||||
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
||||
github.com/Microsoft/hcsshim v0.9.4 h1:mnUj0ivWy6UzbB1uLFqKR6F+ZyiDc7j4iGgHTpO+5+I=
|
||||
github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
@ -108,6 +114,7 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
@ -132,22 +139,28 @@ github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
@ -166,20 +179,25 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z
|
||||
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
||||
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
||||
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=
|
||||
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||
github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||
github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=
|
||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
||||
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68 h1:hkGVFjz+plgr5UfxZUTPFbUFIF/Km6/s+RVRIRHLrrY=
|
||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
|
||||
github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA=
|
||||
github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
|
||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
@ -190,47 +208,68 @@ github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
|
||||
github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ=
|
||||
github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
|
||||
github.com/containerd/containerd v1.5.0-beta.4 h1:zjz4MOAOFgdBlwid2nNUlJ3YLpVi/97L36lfMYJex60=
|
||||
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
|
||||
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
||||
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
|
||||
github.com/containerd/containerd v1.6.8 h1:h4dOFDwzHmqFEP754PgfgTeVXFnLiRc6kiqC7tplDJs=
|
||||
github.com/containerd/containerd v1.6.8/go.mod h1:By6p5KqPK0/7/CgO/A6t/Gz+CUYUu2zf1hUaaymVXB0=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e h1:6JKvHHt396/qabvMhnhUZvWaHZzfVfldxE60TK8YLhg=
|
||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
||||
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
||||
github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
||||
github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||
github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU=
|
||||
github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
|
||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
|
||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||
github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
|
||||
github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
|
||||
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
|
||||
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
||||
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||
github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||
github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=
|
||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
|
||||
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
|
||||
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
|
||||
github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=
|
||||
github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
|
||||
github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||
github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||
github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
|
||||
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
|
||||
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
|
||||
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
|
||||
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@ -246,9 +285,11 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
||||
@ -259,21 +300,28 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.11+incompatible h1:OqzI/g/W54LczvhnccGqniFoQghHx3pklbLuhfXpqGo=
|
||||
github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE=
|
||||
github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
@ -296,6 +344,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
@ -306,8 +355,9 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@ -327,24 +377,27 @@ github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
|
||||
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@ -356,6 +409,7 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -405,8 +459,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
@ -434,6 +489,7 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
@ -445,14 +501,17 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I=
|
||||
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
@ -496,6 +555,7 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
|
||||
@ -507,6 +567,7 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
@ -524,6 +585,7 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
@ -536,16 +598,20 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
|
||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
||||
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
@ -568,9 +634,11 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.4 h1:QJ4UuWgavPynEX3LXxClHDRGzYcgcvTtAMp8az7spuw=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.4/go.mod h1:J7SYS/UTAtnO3I49RQEf+2FYZVwo7XBOh9Im43VrjNs=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
@ -589,44 +657,56 @@ github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGg
|
||||
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||
github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615/go.mod h1:Ad7oeElCZqA1Ufj0U9/liOF4BtVepxRcTvr2ey7zTvM=
|
||||
github.com/moby/sys/mount v0.2.0 h1:WhCW5B355jtxndN5ovugJlMFJawbUODuW8fSnEH6SSM=
|
||||
github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs=
|
||||
github.com/moby/sys/mount v0.3.3/go.mod h1:PBaEorSNTLG5t/+4EgukEQVlAvVEc6ZjTySwKdqp5K0=
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q0rDaRO0MPaOk=
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@ -634,15 +714,17 @@ github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
||||
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
|
||||
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
|
||||
github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w=
|
||||
github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
@ -653,11 +735,14 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
|
||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/paulmach/orb v0.4.0 h1:ilp1MQjRapLJ1+qcays1nZpe0mvkCY+b8JU/qBKRZ1A=
|
||||
github.com/paulmach/orb v0.4.0/go.mod h1:FkcWtplUAIVqAuhAOV2d3rpbnQyliDOjOcLW9dUrfdU=
|
||||
github.com/paulmach/protoscan v0.2.1-0.20210522164731-4e53c6875432/go.mod h1:2sV+uZ/oQh66m4XJVZm5iqUZ62BN88Ex1E+TTS0nLzI=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
@ -678,6 +763,7 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
@ -688,12 +774,15 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
@ -702,6 +791,7 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@ -714,8 +804,10 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
|
||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||
@ -734,17 +826,21 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.8.0 h1:5MmtuhAgYeU6qpa7w7bP0dv6MBYuup0vekhSpSkoq60=
|
||||
github.com/spf13/afero v1.8.0/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
|
||||
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0=
|
||||
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
@ -754,6 +850,7 @@ github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
|
||||
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
|
||||
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
|
||||
@ -762,27 +859,31 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/testcontainers/testcontainers-go v0.12.0 h1:SK0NryGHIx7aifF6YqReORL18aGAA4bsDPtikDVCEyg=
|
||||
github.com/testcontainers/testcontainers-go v0.12.0/go.mod h1:SIndOQXZng0IW8iWU1Js0ynrfZ8xcxrTtDfF6rD2pxs=
|
||||
github.com/testcontainers/testcontainers-go v0.15.0 h1:3Ex7PUGFv0b2bBsdOv6R42+SK2qoZnWBd21LvZYhUtQ=
|
||||
github.com/testcontainers/testcontainers-go v0.15.0/go.mod h1:PkohMRH2X8Hib0IWtifVexDfLPVT+tb5E9hsf7cW12w=
|
||||
github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
|
||||
github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
@ -792,14 +893,17 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc=
|
||||
github.com/yargevad/filepathx v1.0.0/go.mod h1:BprfX/gpYNJHJfc35GjRRpVcwWXS89gGulUIU5tK3tA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -811,8 +915,10 @@ github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
@ -853,6 +959,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
@ -931,6 +1038,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
@ -944,8 +1052,9 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211108170745-6635138e15ea h1:FosBMXtOc8Tp9Hbo4ltl1WJSrTVewZU8MPnTPY2HdH8=
|
||||
golang.org/x/net v0.0.0-20211108170745-6635138e15ea/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 h1:Yqz/iviulwKwAREEeUd3nbBFn0XuyJqkoft2IlrvOhc=
|
||||
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -996,10 +1105,12 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1022,6 +1133,7 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1035,13 +1147,14 @@ golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -1070,14 +1183,18 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211109184856-51b60fd695b3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@ -1096,10 +1213,12 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@ -1115,6 +1234,7 @@ golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@ -1138,14 +1258,17 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
@ -1162,7 +1285,6 @@ golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
@ -1233,6 +1355,7 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
@ -1272,8 +1395,9 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad h1:kqrS+lhvaMHCxul6sKQvKJ8nAAhlVItmZV822hYFH/U=
|
||||
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
@ -1305,8 +1429,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=
|
||||
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
|
||||
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@ -1320,15 +1444,17 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
@ -1353,13 +1479,14 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@ -1370,15 +1497,32 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
|
||||
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
|
||||
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
|
||||
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
|
||||
k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
|
||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
|
||||
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
|
||||
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
|
||||
k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
@ -1386,6 +1530,9 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
|
@ -7,23 +7,22 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/data"
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/database"
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/test"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
func createClickHouseContainer(t *testing.T, ctx context.Context) (testcontainers.Container, nat.Port) {
|
||||
// create a ClickHouse container
|
||||
ctx := context.Background()
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
// can't test without container
|
||||
// can't test without current directory
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -32,9 +31,19 @@ func TestMain(m *testing.M) {
|
||||
Image: fmt.Sprintf("clickhouse/clickhouse-server:%s", test.GetClickHouseTestVersion()),
|
||||
ExposedPorts: []string{"9000/tcp"},
|
||||
WaitingFor: wait.ForLog("Ready for connections"),
|
||||
BindMounts: map[string]string{
|
||||
"/etc/clickhouse-server/config.d/custom.xml": path.Join(cwd, "../../../testdata/docker/custom.xml"),
|
||||
"/etc/clickhouse-server/users.d/admin.xml": path.Join(cwd, "../../../testdata/docker/admin.xml"),
|
||||
Mounts: testcontainers.ContainerMounts{
|
||||
{
|
||||
Source: testcontainers.GenericBindMountSource{
|
||||
HostPath: path.Join(cwd, "../../../testdata/docker/custom.xml"),
|
||||
},
|
||||
Target: "/etc/clickhouse-server/config.d/custom.xml",
|
||||
},
|
||||
{
|
||||
Source: testcontainers.GenericBindMountSource{
|
||||
HostPath: path.Join(cwd, "../../../testdata/docker/admin.xml"),
|
||||
},
|
||||
Target: "/etc/clickhouse-server/users.d/admin.xml",
|
||||
},
|
||||
},
|
||||
}
|
||||
clickhouseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
@ -47,17 +56,17 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
p, _ := clickhouseContainer.MappedPort(ctx, "9000")
|
||||
if err != nil {
|
||||
// can't test without container's port
|
||||
panic(err)
|
||||
}
|
||||
|
||||
os.Setenv("CLICKHOUSE_DB_PORT", p.Port())
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
os.Exit(m.Run())
|
||||
t.Setenv("CLICKHOUSE_DB_PORT", p.Port())
|
||||
|
||||
return clickhouseContainer, p
|
||||
}
|
||||
|
||||
func getClient(t *testing.T) *database.ClickhouseNativeClient {
|
||||
mappedPort, err := strconv.Atoi(os.Getenv("CLICKHOUSE_DB_PORT"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to read port value from environment")
|
||||
}
|
||||
func getClient(t *testing.T, mappedPort int) *database.ClickhouseNativeClient {
|
||||
clickhouseClient, err := database.NewNativeClient("localhost", uint16(mappedPort), "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to build client : %v", err)
|
||||
@ -66,7 +75,11 @@ func getClient(t *testing.T) *database.ClickhouseNativeClient {
|
||||
}
|
||||
|
||||
func TestReadTableNamesForDatabase(t *testing.T) {
|
||||
clickhouseClient := getClient(t)
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
t.Run("client can read tables for a database", func(t *testing.T) {
|
||||
tables, err := clickhouseClient.ReadTableNamesForDatabase("system")
|
||||
require.Nil(t, err)
|
||||
@ -76,12 +89,17 @@ func TestReadTableNamesForDatabase(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReadTable(t *testing.T) {
|
||||
clickhouseClient := getClient(t)
|
||||
t.Run("client can get all rows for system.disks table", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
|
||||
// we read the table system.disks as this should contain only 1 row
|
||||
frame, err := clickhouseClient.ReadTable("system", "disks", []string{}, data.OrderBy{}, 10)
|
||||
require.Nil(t, err)
|
||||
require.ElementsMatch(t, frame.Columns(), [7]string{"name", "path", "free_space", "total_space", "keep_free_space", "type", "cache_path"})
|
||||
require.ElementsMatch(t, frame.Columns(), [9]string{"name", "path", "free_space", "total_space", "unreserved_space", "keep_free_space", "type", "is_encrypted", "cache_path"})
|
||||
i := 0
|
||||
for {
|
||||
values, ok, err := frame.Next()
|
||||
@ -92,8 +110,11 @@ func TestReadTable(t *testing.T) {
|
||||
require.Equal(t, "/var/lib/clickhouse/", values[1])
|
||||
require.Greater(t, values[2], uint64(0))
|
||||
require.Greater(t, values[3], uint64(0))
|
||||
require.Equal(t, values[4], uint64(0))
|
||||
require.Equal(t, "local", values[5])
|
||||
require.Greater(t, values[4], uint64(0))
|
||||
require.Equal(t, values[5], uint64(0))
|
||||
require.Equal(t, "local", values[6])
|
||||
require.Equal(t, values[7], uint8(0))
|
||||
require.Equal(t, values[8], "")
|
||||
} else {
|
||||
require.False(t, ok)
|
||||
break
|
||||
@ -103,6 +124,12 @@ func TestReadTable(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("client can get all rows for system.databases table", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
|
||||
// we read the table system.databases as this should be small and consistent on fresh db instances
|
||||
frame, err := clickhouseClient.ReadTable("system", "databases", []string{}, data.OrderBy{}, 10)
|
||||
require.Nil(t, err)
|
||||
@ -133,12 +160,24 @@ func TestReadTable(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("client can get all rows for system.databases table with except", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
|
||||
frame, err := clickhouseClient.ReadTable("system", "databases", []string{"data_path", "comment"}, data.OrderBy{}, 10)
|
||||
require.Nil(t, err)
|
||||
require.ElementsMatch(t, frame.Columns(), [4]string{"name", "engine", "metadata_path", "uuid"})
|
||||
})
|
||||
|
||||
t.Run("client can limit rows for system.databases", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
|
||||
frame, err := clickhouseClient.ReadTable("system", "databases", []string{}, data.OrderBy{}, 1)
|
||||
require.Nil(t, err)
|
||||
require.ElementsMatch(t, frame.Columns(), [6]string{"name", "engine", "data_path", "metadata_path", "uuid", "comment"})
|
||||
@ -164,6 +203,12 @@ func TestReadTable(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("client can order rows for system.databases", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
|
||||
frame, err := clickhouseClient.ReadTable("system", "databases", []string{}, data.OrderBy{
|
||||
Column: "engine",
|
||||
Order: data.Asc,
|
||||
@ -199,8 +244,13 @@ func TestReadTable(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExecuteStatement(t *testing.T) {
|
||||
clickhouseClient := getClient(t)
|
||||
t.Run("client can execute any statement", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
|
||||
statement := "SELECT path, count(*) as count FROM system.disks GROUP BY path;"
|
||||
frame, err := clickhouseClient.ExecuteStatement("engines", statement)
|
||||
require.Nil(t, err)
|
||||
@ -225,8 +275,13 @@ func TestExecuteStatement(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
clickhouseClient := getClient(t)
|
||||
t.Run("client can read version", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
clickhouseClient := getClient(t, mappedPort.Int())
|
||||
|
||||
version, err := clickhouseClient.Version()
|
||||
require.Nil(t, err)
|
||||
require.NotEmpty(t, version)
|
||||
|
@ -7,19 +7,18 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform"
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/test"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// create a ClickHouse container
|
||||
ctx := context.Background()
|
||||
// create a ClickHouse container
|
||||
func createClickHouseContainer(t *testing.T, ctx context.Context) (testcontainers.Container, nat.Port) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Println("unable to read current directory", err)
|
||||
@ -30,9 +29,19 @@ func TestMain(m *testing.M) {
|
||||
Image: fmt.Sprintf("clickhouse/clickhouse-server:%s", test.GetClickHouseTestVersion()),
|
||||
ExposedPorts: []string{"9000/tcp"},
|
||||
WaitingFor: wait.ForLog("Ready for connections"),
|
||||
BindMounts: map[string]string{
|
||||
"/etc/clickhouse-server/config.d/custom.xml": path.Join(cwd, "../../testdata/docker/custom.xml"),
|
||||
"/etc/clickhouse-server/users.d/admin.xml": path.Join(cwd, "../../testdata/docker/admin.xml"),
|
||||
Mounts: testcontainers.ContainerMounts{
|
||||
{
|
||||
Source: testcontainers.GenericBindMountSource{
|
||||
HostPath: path.Join(cwd, "../../testdata/docker/custom.xml"),
|
||||
},
|
||||
Target: "/etc/clickhouse-server/config.d/custom.xml",
|
||||
},
|
||||
{
|
||||
Source: testcontainers.GenericBindMountSource{
|
||||
HostPath: path.Join(cwd, "../../testdata/docker/admin.xml"),
|
||||
},
|
||||
Target: "/etc/clickhouse-server/users.d/admin.xml",
|
||||
},
|
||||
},
|
||||
}
|
||||
clickhouseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
@ -44,29 +53,35 @@ func TestMain(m *testing.M) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
p, _ := clickhouseContainer.MappedPort(ctx, "9000")
|
||||
p, err := clickhouseContainer.MappedPort(ctx, "9000")
|
||||
if err != nil {
|
||||
// can't test without a port
|
||||
panic(err)
|
||||
}
|
||||
|
||||
os.Setenv("CLICKHOUSE_DB_PORT", p.Port())
|
||||
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
os.Exit(m.Run())
|
||||
return clickhouseContainer, p
|
||||
}
|
||||
|
||||
func TestConnect(t *testing.T) {
|
||||
mappedPort, err := strconv.Atoi(os.Getenv("CLICKHOUSE_DB_PORT"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to read port value from environment")
|
||||
}
|
||||
t.Run("can only connect once", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
clickhouseContainer, mappedPort := createClickHouseContainer(t, ctx)
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
t.Setenv("CLICKHOUSE_DB_PORT", mappedPort.Port())
|
||||
|
||||
port := mappedPort.Int()
|
||||
|
||||
// get before connection
|
||||
manager := platform.GetResourceManager()
|
||||
require.Nil(t, manager.DbClient)
|
||||
// init connection
|
||||
err = manager.Connect("localhost", uint16(mappedPort), "", "")
|
||||
err := manager.Connect("localhost", uint16(port), "", "")
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, manager.DbClient)
|
||||
// try and re-fetch connection
|
||||
err = manager.Connect("localhost", uint16(mappedPort), "", "")
|
||||
err = manager.Connect("localhost", uint16(port), "", "")
|
||||
require.NotNil(t, err)
|
||||
require.Equal(t, "connect can only be called once", err.Error())
|
||||
})
|
||||
|
@ -5,70 +5,93 @@ package utils_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/test"
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/utils"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// create a ClickHouse container
|
||||
ctx := context.Background()
|
||||
cwd, err := os.Getwd()
|
||||
func getProcessesInContainer(t *testing.T, container testcontainers.Container) ([]string, error) {
|
||||
result, reader, err := container.Exec(context.Background(), []string{"ps", "-aux"})
|
||||
if err != nil {
|
||||
fmt.Println("unable to read current directory", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
// for now, we test against a hardcoded database-server version but we should make this a property
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: fmt.Sprintf("clickhouse/clickhouse-server:%s", test.GetClickHouseTestVersion()),
|
||||
ExposedPorts: []string{"9000/tcp"},
|
||||
WaitingFor: wait.ForLog("Ready for connections"),
|
||||
BindMounts: map[string]string{
|
||||
"/etc/clickhouse-server/config.d/custom.xml": path.Join(cwd, "../../../testdata/docker/custom.xml"),
|
||||
},
|
||||
}
|
||||
clickhouseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
require.Zero(t, result)
|
||||
require.NotNil(t, reader)
|
||||
|
||||
b, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
// can't test without container
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
require.NotNil(t, b)
|
||||
|
||||
p, _ := clickhouseContainer.MappedPort(ctx, "9000")
|
||||
lines := strings.Split(string(b), "\n")
|
||||
|
||||
os.Setenv("CLICKHOUSE_DB_PORT", p.Port())
|
||||
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
os.Exit(m.Run())
|
||||
// discard PS header
|
||||
return lines[1:], nil
|
||||
}
|
||||
|
||||
func TestFindClickHouseProcesses(t *testing.T) {
|
||||
func TestFindClickHouseProcessesAndConfigs(t *testing.T) {
|
||||
|
||||
t.Run("can find ClickHouse processes", func(t *testing.T) {
|
||||
processes, err := utils.FindClickHouseProcesses()
|
||||
t.Run("can find ClickHouse processes and configs", func(t *testing.T) {
|
||||
// create a ClickHouse container
|
||||
ctx := context.Background()
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Println("unable to read current directory", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// run a ClickHouse container that guarantees that it runs only for the duration of the test
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: fmt.Sprintf("clickhouse/clickhouse-server:%s", test.GetClickHouseTestVersion()),
|
||||
ExposedPorts: []string{"9000/tcp"},
|
||||
WaitingFor: wait.ForLog("Ready for connections"),
|
||||
Mounts: testcontainers.ContainerMounts{
|
||||
{
|
||||
Source: testcontainers.GenericBindMountSource{
|
||||
HostPath: path.Join(cwd, "../../../testdata/docker/custom.xml"),
|
||||
},
|
||||
Target: "/etc/clickhouse-server/config.d/custom.xml",
|
||||
},
|
||||
},
|
||||
}
|
||||
clickhouseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
if err != nil {
|
||||
// can't test without container
|
||||
panic(err)
|
||||
}
|
||||
|
||||
p, _ := clickhouseContainer.MappedPort(ctx, "9000")
|
||||
|
||||
t.Setenv("CLICKHOUSE_DB_PORT", p.Port())
|
||||
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
|
||||
lines, err := getProcessesInContainer(t, clickhouseContainer)
|
||||
require.Nil(t, err)
|
||||
// we might have clickhouse running locally during development as well as the above container so we allow 1 or more
|
||||
require.GreaterOrEqual(t, len(processes), 1)
|
||||
require.Equal(t, processes[0].List[0], "/usr/bin/clickhouse-server")
|
||||
// flexible as services/containers pass the config differently
|
||||
require.Contains(t, processes[0].List[1], "/etc/clickhouse-server/config.xml")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFindConfigsFromClickHouseProcesses(t *testing.T) {
|
||||
|
||||
t.Run("can find ClickHouse configs", func(t *testing.T) {
|
||||
configs, err := utils.FindConfigsFromClickHouseProcesses()
|
||||
require.Nil(t, err)
|
||||
require.GreaterOrEqual(t, len(configs), 1)
|
||||
require.Equal(t, configs[0], "/etc/clickhouse-server/config.xml")
|
||||
require.NotEmpty(t, lines)
|
||||
|
||||
for _, line := range lines {
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) < 11 {
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(parts[10], "clickhouse-server") {
|
||||
continue
|
||||
}
|
||||
|
||||
require.Equal(t, "/usr/bin/clickhouse-server", parts[10])
|
||||
require.Equal(t, "--config-file=/etc/clickhouse-server/config.xml", parts[11])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal"
|
||||
@ -25,7 +24,8 @@ import (
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// Execute a full default capture, with simple output, and check if a bundle is produced and it's not empty
|
||||
func TestCapture(t *testing.T) {
|
||||
// create a ClickHouse container
|
||||
ctx := context.Background()
|
||||
cwd, err := os.Getwd()
|
||||
@ -39,9 +39,19 @@ func TestMain(m *testing.M) {
|
||||
Image: fmt.Sprintf("clickhouse/clickhouse-server:%s", test.GetClickHouseTestVersion()),
|
||||
ExposedPorts: []string{"9000/tcp"},
|
||||
WaitingFor: wait.ForLog("Ready for connections"),
|
||||
BindMounts: map[string]string{
|
||||
"/etc/clickhouse-server/config.d/custom.xml": path.Join(cwd, "../testdata/docker/custom.xml"),
|
||||
"/etc/clickhouse-server/users.d/admin.xml": path.Join(cwd, "../testdata/docker/admin.xml"),
|
||||
Mounts: testcontainers.ContainerMounts{
|
||||
{
|
||||
Source: testcontainers.GenericBindMountSource{
|
||||
HostPath: path.Join(cwd, "../testdata/docker/custom.xml"),
|
||||
},
|
||||
Target: "/etc/clickhouse-server/config.d/custom.xml",
|
||||
},
|
||||
{
|
||||
Source: testcontainers.GenericBindMountSource{
|
||||
HostPath: path.Join(cwd, "../testdata/docker/admin.xml"),
|
||||
},
|
||||
Target: "/etc/clickhouse-server/users.d/admin.xml",
|
||||
},
|
||||
},
|
||||
}
|
||||
clickhouseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
@ -55,18 +65,12 @@ func TestMain(m *testing.M) {
|
||||
|
||||
p, _ := clickhouseContainer.MappedPort(ctx, "9000")
|
||||
|
||||
os.Setenv("CLICKHOUSE_DB_PORT", p.Port())
|
||||
t.Setenv("CLICKHOUSE_DB_PORT", p.Port())
|
||||
defer clickhouseContainer.Terminate(ctx) //nolint
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// Execute a full default capture, with simple output, and check if a bundle is produced and it's not empty
|
||||
func TestCapture(t *testing.T) {
|
||||
tmrDir := t.TempDir()
|
||||
port, err := strconv.ParseUint(os.Getenv("CLICKHOUSE_DB_PORT"), 10, 16)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to read port value from environment")
|
||||
}
|
||||
port := p.Int()
|
||||
|
||||
// test a simple output exists
|
||||
_, err = outputs.GetOutputByName("simple")
|
||||
require.Nil(t, err)
|
||||
|
@ -1075,34 +1075,33 @@ struct AggregateFunctionSingleValueOrNullData : Data
|
||||
bool first_value = true;
|
||||
bool is_null = false;
|
||||
|
||||
bool changeIfBetter(const IColumn & column, size_t row_num, Arena * arena)
|
||||
void changeIfBetter(const IColumn & column, size_t row_num, Arena * arena)
|
||||
{
|
||||
if (first_value)
|
||||
{
|
||||
first_value = false;
|
||||
this->change(column, row_num, arena);
|
||||
return true;
|
||||
}
|
||||
else if (!this->isEqualTo(column, row_num))
|
||||
{
|
||||
is_null = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool changeIfBetter(const Self & to, Arena * arena)
|
||||
void changeIfBetter(const Self & to, Arena * arena)
|
||||
{
|
||||
if (!to.has())
|
||||
return;
|
||||
|
||||
if (first_value)
|
||||
{
|
||||
first_value = false;
|
||||
this->change(to, arena);
|
||||
return true;
|
||||
}
|
||||
else if (!this->isEqualTo(to))
|
||||
{
|
||||
is_null = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void addManyDefaults(const IColumn & column, size_t /*length*/, Arena * arena) { this->changeIfBetter(column, 0, arena); }
|
||||
|
@ -49,11 +49,11 @@ public:
|
||||
/// Do not apply for `count()` with without arguments or `count(*)`, only `count(x)` is supported.
|
||||
return;
|
||||
|
||||
argument_to_functions_mapping[argument_nodes[0]].push_back(&node);
|
||||
argument_to_functions_mapping[argument_nodes[0]].insert(&node);
|
||||
}
|
||||
|
||||
/// argument -> list of sum/count/avg functions with this argument
|
||||
QueryTreeNodePtrWithHashMap<std::vector<QueryTreeNodePtr *>> argument_to_functions_mapping;
|
||||
QueryTreeNodePtrWithHashMap<std::unordered_set<QueryTreeNodePtr *>> argument_to_functions_mapping;
|
||||
|
||||
private:
|
||||
std::unordered_set<String> names_to_collect;
|
||||
@ -79,6 +79,16 @@ FunctionNodePtr createResolvedAggregateFunction(const String & name, const Query
|
||||
function_node->resolveAsAggregateFunction(aggregate_function, aggregate_function->getReturnType());
|
||||
function_node->getArguments().getNodes() = { argument };
|
||||
|
||||
function_node->getArguments().getNodes() = { argument };
|
||||
|
||||
if (!parameters.empty())
|
||||
{
|
||||
QueryTreeNodes parameter_nodes;
|
||||
for (const auto & param : parameters)
|
||||
parameter_nodes.emplace_back(std::make_shared<ConstantNode>(param));
|
||||
function_node->getParameters().getNodes() = std::move(parameter_nodes);
|
||||
}
|
||||
|
||||
return function_node;
|
||||
}
|
||||
|
||||
@ -128,7 +138,9 @@ void replaceWithSumCount(QueryTreeNodePtr & node, const FunctionNodePtr & sum_co
|
||||
}
|
||||
}
|
||||
|
||||
FunctionNodePtr createFusedQuantilesNode(const std::vector<QueryTreeNodePtr *> nodes, const QueryTreeNodePtr & argument)
|
||||
/// Reorder nodes according to the value of the quantile level parameter.
|
||||
/// Levels are sorted in ascending order to make pass result deterministic.
|
||||
FunctionNodePtr createFusedQuantilesNode(std::vector<QueryTreeNodePtr *> & nodes, const QueryTreeNodePtr & argument)
|
||||
{
|
||||
Array parameters;
|
||||
parameters.reserve(nodes.size());
|
||||
@ -152,7 +164,34 @@ FunctionNodePtr createFusedQuantilesNode(const std::vector<QueryTreeNodePtr *> n
|
||||
if (!constant_value)
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Function '{}' should have constant parameter", function_name);
|
||||
|
||||
parameters.push_back(constant_value->getValue());
|
||||
const auto & value = constant_value->getValue();
|
||||
if (value.getType() != Field::Types::Float64)
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS,
|
||||
"Function '{}' should have parameter of type Float64, got '{}'",
|
||||
function_name, value.getTypeName());
|
||||
|
||||
parameters.push_back(value);
|
||||
}
|
||||
|
||||
{
|
||||
/// Sort nodes and parameters in ascending order of quantile level
|
||||
std::vector<size_t> permutation(nodes.size());
|
||||
std::iota(permutation.begin(), permutation.end(), 0);
|
||||
std::sort(permutation.begin(), permutation.end(), [&](size_t i, size_t j) { return parameters[i].get<Float64>() < parameters[j].get<Float64>(); });
|
||||
|
||||
std::vector<QueryTreeNodePtr *> new_nodes;
|
||||
new_nodes.reserve(permutation.size());
|
||||
|
||||
Array new_parameters;
|
||||
new_parameters.reserve(permutation.size());
|
||||
|
||||
for (size_t i : permutation)
|
||||
{
|
||||
new_nodes.emplace_back(nodes[i]);
|
||||
new_parameters.emplace_back(std::move(parameters[i]));
|
||||
}
|
||||
nodes = std::move(new_nodes);
|
||||
parameters = std::move(new_parameters);
|
||||
}
|
||||
|
||||
return createResolvedAggregateFunction("quantiles", argument, parameters);
|
||||
@ -183,12 +222,14 @@ void tryFuseQuantiles(QueryTreeNodePtr query_tree_node, ContextPtr context)
|
||||
FuseFunctionsVisitor visitor_quantile({"quantile"});
|
||||
visitor_quantile.visit(query_tree_node);
|
||||
|
||||
for (auto & [argument, nodes] : visitor_quantile.argument_to_functions_mapping)
|
||||
for (auto & [argument, nodes_set] : visitor_quantile.argument_to_functions_mapping)
|
||||
{
|
||||
size_t nodes_size = nodes.size();
|
||||
size_t nodes_size = nodes_set.size();
|
||||
if (nodes_size < 2)
|
||||
continue;
|
||||
|
||||
std::vector<QueryTreeNodePtr *> nodes(nodes_set.begin(), nodes_set.end());
|
||||
|
||||
auto quantiles_node = createFusedQuantilesNode(nodes, argument.node);
|
||||
auto result_array_type = std::dynamic_pointer_cast<const DataTypeArray>(quantiles_node->getResultType());
|
||||
if (!result_array_type)
|
||||
@ -196,8 +237,11 @@ void tryFuseQuantiles(QueryTreeNodePtr query_tree_node, ContextPtr context)
|
||||
"Unexpected return type '{}' of function '{}', should be array",
|
||||
quantiles_node->getResultType(), quantiles_node->getFunctionName());
|
||||
|
||||
for (size_t i = 0; i < nodes_size; ++i)
|
||||
*nodes[i] = createArrayElementFunction(context, result_array_type->getNestedType(), quantiles_node, i + 1);
|
||||
for (size_t i = 0; i < nodes_set.size(); ++i)
|
||||
{
|
||||
size_t array_index = i + 1;
|
||||
*nodes[i] = createArrayElementFunction(context, result_array_type->getNestedType(), quantiles_node, array_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1671,6 +1671,11 @@ void ClientBase::processParsedSingleQuery(const String & full_query, const Strin
|
||||
std::cerr << progress_indication.elapsedSeconds() << "\n";
|
||||
}
|
||||
|
||||
if (!is_interactive && print_num_processed_rows)
|
||||
{
|
||||
std::cout << "Processed rows: " << processed_rows << "\n";
|
||||
}
|
||||
|
||||
if (have_error && report_error)
|
||||
processError(full_query);
|
||||
}
|
||||
@ -2368,6 +2373,7 @@ void ClientBase::init(int argc, char ** argv)
|
||||
("hardware-utilization", "print hardware utilization information in progress bar")
|
||||
("print-profile-events", po::value(&profile_events.print)->zero_tokens(), "Printing ProfileEvents packets")
|
||||
("profile-events-delay-ms", po::value<UInt64>()->default_value(profile_events.delay_ms), "Delay between printing `ProfileEvents` packets (-1 - print only totals, 0 - print every single packet)")
|
||||
("processed-rows", "print the number of locally processed rows")
|
||||
|
||||
("interactive", "Process queries-file or --query query and start interactive mode")
|
||||
("pager", po::value<std::string>(), "Pipe all output into this command (less or similar)")
|
||||
@ -2446,6 +2452,8 @@ void ClientBase::init(int argc, char ** argv)
|
||||
config().setBool("print-profile-events", true);
|
||||
if (options.count("profile-events-delay-ms"))
|
||||
config().setUInt64("profile-events-delay-ms", options["profile-events-delay-ms"].as<UInt64>());
|
||||
if (options.count("processed-rows"))
|
||||
print_num_processed_rows = true;
|
||||
if (options.count("progress"))
|
||||
{
|
||||
switch (options["progress"].as<ProgressOption>())
|
||||
|
@ -253,6 +253,7 @@ protected:
|
||||
bool need_render_profile_events = true;
|
||||
bool written_first_block = false;
|
||||
size_t processed_rows = 0; /// How many rows have been read or written.
|
||||
bool print_num_processed_rows = false; /// Whether to print the number of processed rows at
|
||||
|
||||
bool print_stack_trace = false;
|
||||
/// The last exception that was received from the server. Is used for the
|
||||
|
@ -96,9 +96,8 @@ static ElementIdentifier getElementIdentifier(Node * element)
|
||||
{
|
||||
const NamedNodeMapPtr attrs = element->attributes();
|
||||
std::vector<std::pair<std::string, std::string>> attrs_kv;
|
||||
for (size_t i = 0, size = attrs->length(); i < size; ++i)
|
||||
for (const Node * node = attrs->item(0); node; node = node->nextSibling())
|
||||
{
|
||||
const Node * node = attrs->item(i);
|
||||
std::string name = node->nodeName();
|
||||
const auto * subst_name_pos = std::find(ConfigProcessor::SUBSTITUTION_ATTRS.begin(), ConfigProcessor::SUBSTITUTION_ATTRS.end(), name);
|
||||
if (name == "replace" || name == "remove" ||
|
||||
@ -123,9 +122,8 @@ static ElementIdentifier getElementIdentifier(Node * element)
|
||||
static Node * getRootNode(Document * document)
|
||||
{
|
||||
const NodeListPtr children = document->childNodes();
|
||||
for (size_t i = 0, size = children->length(); i < size; ++i)
|
||||
for (Node * child = children->item(0); child; child = child->nextSibling())
|
||||
{
|
||||
Node * child = children->item(i);
|
||||
/// Besides the root element there can be comment nodes on the top level.
|
||||
/// Skip them.
|
||||
if (child->nodeType() == Node::ELEMENT_NODE)
|
||||
@ -145,10 +143,8 @@ static void deleteAttributesRecursive(Node * root)
|
||||
const NodeListPtr children = root->childNodes();
|
||||
std::vector<Node *> children_to_delete;
|
||||
|
||||
for (size_t i = 0, size = children->length(); i < size; ++i)
|
||||
for (Node * child = children->item(0); child; child = child->nextSibling())
|
||||
{
|
||||
Node * child = children->item(i);
|
||||
|
||||
if (child->nodeType() == Node::ELEMENT_NODE)
|
||||
{
|
||||
Element & child_element = dynamic_cast<Element &>(*child);
|
||||
@ -189,10 +185,10 @@ void ConfigProcessor::mergeRecursive(XMLDocumentPtr config, Node * config_root,
|
||||
node = next_node;
|
||||
}
|
||||
|
||||
for (size_t i = 0, size = with_nodes->length(); i < size; ++i)
|
||||
Node * next_with_node = nullptr;
|
||||
for (Node * with_node = with_nodes->item(0); with_node; with_node = next_with_node)
|
||||
{
|
||||
Node * with_node = with_nodes->item(i);
|
||||
|
||||
next_with_node = with_node->nextSibling();
|
||||
bool merged = false;
|
||||
bool remove = false;
|
||||
if (with_node->nodeType() == Node::ELEMENT_NODE)
|
||||
@ -342,9 +338,11 @@ void ConfigProcessor::doIncludesRecursive(
|
||||
if (node->nodeName() == "include")
|
||||
{
|
||||
const NodeListPtr children = node_to_include->childNodes();
|
||||
for (size_t i = 0, size = children->length(); i < size; ++i)
|
||||
Node * next_child = nullptr;
|
||||
for (Node * child = children->item(0); child; child = next_child)
|
||||
{
|
||||
NodePtr new_node = config->importNode(children->item(i), true);
|
||||
next_child = child->nextSibling();
|
||||
NodePtr new_node = config->importNode(child, true);
|
||||
node->parentNode()->insertBefore(new_node, node);
|
||||
}
|
||||
|
||||
@ -366,16 +364,20 @@ void ConfigProcessor::doIncludesRecursive(
|
||||
}
|
||||
|
||||
const NodeListPtr children = node_to_include->childNodes();
|
||||
for (size_t i = 0, size = children->length(); i < size; ++i)
|
||||
Node * next_child = nullptr;
|
||||
for (Node * child = children->item(0); child; child = next_child)
|
||||
{
|
||||
NodePtr new_node = config->importNode(children->item(i), true);
|
||||
next_child = child->nextSibling();
|
||||
NodePtr new_node = config->importNode(child, true);
|
||||
node->appendChild(new_node);
|
||||
}
|
||||
|
||||
const NamedNodeMapPtr from_attrs = node_to_include->attributes();
|
||||
for (size_t i = 0, size = from_attrs->length(); i < size; ++i)
|
||||
Node * next_attr = nullptr;
|
||||
for (Node * attr = from_attrs->item(0); attr; attr = next_attr)
|
||||
{
|
||||
element.setAttributeNode(dynamic_cast<Attr *>(config->importNode(from_attrs->item(i), true)));
|
||||
next_attr = attr->nextSibling();
|
||||
element.setAttributeNode(dynamic_cast<Attr *>(config->importNode(attr, true)));
|
||||
}
|
||||
|
||||
included_something = true;
|
||||
@ -437,9 +439,12 @@ void ConfigProcessor::doIncludesRecursive(
|
||||
else
|
||||
{
|
||||
NodeListPtr children = node->childNodes();
|
||||
Node * child = nullptr;
|
||||
for (size_t i = 0; (child = children->item(i)); ++i)
|
||||
Node * next_child = nullptr;
|
||||
for (Node * child = children->item(0); child; child = next_child)
|
||||
{
|
||||
next_child = child->nextSibling();
|
||||
doIncludesRecursive(config, include_from, child, zk_node_cache, zk_changed_event, contributing_zk_paths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
63
src/Common/EventFD.cpp
Normal file
63
src/Common/EventFD.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
|
||||
#include <Common/EventFD.h>
|
||||
#include <Common/Exception.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int CANNOT_PIPE;
|
||||
extern const int CANNOT_READ_FROM_SOCKET;
|
||||
extern const int CANNOT_WRITE_TO_SOCKET;
|
||||
}
|
||||
|
||||
EventFD::EventFD()
|
||||
{
|
||||
fd = eventfd(0 /* initval */, 0 /* flags */);
|
||||
if (fd == -1)
|
||||
throwFromErrno("Cannot create eventfd", ErrorCodes::CANNOT_PIPE);
|
||||
}
|
||||
|
||||
uint64_t EventFD::read() const
|
||||
{
|
||||
uint64_t buf = 0;
|
||||
while (-1 == ::read(fd, &buf, sizeof(buf)))
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
break;
|
||||
|
||||
if (errno != EINTR)
|
||||
throwFromErrno("Cannot read from eventfd", ErrorCodes::CANNOT_READ_FROM_SOCKET);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool EventFD::write(uint64_t increase) const
|
||||
{
|
||||
while (-1 == ::write(fd, &increase, sizeof(increase)))
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
return false;
|
||||
|
||||
if (errno != EINTR)
|
||||
throwFromErrno("Cannot write to eventfd", ErrorCodes::CANNOT_WRITE_TO_SOCKET);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EventFD::~EventFD()
|
||||
{
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
38
src/Common/EventFD.h
Normal file
38
src/Common/EventFD.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
struct EventFD
|
||||
{
|
||||
EventFD();
|
||||
~EventFD();
|
||||
|
||||
/// Both read() and write() are blocking.
|
||||
/// TODO: add non-blocking flag to ctor.
|
||||
uint64_t read() const;
|
||||
bool write(uint64_t increase = 1) const;
|
||||
|
||||
int fd = -1;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
struct EventFD
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
65
src/Common/tests/gtest_config_processor.cpp
Normal file
65
src/Common/tests/gtest_config_processor.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include <Common/Config/ConfigProcessor.h>
|
||||
#include <IO/WriteBufferFromFile.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Poco/Timestamp.h>
|
||||
#include <Poco/Util/XMLConfiguration.h>
|
||||
#include <base/scope_guard.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
TEST(Common, ConfigProcessorManyElements)
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
auto path = fs::path("/tmp/test_config_processor/");
|
||||
|
||||
fs::create_directories(path);
|
||||
fs::create_directories(path / "config.d");
|
||||
SCOPE_EXIT({ fs::remove_all(path); });
|
||||
|
||||
auto config_file = std::make_unique<Poco::File>(path / "config.xml");
|
||||
|
||||
constexpr size_t element_count = 1000000;
|
||||
|
||||
{
|
||||
DB::WriteBufferFromFile out(config_file->path());
|
||||
writeString("<clickhouse>\n", out);
|
||||
for (size_t i = 0; i < element_count; ++i)
|
||||
writeString("<x><name>" + std::to_string(i) + "</name></x>\n", out);
|
||||
writeString("</clickhouse>\n", out);
|
||||
}
|
||||
|
||||
Poco::Timestamp load_start;
|
||||
|
||||
DB::ConfigProcessor processor(config_file->path(), /* throw_on_bad_incl = */ false, /* log_to_console = */ false);
|
||||
bool has_zk_includes;
|
||||
DB::XMLDocumentPtr config_xml = processor.processConfig(&has_zk_includes);
|
||||
DB::ConfigurationPtr configuration(new Poco::Util::XMLConfiguration(config_xml));
|
||||
|
||||
float load_elapsed_ms = (Poco::Timestamp() - load_start) / 1000.0f;
|
||||
std::cerr << "Config loading took " << load_elapsed_ms << " ms" << std::endl;
|
||||
|
||||
ASSERT_EQ("0", configuration->getString("x.name"));
|
||||
ASSERT_EQ("1", configuration->getString("x[1].name"));
|
||||
constexpr size_t last = element_count - 1;
|
||||
ASSERT_EQ(std::to_string(last), configuration->getString("x[" + std::to_string(last) + "].name"));
|
||||
|
||||
/// More that 5 min is way too slow
|
||||
ASSERT_LE(load_elapsed_ms, 300*1000);
|
||||
|
||||
Poco::Timestamp enumerate_start;
|
||||
|
||||
Poco::Util::AbstractConfiguration::Keys keys;
|
||||
configuration->keys("", keys);
|
||||
|
||||
float enumerate_elapsed_ms = (Poco::Timestamp() - enumerate_start) / 1000.0f;
|
||||
std::cerr << "Key enumeration took " << enumerate_elapsed_ms << " ms" << std::endl;
|
||||
|
||||
ASSERT_EQ(element_count, keys.size());
|
||||
ASSERT_EQ("x", keys[0]);
|
||||
ASSERT_EQ("x[1]", keys[1]);
|
||||
|
||||
/// More that 5 min is way too slow
|
||||
ASSERT_LE(enumerate_elapsed_ms, 300*1000);
|
||||
}
|
@ -631,6 +631,8 @@ static constexpr UInt64 operator""_GiB(unsigned long long value)
|
||||
M(Bool, allow_unrestricted_reads_from_keeper, false, "Allow unrestricted (without condition on path) reads from system.zookeeper table, can be handy, but is not safe for zookeeper", 0) \
|
||||
M(Bool, allow_deprecated_database_ordinary, false, "Allow to create databases with deprecated Ordinary engine", 0) \
|
||||
M(Bool, allow_deprecated_syntax_for_merge_tree, false, "Allow to create *MergeTree tables with deprecated engine definition syntax", 0) \
|
||||
M(Bool, allow_asynchronous_read_from_io_pool_for_merge_tree, false, "Use background I/O pool to read from MergeTree tables. This setting may increase performance for I/O bound queries", 0) \
|
||||
M(UInt64, max_streams_for_merge_tree_reading, 0, "If is not zero, limit the number of reading streams for MergeTree table.", 0) \
|
||||
\
|
||||
M(Bool, force_grouping_standard_compatibility, true, "Make GROUPING function to return 1 when argument is not used as an aggregation key", 0) \
|
||||
\
|
||||
|
@ -119,7 +119,7 @@ void JSONDataParser<ParserImpl>::traverseArrayElement(const Element & element, P
|
||||
if (values[i].isNull())
|
||||
continue;
|
||||
|
||||
UInt128 hash = PathInData::getPartsHash(paths[i]);
|
||||
UInt128 hash = PathInData::getPartsHash(paths[i].begin(), paths[i].end());
|
||||
if (auto * found = ctx.arrays_by_path.find(hash))
|
||||
{
|
||||
auto & path_array = found->getMapped().second;
|
||||
@ -128,11 +128,11 @@ void JSONDataParser<ParserImpl>::traverseArrayElement(const Element & element, P
|
||||
/// If current element of array is part of Nested,
|
||||
/// collect its size or check it if the size of
|
||||
/// the Nested has been already collected.
|
||||
auto nested_key = getNameOfNested(paths[i], values[i]);
|
||||
if (!nested_key.empty())
|
||||
auto nested_hash = getHashOfNestedPath(paths[i], values[i]);
|
||||
if (nested_hash)
|
||||
{
|
||||
size_t array_size = values[i].template get<const Array &>().size();
|
||||
auto & current_nested_sizes = ctx.nested_sizes_by_key[nested_key];
|
||||
auto & current_nested_sizes = ctx.nested_sizes_by_path[*nested_hash];
|
||||
|
||||
if (current_nested_sizes.size() == ctx.current_size)
|
||||
current_nested_sizes.push_back(array_size);
|
||||
@ -151,11 +151,11 @@ void JSONDataParser<ParserImpl>::traverseArrayElement(const Element & element, P
|
||||
path_array.reserve(ctx.total_size);
|
||||
path_array.resize(ctx.current_size);
|
||||
|
||||
auto nested_key = getNameOfNested(paths[i], values[i]);
|
||||
if (!nested_key.empty())
|
||||
auto nested_hash = getHashOfNestedPath(paths[i], values[i]);
|
||||
if (nested_hash)
|
||||
{
|
||||
size_t array_size = values[i].template get<const Array &>().size();
|
||||
auto & current_nested_sizes = ctx.nested_sizes_by_key[nested_key];
|
||||
auto & current_nested_sizes = ctx.nested_sizes_by_path[*nested_hash];
|
||||
|
||||
if (current_nested_sizes.empty())
|
||||
{
|
||||
@ -217,11 +217,11 @@ bool JSONDataParser<ParserImpl>::tryInsertDefaultFromNested(
|
||||
return false;
|
||||
|
||||
/// Last element is not Null, because otherwise this path wouldn't exist.
|
||||
auto nested_key = getNameOfNested(path, array.back());
|
||||
if (nested_key.empty())
|
||||
auto hash = getHashOfNestedPath(path, array.back());
|
||||
if (!hash)
|
||||
return false;
|
||||
|
||||
auto * mapped = ctx.nested_sizes_by_key.find(nested_key);
|
||||
auto * mapped = ctx.nested_sizes_by_path.find(*hash);
|
||||
if (!mapped)
|
||||
return false;
|
||||
|
||||
@ -251,21 +251,21 @@ Field JSONDataParser<ParserImpl>::getValueAsField(const Element & element)
|
||||
}
|
||||
|
||||
template <typename ParserImpl>
|
||||
StringRef JSONDataParser<ParserImpl>::getNameOfNested(const PathInData::Parts & path, const Field & value)
|
||||
std::optional<UInt128> JSONDataParser<ParserImpl>::getHashOfNestedPath(const PathInData::Parts & path, const Field & value)
|
||||
{
|
||||
if (value.getType() != Field::Types::Array || path.empty())
|
||||
return {};
|
||||
|
||||
/// Find first key that is marked as nested,
|
||||
/// because we may have tuple of Nested and there could be
|
||||
/// Find first key that is marked as nested and return hash of its path.
|
||||
/// It's needed because we may have tuple of Nested and there could be
|
||||
/// several arrays with the same prefix, but with independent sizes.
|
||||
/// Consider we have array element with type `k2 Tuple(k3 Nested(...), k5 Nested(...))`
|
||||
/// Then subcolumns `k2.k3` and `k2.k5` may have indepented sizes and we should extract
|
||||
/// `k3` and `k5` keys instead of `k2`.
|
||||
|
||||
for (const auto & part : path)
|
||||
if (part.is_nested)
|
||||
return StringRef{part.key};
|
||||
for (size_t i = 0; i != path.size(); ++i)
|
||||
if (path[i].is_nested)
|
||||
return PathInData::getPartsHash(path.begin(), std::next(path.begin(), i + 1));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ private:
|
||||
|
||||
using PathPartsWithArray = std::pair<PathInData::Parts, Array>;
|
||||
using PathToArray = HashMapWithStackMemory<UInt128, PathPartsWithArray, UInt128TrivialHash, 5>;
|
||||
using KeyToSizes = HashMapWithStackMemory<StringRef, std::vector<size_t>, StringRefHash, 5>;
|
||||
using PathToSizes = HashMapWithStackMemory<UInt128, std::vector<size_t>, UInt128TrivialHash, 5>;
|
||||
|
||||
struct ParseArrayContext
|
||||
{
|
||||
@ -42,7 +42,7 @@ private:
|
||||
size_t total_size = 0;
|
||||
|
||||
PathToArray arrays_by_path;
|
||||
KeyToSizes nested_sizes_by_key;
|
||||
PathToSizes nested_sizes_by_path;
|
||||
Arena strings_pool;
|
||||
};
|
||||
|
||||
@ -56,7 +56,7 @@ private:
|
||||
ParseArrayContext & ctx, const PathInData::Parts & path, Array & array);
|
||||
|
||||
static Field getValueAsField(const Element & element);
|
||||
static StringRef getNameOfNested(const PathInData::Parts & path, const Field & value);
|
||||
static std::optional<UInt128> getHashOfNestedPath(const PathInData::Parts & path, const Field & value);
|
||||
|
||||
ParserImpl parser;
|
||||
};
|
||||
|
@ -54,15 +54,15 @@ PathInData & PathInData::operator=(const PathInData & other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
UInt128 PathInData::getPartsHash(const Parts & parts_)
|
||||
UInt128 PathInData::getPartsHash(const Parts::const_iterator & begin, const Parts::const_iterator & end)
|
||||
{
|
||||
SipHash hash;
|
||||
hash.update(parts_.size());
|
||||
for (const auto & part : parts_)
|
||||
hash.update(std::distance(begin, end));
|
||||
for (auto part_it = begin; part_it != end; ++part_it)
|
||||
{
|
||||
hash.update(part.key.data(), part.key.length());
|
||||
hash.update(part.is_nested);
|
||||
hash.update(part.anonymous_array_level);
|
||||
hash.update(part_it->key.data(), part_it->key.length());
|
||||
hash.update(part_it->is_nested);
|
||||
hash.update(part_it->anonymous_array_level);
|
||||
}
|
||||
|
||||
UInt128 res;
|
||||
@ -104,7 +104,7 @@ void PathInData::buildParts(const Parts & other_parts)
|
||||
|
||||
size_t PathInData::Hash::operator()(const PathInData & value) const
|
||||
{
|
||||
auto hash = getPartsHash(value.parts);
|
||||
auto hash = getPartsHash(value.parts.begin(), value.parts.end());
|
||||
return hash.items[0] ^ hash.items[1];
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
PathInData(const PathInData & other);
|
||||
PathInData & operator=(const PathInData & other);
|
||||
|
||||
static UInt128 getPartsHash(const Parts & parts_);
|
||||
static UInt128 getPartsHash(const Parts::const_iterator & begin, const Parts::const_iterator & end);
|
||||
|
||||
bool empty() const { return parts.empty(); }
|
||||
|
||||
|
@ -588,6 +588,19 @@ void FormatFactory::markFormatSupportsSubsetOfColumns(const String & name)
|
||||
target = true;
|
||||
}
|
||||
|
||||
void FormatFactory::markFormatSupportsSubcolumns(const String & name)
|
||||
{
|
||||
auto & target = dict[name].supports_subcolumns;
|
||||
if (target)
|
||||
throw Exception("FormatFactory: Format " + name + " is already marked as supporting subcolumns", ErrorCodes::LOGICAL_ERROR);
|
||||
target = true;
|
||||
}
|
||||
|
||||
bool FormatFactory::checkIfFormatSupportsSubcolumns(const String & name) const
|
||||
{
|
||||
const auto & target = getCreators(name);
|
||||
return target.supports_subcolumns;
|
||||
}
|
||||
|
||||
bool FormatFactory::checkIfFormatSupportsSubsetOfColumns(const String & name) const
|
||||
{
|
||||
|
@ -118,6 +118,7 @@ private:
|
||||
SchemaReaderCreator schema_reader_creator;
|
||||
ExternalSchemaReaderCreator external_schema_reader_creator;
|
||||
bool supports_parallel_formatting{false};
|
||||
bool supports_subcolumns{false};
|
||||
bool supports_subset_of_columns{false};
|
||||
NonTrivialPrefixAndSuffixChecker non_trivial_prefix_and_suffix_checker;
|
||||
AppendSupportChecker append_support_checker;
|
||||
@ -205,8 +206,10 @@ public:
|
||||
void registerExternalSchemaReader(const String & name, ExternalSchemaReaderCreator external_schema_reader_creator);
|
||||
|
||||
void markOutputFormatSupportsParallelFormatting(const String & name);
|
||||
void markFormatSupportsSubcolumns(const String & name);
|
||||
void markFormatSupportsSubsetOfColumns(const String & name);
|
||||
|
||||
bool checkIfFormatSupportsSubcolumns(const String & name) const;
|
||||
bool checkIfFormatSupportsSubsetOfColumns(const String & name) const;
|
||||
|
||||
bool checkIfFormatHasSchemaReader(const String & name) const;
|
||||
|
@ -2148,7 +2148,13 @@ struct ToNumberMonotonicity
|
||||
return { .is_monotonic = true, .is_always_monotonic = true };
|
||||
|
||||
/// If converting from Float, for monotonicity, arguments must fit in range of result type.
|
||||
if (WhichDataType(type).isFloat())
|
||||
bool is_type_float = false;
|
||||
if (const auto * low_cardinality = typeid_cast<const DataTypeLowCardinality *>(&type))
|
||||
is_type_float = WhichDataType(low_cardinality->getDictionaryType()).isFloat();
|
||||
else
|
||||
is_type_float = WhichDataType(type).isFloat();
|
||||
|
||||
if (is_type_float)
|
||||
{
|
||||
if (left.isNull() || right.isNull())
|
||||
return {};
|
||||
|
@ -4,11 +4,14 @@
|
||||
#include <unordered_set>
|
||||
#include <stack>
|
||||
|
||||
#include <Parsers/ASTAlterQuery.h>
|
||||
#include <Parsers/ASTCreateQuery.h>
|
||||
#include <Parsers/ASTFunction.h>
|
||||
#include <Parsers/ASTCreateFunctionQuery.h>
|
||||
#include <Parsers/ASTExpressionList.h>
|
||||
#include <Parsers/ASTIdentifier.h>
|
||||
#include <Functions/UserDefined/UserDefinedSQLFunctionFactory.h>
|
||||
#include "Parsers/ASTColumnDeclaration.h"
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -19,24 +22,96 @@ namespace ErrorCodes
|
||||
extern const int UNSUPPORTED_METHOD;
|
||||
}
|
||||
|
||||
void UserDefinedSQLFunctionMatcher::visit(ASTPtr & ast, Data &)
|
||||
void UserDefinedSQLFunctionVisitor::visit(ASTPtr & ast)
|
||||
{
|
||||
auto * function = ast->as<ASTFunction>();
|
||||
if (!function)
|
||||
const auto visit_child_with_shared_ptr = [&](ASTPtr & child)
|
||||
{
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
auto * old_value = child.get();
|
||||
visit(child);
|
||||
ast->setOrReplace(old_value, child);
|
||||
};
|
||||
|
||||
if (auto * col_decl = ast->as<ASTColumnDeclaration>())
|
||||
{
|
||||
visit_child_with_shared_ptr(col_decl->default_expression);
|
||||
visit_child_with_shared_ptr(col_decl->ttl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto * storage = ast->as<ASTStorage>())
|
||||
{
|
||||
const auto visit_child = [&](IAST * & child)
|
||||
{
|
||||
if (!child)
|
||||
return;
|
||||
|
||||
if (const auto * function = child->template as<ASTFunction>())
|
||||
{
|
||||
std::unordered_set<std::string> udf_in_replace_process;
|
||||
auto replace_result = tryToReplaceFunction(*function, udf_in_replace_process);
|
||||
if (replace_result)
|
||||
ast->setOrReplace(child, replace_result);
|
||||
}
|
||||
|
||||
visit(child);
|
||||
};
|
||||
|
||||
visit_child(storage->partition_by);
|
||||
visit_child(storage->primary_key);
|
||||
visit_child(storage->order_by);
|
||||
visit_child(storage->sample_by);
|
||||
visit_child(storage->ttl_table);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto * alter = ast->as<ASTAlterCommand>())
|
||||
{
|
||||
visit_child_with_shared_ptr(alter->col_decl);
|
||||
visit_child_with_shared_ptr(alter->column);
|
||||
visit_child_with_shared_ptr(alter->partition);
|
||||
visit_child_with_shared_ptr(alter->order_by);
|
||||
visit_child_with_shared_ptr(alter->sample_by);
|
||||
visit_child_with_shared_ptr(alter->index_decl);
|
||||
visit_child_with_shared_ptr(alter->index);
|
||||
visit_child_with_shared_ptr(alter->constraint_decl);
|
||||
visit_child_with_shared_ptr(alter->constraint);
|
||||
visit_child_with_shared_ptr(alter->projection_decl);
|
||||
visit_child_with_shared_ptr(alter->projection);
|
||||
visit_child_with_shared_ptr(alter->predicate);
|
||||
visit_child_with_shared_ptr(alter->update_assignments);
|
||||
visit_child_with_shared_ptr(alter->values);
|
||||
visit_child_with_shared_ptr(alter->ttl);
|
||||
visit_child_with_shared_ptr(alter->select);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto * function = ast->template as<ASTFunction>())
|
||||
{
|
||||
std::unordered_set<std::string> udf_in_replace_process;
|
||||
auto replace_result = tryToReplaceFunction(*function, udf_in_replace_process);
|
||||
if (replace_result)
|
||||
ast = replace_result;
|
||||
}
|
||||
|
||||
for (auto & child : ast->children)
|
||||
visit(child);
|
||||
}
|
||||
|
||||
void UserDefinedSQLFunctionVisitor::visit(IAST * ast)
|
||||
{
|
||||
if (!ast)
|
||||
return;
|
||||
|
||||
std::unordered_set<std::string> udf_in_replace_process;
|
||||
auto replace_result = tryToReplaceFunction(*function, udf_in_replace_process);
|
||||
if (replace_result)
|
||||
ast = replace_result;
|
||||
for (auto & child : ast->children)
|
||||
visit(child);
|
||||
}
|
||||
|
||||
bool UserDefinedSQLFunctionMatcher::needChildVisit(const ASTPtr &, const ASTPtr &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ASTPtr UserDefinedSQLFunctionMatcher::tryToReplaceFunction(const ASTFunction & function, std::unordered_set<std::string> & udf_in_replace_process)
|
||||
ASTPtr UserDefinedSQLFunctionVisitor::tryToReplaceFunction(const ASTFunction & function, std::unordered_set<std::string> & udf_in_replace_process)
|
||||
{
|
||||
if (udf_in_replace_process.find(function.name) != udf_in_replace_process.end())
|
||||
throw Exception(ErrorCodes::UNSUPPORTED_METHOD,
|
||||
|
@ -19,26 +19,14 @@ class ASTFunction;
|
||||
* After applying visitor:
|
||||
* SELECT number + 1 FROM system.numbers LIMIT 10;
|
||||
*/
|
||||
class UserDefinedSQLFunctionMatcher
|
||||
class UserDefinedSQLFunctionVisitor
|
||||
{
|
||||
public:
|
||||
using Visitor = InDepthNodeVisitor<UserDefinedSQLFunctionMatcher, true>;
|
||||
|
||||
struct Data
|
||||
{
|
||||
};
|
||||
|
||||
static void visit(ASTPtr & ast, Data & data);
|
||||
static bool needChildVisit(const ASTPtr & node, const ASTPtr & child);
|
||||
|
||||
static void visit(ASTPtr & ast);
|
||||
private:
|
||||
static void visit(ASTFunction & func, const Data & data);
|
||||
|
||||
static void visit(IAST *);
|
||||
static ASTPtr tryToReplaceFunction(const ASTFunction & function, std::unordered_set<std::string> & udf_in_replace_process);
|
||||
|
||||
};
|
||||
|
||||
/// Visits AST nodes and collect their aliases in one map (with links to source nodes).
|
||||
using UserDefinedSQLFunctionVisitor = UserDefinedSQLFunctionMatcher::Visitor;
|
||||
|
||||
}
|
||||
|
@ -1215,6 +1215,8 @@ void DatabaseCatalog::cleanupStoreDirectoryTask()
|
||||
|
||||
if (affected_dirs)
|
||||
LOG_INFO(log, "Cleaned up {} directories from store/ on disk {}", affected_dirs, disk_name);
|
||||
else
|
||||
LOG_TEST(log, "Nothing to clean up from store/ on disk {}", disk_name);
|
||||
}
|
||||
|
||||
(*cleanup_task)->scheduleAfter(unused_dir_cleanup_period_sec * 1000);
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include <Storages/PartitionCommands.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
|
||||
#include <Functions/UserDefined/UserDefinedSQLFunctionFactory.h>
|
||||
#include <Functions/UserDefined/UserDefinedSQLFunctionVisitor.h>
|
||||
|
||||
#include <boost/range/algorithm_ext/push_back.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@ -66,6 +69,9 @@ BlockIO InterpreterAlterQuery::executeToTable(const ASTAlterQuery & alter)
|
||||
{
|
||||
BlockIO res;
|
||||
|
||||
if (!UserDefinedSQLFunctionFactory::instance().empty())
|
||||
UserDefinedSQLFunctionVisitor::visit(query_ptr);
|
||||
|
||||
if (!alter.cluster.empty() && !maybeRemoveOnCluster(query_ptr, getContext()))
|
||||
{
|
||||
DDLQueryOnClusterParams params;
|
||||
|
@ -71,6 +71,9 @@
|
||||
#include <Common/logger_useful.h>
|
||||
#include <DataTypes/DataTypeFixedString.h>
|
||||
|
||||
#include <Functions/UserDefined/UserDefinedSQLFunctionFactory.h>
|
||||
#include <Functions/UserDefined/UserDefinedSQLFunctionVisitor.h>
|
||||
|
||||
|
||||
#define MAX_FIXEDSTRING_SIZE_WITHOUT_SUSPICIOUS 256
|
||||
|
||||
@ -368,6 +371,7 @@ ASTPtr InterpreterCreateQuery::formatColumns(const NamesAndTypesList & columns,
|
||||
const char * alias_end = alias_pos + alias.size();
|
||||
ParserExpression expression_parser;
|
||||
column_declaration->default_expression = parseQuery(expression_parser, alias_pos, alias_end, "expression", 0, DBMS_DEFAULT_MAX_PARSER_DEPTH);
|
||||
column_declaration->children.push_back(column_declaration->default_expression);
|
||||
|
||||
columns_list->children.emplace_back(column_declaration);
|
||||
}
|
||||
@ -1156,6 +1160,10 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
|
||||
visitor.visit(*create.columns_list);
|
||||
}
|
||||
|
||||
// substitute possible UDFs with their definitions
|
||||
if (!UserDefinedSQLFunctionFactory::instance().empty())
|
||||
UserDefinedSQLFunctionVisitor::visit(query_ptr);
|
||||
|
||||
/// Set and retrieve list of columns, indices and constraints. Set table engine if needed. Rewrite query in canonical way.
|
||||
TableProperties properties = getTablePropertiesAndNormalizeCreateQuery(create);
|
||||
|
||||
|
@ -246,36 +246,6 @@ GroupByKeysInfo getGroupByKeysInfo(const ASTs & group_by_keys)
|
||||
return data;
|
||||
}
|
||||
|
||||
///eliminate functions of other GROUP BY keys
|
||||
void optimizeGroupByFunctionKeys(ASTSelectQuery * select_query)
|
||||
{
|
||||
if (!select_query->groupBy())
|
||||
return;
|
||||
|
||||
auto group_by = select_query->groupBy();
|
||||
const auto & group_by_keys = group_by->children;
|
||||
|
||||
ASTs modified; ///result
|
||||
|
||||
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_by_keys);
|
||||
|
||||
if (!group_by_keys_data.has_function)
|
||||
return;
|
||||
|
||||
GroupByFunctionKeysVisitor::Data visitor_data{group_by_keys_data.key_names};
|
||||
GroupByFunctionKeysVisitor(visitor_data).visit(group_by);
|
||||
|
||||
modified.reserve(group_by_keys.size());
|
||||
|
||||
/// filling the result
|
||||
for (const auto & group_key : group_by_keys)
|
||||
if (group_by_keys_data.key_names.contains(group_key->getColumnName()))
|
||||
modified.push_back(group_key);
|
||||
|
||||
/// modifying the input
|
||||
group_by->children = modified;
|
||||
}
|
||||
|
||||
/// Eliminates min/max/any-aggregators of functions of GROUP BY keys
|
||||
void optimizeAggregateFunctionsOfGroupByKeys(ASTSelectQuery * select_query, ASTPtr & node)
|
||||
{
|
||||
@ -793,6 +763,36 @@ void TreeOptimizer::optimizeCountConstantAndSumOne(ASTPtr & query)
|
||||
RewriteCountVariantsVisitor::visit(query);
|
||||
}
|
||||
|
||||
///eliminate functions of other GROUP BY keys
|
||||
void TreeOptimizer::optimizeGroupByFunctionKeys(ASTSelectQuery * select_query)
|
||||
{
|
||||
if (!select_query->groupBy())
|
||||
return;
|
||||
|
||||
auto group_by = select_query->groupBy();
|
||||
const auto & group_by_keys = group_by->children;
|
||||
|
||||
ASTs modified; ///result
|
||||
|
||||
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_by_keys);
|
||||
|
||||
if (!group_by_keys_data.has_function)
|
||||
return;
|
||||
|
||||
GroupByFunctionKeysVisitor::Data visitor_data{group_by_keys_data.key_names};
|
||||
GroupByFunctionKeysVisitor(visitor_data).visit(group_by);
|
||||
|
||||
modified.reserve(group_by_keys.size());
|
||||
|
||||
/// filling the result
|
||||
for (const auto & group_key : group_by_keys)
|
||||
if (group_by_keys_data.key_names.contains(group_key->getColumnName()))
|
||||
modified.push_back(group_key);
|
||||
|
||||
/// modifying the input
|
||||
group_by->children = modified;
|
||||
}
|
||||
|
||||
void TreeOptimizer::apply(ASTPtr & query, TreeRewriterResult & result,
|
||||
const std::vector<TableWithColumnNamesAndTypes> & tables_with_columns, ContextPtr context)
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
|
||||
static void optimizeIf(ASTPtr & query, Aliases & aliases, bool if_chain_to_multiif);
|
||||
static void optimizeCountConstantAndSumOne(ASTPtr & query);
|
||||
static void optimizeGroupByFunctionKeys(ASTSelectQuery * select_query);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1359,7 +1359,9 @@ TreeRewriterResultPtr TreeRewriter::analyzeSelect(
|
||||
TreeOptimizer::optimizeIf(query, result.aliases, settings.optimize_if_chain_to_multiif);
|
||||
|
||||
/// Only apply AST optimization for initial queries.
|
||||
if (getContext()->getClientInfo().query_kind != ClientInfo::QueryKind::SECONDARY_QUERY && !select_options.ignore_ast_optimizations)
|
||||
const bool ast_optimizations_allowed
|
||||
= getContext()->getClientInfo().query_kind != ClientInfo::QueryKind::SECONDARY_QUERY && !select_options.ignore_ast_optimizations;
|
||||
if (ast_optimizations_allowed)
|
||||
TreeOptimizer::apply(query, result, tables_with_columns, getContext());
|
||||
|
||||
/// array_join_alias_to_name, array_join_result_to_source.
|
||||
@ -1396,6 +1398,10 @@ TreeRewriterResultPtr TreeRewriter::analyzeSelect(
|
||||
/// If query is changed, we need to redo some work to correct name resolution.
|
||||
if (is_changed)
|
||||
{
|
||||
/// We should re-apply the optimization, because an expression substituted from alias column might be a function of a group key.
|
||||
if (ast_optimizations_allowed && settings.optimize_group_by_function_keys)
|
||||
TreeOptimizer::optimizeGroupByFunctionKeys(select_query);
|
||||
|
||||
result.aggregates = getAggregates(query, *select_query);
|
||||
result.window_function_asts = getWindowFunctions(query, *select_query);
|
||||
result.expressions_with_window_function = getExpressionsWithWindowFunctions(query);
|
||||
@ -1473,10 +1479,7 @@ void TreeRewriter::normalize(
|
||||
ASTPtr & query, Aliases & aliases, const NameSet & source_columns_set, bool ignore_alias, const Settings & settings, bool allow_self_aliases, ContextPtr context_)
|
||||
{
|
||||
if (!UserDefinedSQLFunctionFactory::instance().empty())
|
||||
{
|
||||
UserDefinedSQLFunctionVisitor::Data data_user_defined_functions_visitor;
|
||||
UserDefinedSQLFunctionVisitor(data_user_defined_functions_visitor).visit(query);
|
||||
}
|
||||
UserDefinedSQLFunctionVisitor::visit(query);
|
||||
|
||||
CustomizeCountDistinctVisitor::Data data_count_distinct{settings.count_distinct_implementation};
|
||||
CustomizeCountDistinctVisitor(data_count_distinct).visit(query);
|
||||
|
@ -187,6 +187,7 @@ void registerInputFormatArrow(FormatFactory & factory)
|
||||
{
|
||||
return std::make_shared<ArrowBlockInputFormat>(buf, sample, false, format_settings);
|
||||
});
|
||||
factory.markFormatSupportsSubcolumns("Arrow");
|
||||
factory.markFormatSupportsSubsetOfColumns("Arrow");
|
||||
factory.registerInputFormat(
|
||||
"ArrowStream",
|
||||
|
@ -198,6 +198,7 @@ void registerInputFormatORC(FormatFactory & factory)
|
||||
{
|
||||
return std::make_shared<ORCBlockInputFormat>(buf, sample, settings);
|
||||
});
|
||||
factory.markFormatSupportsSubcolumns("ORC");
|
||||
factory.markFormatSupportsSubsetOfColumns("ORC");
|
||||
}
|
||||
|
||||
|
@ -201,6 +201,7 @@ void registerInputFormatParquet(FormatFactory & factory)
|
||||
{
|
||||
return std::make_shared<ParquetBlockInputFormat>(buf, sample, settings);
|
||||
});
|
||||
factory.markFormatSupportsSubcolumns("Parquet");
|
||||
factory.markFormatSupportsSubsetOfColumns("Parquet");
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <Storages/MergeTree/MergeTreeReadPool.h>
|
||||
#include <Storages/MergeTree/MergeTreeReverseSelectProcessor.h>
|
||||
#include <Storages/MergeTree/MergeTreeThreadSelectProcessor.h>
|
||||
#include <Storages/MergeTree/MergeTreeSource.h>
|
||||
#include <Storages/VirtualColumnUtils.h>
|
||||
#include <Common/logger_useful.h>
|
||||
#include <base/sort.h>
|
||||
@ -64,6 +65,8 @@ static MergeTreeReaderSettings getMergeTreeReaderSettings(
|
||||
.checksum_on_read = settings.checksum_on_read,
|
||||
.read_in_order = query_info.input_order_info != nullptr,
|
||||
.apply_deleted_mask = context->applyDeletedMask(),
|
||||
.use_asynchronous_read_from_pool = settings.allow_asynchronous_read_from_io_pool_for_merge_tree
|
||||
&& (settings.max_streams_to_max_threads_ratio > 1 || settings.allow_asynchronous_read_from_io_pool_for_merge_tree),
|
||||
};
|
||||
}
|
||||
|
||||
@ -88,7 +91,7 @@ ReadFromMergeTree::ReadFromMergeTree(
|
||||
Poco::Logger * log_,
|
||||
MergeTreeDataSelectAnalysisResultPtr analyzed_result_ptr_,
|
||||
bool enable_parallel_reading)
|
||||
: ISourceStep(DataStream{.header = MergeTreeBaseSelectProcessor::transformHeader(
|
||||
: ISourceStep(DataStream{.header = IMergeTreeSelectAlgorithm::transformHeader(
|
||||
storage_snapshot_->getSampleBlockForColumns(real_column_names_),
|
||||
getPrewhereInfoFromQueryInfo(query_info_),
|
||||
data_.getPartitionValueType(),
|
||||
@ -124,6 +127,21 @@ ReadFromMergeTree::ReadFromMergeTree(
|
||||
if (enable_parallel_reading)
|
||||
read_task_callback = context->getMergeTreeReadTaskCallback();
|
||||
|
||||
const auto & settings = context->getSettingsRef();
|
||||
if (settings.max_streams_for_merge_tree_reading)
|
||||
{
|
||||
if (settings.allow_asynchronous_read_from_io_pool_for_merge_tree)
|
||||
{
|
||||
/// When async reading is enabled, allow to read using more streams.
|
||||
/// Will add resize to output_streams_limit to reduce memory usage.
|
||||
output_streams_limit = std::min<size_t>(requested_num_streams, settings.max_streams_for_merge_tree_reading);
|
||||
requested_num_streams = std::max<size_t>(requested_num_streams, settings.max_streams_for_merge_tree_reading);
|
||||
}
|
||||
else
|
||||
/// Just limit requested_num_streams otherwise.
|
||||
requested_num_streams = std::min<size_t>(requested_num_streams, settings.max_streams_for_merge_tree_reading);
|
||||
}
|
||||
|
||||
/// Add explicit description.
|
||||
setStepDescription(data.getStorageID().getFullNameNotQuoted());
|
||||
|
||||
@ -210,12 +228,14 @@ Pipe ReadFromMergeTree::readFromPool(
|
||||
};
|
||||
}
|
||||
|
||||
auto source = std::make_shared<MergeTreeThreadSelectProcessor>(
|
||||
auto algorithm = std::make_unique<MergeTreeThreadSelectAlgorithm>(
|
||||
i, pool, min_marks_for_concurrent_read, max_block_size,
|
||||
settings.preferred_block_size_bytes, settings.preferred_max_column_in_block_size_bytes,
|
||||
data, storage_snapshot, use_uncompressed_cache,
|
||||
prewhere_info, actions_settings, reader_settings, virt_column_names, std::move(extension));
|
||||
|
||||
auto source = std::make_shared<MergeTreeSource>(std::move(algorithm));
|
||||
|
||||
/// Set the approximate number of rows for the first source only
|
||||
/// In case of parallel processing on replicas do not set approximate rows at all.
|
||||
/// Because the value will be identical on every replicas and will be accounted
|
||||
@ -223,13 +243,17 @@ Pipe ReadFromMergeTree::readFromPool(
|
||||
if (i == 0 && !client_info.collaborate_with_initiator)
|
||||
source->addTotalRowsApprox(total_rows);
|
||||
|
||||
|
||||
pipes.emplace_back(std::move(source));
|
||||
}
|
||||
|
||||
return Pipe::unitePipes(std::move(pipes));
|
||||
auto pipe = Pipe::unitePipes(std::move(pipes));
|
||||
if (output_streams_limit && output_streams_limit < pipe.numOutputPorts())
|
||||
pipe.resize(output_streams_limit);
|
||||
return pipe;
|
||||
}
|
||||
|
||||
template<typename TSource>
|
||||
template<typename Algorithm>
|
||||
ProcessorPtr ReadFromMergeTree::createSource(
|
||||
const RangesInDataPart & part,
|
||||
const Names & required_columns,
|
||||
@ -260,13 +284,15 @@ ProcessorPtr ReadFromMergeTree::createSource(
|
||||
/// because we don't know actual amount of read rows in case when limit is set.
|
||||
bool set_rows_approx = !extension.has_value() && !reader_settings.read_in_order;
|
||||
|
||||
auto source = std::make_shared<TSource>(
|
||||
auto algorithm = std::make_unique<Algorithm>(
|
||||
data, storage_snapshot, part.data_part, max_block_size, preferred_block_size_bytes,
|
||||
preferred_max_column_in_block_size_bytes, required_columns, part.ranges, use_uncompressed_cache, prewhere_info,
|
||||
actions_settings, reader_settings, virt_column_names, part.part_index_in_query, has_limit_below_one_block, std::move(extension));
|
||||
|
||||
auto source = std::make_shared<MergeTreeSource>(std::move(algorithm));
|
||||
|
||||
if (set_rows_approx)
|
||||
source -> addTotalRowsApprox(total_rows);
|
||||
source->addTotalRowsApprox(total_rows);
|
||||
|
||||
return source;
|
||||
}
|
||||
@ -286,8 +312,8 @@ Pipe ReadFromMergeTree::readInOrder(
|
||||
for (const auto & part : parts_with_range)
|
||||
{
|
||||
auto source = read_type == ReadType::InReverseOrder
|
||||
? createSource<MergeTreeReverseSelectProcessor>(part, required_columns, use_uncompressed_cache, has_limit_below_one_block)
|
||||
: createSource<MergeTreeInOrderSelectProcessor>(part, required_columns, use_uncompressed_cache, has_limit_below_one_block);
|
||||
? createSource<MergeTreeReverseSelectAlgorithm>(part, required_columns, use_uncompressed_cache, has_limit_below_one_block)
|
||||
: createSource<MergeTreeInOrderSelectAlgorithm>(part, required_columns, use_uncompressed_cache, has_limit_below_one_block);
|
||||
|
||||
pipes.emplace_back(std::move(source));
|
||||
}
|
||||
@ -1088,6 +1114,11 @@ void ReadFromMergeTree::requestReadingInOrder(size_t prefix_size, int direction,
|
||||
|
||||
reader_settings.read_in_order = true;
|
||||
|
||||
/// In case or read-in-order, don't create too many reading streams.
|
||||
/// Almost always we are reading from a single stream at a time because of merge sort.
|
||||
if (output_streams_limit)
|
||||
requested_num_streams = output_streams_limit;
|
||||
|
||||
/// update sort info for output stream
|
||||
SortDescription sort_description;
|
||||
const Names & sorting_key_columns = storage_snapshot->getMetadataForQuery()->getSortingKeyColumns();
|
||||
|
@ -184,7 +184,8 @@ private:
|
||||
ContextPtr context;
|
||||
|
||||
const size_t max_block_size;
|
||||
const size_t requested_num_streams;
|
||||
size_t requested_num_streams;
|
||||
size_t output_streams_limit = 0;
|
||||
const size_t preferred_block_size_bytes;
|
||||
const size_t preferred_max_column_in_block_size_bytes;
|
||||
const bool sample_factor_column_queried;
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Common/randomSeed.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
@ -1024,6 +1023,7 @@ void AlterCommands::prepare(const StorageInMemoryMetadata & metadata)
|
||||
command.ignore = true;
|
||||
}
|
||||
}
|
||||
|
||||
prepared = true;
|
||||
}
|
||||
|
||||
|
@ -773,7 +773,6 @@ Pipe StorageHive::read(
|
||||
sources_info->partition_name_types = partition_name_types;
|
||||
|
||||
const auto header_block = storage_snapshot->metadata->getSampleBlock();
|
||||
bool support_subset_columns = supportsSubcolumns();
|
||||
|
||||
auto settings = context_->getSettingsRef();
|
||||
auto case_insensitive_matching = [&]() -> bool
|
||||
@ -793,15 +792,14 @@ Pipe StorageHive::read(
|
||||
sample_block.insert(header_block.getByName(column));
|
||||
continue;
|
||||
}
|
||||
else if (support_subset_columns)
|
||||
|
||||
auto subset_column = nested_columns_extractor.extractColumn(column);
|
||||
if (subset_column)
|
||||
{
|
||||
auto subset_column = nested_columns_extractor.extractColumn(column);
|
||||
if (subset_column)
|
||||
{
|
||||
sample_block.insert(std::move(*subset_column));
|
||||
continue;
|
||||
}
|
||||
sample_block.insert(std::move(*subset_column));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (column == "_path")
|
||||
sources_info->need_path_column = true;
|
||||
if (column == "_file")
|
||||
|
@ -142,7 +142,11 @@ MergeInfo MergeListElement::getInfo() const
|
||||
return res;
|
||||
}
|
||||
|
||||
MergeListElement::~MergeListElement() = default;
|
||||
MergeListElement::~MergeListElement()
|
||||
{
|
||||
CurrentThread::getMemoryTracker()->adjustWithUntrackedMemory(untracked_memory);
|
||||
untracked_memory = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ private:
|
||||
MergeListEntry & merge_list_entry;
|
||||
MemoryTracker * background_thread_memory_tracker;
|
||||
MemoryTracker * background_thread_memory_tracker_prev_parent = nullptr;
|
||||
UInt64 prev_untracked_memory_limit;
|
||||
UInt64 prev_untracked_memory;
|
||||
Int64 prev_untracked_memory_limit;
|
||||
Int64 prev_untracked_memory;
|
||||
String prev_query_id;
|
||||
};
|
||||
|
||||
|
@ -25,8 +25,20 @@ namespace ErrorCodes
|
||||
extern const int QUERY_WAS_CANCELLED;
|
||||
}
|
||||
|
||||
static void injectNonConstVirtualColumns(
|
||||
size_t rows,
|
||||
Block & block,
|
||||
const Names & virtual_columns);
|
||||
|
||||
MergeTreeBaseSelectProcessor::MergeTreeBaseSelectProcessor(
|
||||
static void injectPartConstVirtualColumns(
|
||||
size_t rows,
|
||||
Block & block,
|
||||
MergeTreeReadTask * task,
|
||||
const DataTypePtr & partition_value_type,
|
||||
const Names & virtual_columns);
|
||||
|
||||
|
||||
IMergeTreeSelectAlgorithm::IMergeTreeSelectAlgorithm(
|
||||
Block header,
|
||||
const MergeTreeData & storage_,
|
||||
const StorageSnapshotPtr & storage_snapshot_,
|
||||
@ -39,8 +51,7 @@ MergeTreeBaseSelectProcessor::MergeTreeBaseSelectProcessor(
|
||||
bool use_uncompressed_cache_,
|
||||
const Names & virt_column_names_,
|
||||
std::optional<ParallelReadingExtension> extension_)
|
||||
: ISource(transformHeader(std::move(header), prewhere_info_, storage_.getPartitionValueType(), virt_column_names_))
|
||||
, storage(storage_)
|
||||
: storage(storage_)
|
||||
, storage_snapshot(storage_snapshot_)
|
||||
, prewhere_info(prewhere_info_)
|
||||
, prewhere_actions(getPrewhereActions(prewhere_info, actions_settings))
|
||||
@ -53,30 +64,20 @@ MergeTreeBaseSelectProcessor::MergeTreeBaseSelectProcessor(
|
||||
, partition_value_type(storage.getPartitionValueType())
|
||||
, extension(extension_)
|
||||
{
|
||||
header_without_virtual_columns = getPort().getHeader();
|
||||
header_without_const_virtual_columns = applyPrewhereActions(std::move(header), prewhere_info);
|
||||
size_t non_const_columns_offset = header_without_const_virtual_columns.columns();
|
||||
injectNonConstVirtualColumns(0, header_without_const_virtual_columns, virt_column_names);
|
||||
|
||||
/// Reverse order is to minimize reallocations when removing columns from the block
|
||||
for (auto it = virt_column_names.rbegin(); it != virt_column_names.rend(); ++it)
|
||||
{
|
||||
if (*it == "_part_offset")
|
||||
{
|
||||
non_const_virtual_column_names.emplace_back(*it);
|
||||
}
|
||||
else if (*it == LightweightDeleteDescription::FILTER_COLUMN.name)
|
||||
{
|
||||
non_const_virtual_column_names.emplace_back(*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Remove virtual columns that are going to be filled with const values
|
||||
if (header_without_virtual_columns.has(*it))
|
||||
header_without_virtual_columns.erase(*it);
|
||||
}
|
||||
}
|
||||
for (size_t col_num = non_const_columns_offset; col_num < header_without_const_virtual_columns.columns(); ++col_num)
|
||||
non_const_virtual_column_names.emplace_back(header_without_const_virtual_columns.getByPosition(col_num).name);
|
||||
|
||||
result_header = header_without_const_virtual_columns;
|
||||
injectPartConstVirtualColumns(0, result_header, nullptr, partition_value_type, virt_column_names);
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<PrewhereExprInfo> MergeTreeBaseSelectProcessor::getPrewhereActions(PrewhereInfoPtr prewhere_info, const ExpressionActionsSettings & actions_settings)
|
||||
std::unique_ptr<PrewhereExprInfo> IMergeTreeSelectAlgorithm::getPrewhereActions(PrewhereInfoPtr prewhere_info, const ExpressionActionsSettings & actions_settings)
|
||||
{
|
||||
std::unique_ptr<PrewhereExprInfo> prewhere_actions;
|
||||
if (prewhere_info)
|
||||
@ -111,7 +112,7 @@ std::unique_ptr<PrewhereExprInfo> MergeTreeBaseSelectProcessor::getPrewhereActio
|
||||
}
|
||||
|
||||
|
||||
bool MergeTreeBaseSelectProcessor::getNewTask()
|
||||
bool IMergeTreeSelectAlgorithm::getNewTask()
|
||||
{
|
||||
/// No parallel reading feature
|
||||
if (!extension.has_value())
|
||||
@ -127,7 +128,7 @@ bool MergeTreeBaseSelectProcessor::getNewTask()
|
||||
}
|
||||
|
||||
|
||||
bool MergeTreeBaseSelectProcessor::getNewTaskParallelReading()
|
||||
bool IMergeTreeSelectAlgorithm::getNewTaskParallelReading()
|
||||
{
|
||||
if (getTaskFromBuffer())
|
||||
return true;
|
||||
@ -152,7 +153,7 @@ bool MergeTreeBaseSelectProcessor::getNewTaskParallelReading()
|
||||
}
|
||||
|
||||
|
||||
bool MergeTreeBaseSelectProcessor::getTaskFromBuffer()
|
||||
bool IMergeTreeSelectAlgorithm::getTaskFromBuffer()
|
||||
{
|
||||
while (!buffered_ranges.empty())
|
||||
{
|
||||
@ -174,7 +175,7 @@ bool MergeTreeBaseSelectProcessor::getTaskFromBuffer()
|
||||
}
|
||||
|
||||
|
||||
bool MergeTreeBaseSelectProcessor::getDelayedTasks()
|
||||
bool IMergeTreeSelectAlgorithm::getDelayedTasks()
|
||||
{
|
||||
while (!delayed_tasks.empty())
|
||||
{
|
||||
@ -197,20 +198,23 @@ bool MergeTreeBaseSelectProcessor::getDelayedTasks()
|
||||
}
|
||||
|
||||
|
||||
Chunk MergeTreeBaseSelectProcessor::generate()
|
||||
ChunkAndProgress IMergeTreeSelectAlgorithm::read()
|
||||
{
|
||||
while (!isCancelled())
|
||||
size_t num_read_rows = 0;
|
||||
size_t num_read_bytes = 0;
|
||||
|
||||
while (!is_cancelled)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((!task || task->isFinished()) && !getNewTask())
|
||||
return {};
|
||||
break;
|
||||
}
|
||||
catch (const Exception & e)
|
||||
{
|
||||
/// See MergeTreeBaseSelectProcessor::getTaskFromBuffer()
|
||||
if (e.code() == ErrorCodes::QUERY_WAS_CANCELLED)
|
||||
return {};
|
||||
break;
|
||||
throw;
|
||||
}
|
||||
|
||||
@ -220,24 +224,35 @@ Chunk MergeTreeBaseSelectProcessor::generate()
|
||||
{
|
||||
injectVirtualColumns(res.block, res.row_count, task.get(), partition_value_type, virt_column_names);
|
||||
|
||||
/// Reorder the columns according to output header
|
||||
const auto & output_header = output.getHeader();
|
||||
/// Reorder the columns according to result_header
|
||||
Columns ordered_columns;
|
||||
ordered_columns.reserve(output_header.columns());
|
||||
for (size_t i = 0; i < output_header.columns(); ++i)
|
||||
ordered_columns.reserve(result_header.columns());
|
||||
for (size_t i = 0; i < result_header.columns(); ++i)
|
||||
{
|
||||
auto name = output_header.getByPosition(i).name;
|
||||
auto name = result_header.getByPosition(i).name;
|
||||
ordered_columns.push_back(res.block.getByName(name).column);
|
||||
}
|
||||
|
||||
return Chunk(ordered_columns, res.row_count);
|
||||
/// Account a progress from previous empty chunks.
|
||||
res.num_read_rows += num_read_rows;
|
||||
res.num_read_bytes += num_read_bytes;
|
||||
|
||||
return ChunkAndProgress{
|
||||
.chunk = Chunk(ordered_columns, res.row_count),
|
||||
.num_read_rows = res.num_read_rows,
|
||||
.num_read_bytes = res.num_read_bytes};
|
||||
}
|
||||
else
|
||||
{
|
||||
num_read_rows += res.num_read_rows;
|
||||
num_read_bytes += res.num_read_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
return {Chunk(), num_read_rows, num_read_bytes};
|
||||
}
|
||||
|
||||
void MergeTreeBaseSelectProcessor::initializeMergeTreeReadersForPart(
|
||||
void IMergeTreeSelectAlgorithm::initializeMergeTreeReadersForPart(
|
||||
MergeTreeData::DataPartPtr & data_part,
|
||||
const MergeTreeReadTaskColumns & task_columns, const StorageMetadataPtr & metadata_snapshot,
|
||||
const MarkRanges & mark_ranges, const IMergeTreeReader::ValueSizeMap & value_size_map,
|
||||
@ -268,7 +283,7 @@ void MergeTreeBaseSelectProcessor::initializeMergeTreeReadersForPart(
|
||||
}
|
||||
}
|
||||
|
||||
void MergeTreeBaseSelectProcessor::initializeRangeReaders(MergeTreeReadTask & current_task)
|
||||
void IMergeTreeSelectAlgorithm::initializeRangeReaders(MergeTreeReadTask & current_task)
|
||||
{
|
||||
return initializeRangeReadersImpl(
|
||||
current_task.range_reader, current_task.pre_range_readers, prewhere_info, prewhere_actions.get(),
|
||||
@ -276,7 +291,7 @@ void MergeTreeBaseSelectProcessor::initializeRangeReaders(MergeTreeReadTask & cu
|
||||
pre_reader_for_step, lightweight_delete_filter_step, non_const_virtual_column_names);
|
||||
}
|
||||
|
||||
void MergeTreeBaseSelectProcessor::initializeRangeReadersImpl(
|
||||
void IMergeTreeSelectAlgorithm::initializeRangeReadersImpl(
|
||||
MergeTreeRangeReader & range_reader, std::deque<MergeTreeRangeReader> & pre_range_readers,
|
||||
PrewhereInfoPtr prewhere_info, const PrewhereExprInfo * prewhere_actions,
|
||||
IMergeTreeReader * reader, bool has_lightweight_delete, const MergeTreeReaderSettings & reader_settings,
|
||||
@ -368,7 +383,7 @@ static UInt64 estimateNumRows(const MergeTreeReadTask & current_task, UInt64 cur
|
||||
}
|
||||
|
||||
|
||||
MergeTreeBaseSelectProcessor::BlockAndRowCount MergeTreeBaseSelectProcessor::readFromPartImpl()
|
||||
IMergeTreeSelectAlgorithm::BlockAndProgress IMergeTreeSelectAlgorithm::readFromPartImpl()
|
||||
{
|
||||
if (task->size_predictor)
|
||||
task->size_predictor->startBlock();
|
||||
@ -398,7 +413,8 @@ MergeTreeBaseSelectProcessor::BlockAndRowCount MergeTreeBaseSelectProcessor::rea
|
||||
|
||||
UInt64 num_filtered_rows = read_result.numReadRows() - read_result.num_rows;
|
||||
|
||||
progress(read_result.numReadRows(), read_result.numBytesRead());
|
||||
size_t num_read_rows = read_result.numReadRows();
|
||||
size_t num_read_bytes = read_result.numBytesRead();
|
||||
|
||||
if (task->size_predictor)
|
||||
{
|
||||
@ -408,16 +424,21 @@ MergeTreeBaseSelectProcessor::BlockAndRowCount MergeTreeBaseSelectProcessor::rea
|
||||
task->size_predictor->update(sample_block, read_result.columns, read_result.num_rows);
|
||||
}
|
||||
|
||||
if (read_result.num_rows == 0)
|
||||
return {};
|
||||
Block block;
|
||||
if (read_result.num_rows != 0)
|
||||
block = sample_block.cloneWithColumns(read_result.columns);
|
||||
|
||||
BlockAndRowCount res = { sample_block.cloneWithColumns(read_result.columns), read_result.num_rows };
|
||||
BlockAndProgress res = {
|
||||
.block = std::move(block),
|
||||
.row_count = read_result.num_rows,
|
||||
.num_read_rows = num_read_rows,
|
||||
.num_read_bytes = num_read_bytes };
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
MergeTreeBaseSelectProcessor::BlockAndRowCount MergeTreeBaseSelectProcessor::readFromPart()
|
||||
IMergeTreeSelectAlgorithm::BlockAndProgress IMergeTreeSelectAlgorithm::readFromPart()
|
||||
{
|
||||
if (!task->range_reader.isInitialized())
|
||||
initializeRangeReaders(*task);
|
||||
@ -474,9 +495,10 @@ namespace
|
||||
/// Adds virtual columns that are not const for all rows
|
||||
static void injectNonConstVirtualColumns(
|
||||
size_t rows,
|
||||
VirtualColumnsInserter & inserter,
|
||||
Block & block,
|
||||
const Names & virtual_columns)
|
||||
{
|
||||
VirtualColumnsInserter inserter(block);
|
||||
for (const auto & virtual_column_name : virtual_columns)
|
||||
{
|
||||
if (virtual_column_name == "_part_offset")
|
||||
@ -511,11 +533,12 @@ static void injectNonConstVirtualColumns(
|
||||
/// Adds virtual columns that are const for the whole part
|
||||
static void injectPartConstVirtualColumns(
|
||||
size_t rows,
|
||||
VirtualColumnsInserter & inserter,
|
||||
Block & block,
|
||||
MergeTreeReadTask * task,
|
||||
const DataTypePtr & partition_value_type,
|
||||
const Names & virtual_columns)
|
||||
{
|
||||
VirtualColumnsInserter inserter(block);
|
||||
/// add virtual columns
|
||||
/// Except _sample_factor, which is added from the outside.
|
||||
if (!virtual_columns.empty())
|
||||
@ -584,19 +607,16 @@ static void injectPartConstVirtualColumns(
|
||||
}
|
||||
}
|
||||
|
||||
void MergeTreeBaseSelectProcessor::injectVirtualColumns(
|
||||
void IMergeTreeSelectAlgorithm::injectVirtualColumns(
|
||||
Block & block, size_t row_count, MergeTreeReadTask * task, const DataTypePtr & partition_value_type, const Names & virtual_columns)
|
||||
{
|
||||
VirtualColumnsInserter inserter{block};
|
||||
|
||||
/// First add non-const columns that are filled by the range reader and then const columns that we will fill ourselves.
|
||||
/// Note that the order is important: virtual columns filled by the range reader must go first
|
||||
injectNonConstVirtualColumns(row_count, inserter, virtual_columns);
|
||||
injectPartConstVirtualColumns(row_count, inserter, task, partition_value_type, virtual_columns);
|
||||
injectNonConstVirtualColumns(row_count, block, virtual_columns);
|
||||
injectPartConstVirtualColumns(row_count, block, task, partition_value_type, virtual_columns);
|
||||
}
|
||||
|
||||
Block MergeTreeBaseSelectProcessor::transformHeader(
|
||||
Block block, const PrewhereInfoPtr & prewhere_info, const DataTypePtr & partition_value_type, const Names & virtual_columns)
|
||||
Block IMergeTreeSelectAlgorithm::applyPrewhereActions(Block block, const PrewhereInfoPtr & prewhere_info)
|
||||
{
|
||||
if (prewhere_info)
|
||||
{
|
||||
@ -638,11 +658,18 @@ Block MergeTreeBaseSelectProcessor::transformHeader(
|
||||
}
|
||||
}
|
||||
|
||||
injectVirtualColumns(block, 0, nullptr, partition_value_type, virtual_columns);
|
||||
return block;
|
||||
}
|
||||
|
||||
std::unique_ptr<MergeTreeBlockSizePredictor> MergeTreeBaseSelectProcessor::getSizePredictor(
|
||||
Block IMergeTreeSelectAlgorithm::transformHeader(
|
||||
Block block, const PrewhereInfoPtr & prewhere_info, const DataTypePtr & partition_value_type, const Names & virtual_columns)
|
||||
{
|
||||
auto transformed = applyPrewhereActions(std::move(block), prewhere_info);
|
||||
injectVirtualColumns(transformed, 0, nullptr, partition_value_type, virtual_columns);
|
||||
return transformed;
|
||||
}
|
||||
|
||||
std::unique_ptr<MergeTreeBlockSizePredictor> IMergeTreeSelectAlgorithm::getSizePredictor(
|
||||
const MergeTreeData::DataPartPtr & data_part,
|
||||
const MergeTreeReadTaskColumns & task_columns,
|
||||
const Block & sample_block)
|
||||
@ -660,7 +687,7 @@ std::unique_ptr<MergeTreeBlockSizePredictor> MergeTreeBaseSelectProcessor::getSi
|
||||
}
|
||||
|
||||
|
||||
MergeTreeBaseSelectProcessor::Status MergeTreeBaseSelectProcessor::performRequestToCoordinator(MarkRanges requested_ranges, bool delayed)
|
||||
IMergeTreeSelectAlgorithm::Status IMergeTreeSelectAlgorithm::performRequestToCoordinator(MarkRanges requested_ranges, bool delayed)
|
||||
{
|
||||
String partition_id = task->data_part->info.partition_id;
|
||||
String part_name;
|
||||
@ -732,7 +759,7 @@ MergeTreeBaseSelectProcessor::Status MergeTreeBaseSelectProcessor::performReques
|
||||
}
|
||||
|
||||
|
||||
size_t MergeTreeBaseSelectProcessor::estimateMaxBatchSizeForHugeRanges()
|
||||
size_t IMergeTreeSelectAlgorithm::estimateMaxBatchSizeForHugeRanges()
|
||||
{
|
||||
/// This is an empirical number and it is so,
|
||||
/// because we have an adaptive granularity by default.
|
||||
@ -768,7 +795,7 @@ size_t MergeTreeBaseSelectProcessor::estimateMaxBatchSizeForHugeRanges()
|
||||
return max_size_for_one_request / sum_average_marks_size;
|
||||
}
|
||||
|
||||
void MergeTreeBaseSelectProcessor::splitCurrentTaskRangesAndFillBuffer()
|
||||
void IMergeTreeSelectAlgorithm::splitCurrentTaskRangesAndFillBuffer()
|
||||
{
|
||||
const size_t max_batch_size = estimateMaxBatchSizeForHugeRanges();
|
||||
|
||||
@ -824,6 +851,6 @@ void MergeTreeBaseSelectProcessor::splitCurrentTaskRangesAndFillBuffer()
|
||||
buffered_ranges.pop_back();
|
||||
}
|
||||
|
||||
MergeTreeBaseSelectProcessor::~MergeTreeBaseSelectProcessor() = default;
|
||||
IMergeTreeSelectAlgorithm::~IMergeTreeSelectAlgorithm() = default;
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <Storages/MergeTree/MergeTreeBlockReadUtils.h>
|
||||
#include <Storages/MergeTree/MergeTreeData.h>
|
||||
#include <Storages/SelectQueryInfo.h>
|
||||
#include <Storages/MergeTree/IMergeTreeReader.h>
|
||||
#include <Storages/MergeTree/RequestResponse.h>
|
||||
|
||||
#include <Processors/ISource.h>
|
||||
#include <Processors/Chunk.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -17,6 +15,12 @@ class UncompressedCache;
|
||||
class MarkCache;
|
||||
struct PrewhereExprInfo;
|
||||
|
||||
struct ChunkAndProgress
|
||||
{
|
||||
Chunk chunk;
|
||||
size_t num_read_rows = 0;
|
||||
size_t num_read_bytes = 0;
|
||||
};
|
||||
|
||||
struct ParallelReadingExtension
|
||||
{
|
||||
@ -29,11 +33,11 @@ struct ParallelReadingExtension
|
||||
Names colums_to_read;
|
||||
};
|
||||
|
||||
/// Base class for MergeTreeThreadSelectProcessor and MergeTreeSelectProcessor
|
||||
class MergeTreeBaseSelectProcessor : public ISource
|
||||
/// Base class for MergeTreeThreadSelectAlgorithm and MergeTreeSelectAlgorithm
|
||||
class IMergeTreeSelectAlgorithm
|
||||
{
|
||||
public:
|
||||
MergeTreeBaseSelectProcessor(
|
||||
IMergeTreeSelectAlgorithm(
|
||||
Block header,
|
||||
const MergeTreeData & storage_,
|
||||
const StorageSnapshotPtr & storage_snapshot_,
|
||||
@ -47,7 +51,7 @@ public:
|
||||
const Names & virt_column_names_ = {},
|
||||
std::optional<ParallelReadingExtension> extension_ = {});
|
||||
|
||||
~MergeTreeBaseSelectProcessor() override;
|
||||
virtual ~IMergeTreeSelectAlgorithm();
|
||||
|
||||
static Block transformHeader(
|
||||
Block block, const PrewhereInfoPtr & prewhere_info, const DataTypePtr & partition_value_type, const Names & virtual_columns);
|
||||
@ -57,16 +61,26 @@ public:
|
||||
const MergeTreeReadTaskColumns & task_columns,
|
||||
const Block & sample_block);
|
||||
|
||||
Block getHeader() const { return result_header; }
|
||||
|
||||
ChunkAndProgress read();
|
||||
|
||||
void cancel() { is_cancelled = true; }
|
||||
|
||||
const MergeTreeReaderSettings & getSettings() const { return reader_settings; }
|
||||
|
||||
virtual std::string getName() const = 0;
|
||||
|
||||
protected:
|
||||
/// This struct allow to return block with no columns but with non-zero number of rows similar to Chunk
|
||||
struct BlockAndRowCount
|
||||
struct BlockAndProgress
|
||||
{
|
||||
Block block;
|
||||
size_t row_count = 0;
|
||||
size_t num_read_rows = 0;
|
||||
size_t num_read_bytes = 0;
|
||||
};
|
||||
|
||||
Chunk generate() final;
|
||||
|
||||
/// Creates new this->task and return a flag whether it was successful or not
|
||||
virtual bool getNewTaskImpl() = 0;
|
||||
/// Creates new readers for a task it is needed. These methods are separate, because
|
||||
@ -81,9 +95,9 @@ protected:
|
||||
/// Closes readers and unlock part locks
|
||||
virtual void finish() = 0;
|
||||
|
||||
virtual BlockAndRowCount readFromPart();
|
||||
virtual BlockAndProgress readFromPart();
|
||||
|
||||
BlockAndRowCount readFromPartImpl();
|
||||
BlockAndProgress readFromPartImpl();
|
||||
|
||||
/// Used for filling header with no rows as well as block with data
|
||||
static void
|
||||
@ -137,7 +151,9 @@ protected:
|
||||
DataTypePtr partition_value_type;
|
||||
|
||||
/// This header is used for chunks from readFromPart().
|
||||
Block header_without_virtual_columns;
|
||||
Block header_without_const_virtual_columns;
|
||||
/// A result of getHeader(). A chunk which this header is returned from read().
|
||||
Block result_header;
|
||||
|
||||
std::shared_ptr<UncompressedCache> owned_uncompressed_cache;
|
||||
std::shared_ptr<MarkCache> owned_mark_cache;
|
||||
@ -156,6 +172,8 @@ protected:
|
||||
private:
|
||||
Poco::Logger * log = &Poco::Logger::get("MergeTreeBaseSelectProcessor");
|
||||
|
||||
std::atomic<bool> is_cancelled{false};
|
||||
|
||||
enum class Status
|
||||
{
|
||||
Accepted,
|
||||
@ -194,6 +212,9 @@ private:
|
||||
Status performRequestToCoordinator(MarkRanges requested_ranges, bool delayed);
|
||||
|
||||
void splitCurrentTaskRangesAndFillBuffer();
|
||||
static Block applyPrewhereActions(Block block, const PrewhereInfoPtr & prewhere_info);
|
||||
};
|
||||
|
||||
using MergeTreeSelectAlgorithmPtr = std::unique_ptr<IMergeTreeSelectAlgorithm>;
|
||||
|
||||
}
|
||||
|
@ -4715,6 +4715,22 @@ std::set<String> MergeTreeData::getPartitionIdsAffectedByCommands(
|
||||
return affected_partition_ids;
|
||||
}
|
||||
|
||||
std::unordered_set<String> MergeTreeData::getAllPartitionIds() const
|
||||
{
|
||||
auto lock = lockParts();
|
||||
std::unordered_set<String> res;
|
||||
std::string_view prev_id;
|
||||
for (const auto & part : getDataPartsStateRange(DataPartState::Active))
|
||||
{
|
||||
if (prev_id == part->info.partition_id)
|
||||
continue;
|
||||
|
||||
res.insert(part->info.partition_id);
|
||||
prev_id = part->info.partition_id;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
MergeTreeData::DataPartsVector MergeTreeData::getDataPartsVectorForInternalUsage(
|
||||
const DataPartStates & affordable_states, const DataPartsLock & /*lock*/, DataPartStateVector * out_states) const
|
||||
|
@ -801,6 +801,9 @@ public:
|
||||
std::unordered_set<String> getPartitionIDsFromQuery(const ASTs & asts, ContextPtr context) const;
|
||||
std::set<String> getPartitionIdsAffectedByCommands(const MutationCommands & commands, ContextPtr query_context) const;
|
||||
|
||||
/// Returns set of partition_ids of all Active parts
|
||||
std::unordered_set<String> getAllPartitionIds() const;
|
||||
|
||||
/// Extracts MergeTreeData of other *MergeTree* storage
|
||||
/// and checks that their structure suitable for ALTER TABLE ATTACH PARTITION FROM
|
||||
/// Tables structure should be locked.
|
||||
|
@ -27,6 +27,8 @@ struct MergeTreeReaderSettings
|
||||
bool read_in_order = false;
|
||||
/// Deleted mask is applied to all reads except internal select from mutate some part columns.
|
||||
bool apply_deleted_mask = true;
|
||||
/// Put reading task in a common I/O pool, return Async state on prepare()
|
||||
bool use_asynchronous_read_from_pool = false;
|
||||
};
|
||||
|
||||
struct MergeTreeWriterSettings
|
||||
|
@ -8,7 +8,7 @@ namespace ErrorCodes
|
||||
extern const int MEMORY_LIMIT_EXCEEDED;
|
||||
}
|
||||
|
||||
bool MergeTreeInOrderSelectProcessor::getNewTaskImpl()
|
||||
bool MergeTreeInOrderSelectAlgorithm::getNewTaskImpl()
|
||||
try
|
||||
{
|
||||
if (all_mark_ranges.empty())
|
||||
|
@ -8,12 +8,12 @@ namespace DB
|
||||
/// Used to read data from single part with select query in order of primary key.
|
||||
/// Cares about PREWHERE, virtual columns, indexes etc.
|
||||
/// To read data from multiple parts, Storage (MergeTree) creates multiple such objects.
|
||||
class MergeTreeInOrderSelectProcessor final : public MergeTreeSelectProcessor
|
||||
class MergeTreeInOrderSelectAlgorithm final : public MergeTreeSelectAlgorithm
|
||||
{
|
||||
public:
|
||||
template <typename... Args>
|
||||
explicit MergeTreeInOrderSelectProcessor(Args &&... args)
|
||||
: MergeTreeSelectProcessor{std::forward<Args>(args)...}
|
||||
explicit MergeTreeInOrderSelectAlgorithm(Args &&... args)
|
||||
: MergeTreeSelectAlgorithm{std::forward<Args>(args)...}
|
||||
{
|
||||
LOG_TRACE(log, "Reading {} ranges in order from part {}, approx. {} rows starting from {}",
|
||||
all_mark_ranges.size(), data_part->name, total_rows,
|
||||
|
@ -217,7 +217,7 @@ std::vector<size_t> MergeTreeReadPool::fillPerPartInfo(const RangesInDataParts &
|
||||
column_names, virtual_column_names, prewhere_info, /*with_subcolumns=*/ true);
|
||||
|
||||
auto size_predictor = !predict_block_size_bytes ? nullptr
|
||||
: MergeTreeBaseSelectProcessor::getSizePredictor(part.data_part, task_columns, sample_block);
|
||||
: IMergeTreeSelectAlgorithm::getSizePredictor(part.data_part, task_columns, sample_block);
|
||||
|
||||
auto & per_part = per_part_params.emplace_back();
|
||||
|
||||
|
@ -8,7 +8,7 @@ namespace ErrorCodes
|
||||
extern const int MEMORY_LIMIT_EXCEEDED;
|
||||
}
|
||||
|
||||
bool MergeTreeReverseSelectProcessor::getNewTaskImpl()
|
||||
bool MergeTreeReverseSelectAlgorithm::getNewTaskImpl()
|
||||
try
|
||||
{
|
||||
if (chunks.empty() && all_mark_ranges.empty())
|
||||
@ -44,9 +44,9 @@ catch (...)
|
||||
throw;
|
||||
}
|
||||
|
||||
MergeTreeBaseSelectProcessor::BlockAndRowCount MergeTreeReverseSelectProcessor::readFromPart()
|
||||
MergeTreeReverseSelectAlgorithm::BlockAndProgress MergeTreeReverseSelectAlgorithm::readFromPart()
|
||||
{
|
||||
BlockAndRowCount res;
|
||||
BlockAndProgress res;
|
||||
|
||||
if (!chunks.empty())
|
||||
{
|
||||
|
@ -9,12 +9,12 @@ namespace DB
|
||||
/// in reverse order of primary key.
|
||||
/// Cares about PREWHERE, virtual columns, indexes etc.
|
||||
/// To read data from multiple parts, Storage (MergeTree) creates multiple such objects.
|
||||
class MergeTreeReverseSelectProcessor final : public MergeTreeSelectProcessor
|
||||
class MergeTreeReverseSelectAlgorithm final : public MergeTreeSelectAlgorithm
|
||||
{
|
||||
public:
|
||||
template <typename... Args>
|
||||
explicit MergeTreeReverseSelectProcessor(Args &&... args)
|
||||
: MergeTreeSelectProcessor{std::forward<Args>(args)...}
|
||||
explicit MergeTreeReverseSelectAlgorithm(Args &&... args)
|
||||
: MergeTreeSelectAlgorithm{std::forward<Args>(args)...}
|
||||
{
|
||||
LOG_TRACE(log, "Reading {} ranges in reverse order from part {}, approx. {} rows starting from {}",
|
||||
all_mark_ranges.size(), data_part->name, total_rows,
|
||||
@ -27,9 +27,9 @@ private:
|
||||
bool getNewTaskImpl() override;
|
||||
void finalizeNewTask() override {}
|
||||
|
||||
BlockAndRowCount readFromPart() override;
|
||||
BlockAndProgress readFromPart() override;
|
||||
|
||||
std::vector<BlockAndRowCount> chunks;
|
||||
std::vector<BlockAndProgress> chunks;
|
||||
Poco::Logger * log = &Poco::Logger::get("MergeTreeReverseSelectProcessor");
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
MergeTreeSelectProcessor::MergeTreeSelectProcessor(
|
||||
MergeTreeSelectAlgorithm::MergeTreeSelectAlgorithm(
|
||||
const MergeTreeData & storage_,
|
||||
const StorageSnapshotPtr & storage_snapshot_,
|
||||
const MergeTreeData::DataPartPtr & owned_data_part_,
|
||||
@ -25,7 +25,7 @@ MergeTreeSelectProcessor::MergeTreeSelectProcessor(
|
||||
size_t part_index_in_query_,
|
||||
bool has_limit_below_one_block_,
|
||||
std::optional<ParallelReadingExtension> extension_)
|
||||
: MergeTreeBaseSelectProcessor{
|
||||
: IMergeTreeSelectAlgorithm{
|
||||
storage_snapshot_->getSampleBlockForColumns(required_columns_),
|
||||
storage_, storage_snapshot_, prewhere_info_, std::move(actions_settings), max_block_size_rows_,
|
||||
preferred_block_size_bytes_, preferred_max_column_in_block_size_bytes_,
|
||||
@ -38,10 +38,10 @@ MergeTreeSelectProcessor::MergeTreeSelectProcessor(
|
||||
has_limit_below_one_block(has_limit_below_one_block_),
|
||||
total_rows(data_part->index_granularity.getRowsCountInRanges(all_mark_ranges))
|
||||
{
|
||||
ordered_names = header_without_virtual_columns.getNames();
|
||||
ordered_names = header_without_const_virtual_columns.getNames();
|
||||
}
|
||||
|
||||
void MergeTreeSelectProcessor::initializeReaders()
|
||||
void MergeTreeSelectAlgorithm::initializeReaders()
|
||||
{
|
||||
task_columns = getReadTaskColumns(
|
||||
LoadedMergeTreeDataPartInfoForReader(data_part), storage_snapshot,
|
||||
@ -61,7 +61,7 @@ void MergeTreeSelectProcessor::initializeReaders()
|
||||
}
|
||||
|
||||
|
||||
void MergeTreeSelectProcessor::finish()
|
||||
void MergeTreeSelectAlgorithm::finish()
|
||||
{
|
||||
/** Close the files (before destroying the object).
|
||||
* When many sources are created, but simultaneously reading only a few of them,
|
||||
@ -72,6 +72,6 @@ void MergeTreeSelectProcessor::finish()
|
||||
data_part.reset();
|
||||
}
|
||||
|
||||
MergeTreeSelectProcessor::~MergeTreeSelectProcessor() = default;
|
||||
MergeTreeSelectAlgorithm::~MergeTreeSelectAlgorithm() = default;
|
||||
|
||||
}
|
||||
|
@ -13,10 +13,10 @@ namespace DB
|
||||
/// Used to read data from single part with select query
|
||||
/// Cares about PREWHERE, virtual columns, indexes etc.
|
||||
/// To read data from multiple parts, Storage (MergeTree) creates multiple such objects.
|
||||
class MergeTreeSelectProcessor : public MergeTreeBaseSelectProcessor
|
||||
class MergeTreeSelectAlgorithm : public IMergeTreeSelectAlgorithm
|
||||
{
|
||||
public:
|
||||
MergeTreeSelectProcessor(
|
||||
MergeTreeSelectAlgorithm(
|
||||
const MergeTreeData & storage,
|
||||
const StorageSnapshotPtr & storage_snapshot_,
|
||||
const MergeTreeData::DataPartPtr & owned_data_part,
|
||||
@ -34,13 +34,13 @@ public:
|
||||
bool has_limit_below_one_block_ = false,
|
||||
std::optional<ParallelReadingExtension> extension_ = {});
|
||||
|
||||
~MergeTreeSelectProcessor() override;
|
||||
~MergeTreeSelectAlgorithm() override;
|
||||
|
||||
protected:
|
||||
/// Defer initialization from constructor, because it may be heavy
|
||||
/// and it's better to do it lazily in `getNewTaskImpl`, which is executing in parallel.
|
||||
void initializeReaders();
|
||||
void finish() override final;
|
||||
void finish() final;
|
||||
|
||||
/// Used by Task
|
||||
Names required_columns;
|
||||
|
224
src/Storages/MergeTree/MergeTreeSource.cpp
Normal file
224
src/Storages/MergeTree/MergeTreeSource.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
#include <Storages/MergeTree/MergeTreeSource.h>
|
||||
#include <Storages/MergeTree/MergeTreeBaseSelectProcessor.h>
|
||||
#include <Interpreters/threadPoolCallbackRunner.h>
|
||||
#include <IO/IOThreadPool.h>
|
||||
#include <Common/EventFD.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
MergeTreeSource::MergeTreeSource(MergeTreeSelectAlgorithmPtr algorithm_)
|
||||
: ISource(algorithm_->getHeader())
|
||||
, algorithm(std::move(algorithm_))
|
||||
{
|
||||
#if defined(OS_LINUX)
|
||||
if (algorithm->getSettings().use_asynchronous_read_from_pool)
|
||||
async_reading_state = std::make_unique<AsyncReadingState>();
|
||||
#endif
|
||||
}
|
||||
|
||||
MergeTreeSource::~MergeTreeSource() = default;
|
||||
|
||||
std::string MergeTreeSource::getName() const
|
||||
{
|
||||
return algorithm->getName();
|
||||
}
|
||||
|
||||
void MergeTreeSource::onCancel()
|
||||
{
|
||||
algorithm->cancel();
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
struct MergeTreeSource::AsyncReadingState
|
||||
{
|
||||
/// NotStarted -> InProgress -> IsFinished -> NotStarted ...
|
||||
enum class Stage
|
||||
{
|
||||
NotStarted,
|
||||
InProgress,
|
||||
IsFinished,
|
||||
};
|
||||
|
||||
struct Control
|
||||
{
|
||||
/// setResult and setException are the only methods
|
||||
/// which can be called from background thread.
|
||||
/// Invariant:
|
||||
/// * background thread changes status InProgress -> IsFinished
|
||||
/// * (status == InProgress) => (MergeTreeBaseSelectProcessor is alive)
|
||||
|
||||
void setResult(ChunkAndProgress chunk_)
|
||||
{
|
||||
chassert(stage == Stage::InProgress);
|
||||
chunk = std::move(chunk_);
|
||||
finish();
|
||||
}
|
||||
|
||||
void setException(std::exception_ptr exception_)
|
||||
{
|
||||
chassert(stage == Stage::InProgress);
|
||||
exception = exception_;
|
||||
finish();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// Executor requires file descriptor (which can be polled) to be returned for async execution.
|
||||
/// We are using EventFD here.
|
||||
/// Thread from background pool writes to fd when task is finished.
|
||||
/// Working thread should read from fd when task is finished or canceled to wait for bg thread.
|
||||
EventFD event;
|
||||
std::atomic<Stage> stage = Stage::NotStarted;
|
||||
|
||||
ChunkAndProgress chunk;
|
||||
std::exception_ptr exception;
|
||||
|
||||
void finish()
|
||||
{
|
||||
stage = Stage::IsFinished;
|
||||
event.write();
|
||||
}
|
||||
|
||||
ChunkAndProgress getResult()
|
||||
{
|
||||
chassert(stage == Stage::IsFinished);
|
||||
event.read();
|
||||
stage = Stage::NotStarted;
|
||||
|
||||
if (exception)
|
||||
std::rethrow_exception(exception);
|
||||
|
||||
return std::move(chunk);
|
||||
}
|
||||
|
||||
friend struct AsyncReadingState;
|
||||
};
|
||||
|
||||
std::shared_ptr<Control> start()
|
||||
{
|
||||
chassert(control->stage == Stage::NotStarted);
|
||||
control->stage = Stage::InProgress;
|
||||
return control;
|
||||
}
|
||||
|
||||
void schedule(ThreadPool::Job job)
|
||||
{
|
||||
callback_runner(std::move(job), 0);
|
||||
}
|
||||
|
||||
ChunkAndProgress getResult()
|
||||
{
|
||||
return control->getResult();
|
||||
}
|
||||
|
||||
Stage getStage() const { return control->stage; }
|
||||
int getFD() const { return control->event.fd; }
|
||||
|
||||
AsyncReadingState()
|
||||
{
|
||||
control = std::make_shared<Control>();
|
||||
callback_runner = threadPoolCallbackRunner<void>(IOThreadPool::get(), "MergeTreeRead");
|
||||
}
|
||||
|
||||
~AsyncReadingState()
|
||||
{
|
||||
/// Here we wait for async task if needed.
|
||||
/// ~AsyncReadingState and Control::finish can be run concurrently.
|
||||
/// It's important to store std::shared_ptr<Control> into bg pool task.
|
||||
/// Otherwise following is possible:
|
||||
///
|
||||
/// (executing thread) (bg pool thread)
|
||||
/// Control::finish()
|
||||
/// stage = Stage::IsFinished;
|
||||
/// ~MergeTreeBaseSelectProcessor()
|
||||
/// ~AsyncReadingState()
|
||||
/// control->stage != Stage::InProgress
|
||||
/// ~EventFD()
|
||||
/// event.write()
|
||||
if (control->stage == Stage::InProgress)
|
||||
control->event.read();
|
||||
}
|
||||
|
||||
private:
|
||||
ThreadPoolCallbackRunner<void> callback_runner;
|
||||
std::shared_ptr<Control> control;
|
||||
};
|
||||
#endif
|
||||
|
||||
ISource::Status MergeTreeSource::prepare()
|
||||
{
|
||||
#if defined(OS_LINUX)
|
||||
if (!async_reading_state)
|
||||
return ISource::prepare();
|
||||
|
||||
/// Check if query was cancelled before returning Async status. Otherwise it may lead to infinite loop.
|
||||
if (isCancelled())
|
||||
{
|
||||
getPort().finish();
|
||||
return ISource::Status::Finished;
|
||||
}
|
||||
|
||||
if (async_reading_state && async_reading_state->getStage() == AsyncReadingState::Stage::InProgress)
|
||||
return ISource::Status::Async;
|
||||
#endif
|
||||
|
||||
return ISource::prepare();
|
||||
}
|
||||
|
||||
|
||||
std::optional<Chunk> MergeTreeSource::reportProgress(ChunkAndProgress chunk)
|
||||
{
|
||||
if (chunk.num_read_rows || chunk.num_read_bytes)
|
||||
progress(chunk.num_read_rows, chunk.num_read_bytes);
|
||||
|
||||
if (chunk.chunk.hasRows())
|
||||
return std::move(chunk.chunk);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
std::optional<Chunk> MergeTreeSource::tryGenerate()
|
||||
{
|
||||
#if defined(OS_LINUX)
|
||||
if (async_reading_state)
|
||||
{
|
||||
if (async_reading_state->getStage() == AsyncReadingState::Stage::IsFinished)
|
||||
return reportProgress(async_reading_state->getResult());
|
||||
|
||||
chassert(async_reading_state->getStage() == AsyncReadingState::Stage::NotStarted);
|
||||
|
||||
/// It is important to store control into job.
|
||||
/// Otherwise, race between job and ~MergeTreeBaseSelectProcessor is possible.
|
||||
auto job = [this, control = async_reading_state->start()]() mutable
|
||||
{
|
||||
auto holder = std::move(control);
|
||||
|
||||
try
|
||||
{
|
||||
holder->setResult(algorithm->read());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
holder->setException(std::current_exception());
|
||||
}
|
||||
};
|
||||
|
||||
async_reading_state->schedule(std::move(job));
|
||||
|
||||
return Chunk();
|
||||
}
|
||||
#endif
|
||||
|
||||
return reportProgress(algorithm->read());
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
int MergeTreeSource::schedule()
|
||||
{
|
||||
return async_reading_state->getFD();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
42
src/Storages/MergeTree/MergeTreeSource.h
Normal file
42
src/Storages/MergeTree/MergeTreeSource.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <Processors/ISource.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
class IMergeTreeSelectAlgorithm;
|
||||
using MergeTreeSelectAlgorithmPtr = std::unique_ptr<IMergeTreeSelectAlgorithm>;
|
||||
|
||||
struct ChunkAndProgress;
|
||||
|
||||
class MergeTreeSource final : public ISource
|
||||
{
|
||||
public:
|
||||
explicit MergeTreeSource(MergeTreeSelectAlgorithmPtr algorithm_);
|
||||
~MergeTreeSource() override;
|
||||
|
||||
std::string getName() const override;
|
||||
|
||||
Status prepare() override;
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
int schedule() override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::optional<Chunk> tryGenerate() override;
|
||||
|
||||
void onCancel() override;
|
||||
|
||||
private:
|
||||
MergeTreeSelectAlgorithmPtr algorithm;
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
struct AsyncReadingState;
|
||||
std::unique_ptr<AsyncReadingState> async_reading_state;
|
||||
#endif
|
||||
|
||||
std::optional<Chunk> reportProgress(ChunkAndProgress chunk);
|
||||
};
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ namespace ErrorCodes
|
||||
extern const int LOGICAL_ERROR;
|
||||
}
|
||||
|
||||
MergeTreeThreadSelectProcessor::MergeTreeThreadSelectProcessor(
|
||||
MergeTreeThreadSelectAlgorithm::MergeTreeThreadSelectAlgorithm(
|
||||
size_t thread_,
|
||||
const MergeTreeReadPoolPtr & pool_,
|
||||
size_t min_marks_to_read_,
|
||||
@ -28,7 +28,7 @@ MergeTreeThreadSelectProcessor::MergeTreeThreadSelectProcessor(
|
||||
const Names & virt_column_names_,
|
||||
std::optional<ParallelReadingExtension> extension_)
|
||||
:
|
||||
MergeTreeBaseSelectProcessor{
|
||||
IMergeTreeSelectAlgorithm{
|
||||
pool_->getHeader(), storage_, storage_snapshot_, prewhere_info_, std::move(actions_settings), max_block_size_rows_,
|
||||
preferred_block_size_bytes_, preferred_max_column_in_block_size_bytes_,
|
||||
reader_settings_, use_uncompressed_cache_, virt_column_names_, extension_},
|
||||
@ -86,18 +86,18 @@ MergeTreeThreadSelectProcessor::MergeTreeThreadSelectProcessor(
|
||||
}
|
||||
|
||||
|
||||
ordered_names = getPort().getHeader().getNames();
|
||||
ordered_names = getHeader().getNames();
|
||||
}
|
||||
|
||||
/// Requests read task from MergeTreeReadPool and signals whether it got one
|
||||
bool MergeTreeThreadSelectProcessor::getNewTaskImpl()
|
||||
bool MergeTreeThreadSelectAlgorithm::getNewTaskImpl()
|
||||
{
|
||||
task = pool->getTask(min_marks_to_read, thread, ordered_names);
|
||||
return static_cast<bool>(task);
|
||||
}
|
||||
|
||||
|
||||
void MergeTreeThreadSelectProcessor::finalizeNewTask()
|
||||
void MergeTreeThreadSelectAlgorithm::finalizeNewTask()
|
||||
{
|
||||
const std::string part_name = task->data_part->isProjectionPart() ? task->data_part->getParentPart()->name : task->data_part->name;
|
||||
|
||||
@ -129,13 +129,13 @@ void MergeTreeThreadSelectProcessor::finalizeNewTask()
|
||||
}
|
||||
|
||||
|
||||
void MergeTreeThreadSelectProcessor::finish()
|
||||
void MergeTreeThreadSelectAlgorithm::finish()
|
||||
{
|
||||
reader.reset();
|
||||
pre_reader_for_step.clear();
|
||||
}
|
||||
|
||||
|
||||
MergeTreeThreadSelectProcessor::~MergeTreeThreadSelectProcessor() = default;
|
||||
MergeTreeThreadSelectAlgorithm::~MergeTreeThreadSelectAlgorithm() = default;
|
||||
|
||||
}
|
||||
|
@ -11,10 +11,10 @@ class MergeTreeReadPool;
|
||||
/** Used in conjunction with MergeTreeReadPool, asking it for more work to do and performing whatever reads it is asked
|
||||
* to perform.
|
||||
*/
|
||||
class MergeTreeThreadSelectProcessor final : public MergeTreeBaseSelectProcessor
|
||||
class MergeTreeThreadSelectAlgorithm final : public IMergeTreeSelectAlgorithm
|
||||
{
|
||||
public:
|
||||
MergeTreeThreadSelectProcessor(
|
||||
MergeTreeThreadSelectAlgorithm(
|
||||
size_t thread_,
|
||||
const std::shared_ptr<MergeTreeReadPool> & pool_,
|
||||
size_t min_marks_to_read_,
|
||||
@ -32,7 +32,7 @@ public:
|
||||
|
||||
String getName() const override { return "MergeTreeThread"; }
|
||||
|
||||
~MergeTreeThreadSelectProcessor() override;
|
||||
~MergeTreeThreadSelectAlgorithm() override;
|
||||
|
||||
protected:
|
||||
/// Requests read task from MergeTreeReadPool and signals whether it got one
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
StorageReplicatedMergeTree & storage_,
|
||||
Callback && task_result_callback_)
|
||||
: ReplicatedMergeMutateTaskBase(
|
||||
&Poco::Logger::get(storage_.getStorageID().getShortName() + "::" + selected_entry_->log_entry->new_part_name + "(MutateFromLogEntryTask)"),
|
||||
&Poco::Logger::get(storage_.getStorageID().getShortName() + "::" + selected_entry_->log_entry->new_part_name + " (MutateFromLogEntryTask)"),
|
||||
storage_,
|
||||
selected_entry_,
|
||||
task_result_callback_)
|
||||
|
@ -1772,9 +1772,9 @@ size_t ReplicatedMergeTreeQueue::countFinishedMutations() const
|
||||
}
|
||||
|
||||
|
||||
ReplicatedMergeTreeMergePredicate ReplicatedMergeTreeQueue::getMergePredicate(zkutil::ZooKeeperPtr & zookeeper)
|
||||
ReplicatedMergeTreeMergePredicate ReplicatedMergeTreeQueue::getMergePredicate(zkutil::ZooKeeperPtr & zookeeper, PartitionIdsHint && partition_ids_hint)
|
||||
{
|
||||
return ReplicatedMergeTreeMergePredicate(*this, zookeeper);
|
||||
return ReplicatedMergeTreeMergePredicate(*this, zookeeper, std::move(partition_ids_hint));
|
||||
}
|
||||
|
||||
|
||||
@ -1882,8 +1882,13 @@ bool ReplicatedMergeTreeQueue::tryFinalizeMutations(zkutil::ZooKeeperPtr zookeep
|
||||
|
||||
/// We need to check committing block numbers and new parts which could be committed.
|
||||
/// Actually we don't need most of predicate logic here but it all the code related to committing blocks
|
||||
/// and updatading queue state is implemented there.
|
||||
auto merge_pred = getMergePredicate(zookeeper);
|
||||
/// and updatating queue state is implemented there.
|
||||
PartitionIdsHint partition_ids_hint;
|
||||
for (const auto & candidate : candidates)
|
||||
for (const auto & partitions : candidate->block_numbers)
|
||||
partition_ids_hint.insert(partitions.first);
|
||||
|
||||
auto merge_pred = getMergePredicate(zookeeper, std::move(partition_ids_hint));
|
||||
|
||||
std::vector<const ReplicatedMergeTreeMutationEntry *> finished;
|
||||
for (const auto & candidate : candidates)
|
||||
@ -2081,8 +2086,9 @@ ReplicatedMergeTreeQueue::QueueLocks ReplicatedMergeTreeQueue::lockQueue()
|
||||
}
|
||||
|
||||
ReplicatedMergeTreeMergePredicate::ReplicatedMergeTreeMergePredicate(
|
||||
ReplicatedMergeTreeQueue & queue_, zkutil::ZooKeeperPtr & zookeeper)
|
||||
ReplicatedMergeTreeQueue & queue_, zkutil::ZooKeeperPtr & zookeeper, PartitionIdsHint && partition_ids_hint_)
|
||||
: queue(queue_)
|
||||
, partition_ids_hint(std::move(partition_ids_hint_))
|
||||
, prev_virtual_parts(queue.format_version)
|
||||
{
|
||||
{
|
||||
@ -2094,7 +2100,15 @@ ReplicatedMergeTreeMergePredicate::ReplicatedMergeTreeMergePredicate(
|
||||
auto quorum_status_future = zookeeper->asyncTryGet(fs::path(queue.zookeeper_path) / "quorum" / "status");
|
||||
|
||||
/// Load current inserts
|
||||
Strings partitions = zookeeper->getChildren(fs::path(queue.zookeeper_path) / "block_numbers");
|
||||
/// Hint avoids listing partitions that we don't really need.
|
||||
/// Dropped (or cleaned up by TTL) partitions are never removed from ZK,
|
||||
/// so without hint it can do a few thousands requests (if not using MultiRead).
|
||||
Strings partitions;
|
||||
if (partition_ids_hint.empty())
|
||||
partitions = zookeeper->getChildren(fs::path(queue.zookeeper_path) / "block_numbers");
|
||||
else
|
||||
std::copy(partition_ids_hint.begin(), partition_ids_hint.end(), std::back_inserter(partitions));
|
||||
|
||||
std::vector<std::string> paths;
|
||||
paths.reserve(partitions.size());
|
||||
for (const String & partition : partitions)
|
||||
@ -2226,6 +2240,13 @@ bool ReplicatedMergeTreeMergePredicate::canMergeTwoParts(
|
||||
|
||||
if (left_max_block + 1 < right_min_block)
|
||||
{
|
||||
if (!partition_ids_hint.empty() && !partition_ids_hint.contains(left->info.partition_id))
|
||||
{
|
||||
if (out_reason)
|
||||
*out_reason = fmt::format("Uncommitted block were not loaded for unexpected partition {}", left->info.partition_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto committing_blocks_in_partition = committing_blocks.find(left->info.partition_id);
|
||||
if (committing_blocks_in_partition != committing_blocks.end())
|
||||
{
|
||||
@ -2419,6 +2440,9 @@ bool ReplicatedMergeTreeMergePredicate::isMutationFinished(const std::string & z
|
||||
const String & partition_id = kv.first;
|
||||
Int64 block_num = kv.second;
|
||||
|
||||
if (!partition_ids_hint.empty() && !partition_ids_hint.contains(partition_id))
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Partition id {} was not provided as hint, it's a bug", partition_id);
|
||||
|
||||
auto partition_it = committing_blocks.find(partition_id);
|
||||
if (partition_it != committing_blocks.end())
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ class MergeTreeDataMergerMutator;
|
||||
class ReplicatedMergeTreeMergePredicate;
|
||||
class ReplicatedMergeTreeMergeStrategyPicker;
|
||||
|
||||
using PartitionIdsHint = std::unordered_set<String>;
|
||||
|
||||
class ReplicatedMergeTreeQueue
|
||||
{
|
||||
@ -382,7 +383,7 @@ public:
|
||||
size_t countFinishedMutations() const;
|
||||
|
||||
/// Returns functor which used by MergeTreeMergerMutator to select parts for merge
|
||||
ReplicatedMergeTreeMergePredicate getMergePredicate(zkutil::ZooKeeperPtr & zookeeper);
|
||||
ReplicatedMergeTreeMergePredicate getMergePredicate(zkutil::ZooKeeperPtr & zookeeper, PartitionIdsHint && partition_ids_hint);
|
||||
|
||||
/// Return the version (block number) of the last mutation that we don't need to apply to the part
|
||||
/// with getDataVersion() == data_version. (Either this mutation was already applied or the part
|
||||
@ -486,7 +487,7 @@ public:
|
||||
class ReplicatedMergeTreeMergePredicate
|
||||
{
|
||||
public:
|
||||
ReplicatedMergeTreeMergePredicate(ReplicatedMergeTreeQueue & queue_, zkutil::ZooKeeperPtr & zookeeper);
|
||||
ReplicatedMergeTreeMergePredicate(ReplicatedMergeTreeQueue & queue_, zkutil::ZooKeeperPtr & zookeeper, PartitionIdsHint && partition_ids_hint_);
|
||||
|
||||
/// Depending on the existence of left part checks a merge predicate for two parts or for single part.
|
||||
bool operator()(const MergeTreeData::DataPartPtr & left,
|
||||
@ -531,6 +532,8 @@ public:
|
||||
private:
|
||||
const ReplicatedMergeTreeQueue & queue;
|
||||
|
||||
PartitionIdsHint partition_ids_hint;
|
||||
|
||||
/// A snapshot of active parts that would appear if the replica executes all log entries in its queue.
|
||||
ActiveDataPartSet prev_virtual_parts;
|
||||
/// partition ID -> block numbers of the inserts and mutations that are about to commit
|
||||
|
@ -3128,7 +3128,7 @@ void StorageReplicatedMergeTree::mergeSelectingTask()
|
||||
|
||||
auto zookeeper = getZooKeeperAndAssertNotReadonly();
|
||||
|
||||
ReplicatedMergeTreeMergePredicate merge_pred = queue.getMergePredicate(zookeeper);
|
||||
ReplicatedMergeTreeMergePredicate merge_pred = queue.getMergePredicate(zookeeper, getAllPartitionIds());
|
||||
|
||||
/// If many merges is already queued, then will queue only small enough merges.
|
||||
/// Otherwise merge queue could be filled with only large merges,
|
||||
@ -4552,10 +4552,11 @@ bool StorageReplicatedMergeTree::optimize(
|
||||
if (!is_leader)
|
||||
throw Exception("OPTIMIZE cannot be done on this replica because it is not a leader", ErrorCodes::NOT_A_LEADER);
|
||||
|
||||
auto handle_noop = [&] (const String & message)
|
||||
auto handle_noop = [&] (const char * fmt_string, auto ...args)
|
||||
{
|
||||
LOG_DEBUG(log, fmt::runtime(fmt_string), args...);
|
||||
if (query_context->getSettingsRef().optimize_throw_if_noop)
|
||||
throw Exception(message, ErrorCodes::CANNOT_ASSIGN_OPTIMIZE);
|
||||
throw Exception(ErrorCodes::CANNOT_ASSIGN_OPTIMIZE, fmt::runtime(fmt_string), args...);
|
||||
return false;
|
||||
};
|
||||
|
||||
@ -4573,7 +4574,19 @@ bool StorageReplicatedMergeTree::optimize(
|
||||
/// We must select parts for merge under merge_selecting_mutex because other threads
|
||||
/// (merge_selecting_thread or OPTIMIZE queries) could assign new merges.
|
||||
std::lock_guard merge_selecting_lock(merge_selecting_mutex);
|
||||
ReplicatedMergeTreeMergePredicate can_merge = queue.getMergePredicate(zookeeper);
|
||||
PartitionIdsHint partition_ids_hint;
|
||||
if (partition_id.empty())
|
||||
{
|
||||
partition_ids_hint = getAllPartitionIds();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto parts_lock = lockParts();
|
||||
if (!getAnyPartInPartition(partition_id, parts_lock))
|
||||
handle_noop("Cannot select parts for optimization: there are no parts in partition {}", partition_id);
|
||||
partition_ids_hint.insert(partition_id);
|
||||
}
|
||||
ReplicatedMergeTreeMergePredicate can_merge = queue.getMergePredicate(zookeeper, std::move(partition_ids_hint));
|
||||
|
||||
auto future_merged_part = std::make_shared<FutureMergedMutatedPart>();
|
||||
if (storage_settings.get()->assign_part_uuids)
|
||||
@ -4606,9 +4619,7 @@ bool StorageReplicatedMergeTree::optimize(
|
||||
assert(disable_reason != unknown_disable_reason);
|
||||
if (!partition_id.empty())
|
||||
disable_reason += fmt::format(" (in partition {})", partition_id);
|
||||
String message = fmt::format(message_fmt, disable_reason);
|
||||
LOG_INFO(log, fmt::runtime(message));
|
||||
return handle_noop(message);
|
||||
return handle_noop(message_fmt, disable_reason);
|
||||
}
|
||||
|
||||
ReplicatedMergeTreeLogEntryData merge_entry;
|
||||
@ -4620,9 +4631,8 @@ bool StorageReplicatedMergeTree::optimize(
|
||||
|
||||
if (create_result == CreateMergeEntryResult::MissingPart)
|
||||
{
|
||||
String message = "Can't create merge queue node in ZooKeeper, because some parts are missing";
|
||||
LOG_TRACE(log, fmt::runtime(message));
|
||||
return handle_noop(message);
|
||||
static constexpr const char * message_fmt = "Can't create merge queue node in ZooKeeper, because some parts are missing";
|
||||
return handle_noop(message_fmt);
|
||||
}
|
||||
|
||||
if (create_result == CreateMergeEntryResult::LogUpdated)
|
||||
@ -4633,9 +4643,8 @@ bool StorageReplicatedMergeTree::optimize(
|
||||
}
|
||||
|
||||
assert(try_no == max_retries);
|
||||
String message = fmt::format("Can't create merge queue node in ZooKeeper, because log was updated in every of {} tries", try_no);
|
||||
LOG_TRACE(log, fmt::runtime(message));
|
||||
return handle_noop(message);
|
||||
static constexpr const char * message_fmt = "Can't create merge queue node in ZooKeeper, because log was updated in every of {} tries";
|
||||
return handle_noop(message_fmt, try_no);
|
||||
};
|
||||
|
||||
bool assigned = false;
|
||||
@ -7057,7 +7066,7 @@ void StorageReplicatedMergeTree::movePartitionToShard(
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Part {} does not have an uuid assigned and it can't be moved between shards", part_name);
|
||||
|
||||
|
||||
ReplicatedMergeTreeMergePredicate merge_pred = queue.getMergePredicate(zookeeper);
|
||||
ReplicatedMergeTreeMergePredicate merge_pred = queue.getMergePredicate(zookeeper, PartitionIdsHint{part_info.partition_id});
|
||||
|
||||
/// The following block is pretty much copy & paste from StorageReplicatedMergeTree::dropPart to avoid conflicts while this is WIP.
|
||||
/// Extract it to a common method and re-use it before merging.
|
||||
@ -7265,7 +7274,7 @@ bool StorageReplicatedMergeTree::dropPartImpl(
|
||||
|
||||
while (true)
|
||||
{
|
||||
ReplicatedMergeTreeMergePredicate merge_pred = queue.getMergePredicate(zookeeper);
|
||||
ReplicatedMergeTreeMergePredicate merge_pred = queue.getMergePredicate(zookeeper, PartitionIdsHint{part_info.partition_id});
|
||||
|
||||
auto part = getPartIfExists(part_info, {MergeTreeDataPartState::Active});
|
||||
|
||||
@ -8334,7 +8343,7 @@ bool StorageReplicatedMergeTree::createEmptyPartInsteadOfLost(zkutil::ZooKeeperP
|
||||
/// We can enqueue part for check from DataPartExchange or SelectProcessor
|
||||
/// and it's hard to synchronize it with ReplicatedMergeTreeQueue and PartCheckThread...
|
||||
/// But at least we can ignore parts that are definitely not needed according to virtual parts and drop ranges.
|
||||
auto pred = queue.getMergePredicate(zookeeper);
|
||||
auto pred = queue.getMergePredicate(zookeeper, PartitionIdsHint{new_part_info.partition_id});
|
||||
String covering_virtual = pred.getCoveringVirtualPart(lost_part_name);
|
||||
if (covering_virtual.empty())
|
||||
{
|
||||
|
@ -832,6 +832,11 @@ std::shared_ptr<StorageS3Source::IteratorWrapper> StorageS3::createFileIterator(
|
||||
}
|
||||
}
|
||||
|
||||
bool StorageS3::supportsSubcolumns() const
|
||||
{
|
||||
return FormatFactory::instance().checkIfFormatSupportsSubcolumns(format_name);
|
||||
}
|
||||
|
||||
bool StorageS3::supportsSubsetOfColumns() const
|
||||
{
|
||||
return FormatFactory::instance().checkIfFormatSupportsSubsetOfColumns(format_name);
|
||||
|
@ -254,6 +254,8 @@ private:
|
||||
ContextPtr ctx,
|
||||
std::unordered_map<String, S3::ObjectInfo> * object_infos = nullptr);
|
||||
|
||||
bool supportsSubcolumns() const override;
|
||||
|
||||
bool supportsSubsetOfColumns() const override;
|
||||
|
||||
static std::optional<ColumnsDescription> tryGetColumnsFromCache(
|
||||
|
@ -13,8 +13,10 @@ import jwt
|
||||
import requests # type: ignore
|
||||
import boto3 # type: ignore
|
||||
|
||||
PULL_REQUEST_CI = "PullRequestCI"
|
||||
|
||||
NEED_RERUN_OR_CANCELL_WORKFLOWS = {
|
||||
"PullRequestCI",
|
||||
PULL_REQUEST_CI,
|
||||
"DocsCheck",
|
||||
"DocsReleaseChecks",
|
||||
"BackportPR",
|
||||
@ -114,7 +116,16 @@ def _exec_get_with_retry(url: str, token: str) -> dict:
|
||||
|
||||
WorkflowDescription = namedtuple(
|
||||
"WorkflowDescription",
|
||||
["url", "run_id", "head_sha", "status", "rerun_url", "cancel_url", "conclusion"],
|
||||
[
|
||||
"url",
|
||||
"run_id",
|
||||
"name",
|
||||
"head_sha",
|
||||
"status",
|
||||
"rerun_url",
|
||||
"cancel_url",
|
||||
"conclusion",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@ -169,6 +180,7 @@ def get_workflows_description_for_pull_request(
|
||||
WorkflowDescription(
|
||||
url=workflow["url"],
|
||||
run_id=workflow["id"],
|
||||
name=workflow["name"],
|
||||
head_sha=workflow["head_sha"],
|
||||
status=workflow["status"],
|
||||
rerun_url=workflow["rerun_url"],
|
||||
@ -229,6 +241,7 @@ def get_workflow_description_fallback(
|
||||
WorkflowDescription(
|
||||
url=wf["url"],
|
||||
run_id=wf["id"],
|
||||
name=workflow["name"],
|
||||
head_sha=wf["head_sha"],
|
||||
status=wf["status"],
|
||||
rerun_url=wf["rerun_url"],
|
||||
@ -246,6 +259,7 @@ def get_workflow_description(workflow_url, token) -> WorkflowDescription:
|
||||
return WorkflowDescription(
|
||||
url=workflow["url"],
|
||||
run_id=workflow["id"],
|
||||
name=workflow["name"],
|
||||
head_sha=workflow["head_sha"],
|
||||
status=workflow["status"],
|
||||
rerun_url=workflow["rerun_url"],
|
||||
@ -268,8 +282,8 @@ def _exec_post_with_retry(url, token):
|
||||
raise Exception("Cannot execute POST request with retry")
|
||||
|
||||
|
||||
def exec_workflow_url(urls_to_cancel, token):
|
||||
for url in urls_to_cancel:
|
||||
def exec_workflow_url(urls_to_post, token):
|
||||
for url in urls_to_post:
|
||||
print("Post for workflow workflow using url", url)
|
||||
_exec_post_with_retry(url, token)
|
||||
print("Workflow post finished")
|
||||
@ -289,7 +303,7 @@ def main(event):
|
||||
pull_request = event_data["pull_request"]
|
||||
labels = {label["name"] for label in pull_request["labels"]}
|
||||
print("PR has labels", labels)
|
||||
if action == "closed" or "do not test" in labels:
|
||||
if action == "closed" or (action == "labeled" and "do not test" in labels):
|
||||
print("PR merged/closed or manually labeled 'do not test' will kill workflows")
|
||||
workflow_descriptions = get_workflows_description_for_pull_request(
|
||||
pull_request, token
|
||||
@ -307,6 +321,29 @@ def main(event):
|
||||
urls_to_cancel.append(workflow_description.cancel_url)
|
||||
print(f"Found {len(urls_to_cancel)} workflows to cancel")
|
||||
exec_workflow_url(urls_to_cancel, token)
|
||||
return
|
||||
elif action == "edited":
|
||||
print("PR is edited, check if it needs to rerun")
|
||||
workflow_descriptions = get_workflows_description_for_pull_request(
|
||||
pull_request, token
|
||||
)
|
||||
workflow_descriptions = (
|
||||
workflow_descriptions
|
||||
or get_workflow_description_fallback(pull_request, token)
|
||||
)
|
||||
workflow_descriptions.sort(key=lambda x: x.run_id)
|
||||
most_recent_workflow = workflow_descriptions[-1]
|
||||
if (
|
||||
most_recent_workflow.status == "completed"
|
||||
and most_recent_workflow.name == PULL_REQUEST_CI
|
||||
):
|
||||
print(
|
||||
"The PR's body is changed and workflow is finished. "
|
||||
"Rerun to check the description"
|
||||
)
|
||||
exec_workflow_url([most_recent_workflow.rerun_url], token)
|
||||
print("Rerun finished, exiting")
|
||||
return
|
||||
elif action == "synchronize":
|
||||
print("PR is synchronized, going to stop old actions")
|
||||
workflow_descriptions = get_workflows_description_for_pull_request(
|
||||
@ -339,8 +376,8 @@ def main(event):
|
||||
print("Not found any workflows")
|
||||
return
|
||||
|
||||
sorted_workflows = list(sorted(workflow_descriptions, key=lambda x: x.run_id))
|
||||
most_recent_workflow = sorted_workflows[-1]
|
||||
workflow_descriptions.sort(key=lambda x: x.run_id)
|
||||
most_recent_workflow = workflow_descriptions[-1]
|
||||
print("Latest workflow", most_recent_workflow)
|
||||
if (
|
||||
most_recent_workflow.status != "completed"
|
||||
|
@ -1,12 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import requests
|
||||
import argparse
|
||||
import jwt
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
|
||||
import boto3 # type: ignore
|
||||
import jwt
|
||||
import requests # type: ignore
|
||||
|
||||
|
||||
def get_installation_id(jwt_token):
|
||||
headers = {
|
||||
@ -51,8 +53,6 @@ def get_runner_registration_token(access_token):
|
||||
|
||||
|
||||
def get_key_and_app_from_aws():
|
||||
import boto3
|
||||
|
||||
secret_name = "clickhouse_github_secret_key"
|
||||
session = boto3.session.Session()
|
||||
client = session.client(
|
@ -0,0 +1 @@
|
||||
../team_keys_lambda/build_and_deploy_archive.sh
|
@ -94,51 +94,6 @@ def list_runners(access_token):
|
||||
return result
|
||||
|
||||
|
||||
def push_metrics_to_cloudwatch(listed_runners, namespace):
|
||||
import boto3
|
||||
|
||||
client = boto3.client("cloudwatch")
|
||||
metrics_data = []
|
||||
busy_runners = sum(1 for runner in listed_runners if runner.busy)
|
||||
metrics_data.append(
|
||||
{
|
||||
"MetricName": "BusyRunners",
|
||||
"Value": busy_runners,
|
||||
"Unit": "Count",
|
||||
}
|
||||
)
|
||||
total_active_runners = sum(1 for runner in listed_runners if not runner.offline)
|
||||
metrics_data.append(
|
||||
{
|
||||
"MetricName": "ActiveRunners",
|
||||
"Value": total_active_runners,
|
||||
"Unit": "Count",
|
||||
}
|
||||
)
|
||||
total_runners = len(listed_runners)
|
||||
metrics_data.append(
|
||||
{
|
||||
"MetricName": "TotalRunners",
|
||||
"Value": total_runners,
|
||||
"Unit": "Count",
|
||||
}
|
||||
)
|
||||
if total_active_runners == 0:
|
||||
busy_ratio = 100
|
||||
else:
|
||||
busy_ratio = busy_runners / total_active_runners * 100
|
||||
|
||||
metrics_data.append(
|
||||
{
|
||||
"MetricName": "BusyRunnersRatio",
|
||||
"Value": busy_ratio,
|
||||
"Unit": "Percent",
|
||||
}
|
||||
)
|
||||
|
||||
client.put_metric_data(Namespace="RunnersMetrics", MetricData=metrics_data)
|
||||
|
||||
|
||||
def how_many_instances_to_kill(event_data):
|
||||
data_array = event_data["CapacityToTerminate"]
|
||||
to_kill_by_zone = {}
|
||||
@ -254,10 +209,6 @@ def main(github_secret_key, github_app_id, event):
|
||||
else:
|
||||
print(f"Cannot delete {runner.name} from github")
|
||||
|
||||
## push metrics
|
||||
# runners = list_runners(access_token)
|
||||
# push_metrics_to_cloudwatch(runners, 'RunnersMetrics')
|
||||
|
||||
response = {"InstanceIDs": instances_to_kill}
|
||||
print(response)
|
||||
return response
|
1
tests/ci/terminate_runner_lambda/build_and_deploy_archive.sh
Symbolic link
1
tests/ci/terminate_runner_lambda/build_and_deploy_archive.sh
Symbolic link
@ -0,0 +1 @@
|
||||
../team_keys_lambda/build_and_deploy_archive.sh
|
@ -1,13 +0,0 @@
|
||||
FROM public.ecr.aws/lambda/python:3.9
|
||||
|
||||
# Install the function's dependencies using file requirements.txt
|
||||
# from your project folder.
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"
|
||||
|
||||
# Copy function code
|
||||
COPY app.py ${LAMBDA_TASK_ROOT}
|
||||
|
||||
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
|
||||
CMD [ "app.handler" ]
|
@ -1,13 +0,0 @@
|
||||
FROM public.ecr.aws/lambda/python:3.9
|
||||
|
||||
# Install the function's dependencies using file requirements.txt
|
||||
# from your project folder.
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"
|
||||
|
||||
# Copy function code
|
||||
COPY app.py ${LAMBDA_TASK_ROOT}
|
||||
|
||||
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
|
||||
CMD [ "app.handler" ]
|
@ -280,6 +280,7 @@ def test_store_cleanup(started_cluster):
|
||||
"Removing unused directory", timeout=90, look_behind_lines=1000
|
||||
)
|
||||
node1.wait_for_log_line("directories from store")
|
||||
node1.wait_for_log_line("Nothing to clean up from store/")
|
||||
|
||||
store = node1.exec_in_container(["ls", f"{path_to_data}/store"])
|
||||
assert "100" in store
|
||||
|
@ -2,14 +2,9 @@
|
||||
import pytest
|
||||
from helpers.cluster import ClickHouseCluster
|
||||
import helpers.keeper_utils as keeper_utils
|
||||
from kazoo.client import KazooClient, KazooState
|
||||
from kazoo.security import ACL, make_digest_acl, make_acl
|
||||
from kazoo.exceptions import (
|
||||
AuthFailedError,
|
||||
InvalidACLError,
|
||||
NoAuthError,
|
||||
KazooException,
|
||||
)
|
||||
from kazoo.client import KazooClient
|
||||
from kazoo.retry import KazooRetry
|
||||
from kazoo.security import make_acl
|
||||
import os
|
||||
import time
|
||||
|
||||
@ -99,7 +94,9 @@ def get_fake_zk(timeout=60.0):
|
||||
|
||||
def get_genuine_zk(timeout=60.0):
|
||||
_genuine_zk_instance = KazooClient(
|
||||
hosts=cluster.get_instance_ip("node") + ":2181", timeout=timeout
|
||||
hosts=cluster.get_instance_ip("node") + ":2181",
|
||||
timeout=timeout,
|
||||
connection_retry=KazooRetry(max_tries=20),
|
||||
)
|
||||
_genuine_zk_instance.start()
|
||||
return _genuine_zk_instance
|
||||
@ -225,6 +222,12 @@ def test_smoke(started_cluster, create_snapshots):
|
||||
|
||||
compare_states(genuine_connection, fake_connection)
|
||||
|
||||
genuine_connection.stop()
|
||||
genuine_connection.close()
|
||||
|
||||
fake_connection.stop()
|
||||
fake_connection.close()
|
||||
|
||||
|
||||
def get_bytes(s):
|
||||
return s.encode()
|
||||
@ -309,6 +312,12 @@ def test_simple_crud_requests(started_cluster, create_snapshots):
|
||||
second_children = list(sorted(fake_connection.get_children("/test_sequential")))
|
||||
assert first_children == second_children, "Childrens are not equal on path " + path
|
||||
|
||||
genuine_connection.stop()
|
||||
genuine_connection.close()
|
||||
|
||||
fake_connection.stop()
|
||||
fake_connection.close()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("create_snapshots"), [True, False])
|
||||
def test_multi_and_failed_requests(started_cluster, create_snapshots):
|
||||
@ -379,6 +388,12 @@ def test_multi_and_failed_requests(started_cluster, create_snapshots):
|
||||
assert eph1 == eph2
|
||||
compare_stats(stat1, stat2, "/test_multitransactions", ignore_pzxid=True)
|
||||
|
||||
genuine_connection.stop()
|
||||
genuine_connection.close()
|
||||
|
||||
fake_connection.stop()
|
||||
fake_connection.close()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("create_snapshots"), [True, False])
|
||||
def test_acls(started_cluster, create_snapshots):
|
||||
@ -446,3 +461,9 @@ def test_acls(started_cluster, create_snapshots):
|
||||
"user2:lo/iTtNMP+gEZlpUNaCqLYO3i5U=",
|
||||
"user3:wr5Y0kEs9nFX3bKrTMKxrlcFeWo=",
|
||||
)
|
||||
|
||||
genuine_connection.stop()
|
||||
genuine_connection.close()
|
||||
|
||||
fake_connection.stop()
|
||||
fake_connection.close()
|
||||
|
@ -11,4 +11,8 @@
|
||||
)
|
||||
SETTINGS max_threads = 2, max_distributed_connections = 2
|
||||
</query>
|
||||
|
||||
<!--<query>select sum(length(URL)) from hits_100m_single settings max_threads=8, max_streams_to_max_threads_ratio=2, allow_asynchronous_read_from_io_pool_for_merge_tree=0</query>-->
|
||||
<query>select sum(length(URL)) from hits_10m_single settings max_threads=2, max_streams_to_max_threads_ratio=16, allow_asynchronous_read_from_io_pool_for_merge_tree=1</query>
|
||||
<query>select sum(length(URL)) from hits_10m_single settings max_threads=2, max_streams_for_merge_tree_reading=32, allow_asynchronous_read_from_io_pool_for_merge_tree=1</query>
|
||||
</test>
|
||||
|
@ -1,5 +1,6 @@
|
||||
DROP TABLE IF EXISTS data_01283;
|
||||
|
||||
set allow_asynchronous_read_from_io_pool_for_merge_tree = 0;
|
||||
set remote_filesystem_read_method = 'read';
|
||||
set local_filesystem_read_method = 'pread';
|
||||
set load_marks_asynchronously = 0;
|
||||
|
@ -3,6 +3,7 @@ drop table if exists table_01323_many_parts;
|
||||
set remote_filesystem_read_method = 'read';
|
||||
set local_filesystem_read_method = 'pread';
|
||||
set load_marks_asynchronously = 0;
|
||||
set allow_asynchronous_read_from_io_pool_for_merge_tree = 0;
|
||||
|
||||
create table table_01323_many_parts (x UInt64) engine = MergeTree order by x partition by x % 100;
|
||||
set max_partitions_per_insert_block = 100;
|
||||
|
@ -1,5 +1,6 @@
|
||||
DROP TABLE IF EXISTS select_final;
|
||||
|
||||
SET allow_asynchronous_read_from_io_pool_for_merge_tree = 0;
|
||||
SET do_not_merge_across_partitions_select_final = 1;
|
||||
SET max_threads = 16;
|
||||
|
||||
|
@ -19,16 +19,16 @@ $CLICKHOUSE_CLIENT -q "create table ${name}_n_x engine=MergeTree order by (n, x)
|
||||
$CLICKHOUSE_CLIENT -q "optimize table ${name}_n final"
|
||||
$CLICKHOUSE_CLIENT -q "optimize table ${name}_n_x final"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "select n, sum(x) OVER (ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n SETTINGS optimize_read_in_order=0, optimize_read_in_window_order=0, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
$CLICKHOUSE_CLIENT --allow_asynchronous_read_from_io_pool_for_merge_tree=0 -q "select n, sum(x) OVER (ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n SETTINGS optimize_read_in_order=0, optimize_read_in_window_order=0, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
$CLICKHOUSE_CLIENT -q "select n, sum(x) OVER (ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n SETTINGS optimize_read_in_order=1, max_memory_usage=$max_memory_usage, max_threads=1 format Null"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "select n, sum(x) OVER (ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=0, optimize_read_in_window_order=0, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
$CLICKHOUSE_CLIENT --allow_asynchronous_read_from_io_pool_for_merge_tree=0 -q "select n, sum(x) OVER (ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=0, optimize_read_in_window_order=0, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
$CLICKHOUSE_CLIENT -q "select n, sum(x) OVER (ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=1, max_memory_usage=$max_memory_usage, max_threads=1 format Null"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "select n, sum(x) OVER (PARTITION BY n ORDER BY x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=0, optimize_read_in_window_order=0, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
$CLICKHOUSE_CLIENT --allow_asynchronous_read_from_io_pool_for_merge_tree=0 -q "select n, sum(x) OVER (PARTITION BY n ORDER BY x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=0, optimize_read_in_window_order=0, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
$CLICKHOUSE_CLIENT -q "select n, sum(x) OVER (PARTITION BY n ORDER BY x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=1, max_memory_usage=$max_memory_usage, max_threads=1 format Null"
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "select n, sum(x) OVER (PARTITION BY n+x%2 ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=1, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
$CLICKHOUSE_CLIENT --allow_asynchronous_read_from_io_pool_for_merge_tree=0 -q "select n, sum(x) OVER (PARTITION BY n+x%2 ORDER BY n, x ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) from ${name}_n_x SETTINGS optimize_read_in_order=1, max_memory_usage=$max_memory_usage, max_threads=1 format Null" 2>&1 | grep -F -q "MEMORY_LIMIT_EXCEEDED" && echo 'OK' || echo 'FAIL'
|
||||
|
||||
$CLICKHOUSE_CLIENT -q "drop table ${name}"
|
||||
$CLICKHOUSE_CLIENT -q "drop table ${name}_n"
|
||||
|
@ -0,0 +1,31 @@
|
||||
-- { echo }
|
||||
drop table if exists test_02245_s3_nested_parquet1;
|
||||
drop table if exists test_02245_s3_nested_parquet2;
|
||||
set input_format_parquet_import_nested = 1;
|
||||
create table test_02245_s3_nested_parquet1(a Int64, b Tuple(a Int64, b String)) engine=S3(s3_conn, filename='test_02245_s3_nested_parquet1_{_partition_id}', format='Parquet') partition by a;
|
||||
insert into test_02245_s3_nested_parquet1 values (1, (2, 'a'));
|
||||
select a, b.a, b.b from s3(s3_conn, filename='test_02245_s3_nested_parquet1_*', format='Parquet'); -- { serverError 47 }
|
||||
create table test_02245_s3_nested_parquet2(a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))) engine=S3(s3_conn, filename='test_02245_s3_nested_parquet2_{_partition_id}', format='Parquet') partition by a;
|
||||
insert into test_02245_s3_nested_parquet2 values (1, (2, (3, 'a')));
|
||||
select a, b.a, b.b.c, b.b.d from s3(s3_conn, filename='test_02245_s3_nested_parquet2_*', format='Parquet', structure='a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))');
|
||||
1 2 3 a
|
||||
drop table if exists test_02245_s3_nested_arrow1;
|
||||
drop table if exists test_02245_s3_nested_arrow2;
|
||||
set input_format_arrow_import_nested=1;
|
||||
create table test_02245_s3_nested_arrow1(a Int64, b Tuple(a Int64, b String)) engine=S3(s3_conn, filename='test_02245_s3_nested_arrow1_{_partition_id}', format='Arrow') partition by a;
|
||||
insert into test_02245_s3_nested_arrow1 values (1, (2, 'a'));
|
||||
select a, b.a, b.b from s3(s3_conn, filename='test_02245_s3_nested_arrow1_*', format='Arrow'); -- { serverError 47 }
|
||||
create table test_02245_s3_nested_arrow2(a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))) engine=S3(s3_conn, filename='test_02245_s3_nested_arrow2_{_partition_id}', format='Arrow') partition by a;
|
||||
insert into test_02245_s3_nested_arrow2 values (1, (2, (3, 'a')));
|
||||
select a, b.a, b.b.c, b.b.d from s3(s3_conn, filename='test_02245_s3_nested_arrow2_*', format='Arrow', structure='a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))');
|
||||
1 2 3 a
|
||||
drop table if exists test_02245_s3_nested_orc1;
|
||||
drop table if exists test_02245_s3_nested_orc2;
|
||||
set input_format_orc_import_nested=1;
|
||||
create table test_02245_s3_nested_orc1(a Int64, b Tuple(a Int64, b String)) engine=S3(s3_conn, filename='test_02245_s3_nested_orc1_{_partition_id}', format='ORC') partition by a;
|
||||
insert into test_02245_s3_nested_orc1 values (1, (2, 'a'));
|
||||
select a, b.a, b.b from s3(s3_conn, filename='test_02245_s3_nested_orc1_*', format='ORC'); -- { serverError 47 }
|
||||
create table test_02245_s3_nested_orc2(a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))) engine=S3(s3_conn, filename='test_02245_s3_nested_orc2_{_partition_id}', format='ORC') partition by a;
|
||||
insert into test_02245_s3_nested_orc2 values (1, (2, (3, 'a')));
|
||||
select a, b.a, b.b.c, b.b.d from s3(s3_conn, filename='test_02245_s3_nested_orc2_*', format='ORC', structure='a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))');
|
||||
1 2 3 a
|
@ -0,0 +1,44 @@
|
||||
-- Tags: no-fasttest
|
||||
-- Tag no-fasttest: Depends on AWS
|
||||
|
||||
-- { echo }
|
||||
drop table if exists test_02245_s3_nested_parquet1;
|
||||
drop table if exists test_02245_s3_nested_parquet2;
|
||||
set input_format_parquet_import_nested = 1;
|
||||
create table test_02245_s3_nested_parquet1(a Int64, b Tuple(a Int64, b String)) engine=S3(s3_conn, filename='test_02245_s3_nested_parquet1_{_partition_id}', format='Parquet') partition by a;
|
||||
insert into test_02245_s3_nested_parquet1 values (1, (2, 'a'));
|
||||
|
||||
select a, b.a, b.b from s3(s3_conn, filename='test_02245_s3_nested_parquet1_*', format='Parquet'); -- { serverError 47 }
|
||||
|
||||
create table test_02245_s3_nested_parquet2(a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))) engine=S3(s3_conn, filename='test_02245_s3_nested_parquet2_{_partition_id}', format='Parquet') partition by a;
|
||||
insert into test_02245_s3_nested_parquet2 values (1, (2, (3, 'a')));
|
||||
|
||||
select a, b.a, b.b.c, b.b.d from s3(s3_conn, filename='test_02245_s3_nested_parquet2_*', format='Parquet', structure='a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))');
|
||||
|
||||
|
||||
drop table if exists test_02245_s3_nested_arrow1;
|
||||
drop table if exists test_02245_s3_nested_arrow2;
|
||||
set input_format_arrow_import_nested=1;
|
||||
create table test_02245_s3_nested_arrow1(a Int64, b Tuple(a Int64, b String)) engine=S3(s3_conn, filename='test_02245_s3_nested_arrow1_{_partition_id}', format='Arrow') partition by a;
|
||||
insert into test_02245_s3_nested_arrow1 values (1, (2, 'a'));
|
||||
|
||||
select a, b.a, b.b from s3(s3_conn, filename='test_02245_s3_nested_arrow1_*', format='Arrow'); -- { serverError 47 }
|
||||
|
||||
create table test_02245_s3_nested_arrow2(a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))) engine=S3(s3_conn, filename='test_02245_s3_nested_arrow2_{_partition_id}', format='Arrow') partition by a;
|
||||
insert into test_02245_s3_nested_arrow2 values (1, (2, (3, 'a')));
|
||||
|
||||
select a, b.a, b.b.c, b.b.d from s3(s3_conn, filename='test_02245_s3_nested_arrow2_*', format='Arrow', structure='a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))');
|
||||
|
||||
|
||||
drop table if exists test_02245_s3_nested_orc1;
|
||||
drop table if exists test_02245_s3_nested_orc2;
|
||||
set input_format_orc_import_nested=1;
|
||||
create table test_02245_s3_nested_orc1(a Int64, b Tuple(a Int64, b String)) engine=S3(s3_conn, filename='test_02245_s3_nested_orc1_{_partition_id}', format='ORC') partition by a;
|
||||
insert into test_02245_s3_nested_orc1 values (1, (2, 'a'));
|
||||
|
||||
select a, b.a, b.b from s3(s3_conn, filename='test_02245_s3_nested_orc1_*', format='ORC'); -- { serverError 47 }
|
||||
|
||||
create table test_02245_s3_nested_orc2(a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))) engine=S3(s3_conn, filename='test_02245_s3_nested_orc2_{_partition_id}', format='ORC') partition by a;
|
||||
insert into test_02245_s3_nested_orc2 values (1, (2, (3, 'a')));
|
||||
|
||||
select a, b.a, b.b.c, b.b.d from s3(s3_conn, filename='test_02245_s3_nested_orc2_*', format='ORC', structure='a Int64, b Tuple(a Int64, b Tuple(c Int64, d String))');
|
@ -0,0 +1,5 @@
|
||||
\N
|
||||
|
||||
\N
|
||||
0 \N \N \N
|
||||
0 \N \N \N
|
@ -0,0 +1,33 @@
|
||||
select singleValueOrNull(number) from numbers(0) with totals;
|
||||
|
||||
SELECT
|
||||
0.5 IN (
|
||||
SELECT singleValueOrNull(*)
|
||||
FROM
|
||||
(
|
||||
SELECT 1048577
|
||||
FROM numbers(0)
|
||||
)
|
||||
WITH TOTALS
|
||||
),
|
||||
NULL,
|
||||
NULL NOT IN (
|
||||
SELECT
|
||||
2147483647,
|
||||
1024 IN (
|
||||
SELECT
|
||||
[NULL, 2147483648, NULL, NULL],
|
||||
number
|
||||
FROM numbers(7, 100)
|
||||
),
|
||||
[NULL, NULL, NULL, NULL, NULL],
|
||||
number
|
||||
FROM numbers(1048576)
|
||||
WHERE NULL
|
||||
),
|
||||
NULL NOT IN (
|
||||
SELECT number
|
||||
FROM numbers(0)
|
||||
)
|
||||
GROUP BY NULL
|
||||
WITH CUBE;
|
@ -32,4 +32,7 @@ SELECT sum(x), count(x), avg(x) FROM (SELECT number :: Decimal32(0) AS x FROM nu
|
||||
SELECT sum(x), count(x), avg(x), toTypeName(sum(x)), toTypeName(count(x)), toTypeName(avg(x)) FROM (SELECT number :: Decimal32(0) AS x FROM numbers(10)) SETTINGS optimize_syntax_fuse_functions = 0;
|
||||
SELECT sum(x), count(x), avg(x), toTypeName(sum(x)), toTypeName(count(x)), toTypeName(avg(x)) FROM (SELECT number :: Decimal32(0) AS x FROM numbers(10));
|
||||
|
||||
-- TODO: uncomment after https://github.com/ClickHouse/ClickHouse/pull/43372
|
||||
-- SELECT avg(b), x - 2 AS b FROM (SELECT number as x FROM numbers(1)) GROUP BY x;
|
||||
|
||||
DROP TABLE fuse_tbl;
|
||||
|
@ -1,89 +1,7 @@
|
||||
799.2 Nullable(Float64) 899.1 Nullable(Float64)
|
||||
800.2 Float64 900.1 Float64
|
||||
800.2 Float64 100.9 Float64
|
||||
498.5 500.5 800.2 801.2 900.1
|
||||
QUERY id: 0
|
||||
PROJECTION COLUMNS
|
||||
quantile(minus(a, 1)) Nullable(Float64)
|
||||
plus(quantile(minus(b, 1)), 1) Float64
|
||||
plus(quantile(0.8)(minus(b, 1)), 1) Float64
|
||||
plus(quantile(0.8)(minus(b, 1)), 2) Float64
|
||||
plus(quantile(0.9)(minus(b, 1)), 1) Float64
|
||||
PROJECTION
|
||||
LIST id: 1, nodes: 5
|
||||
FUNCTION id: 2, function_name: quantile, function_type: aggregate, result_type: Nullable(Float64)
|
||||
ARGUMENTS
|
||||
LIST id: 3, nodes: 1
|
||||
FUNCTION id: 4, function_name: minus, function_type: ordinary, result_type: Nullable(Int64)
|
||||
ARGUMENTS
|
||||
LIST id: 5, nodes: 2
|
||||
COLUMN id: 6, column_name: a, result_type: Nullable(Int32), source_id: 7
|
||||
CONSTANT id: 8, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
FUNCTION id: 9, function_name: plus, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 10, nodes: 2
|
||||
FUNCTION id: 11, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 12, nodes: 2
|
||||
FUNCTION id: 13, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
ARGUMENTS
|
||||
LIST id: 14, nodes: 1
|
||||
FUNCTION id: 15, function_name: minus, function_type: ordinary, result_type: Int64
|
||||
ARGUMENTS
|
||||
LIST id: 16, nodes: 2
|
||||
COLUMN id: 17, column_name: b, result_type: Int32, source_id: 7
|
||||
CONSTANT id: 18, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
CONSTANT id: 19, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
CONSTANT id: 20, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
FUNCTION id: 21, function_name: plus, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 22, nodes: 2
|
||||
FUNCTION id: 23, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 24, nodes: 2
|
||||
FUNCTION id: 13, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
ARGUMENTS
|
||||
LIST id: 14, nodes: 1
|
||||
FUNCTION id: 15, function_name: minus, function_type: ordinary, result_type: Int64
|
||||
ARGUMENTS
|
||||
LIST id: 16, nodes: 2
|
||||
COLUMN id: 17, column_name: b, result_type: Int32, source_id: 7
|
||||
CONSTANT id: 18, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
CONSTANT id: 25, constant_value: UInt64_2, constant_value_type: UInt8
|
||||
CONSTANT id: 26, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
FUNCTION id: 27, function_name: plus, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 28, nodes: 2
|
||||
FUNCTION id: 29, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 30, nodes: 2
|
||||
FUNCTION id: 13, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
ARGUMENTS
|
||||
LIST id: 14, nodes: 1
|
||||
FUNCTION id: 15, function_name: minus, function_type: ordinary, result_type: Int64
|
||||
ARGUMENTS
|
||||
LIST id: 16, nodes: 2
|
||||
COLUMN id: 17, column_name: b, result_type: Int32, source_id: 7
|
||||
CONSTANT id: 18, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
CONSTANT id: 31, constant_value: UInt64_3, constant_value_type: UInt8
|
||||
CONSTANT id: 32, constant_value: UInt64_2, constant_value_type: UInt8
|
||||
FUNCTION id: 33, function_name: plus, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 34, nodes: 2
|
||||
FUNCTION id: 35, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 36, nodes: 2
|
||||
FUNCTION id: 13, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
ARGUMENTS
|
||||
LIST id: 14, nodes: 1
|
||||
FUNCTION id: 15, function_name: minus, function_type: ordinary, result_type: Int64
|
||||
ARGUMENTS
|
||||
LIST id: 16, nodes: 2
|
||||
COLUMN id: 17, column_name: b, result_type: Int32, source_id: 7
|
||||
CONSTANT id: 18, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
CONSTANT id: 37, constant_value: UInt64_4, constant_value_type: UInt8
|
||||
CONSTANT id: 38, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
JOIN TREE
|
||||
TABLE id: 7, table_name: default.fuse_tbl
|
||||
501.5 501.5
|
||||
QUERY id: 0
|
||||
PROJECTION COLUMNS
|
||||
@ -95,54 +13,70 @@ QUERY id: 0
|
||||
ARGUMENTS
|
||||
LIST id: 3, nodes: 2
|
||||
FUNCTION id: 4, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
PARAMETERS
|
||||
LIST id: 5, nodes: 2
|
||||
CONSTANT id: 6, constant_value: Float64_0.5, constant_value_type: Float64
|
||||
CONSTANT id: 7, constant_value: Float64_0.9, constant_value_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 5, nodes: 1
|
||||
COLUMN id: 6, column_name: b, result_type: Float64, source_id: 7
|
||||
CONSTANT id: 8, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
FUNCTION id: 9, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
LIST id: 8, nodes: 1
|
||||
COLUMN id: 9, column_name: b, result_type: Float64, source_id: 10
|
||||
CONSTANT id: 11, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
FUNCTION id: 12, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 10, nodes: 2
|
||||
LIST id: 13, nodes: 2
|
||||
FUNCTION id: 4, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
PARAMETERS
|
||||
LIST id: 5, nodes: 2
|
||||
CONSTANT id: 6, constant_value: Float64_0.5, constant_value_type: Float64
|
||||
CONSTANT id: 7, constant_value: Float64_0.9, constant_value_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 5, nodes: 1
|
||||
COLUMN id: 6, column_name: b, result_type: Float64, source_id: 7
|
||||
CONSTANT id: 11, constant_value: UInt64_2, constant_value_type: UInt8
|
||||
LIST id: 8, nodes: 1
|
||||
COLUMN id: 9, column_name: b, result_type: Float64, source_id: 10
|
||||
CONSTANT id: 14, constant_value: UInt64_2, constant_value_type: UInt8
|
||||
JOIN TREE
|
||||
QUERY id: 7, is_subquery: 1
|
||||
QUERY id: 10, is_subquery: 1
|
||||
PROJECTION COLUMNS
|
||||
b Float64
|
||||
PROJECTION
|
||||
LIST id: 12, nodes: 1
|
||||
FUNCTION id: 13, function_name: plus, function_type: ordinary, result_type: Float64
|
||||
LIST id: 15, nodes: 1
|
||||
FUNCTION id: 16, function_name: plus, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 14, nodes: 2
|
||||
COLUMN id: 15, column_name: x, result_type: Float64, source_id: 16
|
||||
CONSTANT id: 17, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
LIST id: 17, nodes: 2
|
||||
COLUMN id: 18, column_name: x, result_type: Float64, source_id: 19
|
||||
CONSTANT id: 20, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
JOIN TREE
|
||||
QUERY id: 16, is_subquery: 1
|
||||
QUERY id: 19, is_subquery: 1
|
||||
PROJECTION COLUMNS
|
||||
x Float64
|
||||
quantile(0.9)(b) Float64
|
||||
PROJECTION
|
||||
LIST id: 18, nodes: 2
|
||||
FUNCTION id: 19, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
LIST id: 21, nodes: 2
|
||||
FUNCTION id: 22, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 20, nodes: 2
|
||||
FUNCTION id: 21, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
LIST id: 23, nodes: 2
|
||||
FUNCTION id: 24, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
PARAMETERS
|
||||
LIST id: 25, nodes: 2
|
||||
CONSTANT id: 26, constant_value: Float64_0.5, constant_value_type: Float64
|
||||
CONSTANT id: 27, constant_value: Float64_0.9, constant_value_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 22, nodes: 1
|
||||
COLUMN id: 23, column_name: b, result_type: Int32, source_id: 24
|
||||
CONSTANT id: 25, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
FUNCTION id: 26, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
LIST id: 28, nodes: 1
|
||||
COLUMN id: 29, column_name: b, result_type: Int32, source_id: 30
|
||||
CONSTANT id: 31, constant_value: UInt64_1, constant_value_type: UInt8
|
||||
FUNCTION id: 32, function_name: arrayElement, function_type: ordinary, result_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 27, nodes: 2
|
||||
FUNCTION id: 21, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
LIST id: 33, nodes: 2
|
||||
FUNCTION id: 24, function_name: quantiles, function_type: aggregate, result_type: Array(Float64)
|
||||
PARAMETERS
|
||||
LIST id: 25, nodes: 2
|
||||
CONSTANT id: 26, constant_value: Float64_0.5, constant_value_type: Float64
|
||||
CONSTANT id: 27, constant_value: Float64_0.9, constant_value_type: Float64
|
||||
ARGUMENTS
|
||||
LIST id: 22, nodes: 1
|
||||
COLUMN id: 23, column_name: b, result_type: Int32, source_id: 24
|
||||
CONSTANT id: 28, constant_value: UInt64_2, constant_value_type: UInt8
|
||||
LIST id: 28, nodes: 1
|
||||
COLUMN id: 29, column_name: b, result_type: Int32, source_id: 30
|
||||
CONSTANT id: 34, constant_value: UInt64_2, constant_value_type: UInt8
|
||||
JOIN TREE
|
||||
TABLE id: 24, table_name: default.fuse_tbl
|
||||
TABLE id: 30, table_name: default.fuse_tbl
|
||||
GROUP BY
|
||||
LIST id: 29, nodes: 1
|
||||
COLUMN id: 15, column_name: x, result_type: Float64, source_id: 16
|
||||
LIST id: 35, nodes: 1
|
||||
COLUMN id: 18, column_name: x, result_type: Float64, source_id: 19
|
||||
|
@ -9,9 +9,9 @@ INSERT INTO fuse_tbl SELECT number, number + 1 FROM numbers(1000);
|
||||
|
||||
SELECT quantile(0.8)(a), toTypeName(quantile(0.8)(a)), quantile(0.9)(a), toTypeName(quantile(0.9)(a)) FROM fuse_tbl;
|
||||
SELECT quantile(0.8)(b), toTypeName(quantile(0.8)(b)), quantile(0.9)(b), toTypeName(quantile(0.9)(b)) FROM fuse_tbl;
|
||||
SELECT quantile(a - 1), quantile(b - 1) + 1, quantile(0.8)(b - 1) + 1, quantile(0.8)(b - 1) + 2, quantile(0.9)(b - 1) + 1 FROM fuse_tbl;
|
||||
SELECT quantile(0.8)(b), toTypeName(quantile(0.8)(b)), quantile(0.1)(b), toTypeName(quantile(0.1)(b)) FROM fuse_tbl;
|
||||
|
||||
EXPLAIN QUERY TREE run_passes = 1 SELECT quantile(a - 1), quantile(b - 1) + 1, quantile(0.8)(b - 1) + 1, quantile(0.8)(b - 1) + 2, quantile(0.9)(b - 1) + 1 FROM fuse_tbl;
|
||||
SELECT quantile(a - 1), quantile(b - 1) + 1, quantile(0.8)(b - 1) + 1, quantile(0.8)(b - 1) + 2, quantile(0.9)(b - 1) + 1 FROM fuse_tbl;
|
||||
|
||||
SELECT quantile(0.5)(b), quantile(0.9)(b) from (SELECT x + 1 as b FROM (SELECT quantile(0.5)(b) as x, quantile(0.9)(b) FROM fuse_tbl) GROUP BY x);
|
||||
EXPLAIN QUERY TREE run_passes = 1 SELECT quantile(0.5)(b), quantile(0.9)(b) from (SELECT x + 1 as b FROM (SELECT quantile(0.5)(b) as x, quantile(0.9)(b) FROM fuse_tbl) GROUP BY x);
|
||||
|
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
set basedir [file dirname $argv0]
|
||||
set basename [file tail $argv0]
|
||||
exp_internal -f $env(CLICKHOUSE_TMP)/$basename.debuglog 0
|
||||
|
||||
log_user 0
|
||||
set timeout 60
|
||||
match_max 100000
|
||||
set stty_init "rows 25 cols 120"
|
||||
|
||||
expect_after {
|
||||
eof { exp_continue }
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
spawn bash
|
||||
send "source $basedir/../shell_config.sh\r"
|
||||
|
||||
send -- "\$CLICKHOUSE_CLIENT --query 'DROP TABLE IF EXISTS num_processed_rows_test_0' >/dev/null 2>&1\r"
|
||||
|
||||
send -- "\$CLICKHOUSE_CLIENT --query 'CREATE TABLE num_processed_rows_test_0 (val String) ENGINE = Memory;' >/dev/null 2>&1\r"
|
||||
|
||||
### When requested we should get the count on exit:
|
||||
send -- "\$CLICKHOUSE_CLIENT --processed-rows --query \"INSERT INTO num_processed_rows_test_0 VALUES (\'x\');\" \r"
|
||||
expect "Processed rows: 1"
|
||||
|
||||
send "yes | head -n7757 | \$CLICKHOUSE_CLIENT --processed-rows --query 'INSERT INTO num_processed_rows_test_0 format TSV\'\r"
|
||||
expect "Processed rows: 7757"
|
||||
|
||||
|
||||
|
||||
### By default it should not show up:
|
||||
|
||||
send -- "\$CLICKHOUSE_CLIENT --query \"INSERT INTO num_processed_rows_test_0 VALUES (\'x\');\" && echo OK\r"
|
||||
expect -exact "OK\r"
|
||||
|
||||
send "yes | head -n7757 | \$CLICKHOUSE_CLIENT --query 'INSERT INTO num_processed_rows_test_0 format TSV\' && echo OK\r"
|
||||
expect -exact "OK\r"
|
||||
|
||||
send "exit\r"
|
||||
expect eof
|
@ -0,0 +1,11 @@
|
||||
set allow_suspicious_low_cardinality_types=1;
|
||||
|
||||
drop table if exists test;
|
||||
|
||||
create table test (val LowCardinality(Float32)) engine MergeTree order by val;
|
||||
|
||||
insert into test values (nan);
|
||||
|
||||
select count() from test where toUInt64(val) = -1; -- { serverError 70 }
|
||||
|
||||
drop table if exists test;
|
@ -0,0 +1 @@
|
||||
{"list.nested.x.r":[[1,2]],"list.x.r":[[1]]}
|
27
tests/queries/0_stateless/02482_json_nested_arrays_with_same_keys.sh
Executable file
27
tests/queries/0_stateless/02482_json_nested_arrays_with_same_keys.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tags: no-fasttest, no-parallel
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
echo '
|
||||
{
|
||||
"obj" :
|
||||
{
|
||||
"list" :
|
||||
[
|
||||
{
|
||||
"nested" : {
|
||||
"x" : [{"r" : 1}, {"r" : 2}]
|
||||
},
|
||||
"x" : [{"r" : 1}]
|
||||
}
|
||||
]
|
||||
}
|
||||
}' > 02482_object_data.jsonl
|
||||
|
||||
$CLICKHOUSE_LOCAL --allow_experimental_object_type=1 -q "select * from file(02482_object_data.jsonl, auto, 'obj JSON')"
|
||||
|
||||
rm 02482_object_data.jsonl
|
||||
|
@ -0,0 +1,33 @@
|
||||
-- { echo }
|
||||
CREATE FUNCTION 02483_plusone AS (a) -> a + 1;
|
||||
CREATE TABLE 02483_substitute_udf (id UInt32, number UInt32 DEFAULT 02483_plusone(id)) ENGINE=MergeTree() ORDER BY id;
|
||||
DESC TABLE 02483_substitute_udf;
|
||||
id UInt32
|
||||
number UInt32 DEFAULT id + 1
|
||||
INSERT INTO 02483_substitute_udf (id, number) VALUES (1, NULL);
|
||||
SELECT * FROM 02483_substitute_udf ORDER BY id;
|
||||
1 2
|
||||
CREATE FUNCTION 02483_plustwo AS (a) -> a + 2;
|
||||
ALTER TABLE 02483_substitute_udf MODIFY COLUMN number UInt32 DEFAULT 02483_plustwo(id);
|
||||
DESC TABLE 02483_substitute_udf;
|
||||
id UInt32
|
||||
number UInt32 DEFAULT id + 2
|
||||
INSERT INTO 02483_substitute_udf (id, number) VALUES (5, NULL);
|
||||
SELECT * FROM 02483_substitute_udf ORDER BY id;
|
||||
1 2
|
||||
5 7
|
||||
CREATE FUNCTION 02483_plusthree AS (a) -> a + 3;
|
||||
ALTER TABLE 02483_substitute_udf DROP COLUMN number;
|
||||
ALTER TABLE 02483_substitute_udf ADD COLUMN new_number UInt32 DEFAULT 02483_plusthree(id);
|
||||
DESC TABLE 02483_substitute_udf;
|
||||
id UInt32
|
||||
new_number UInt32 DEFAULT id + 3
|
||||
INSERT INTO 02483_substitute_udf (id, new_number) VALUES (10, NULL);
|
||||
SELECT * FROM 02483_substitute_udf ORDER BY id;
|
||||
1 4
|
||||
5 8
|
||||
10 13
|
||||
DROP TABLE 02483_substitute_udf;
|
||||
DROP FUNCTION 02483_plusone;
|
||||
DROP FUNCTION 02483_plustwo;
|
||||
DROP FUNCTION 02483_plusthree;
|
31
tests/queries/0_stateless/02483_substitute_udf_create.sql
Normal file
31
tests/queries/0_stateless/02483_substitute_udf_create.sql
Normal file
@ -0,0 +1,31 @@
|
||||
-- Tags: no-parallel
|
||||
|
||||
DROP TABLE IF EXISTS 02483_substitute_udf;
|
||||
DROP FUNCTION IF EXISTS 02483_plusone;
|
||||
DROP FUNCTION IF EXISTS 02483_plustwo;
|
||||
DROP FUNCTION IF EXISTS 02483_plusthree;
|
||||
|
||||
-- { echo }
|
||||
CREATE FUNCTION 02483_plusone AS (a) -> a + 1;
|
||||
CREATE TABLE 02483_substitute_udf (id UInt32, number UInt32 DEFAULT 02483_plusone(id)) ENGINE=MergeTree() ORDER BY id;
|
||||
DESC TABLE 02483_substitute_udf;
|
||||
INSERT INTO 02483_substitute_udf (id, number) VALUES (1, NULL);
|
||||
SELECT * FROM 02483_substitute_udf ORDER BY id;
|
||||
|
||||
CREATE FUNCTION 02483_plustwo AS (a) -> a + 2;
|
||||
ALTER TABLE 02483_substitute_udf MODIFY COLUMN number UInt32 DEFAULT 02483_plustwo(id);
|
||||
DESC TABLE 02483_substitute_udf;
|
||||
INSERT INTO 02483_substitute_udf (id, number) VALUES (5, NULL);
|
||||
SELECT * FROM 02483_substitute_udf ORDER BY id;
|
||||
|
||||
CREATE FUNCTION 02483_plusthree AS (a) -> a + 3;
|
||||
ALTER TABLE 02483_substitute_udf DROP COLUMN number;
|
||||
ALTER TABLE 02483_substitute_udf ADD COLUMN new_number UInt32 DEFAULT 02483_plusthree(id);
|
||||
DESC TABLE 02483_substitute_udf;
|
||||
INSERT INTO 02483_substitute_udf (id, new_number) VALUES (10, NULL);
|
||||
SELECT * FROM 02483_substitute_udf ORDER BY id;
|
||||
|
||||
DROP TABLE 02483_substitute_udf;
|
||||
DROP FUNCTION 02483_plusone;
|
||||
DROP FUNCTION 02483_plustwo;
|
||||
DROP FUNCTION 02483_plusthree;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user