Merge branch 'master' into 49507_Support_compression_for_keeper_protocol

This commit is contained in:
Smita Kulkarni 2023-10-14 20:08:49 +02:00
commit 13ffebf559
107 changed files with 3099 additions and 1218 deletions

2
contrib/croaring vendored

@ -1 +1 @@
Subproject commit e4a7ad5542746103e71ca8b5e56225baf0014c87
Subproject commit 9b7cc0ff1c41e9457efb6228cfd2c538d0155303

View File

@ -6,13 +6,7 @@ target_compile_definitions (_gtest PUBLIC GTEST_HAS_POSIX_RE=0)
target_include_directories(_gtest SYSTEM PUBLIC "${SRC_DIR}/googletest/include")
target_include_directories(_gtest PRIVATE "${SRC_DIR}/googletest")
add_library(_gtest_main "${SRC_DIR}/googletest/src/gtest_main.cc")
set_target_properties(_gtest_main PROPERTIES VERSION "1.0.0")
target_link_libraries(_gtest_main PUBLIC _gtest)
add_library(_gtest_all INTERFACE)
target_link_libraries(_gtest_all INTERFACE _gtest _gtest_main)
add_library(ch_contrib::gtest_all ALIAS _gtest_all)
add_library(ch_contrib::gtest ALIAS _gtest)
add_library(_gmock "${SRC_DIR}/googlemock/src/gmock-all.cc")
set_target_properties(_gmock PROPERTIES VERSION "1.0.0")

View File

@ -15,8 +15,8 @@ CLICKHOUSE_CI_LOGS_USER=${CLICKHOUSE_CI_LOGS_USER:-ci}
# Pre-configured destination cluster, where to export the data
CLICKHOUSE_CI_LOGS_CLUSTER=${CLICKHOUSE_CI_LOGS_CLUSTER:-system_logs_export}
EXTRA_COLUMNS=${EXTRA_COLUMNS:-"pull_request_number UInt32, commit_sha String, check_start_time DateTime, check_name LowCardinality(String), instance_type LowCardinality(String), instance_id String, "}
EXTRA_COLUMNS_EXPRESSION=${EXTRA_COLUMNS_EXPRESSION:-"0 AS pull_request_number, '' AS commit_sha, now() AS check_start_time, '' AS check_name, '' AS instance_type, '' AS instance_id"}
EXTRA_COLUMNS=${EXTRA_COLUMNS:-"pull_request_number UInt32, commit_sha String, check_start_time DateTime('UTC'), check_name String, instance_type String, instance_id String, "}
EXTRA_COLUMNS_EXPRESSION=${EXTRA_COLUMNS_EXPRESSION:-"CAST(0 AS UInt32) AS pull_request_number, '' AS commit_sha, now() AS check_start_time, '' AS check_name, '' AS instance_type, '' AS instance_id"}
EXTRA_ORDER_BY_COLUMNS=${EXTRA_ORDER_BY_COLUMNS:-"check_name, "}
function __set_connection_args
@ -125,9 +125,9 @@ function setup_logs_replication
echo 'Create %_log tables'
clickhouse-client --query "SHOW TABLES FROM system LIKE '%\\_log'" | while read -r table
do
# Calculate hash of its structure. Note: 1 is the version of extra columns - increment it if extra columns are changed:
# Calculate hash of its structure. Note: 4 is the version of extra columns - increment it if extra columns are changed:
hash=$(clickhouse-client --query "
SELECT sipHash64(1, groupArray((name, type)))
SELECT sipHash64(4, groupArray((name, type)))
FROM (SELECT name, type FROM system.columns
WHERE database = 'system' AND table = '$table'
ORDER BY position)

View File

@ -10,10 +10,6 @@ ClickHouse supports the MySQL wire protocol. This allow tools that are MySQL-com
## Enabling the MySQL Interface On ClickHouse Cloud
:::note
The MySQL interface for ClickHouse Cloud is currently in private preview. Please contact support@clickhouse.com to enable this feature for your ClickHouse Cloud service.
:::
1. After creating your ClickHouse Cloud Service, on the credentials screen, select the MySQL tab
![Credentials screen - Prompt](./images/mysql1.png)

View File

@ -61,17 +61,17 @@ FROM table
SETTINGS use_query_cache = true, enable_writes_to_query_cache = false;
```
For maximum control, it is generally recommended to provide settings "use_query_cache", "enable_writes_to_query_cache" and
"enable_reads_from_query_cache" only with specific queries. It is also possible to enable caching at user or profile level (e.g. via `SET
For maximum control, it is generally recommended to provide settings `use_query_cache`, `enable_writes_to_query_cache` and
`enable_reads_from_query_cache` only with specific queries. It is also possible to enable caching at user or profile level (e.g. via `SET
use_query_cache = true`) but one should keep in mind that all `SELECT` queries including monitoring or debugging queries to system tables
may return cached results then.
The query cache can be cleared using statement `SYSTEM DROP QUERY CACHE`. The content of the query cache is displayed in system table
`system.query_cache`. The number of query cache hits and misses since database start are shown as events "QueryCacheHits" and
"QueryCacheMisses" in system table [system.events](system-tables/events.md). Both counters are only updated for `SELECT` queries which run
with setting `use_query_cache = true`, other queries do not affect "QueryCacheMisses". Field `query_cache_usage` in system table
[system.query_log](system-tables/query_log.md) shows for each executed query whether the query result was written into or read from the
query cache. Asynchronous metrics "QueryCacheEntries" and "QueryCacheBytes" in system table
[system.query_cache](system-tables/query_cache.md). The number of query cache hits and misses since database start are shown as events
"QueryCacheHits" and "QueryCacheMisses" in system table [system.events](system-tables/events.md). Both counters are only updated for
`SELECT` queries which run with setting `use_query_cache = true`, other queries do not affect "QueryCacheMisses". Field `query_cache_usage`
in system table [system.query_log](system-tables/query_log.md) shows for each executed query whether the query result was written into or
read from the query cache. Asynchronous metrics "QueryCacheEntries" and "QueryCacheBytes" in system table
[system.asynchronous_metrics](system-tables/asynchronous_metrics.md) show how many entries / bytes the query cache currently contains.
The query cache exists once per ClickHouse server process. However, cache results are by default not shared between users. This can be
@ -86,9 +86,18 @@ If the query was aborted due to an exception or user cancellation, no entry is w
The size of the query cache in bytes, the maximum number of cache entries and the maximum size of individual cache entries (in bytes and in
records) can be configured using different [server configuration options](server-configuration-parameters/settings.md#server_configuration_parameters_query-cache).
```xml
<query_cache>
<max_size_in_bytes>1073741824</max_size_in_bytes>
<max_entries>1024</max_entries>
<max_entry_size_in_bytes>1048576</max_entry_size_in_bytes>
<max_entry_size_in_rows>30000000</max_entry_size_in_rows>
</query_cache>
```
It is also possible to limit the cache usage of individual users using [settings profiles](settings/settings-profiles.md) and [settings
constraints](settings/constraints-on-settings.md). More specifically, you can restrict the maximum amount of memory (in bytes) a user may
allocate in the query cache and the the maximum number of stored query results. For that, first provide configurations
allocate in the query cache and the maximum number of stored query results. For that, first provide configurations
[query_cache_max_size_in_bytes](settings/settings.md#query-cache-max-size-in-bytes) and
[query_cache_max_entries](settings/settings.md#query-cache-size-max-entries) in a user profile in `users.xml`, then make both settings
readonly:
@ -158,6 +167,7 @@ Also, results of queries with non-deterministic functions are not cached by defa
- functions which depend on the environment: [`currentUser()`](../sql-reference/functions/other-functions.md#currentUser),
[`queryID()`](../sql-reference/functions/other-functions.md#queryID),
[`getMacro()`](../sql-reference/functions/other-functions.md#getMacro) etc.
To force caching of results of queries with non-deterministic functions regardless, use setting
[query_cache_store_results_of_queries_with_nondeterministic_functions](settings/settings.md#query-cache-store-results-of-queries-with-nondeterministic-functions).

View File

@ -2403,7 +2403,8 @@ This section contains the following parameters:
- zookeeper_load_balancing - Specifies the algorithm of ZooKeeper node selection.
* random - randomly selects one of ZooKeeper nodes.
* in_order - selects the first ZooKeeper node, if it's not available then the second, and so on.
* nearest_hostname - selects a ZooKeeper node with a hostname that is most similar to the servers hostname.
* nearest_hostname - selects a ZooKeeper node with a hostname that is most similar to the servers hostname, hostname is compared with name prefix.
* hostname_levenshtein_distance - just like nearest_hostname, but it compares hostname in a levenshtein distance manner.
* first_or_random - selects the first ZooKeeper node, if it's not available then randomly selects one of remaining ZooKeeper nodes.
* round_robin - selects the first ZooKeeper node, if reconnection happens selects the next.
- `compressed_protocol` — If set to true, enables compression in keeper protocol.
@ -2427,7 +2428,7 @@ This section contains the following parameters:
<root>/path/to/zookeeper/node</root>
<!-- Optional. Zookeeper digest ACL string. -->
<identity>user:password</identity>
<!--<zookeeper_load_balancing>random / in_order / nearest_hostname / first_or_random / round_robin</zookeeper_load_balancing>-->
<!--<zookeeper_load_balancing>random / in_order / nearest_hostname / hostname_levenshtein_distance / first_or_random / round_robin</zookeeper_load_balancing>-->
<zookeeper_load_balancing>random</zookeeper_load_balancing>
</zookeeper>
```

View File

@ -1413,6 +1413,7 @@ ClickHouse supports the following algorithms of choosing replicas:
- [Random](#load_balancing-random) (by default)
- [Nearest hostname](#load_balancing-nearest_hostname)
- [Hostname levenshtein distance](#load_balancing-hostname_levenshtein_distance)
- [In order](#load_balancing-in_order)
- [First or random](#load_balancing-first_or_random)
- [Round robin](#load_balancing-round_robin)
@ -1444,6 +1445,25 @@ This method might seem primitive, but it does not require external data about ne
Thus, if there are equivalent replicas, the closest one by name is preferred.
We can also assume that when sending a query to the same server, in the absence of failures, a distributed query will also go to the same servers. So even if different data is placed on the replicas, the query will return mostly the same results.
### Hostname levenshtein distance {#load_balancing-hostname_levenshtein_distance}
``` sql
load_balancing = hostname_levenshtein_distance
```
Just like `nearest_hostname`, but it compares hostname in a [levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) manner. For example:
``` text
example-clickhouse-0-0 ample-clickhouse-0-0
1
example-clickhouse-0-0 example-clickhouse-1-10
2
example-clickhouse-0-0 example-clickhouse-12-0
3
```
### In Order {#load_balancing-in_order}
``` sql

View File

@ -0,0 +1,36 @@
---
slug: /en/operations/system-tables/query_cache
---
# query_cache
Shows the content of the [query cache](../query-cache.md).
Columns:
- `query` ([String](../../sql-reference/data-types/string.md)) — Query string.
- `result_size` ([UInt64](../../sql-reference/data-types/int-uint.md#uint-ranges)) — Size of the query cache entry.
- `stale` ([UInt8](../../sql-reference/data-types/int-uint.md)) — If the query cache entry is stale.
- `shared` ([UInt8](../../sql-reference/data-types/int-uint.md)) — If the query cache entry is shared between multiple users.
- `compressed` ([UInt8](../../sql-reference/data-types/int-uint.md)) — If the query cache entry is compressed.
- `expires_at` ([DateTime](../../sql-reference/data-types/datetime.md)) — When the query cache entry becomes stale.
- `key_hash` ([UInt64](../../sql-reference/data-types/int-uint.md#uint-ranges)) — A hash of the query string, used as a key to find query cache entries.
**Example**
``` sql
SELECT * FROM system.query_cache FORMAT Vertical;
```
``` text
Row 1:
──────
query: SELECT 1 SETTINGS use_query_cache = 1
result_size: 128
stale: 0
shared: 0
compressed: 1
expires_at: 2023-10-13 13:35:45
key_hash: 12188185624808016954
1 row in set. Elapsed: 0.004 sec.
```

View File

@ -441,3 +441,40 @@ DB::Exception: Decimal result's scale is less than argument's one: While process
│ -12 │ 2.1 │ -5.7 │ -5.71428 │
└─────┴─────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘
```
## byteSwap
Reverses the bytes of an integer, i.e. changes its [endianness](https://en.wikipedia.org/wiki/Endianness).
**Syntax**
```sql
byteSwap(a)
```
**Example**
```sql
byteSwap(3351772109)
```
Result:
```result
┌─byteSwap(3351772109)─┐
│ 3455829959 │
└──────────────────────┘
```
The above example can be worked out in the following manner:
1. Convert the base-10 integer to its equivalent hexadecimal format in big-endian format, i.e. 3351772109 -> C7 C7 FB CD (4 bytes)
2. Reverse the bytes, i.e. C7 C7 FB CD -> CD FB C7 C7
3. Convert the result back to an integer assuming big-endian, i.e. CD FB C7 C7 -> 3455829959
One use case of this function is reversing IPv4s:
```result
┌─toIPv4(byteSwap(toUInt32(toIPv4('205.251.199.199'))))─┐
│ 199.199.251.205 │
└───────────────────────────────────────────────────────┘
```

View File

@ -204,6 +204,20 @@ Alias: `timezone`.
Type: [String](../../sql-reference/data-types/string.md).
**Example**
```sql
SELECT timezone()
```
Result:
```response
┌─timezone()─────┐
│ America/Denver │
└────────────────┘
```
**See also**
- [serverTimeZone](#serverTimeZone)
@ -227,6 +241,20 @@ Alias: `serverTimezone`.
Type: [String](../../sql-reference/data-types/string.md).
**Example**
```sql
SELECT serverTimeZone()
```
Result:
```response
┌─serverTimeZone()─┐
│ UTC │
└──────────────────┘
```
**See also**
- [timeZone](#timeZone)
@ -366,37 +394,189 @@ Result:
## toYear
Converts a date or date with time to the year number (AD) as UInt16 value.
Converts a date or date with time to the year number (AD) as `UInt16` value.
Alias: `YEAR`.
**Syntax**
```sql
toYear(value)
```
Alias: `YEAR`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The year of the given date/time
Type: `UInt16`
**Example**
```sql
SELECT toYear(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toYear(toDateTime('2023-04-21 10:20:30'))─┐
│ 2023 │
└───────────────────────────────────────────┘
```
## toQuarter
Converts a date or date with time to the quarter number as UInt8 value.
Converts a date or date with time to the quarter number (1-4) as `UInt8` value.
**Syntax**
```sql
toQuarter(value)
```
Alias: `QUARTER`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The quarter of the year (1, 2, 3 or 4) of the given date/time
Type: `UInt8`
**Example**
```sql
SELECT toQuarter(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toQuarter(toDateTime('2023-04-21 10:20:30'))─┐
│ 2 │
└──────────────────────────────────────────────┘
```
Alias: `QUARTER`.
## toMonth
Converts a date or date with time to the month number (1-12) as UInt8 value.
Converts a date or date with time to the month number (1-12) as `UInt8` value.
Alias: `MONTH`.
**Syntax**
```sql
toMonth(value)
```
Alias: `MONTH`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The month of the year (1 - 12) of the given date/time
Type: `UInt8`
**Example**
```sql
SELECT toMonth(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toMonth(toDateTime('2023-04-21 10:20:30'))─┐
│ 4 │
└────────────────────────────────────────────┘
```
## toDayOfYear
Converts a date or date with time to the number of the day of the year (1-366) as UInt16 value.
Converts a date or date with time to the number of the day of the year (1-366) as `UInt16` value.
Alias: `DAYOFYEAR`.
**Syntax**
```sql
toDayOfYear(value)
```
Alias: `DAYOFYEAR`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The day of the year (1 - 366) of the given date/time
Type: `UInt16`
**Example**
```sql
SELECT toDayOfYear(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toDayOfYear(toDateTime('2023-04-21 10:20:30'))─┐
│ 111 │
└────────────────────────────────────────────────┘
```
## toDayOfMonth
Converts a date or date with time to the number of the day in the month (1-31) as UInt8 value.
Converts a date or date with time to the number of the day in the month (1-31) as `UInt8` value.
Aliases: `DAYOFMONTH`, `DAY`.
**Syntax**
```sql
toDayOfMonth(value)
```
Aliases: `DAYOFMONTH`, `DAY`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The day of the month (1 - 31) of the given date/time
Type: `UInt8`
**Example**
```sql
SELECT toDayOfMonth(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toDayOfMonth(toDateTime('2023-04-21 10:20:30'))─┐
│ 21 │
└─────────────────────────────────────────────────┘
```
## toDayOfWeek
Converts a date or date with time to the number of the day in the week as UInt8 value.
Converts a date or date with time to the number of the day in the week as `UInt8` value.
The two-argument form of `toDayOfWeek()` enables you to specify whether the week starts on Monday or Sunday, and whether the return value should be in the range from 0 to 6 or 1 to 7. If the mode argument is omitted, the default mode is 0. The time zone of the date can be specified as the third argument.
@ -415,25 +595,143 @@ Alias: `DAYOFWEEK`.
toDayOfWeek(t[, mode[, timezone]])
```
**Arguments**
- `t` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
- `mode` - determines what the first day of the week is. Possible values are 0, 1, 2 or 3. See the table above for the differences.
- `timezone` - optional parameter, it behaves like any other conversion function
**Returned value**
- The day of the month (1 - 31) of the given date/time
**Example**
The following date is April 21, 2023, which was a Friday:
```sql
SELECT
toDayOfWeek(toDateTime('2023-04-21')),
toDayOfWeek(toDateTime('2023-04-21'), 1)
```
Result:
```response
┌─toDayOfWeek(toDateTime('2023-04-21'))─┬─toDayOfWeek(toDateTime('2023-04-21'), 1)─┐
│ 5 │ 4 │
└───────────────────────────────────────┴──────────────────────────────────────────┘
```
## toHour
Converts a date with time the number of the hour in 24-hour time (0-23) as UInt8 value.
Converts a date with time to the number of the hour in 24-hour time (0-23) as `UInt8` value.
Assumes that if clocks are moved ahead, it is by one hour and occurs at 2 a.m., and if clocks are moved back, it is by one hour and occurs at 3 a.m. (which is not always true even in Moscow the clocks were twice changed at a different time).
Assumes that if clocks are moved ahead, it is by one hour and occurs at 2 a.m., and if clocks are moved back, it is by one hour and occurs at 3 a.m. (which is not always exactly when it occurs - it depends on the timezone).
Alias: `HOUR`.
**Syntax**
```sql
toHour(value)
```
Alias: `HOUR`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The hour of the day (0 - 23) of the given date/time
Type: `UInt8`
**Example**
```sql
SELECT toHour(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toHour(toDateTime('2023-04-21 10:20:30'))─┐
│ 10 │
└───────────────────────────────────────────┘
```
## toMinute
Converts a date with time to the number of the minute of the hour (0-59) as UInt8 value.
Converts a date with time to the number of the minute of the hour (0-59) as `UInt8` value.
Alias: `MINUTE`.
**Syntax**
```sql
toMinute(value)
```
Alias: `MINUTE`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The minute of the hour (0 - 59) of the given date/time
Type: `UInt8`
**Example**
```sql
SELECT toMinute(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toMinute(toDateTime('2023-04-21 10:20:30'))─┐
│ 20 │
└─────────────────────────────────────────────┘
```
## toSecond
Converts a date with time to the second in the minute (0-59) as UInt8 value. Leap seconds are not considered.
Converts a date with time to the second in the minute (0-59) as `UInt8` value. Leap seconds are not considered.
Alias: `SECOND`.
**Syntax**
```sql
toSecond(value)
```
Alias: `SECOND`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The second in the minute (0 - 59) of the given date/time
Type: `UInt8`
**Example**
```sql
SELECT toSecond(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toSecond(toDateTime('2023-04-21 10:20:30'))─┐
│ 30 │
└─────────────────────────────────────────────┘
```
## toUnixTimestamp
@ -496,48 +794,220 @@ Behavior for
## toStartOfYear
Rounds down a date or date with time to the first day of the year.
Returns the date.
Rounds down a date or date with time to the first day of the year. Returns the date as a `Date` object.
**Syntax**
```sql
toStartOfYear(value)
```
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The first day of the year of the input date/time
Type: `Date`
**Example**
```sql
SELECT toStartOfYear(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toStartOfYear(toDateTime('2023-04-21 10:20:30'))─┐
│ 2023-01-01 │
└──────────────────────────────────────────────────┘
```
## toStartOfISOYear
Rounds down a date or date with time to the first day of ISO year.
Returns the date.
Rounds down a date or date with time to the first day of the ISO year, which can be different than a "regular" year. (See [https://en.wikipedia.org/wiki/ISO_week_date](https://en.wikipedia.org/wiki/ISO_week_date).)
**Syntax**
```sql
toStartOfISOYear(value)
```
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The first day of the year of the input date/time
Type: `Date`
**Example**
```sql
SELECT toStartOfISOYear(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toStartOfISOYear(toDateTime('2023-04-21 10:20:30'))─┐
│ 2023-01-02 │
└─────────────────────────────────────────────────────┘
```
## toStartOfQuarter
Rounds down a date or date with time to the first day of the quarter.
The first day of the quarter is either 1 January, 1 April, 1 July, or 1 October.
Rounds down a date or date with time to the first day of the quarter. The first day of the quarter is either 1 January, 1 April, 1 July, or 1 October.
Returns the date.
**Syntax**
```sql
toStartOfQuarter(value)
```
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The first day of the quarter of the given date/time
Type: `Date`
**Example**
```sql
SELECT toStartOfQuarter(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toStartOfQuarter(toDateTime('2023-04-21 10:20:30'))─┐
│ 2023-04-01 │
└─────────────────────────────────────────────────────┘
```
## toStartOfMonth
Rounds down a date or date with time to the first day of the month.
Returns the date.
Rounds down a date or date with time to the first day of the month. Returns the date.
**Syntax**
```sql
toStartOfMonth(value)
```
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The first day of the month of the given date/time
Type: `Date`
**Example**
```sql
SELECT toStartOfMonth(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toStartOfMonth(toDateTime('2023-04-21 10:20:30'))─┐
│ 2023-04-01 │
└───────────────────────────────────────────────────┘
```
:::note
The behavior of parsing incorrect dates is implementation specific. ClickHouse may return zero date, throw an exception or do “natural” overflow.
The behavior of parsing incorrect dates is implementation specific. ClickHouse may return zero date, throw an exception, or do “natural” overflow.
:::
## toLastDayOfMonth
Rounds a date, or date with time, to the last day of the month.
Returns the date.
Rounds a date or date with time to the last day of the month. Returns the date.
Alias: `LAST_DAY`.
**Syntax**
If `toLastDayOfMonth` is called with an argument of type `Date` greater then 2149-05-31, the result will be calculated from the argument 2149-05-31 instead.
```sql
toLastDayOfMonth(value)
```
Alias: `LAST_DAY`
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The last day of the month of the given date/time
Type: `Date`
**Example**
```sql
SELECT toLastDayOfMonth(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toLastDayOfMonth(toDateTime('2023-04-21 10:20:30'))─┐
│ 2023-04-30 │
└─────────────────────────────────────────────────────┘
```
## toMonday
Rounds down a date, or date with time, to the nearest Monday.
Returns the date.
Rounds down a date or date with time to the nearest Monday. Returns the date.
**Syntax**
```sql
toMonday(value)
```
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The date of the nearest Monday on or prior to the given date
Type: `Date`
**Example**
```sql
SELECT
toMonday(toDateTime('2023-04-21 10:20:30')), /* a Friday */
toMonday(toDate('2023-04-24')), /* already a Monday */
```
Result:
```response
┌─toMonday(toDateTime('2023-04-21 10:20:30'))─┬─toMonday(toDate('2023-04-24'))─┐
│ 2023-04-17 │ 2023-04-24 │
└─────────────────────────────────────────────┴────────────────────────────────┘
```
## toStartOfWeek
Rounds a date or date with time down to the nearest Sunday or Monday.
Returns the date.
The mode argument works exactly like the mode argument in function `toWeek()`. If no mode is specified, mode is assumed as 0.
Rounds a date or date with time down to the nearest Sunday or Monday. Returns the date. The mode argument works exactly like the mode argument in function `toWeek()`. If no mode is specified, it defaults to 0.
**Syntax**
@ -545,10 +1015,43 @@ The mode argument works exactly like the mode argument in function `toWeek()`. I
toStartOfWeek(t[, mode[, timezone]])
```
**Arguments**
- `t` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
- `mode` - determines the first day of the week as described in the [toWeek()](date-time-functions#toweek) function
- `timezone` - Optional parameter, it behaves like any other conversion function
**Returned value**
- The date of the nearest Sunday or Monday on or prior to the given date, depending on the mode
Type: `Date`
**Example**
```sql
SELECT
toStartOfWeek(toDateTime('2023-04-21 10:20:30')), /* a Friday */
toStartOfWeek(toDateTime('2023-04-21 10:20:30'), 1), /* a Friday */
toStartOfWeek(toDate('2023-04-24')), /* a Monday */
toStartOfWeek(toDate('2023-04-24'), 1) /* a Monday */
FORMAT Vertical
```
Result:
```response
Row 1:
──────
toStartOfWeek(toDateTime('2023-04-21 10:20:30')): 2023-04-16
toStartOfWeek(toDateTime('2023-04-21 10:20:30'), 1): 2023-04-17
toStartOfWeek(toDate('2023-04-24')): 2023-04-23
toStartOfWeek(toDate('2023-04-24'), 1): 2023-04-24
```
## toLastDayOfWeek
Rounds a date or date with time up to the nearest Saturday or Sunday.
Returns the date.
Rounds a date or date with time up to the nearest Saturday or Sunday. Returns the date.
The mode argument works exactly like the mode argument in function `toWeek()`. If no mode is specified, mode is assumed as 0.
**Syntax**
@ -557,18 +1060,148 @@ The mode argument works exactly like the mode argument in function `toWeek()`. I
toLastDayOfWeek(t[, mode[, timezone]])
```
**Arguments**
- `t` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
- `mode` - determines the last day of the week as described in the [toWeek()](date-time-functions#toweek) function
- `timezone` - Optional parameter, it behaves like any other conversion function
**Returned value**
- The date of the nearest Sunday or Monday on or after the given date, depending on the mode
Type: `Date`
**Example**
```sql
SELECT
toLastDayOfWeek(toDateTime('2023-04-21 10:20:30')), /* a Friday */
toLastDayOfWeek(toDateTime('2023-04-21 10:20:30'), 1), /* a Friday */
toLastDayOfWeek(toDate('2023-04-22')), /* a Saturday */
toLastDayOfWeek(toDate('2023-04-22'), 1) /* a Saturday */
FORMAT Vertical
```
Result:
```response
Row 1:
──────
toLastDayOfWeek(toDateTime('2023-04-21 10:20:30')): 2023-04-22
toLastDayOfWeek(toDateTime('2023-04-21 10:20:30'), 1): 2023-04-23
toLastDayOfWeek(toDate('2023-04-22')): 2023-04-22
toLastDayOfWeek(toDate('2023-04-22'), 1): 2023-04-23
```
## toStartOfDay
Rounds down a date with time to the start of the day.
**Syntax**
```sql
toStartOfDay(value)
```
**Arguments**
- `value` - a [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The start of the day of the given date/time
Type: `DateTime`
**Example**
```sql
SELECT toStartOfDay(toDateTime('2023-04-21 10:20:30'))
```
Result:
```response
┌─toStartOfDay(toDateTime('2023-04-21 10:20:30'))─┐
│ 2023-04-21 00:00:00 │
└─────────────────────────────────────────────────┘
```
## toStartOfHour
Rounds down a date with time to the start of the hour.
**Syntax**
```sql
toStartOfHour(value)
```
**Arguments**
- `value` - a [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The start of the hour of the given date/time
Type: `DateTime`
**Example**
```sql
SELECT
toStartOfHour(toDateTime('2023-04-21 10:20:30')),
toStartOfHour(toDateTime64('2023-04-21', 6))
```
Result:
```response
┌─toStartOfHour(toDateTime('2023-04-21 10:20:30'))─┬─toStartOfHour(toDateTime64('2023-04-21', 6))─┐
│ 2023-04-21 10:00:00 │ 2023-04-21 00:00:00 │
└──────────────────────────────────────────────────┴──────────────────────────────────────────────┘
```
## toStartOfMinute
Rounds down a date with time to the start of the minute.
**Syntax**
```sql
toStartOfMinute(value)
```
**Arguments**
- `value` - a [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The start of the minute of the given date/time
Type: `DateTime`
**Example**
```sql
SELECT
toStartOfMinute(toDateTime('2023-04-21 10:20:30')),
toStartOfMinute(toDateTime64('2023-04-21 10:20:30.5300', 8))
FORMAT Vertical
```
Result:
```response
Row 1:
──────
toStartOfMinute(toDateTime('2023-04-21 10:20:30')): 2023-04-21 10:20:00
toStartOfMinute(toDateTime64('2023-04-21 10:20:30.5300', 8)): 2023-04-21 10:20:00
```
## toStartOfSecond
Truncates sub-seconds.
@ -630,14 +1263,122 @@ Result:
Rounds down a date with time to the start of the five-minute interval.
**Syntax**
```sql
toStartOfFiveMinutes(value)
```
**Arguments**
- `value` - a [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The start of the five-minute interval of the given date/time
Type: `DateTime`
**Example**
```sql
SELECT
toStartOfFiveMinutes(toDateTime('2023-04-21 10:17:00')),
toStartOfFiveMinutes(toDateTime('2023-04-21 10:20:00')),
toStartOfFiveMinutes(toDateTime('2023-04-21 10:23:00'))
FORMAT Vertical
```
Result:
```response
Row 1:
──────
toStartOfFiveMinutes(toDateTime('2023-04-21 10:17:00')): 2023-04-21 10:15:00
toStartOfFiveMinutes(toDateTime('2023-04-21 10:20:00')): 2023-04-21 10:20:00
toStartOfFiveMinutes(toDateTime('2023-04-21 10:23:00')): 2023-04-21 10:20:00
```
## toStartOfTenMinutes
Rounds down a date with time to the start of the ten-minute interval.
**Syntax**
```sql
toStartOfTenMinutes(value)
```
**Arguments**
- `value` - a [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The start of the ten-minute interval of the given date/time
Type: `DateTime`
**Example**
```sql
SELECT
toStartOfTenMinutes(toDateTime('2023-04-21 10:17:00')),
toStartOfTenMinutes(toDateTime('2023-04-21 10:20:00')),
toStartOfTenMinutes(toDateTime('2023-04-21 10:23:00'))
FORMAT Vertical
```
Result:
```response
Row 1:
──────
toStartOfTenMinutes(toDateTime('2023-04-21 10:17:00')): 2023-04-21 10:10:00
toStartOfTenMinutes(toDateTime('2023-04-21 10:20:00')): 2023-04-21 10:20:00
toStartOfTenMinutes(toDateTime('2023-04-21 10:23:00')): 2023-04-21 10:20:00
```
## toStartOfFifteenMinutes
Rounds down the date with time to the start of the fifteen-minute interval.
**Syntax**
```sql
toStartOfFifteenMinutes(value)
```
**Arguments**
- `value` - a [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md)
**Returned value**
- The start of the fifteen-minute interval of the given date/time
Type: `DateTime`
**Example**
```sql
SELECT
toStartOfFifteenMinutes(toDateTime('2023-04-21 10:17:00')),
toStartOfFifteenMinutes(toDateTime('2023-04-21 10:20:00')),
toStartOfFifteenMinutes(toDateTime('2023-04-21 10:23:00'))
FORMAT Vertical
```
Result:
```response
Row 1:
──────
toStartOfFifteenMinutes(toDateTime('2023-04-21 10:17:00')): 2023-04-21 10:15:00
toStartOfFifteenMinutes(toDateTime('2023-04-21 10:20:00')): 2023-04-21 10:15:00
toStartOfFifteenMinutes(toDateTime('2023-04-21 10:23:00')): 2023-04-21 10:15:00
```
## toStartOfInterval(time_or_data, INTERVAL x unit \[, time_zone\])
This function generalizes other `toStartOf*()` functions. For example,

View File

@ -487,7 +487,7 @@ ClickHouse supports temporary tables which have the following characteristics:
- The DB cant be specified for a temporary table. It is created outside of databases.
- Impossible to create a temporary table with distributed DDL query on all cluster servers (by using `ON CLUSTER`): this table exists only in the current session.
- If a temporary table has the same name as another one and a query specifies the table name without specifying the DB, the temporary table will be used.
- For distributed query processing, temporary tables used in a query are passed to remote servers.
- For distributed query processing, temporary tables with Memory engine used in a query are passed to remote servers.
To create a temporary table, use the following syntax:

View File

@ -20,7 +20,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = ReplacingMergeTree([ver])
) ENGINE = ReplacingMergeTree([ver [, is_deleted]])
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
@ -86,6 +86,59 @@ SELECT * FROM mySecondReplacingMT FINAL;
│ 1 │ first │ 2020-01-01 01:01:01 │
└─────┴─────────┴─────────────────────┘
```
### is_deleted
`is_deleted` — Имя столбца, который используется во время слияния для обозначения того, нужно ли отображать строку или она подлежит удалению; `1` - для удаления строки, `0` - для отображения строки.
Тип данных столбца — `UInt8`.
:::note
`is_deleted` может быть использован, если `ver` используется.
Строка удаляется в следующих случаях:
- при использовании инструкции `OPTIMIZE ... FINAL CLEANUP`
- при использовании инструкции `OPTIMIZE ... FINAL`
- параметр движка `clean_deleted_rows` установлен в значение `Always` (по умолчанию - `Never`)
- есть новые версии строки
Не рекомендуется выполнять `FINAL CLEANUP` или использовать параметр движка `clean_deleted_rows` со значением `Always`, это может привести к неожиданным результатам, например удаленные строки могут вновь появиться.
Вне зависимости от производимых изменений над данными, версия должна увеличиваться. Если у двух строк одна и та же версия, то остается только последняя вставленная строка.
:::
Пример:
```sql
-- with ver and is_deleted
CREATE OR REPLACE TABLE myThirdReplacingMT
(
`key` Int64,
`someCol` String,
`eventTime` DateTime,
`is_deleted` UInt8
)
ENGINE = ReplacingMergeTree(eventTime, is_deleted)
ORDER BY key;
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 01:01:01', 0);
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 01:01:01', 1);
select * from myThirdReplacingMT final;
0 rows in set. Elapsed: 0.003 sec.
-- delete rows with is_deleted
OPTIMIZE TABLE myThirdReplacingMT FINAL CLEANUP;
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 00:00:00', 0);
select * from myThirdReplacingMT final;
┌─key─┬─someCol─┬───────────eventTime─┬─is_deleted─┐
│ 1 │ first │ 2020-01-01 00:00:00 │ 0 │
└─────┴─────────┴─────────────────────┴────────────┘
```
## Секции запроса

View File

@ -1264,6 +1264,15 @@ void Client::processConfig()
global_context->setQueryKindInitial();
global_context->setQuotaClientKey(config().getString("quota_key", ""));
global_context->setQueryKind(query_kind);
if (is_multiquery && !global_context->getSettingsRef().input_format_values_allow_data_after_semicolon.changed)
{
Settings settings = global_context->getSettings();
settings.input_format_values_allow_data_after_semicolon = true;
/// Do not send it to the server
settings.input_format_values_allow_data_after_semicolon.changed = false;
global_context->setSettings(settings);
}
}

View File

@ -269,7 +269,7 @@ ShardPriority getReplicasPriority(const Cluster::Addresses & replicas, const std
res.hostname_difference = std::numeric_limits<size_t>::max();
for (const auto & replica : replicas)
{
size_t difference = getHostNameDifference(local_hostname, replica.host_name);
size_t difference = getHostNamePrefixDistance(local_hostname, replica.host_name);
res.hostname_difference = std::min(difference, res.hostname_difference);
}

View File

@ -783,6 +783,15 @@ void LocalServer::processConfig()
global_context->setQueryKindInitial();
global_context->setQueryKind(query_kind);
if (is_multiquery && !global_context->getSettingsRef().input_format_values_allow_data_after_semicolon.changed)
{
Settings settings = global_context->getSettings();
settings.input_format_values_allow_data_after_semicolon = true;
/// Do not send it to the server
settings.input_format_values_allow_data_after_semicolon.changed = false;
global_context->setSettings(settings);
}
}

View File

@ -9,6 +9,7 @@ profiles:
# random - choose random replica from set of replicas with minimum number of errors
# nearest_hostname - from set of replicas with minimum number of errors, choose replica
# with minimum number of different symbols between replica's hostname and local hostname (Hamming distance).
# hostname_levenshtein_distance - just the same with nearest_hostname but calculate the difference by Levenshtein distance.
# in_order - first live replica is chosen in specified order.
# first_or_random - if first replica one has higher number of errors, pick a random one from replicas with minimum number of errors.
load_balancing: random

View File

@ -1264,7 +1264,8 @@ private:
size_t identifier_bind_size,
const QueryTreeNodePtr & compound_expression,
String compound_expression_source,
IdentifierResolveScope & scope);
IdentifierResolveScope & scope,
bool can_be_not_found = false);
QueryTreeNodePtr tryResolveIdentifierFromExpressionArguments(const IdentifierLookup & identifier_lookup, IdentifierResolveScope & scope);
@ -1313,6 +1314,14 @@ private:
IdentifierResolveScope & scope,
IdentifierResolveSettings identifier_resolve_settings = {});
QueryTreeNodePtr tryResolveIdentifierFromStorage(
const Identifier & identifier,
const QueryTreeNodePtr & table_expression_node,
const TableExpressionData & table_expression_data,
IdentifierResolveScope & scope,
size_t identifier_column_qualifier_parts,
bool can_be_not_found = false);
/// Resolve query tree nodes functions
void qualifyColumnNodesWithProjectionNames(const QueryTreeNodes & column_nodes,
@ -2395,11 +2404,13 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveTableIdentifierFromDatabaseCatalog(con
}
/// Resolve identifier from compound expression
/// If identifier cannot be resolved throw exception or return nullptr if can_be_not_found is true
QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromCompoundExpression(const Identifier & expression_identifier,
size_t identifier_bind_size,
const QueryTreeNodePtr & compound_expression,
String compound_expression_source,
IdentifierResolveScope & scope)
IdentifierResolveScope & scope,
bool can_be_not_found)
{
Identifier compound_expression_identifier;
for (size_t i = 0; i < identifier_bind_size; ++i)
@ -2412,6 +2423,23 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromCompoundExpression(const
if (!expression_type->hasSubcolumn(nested_path.getFullName()))
{
if (auto * column = compound_expression->as<ColumnNode>())
{
const DataTypePtr & column_type = column->getColumn().getTypeInStorage();
if (column_type->getTypeId() == TypeIndex::Object)
{
const auto * object_type = checkAndGetDataType<DataTypeObject>(column_type.get());
if (object_type->getSchemaFormat() == "json" && object_type->hasNullableSubcolumns())
{
QueryTreeNodePtr constant_node_null = std::make_shared<ConstantNode>(Field());
return constant_node_null;
}
}
}
if (can_be_not_found)
return {};
std::unordered_set<Identifier> valid_identifiers;
collectCompoundExpressionValidIdentifiersForTypoCorrection(expression_identifier,
expression_type,
@ -2427,20 +2455,6 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromCompoundExpression(const
compound_expression_from_error_message += compound_expression_source;
}
if (auto * column = compound_expression->as<ColumnNode>())
{
const DataTypePtr & column_type = column->getColumn().getTypeInStorage();
if (column_type->getTypeId() == TypeIndex::Object)
{
const auto * object_type = checkAndGetDataType<DataTypeObject>(column_type.get());
if (object_type->getSchemaFormat() == "json" && object_type->hasNullableSubcolumns())
{
QueryTreeNodePtr constant_node_null = std::make_shared<ConstantNode>(Field());
return constant_node_null;
}
}
}
throw Exception(ErrorCodes::UNKNOWN_IDENTIFIER,
"Identifier {} nested path {} cannot be resolved from type {}{}. In scope {}{}",
expression_identifier,
@ -2796,6 +2810,160 @@ bool QueryAnalyzer::tryBindIdentifierToTableExpressions(const IdentifierLookup &
return can_bind_identifier_to_table_expression;
}
QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromStorage(
const Identifier & identifier,
const QueryTreeNodePtr & table_expression_node,
const TableExpressionData & table_expression_data,
IdentifierResolveScope & scope,
size_t identifier_column_qualifier_parts,
bool can_be_not_found)
{
auto identifier_without_column_qualifier = identifier;
identifier_without_column_qualifier.popFirst(identifier_column_qualifier_parts);
/** Compound identifier cannot be resolved directly from storage if storage is not table.
*
* Example: SELECT test_table.id.value1.value2 FROM test_table;
* In table storage column test_table.id.value1.value2 will exists.
*
* Example: SELECT test_subquery.compound_expression.value FROM (SELECT compound_expression AS value) AS test_subquery;
* Here there is no column with name test_subquery.compound_expression.value, and additional wrap in tuple element is required.
*/
QueryTreeNodePtr result_expression;
bool match_full_identifier = false;
auto it = table_expression_data.column_name_to_column_node.find(identifier_without_column_qualifier.getFullName());
if (it != table_expression_data.column_name_to_column_node.end())
{
match_full_identifier = true;
result_expression = it->second;
}
else
{
it = table_expression_data.column_name_to_column_node.find(identifier_without_column_qualifier.at(0));
if (it != table_expression_data.column_name_to_column_node.end())
result_expression = it->second;
}
bool clone_is_needed = true;
String table_expression_source = table_expression_data.table_expression_description;
if (!table_expression_data.table_expression_name.empty())
table_expression_source += " with name " + table_expression_data.table_expression_name;
if (result_expression && !match_full_identifier && identifier_without_column_qualifier.isCompound())
{
size_t identifier_bind_size = identifier_column_qualifier_parts + 1;
result_expression = tryResolveIdentifierFromCompoundExpression(identifier,
identifier_bind_size,
result_expression,
table_expression_source,
scope,
can_be_not_found);
if (can_be_not_found && !result_expression)
return {};
clone_is_needed = false;
}
if (!result_expression)
{
QueryTreeNodes nested_column_nodes;
DataTypes nested_types;
Array nested_names_array;
for (const auto & [column_name, _] : table_expression_data.column_names_and_types)
{
Identifier column_name_identifier_without_last_part(column_name);
auto column_name_identifier_last_part = column_name_identifier_without_last_part.getParts().back();
column_name_identifier_without_last_part.popLast();
if (identifier_without_column_qualifier.getFullName() != column_name_identifier_without_last_part.getFullName())
continue;
auto column_node_it = table_expression_data.column_name_to_column_node.find(column_name);
if (column_node_it == table_expression_data.column_name_to_column_node.end())
continue;
const auto & column_node = column_node_it->second;
const auto & column_type = column_node->getColumnType();
const auto * column_type_array = typeid_cast<const DataTypeArray *>(column_type.get());
if (!column_type_array)
continue;
nested_column_nodes.push_back(column_node);
nested_types.push_back(column_type_array->getNestedType());
nested_names_array.push_back(Field(std::move(column_name_identifier_last_part)));
}
if (!nested_types.empty())
{
auto nested_function_node = std::make_shared<FunctionNode>("nested");
auto & nested_function_node_arguments = nested_function_node->getArguments().getNodes();
auto nested_function_names_array_type = std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>());
auto nested_function_names_constant_node = std::make_shared<ConstantNode>(std::move(nested_names_array),
std::move(nested_function_names_array_type));
nested_function_node_arguments.push_back(std::move(nested_function_names_constant_node));
nested_function_node_arguments.insert(nested_function_node_arguments.end(),
nested_column_nodes.begin(),
nested_column_nodes.end());
auto nested_function = FunctionFactory::instance().get(nested_function_node->getFunctionName(), scope.context);
nested_function_node->resolveAsFunction(nested_function->build(nested_function_node->getArgumentColumns()));
clone_is_needed = false;
result_expression = std::move(nested_function_node);
}
}
if (!result_expression)
{
std::unordered_set<Identifier> valid_identifiers;
collectTableExpressionValidIdentifiersForTypoCorrection(identifier,
table_expression_node,
table_expression_data,
valid_identifiers);
auto hints = collectIdentifierTypoHints(identifier, valid_identifiers);
throw Exception(ErrorCodes::UNKNOWN_IDENTIFIER, "Identifier '{}' cannot be resolved from {}. In scope {}{}",
identifier.getFullName(),
table_expression_source,
scope.scope_node->formatASTForErrorMessage(),
getHintsErrorMessageSuffix(hints));
}
if (clone_is_needed)
result_expression = result_expression->clone();
auto qualified_identifier = identifier;
for (size_t i = 0; i < identifier_column_qualifier_parts; ++i)
{
auto qualified_identifier_with_removed_part = qualified_identifier;
qualified_identifier_with_removed_part.popFirst();
if (qualified_identifier_with_removed_part.empty())
break;
IdentifierLookup column_identifier_lookup = {qualified_identifier_with_removed_part, IdentifierLookupContext::EXPRESSION};
if (tryBindIdentifierToAliases(column_identifier_lookup, scope))
break;
if (table_expression_data.should_qualify_columns &&
tryBindIdentifierToTableExpressions(column_identifier_lookup, table_expression_node, scope))
break;
qualified_identifier = std::move(qualified_identifier_with_removed_part);
}
auto qualified_identifier_full_name = qualified_identifier.getFullName();
node_to_projection_name.emplace(result_expression, std::move(qualified_identifier_full_name));
return result_expression;
}
QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromTableExpression(const IdentifierLookup & identifier_lookup,
const QueryTreeNodePtr & table_expression_node,
IdentifierResolveScope & scope)
@ -2836,151 +3004,6 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromTableExpression(const Id
return {};
}
auto resolve_identifier_from_storage_or_throw = [&](size_t identifier_column_qualifier_parts) -> QueryTreeNodePtr
{
auto identifier_without_column_qualifier = identifier;
identifier_without_column_qualifier.popFirst(identifier_column_qualifier_parts);
/** Compound identifier cannot be resolved directly from storage if storage is not table.
*
* Example: SELECT test_table.id.value1.value2 FROM test_table;
* In table storage column test_table.id.value1.value2 will exists.
*
* Example: SELECT test_subquery.compound_expression.value FROM (SELECT compound_expression AS value) AS test_subquery;
* Here there is no column with name test_subquery.compound_expression.value, and additional wrap in tuple element is required.
*/
QueryTreeNodePtr result_expression;
bool match_full_identifier = false;
auto it = table_expression_data.column_name_to_column_node.find(identifier_without_column_qualifier.getFullName());
if (it != table_expression_data.column_name_to_column_node.end())
{
match_full_identifier = true;
result_expression = it->second;
}
else
{
it = table_expression_data.column_name_to_column_node.find(identifier_without_column_qualifier.at(0));
if (it != table_expression_data.column_name_to_column_node.end())
result_expression = it->second;
}
bool clone_is_needed = true;
String table_expression_source = table_expression_data.table_expression_description;
if (!table_expression_data.table_expression_name.empty())
table_expression_source += " with name " + table_expression_data.table_expression_name;
if (result_expression && !match_full_identifier && identifier_without_column_qualifier.isCompound())
{
size_t identifier_bind_size = identifier_column_qualifier_parts + 1;
result_expression = tryResolveIdentifierFromCompoundExpression(identifier_lookup.identifier,
identifier_bind_size,
result_expression,
table_expression_source,
scope);
clone_is_needed = false;
}
if (!result_expression)
{
QueryTreeNodes nested_column_nodes;
DataTypes nested_types;
Array nested_names_array;
for (auto & [column_name, _] : table_expression_data.column_names_and_types)
{
Identifier column_name_identifier_without_last_part(column_name);
auto column_name_identifier_last_part = column_name_identifier_without_last_part.getParts().back();
column_name_identifier_without_last_part.popLast();
if (identifier_without_column_qualifier.getFullName() != column_name_identifier_without_last_part.getFullName())
continue;
auto column_node_it = table_expression_data.column_name_to_column_node.find(column_name);
if (column_node_it == table_expression_data.column_name_to_column_node.end())
continue;
const auto & column_node = column_node_it->second;
const auto & column_type = column_node->getColumnType();
const auto * column_type_array = typeid_cast<const DataTypeArray *>(column_type.get());
if (!column_type_array)
continue;
nested_column_nodes.push_back(column_node);
nested_types.push_back(column_type_array->getNestedType());
nested_names_array.push_back(Field(std::move(column_name_identifier_last_part)));
}
if (!nested_types.empty())
{
auto nested_function_node = std::make_shared<FunctionNode>("nested");
auto & nested_function_node_arguments = nested_function_node->getArguments().getNodes();
auto nested_function_names_array_type = std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>());
auto nested_function_names_constant_node = std::make_shared<ConstantNode>(std::move(nested_names_array),
std::move(nested_function_names_array_type));
nested_function_node_arguments.push_back(std::move(nested_function_names_constant_node));
nested_function_node_arguments.insert(nested_function_node_arguments.end(),
nested_column_nodes.begin(),
nested_column_nodes.end());
auto nested_function = FunctionFactory::instance().get(nested_function_node->getFunctionName(), scope.context);
nested_function_node->resolveAsFunction(nested_function->build(nested_function_node->getArgumentColumns()));
clone_is_needed = false;
result_expression = std::move(nested_function_node);
}
}
if (!result_expression)
{
std::unordered_set<Identifier> valid_identifiers;
collectTableExpressionValidIdentifiersForTypoCorrection(identifier,
table_expression_node,
table_expression_data,
valid_identifiers);
auto hints = collectIdentifierTypoHints(identifier, valid_identifiers);
throw Exception(ErrorCodes::UNKNOWN_IDENTIFIER, "Identifier '{}' cannot be resolved from {}. In scope {}{}",
identifier.getFullName(),
table_expression_source,
scope.scope_node->formatASTForErrorMessage(),
getHintsErrorMessageSuffix(hints));
}
if (clone_is_needed)
result_expression = result_expression->clone();
auto qualified_identifier = identifier;
for (size_t i = 0; i < identifier_column_qualifier_parts; ++i)
{
auto qualified_identifier_with_removed_part = qualified_identifier;
qualified_identifier_with_removed_part.popFirst();
if (qualified_identifier_with_removed_part.empty())
break;
IdentifierLookup column_identifier_lookup = {qualified_identifier_with_removed_part, IdentifierLookupContext::EXPRESSION};
if (tryBindIdentifierToAliases(column_identifier_lookup, scope))
break;
if (table_expression_data.should_qualify_columns &&
tryBindIdentifierToTableExpressions(column_identifier_lookup, table_expression_node, scope))
break;
qualified_identifier = std::move(qualified_identifier_with_removed_part);
}
auto qualified_identifier_full_name = qualified_identifier.getFullName();
node_to_projection_name.emplace(result_expression, std::move(qualified_identifier_full_name));
return result_expression;
};
/** If identifier first part binds to some column start or table has full identifier name. Then we can try to find whole identifier in table.
* 1. Try to bind identifier first part to column in table, if true get full identifier from table or throw exception.
* 2. Try to bind identifier first part to table name or storage alias, if true remove first part and try to get full identifier from table or throw exception.
@ -2988,24 +3011,35 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromTableExpression(const Id
* 3. Try to bind identifier first parts to database name and table name, if true remove first two parts and try to get full identifier from table or throw exception.
*/
if (table_expression_data.hasFullIdentifierName(IdentifierView(identifier)))
return resolve_identifier_from_storage_or_throw(0 /*identifier_column_qualifier_parts*/);
return tryResolveIdentifierFromStorage(identifier, table_expression_node, table_expression_data, scope, 0 /*identifier_column_qualifier_parts*/);
if (table_expression_data.canBindIdentifier(IdentifierView(identifier)))
return resolve_identifier_from_storage_or_throw(0 /*identifier_column_qualifier_parts*/);
{
/** This check is insufficient to determine whether and identifier can be resolved from table expression.
* A further check will be performed in `tryResolveIdentifierFromStorage` to see if we have such a subcolumn.
* In cases where the subcolumn cannot be found we want to have `nullptr` instead of exception.
* So, we set `can_be_not_found = true` to have an attempt to resolve the identifier from another table expression.
* Example: `SELECT t.t from (SELECT 1 as t) AS a FULL JOIN (SELECT 1 as t) as t ON a.t = t.t;`
* Initially, we will try to resolve t.t from `a` because `t.` is bound to `1 as t`. However, as it is not a nested column, we will need to resolve it from the second table expression.
*/
auto resolved_identifier = tryResolveIdentifierFromStorage(identifier, table_expression_node, table_expression_data, scope, 0 /*identifier_column_qualifier_parts*/, true /*can_be_not_found*/);
if (resolved_identifier)
return resolved_identifier;
}
if (identifier.getPartsSize() == 1)
return {};
const auto & table_name = table_expression_data.table_name;
if ((!table_name.empty() && path_start == table_name) || (table_expression_node->hasAlias() && path_start == table_expression_node->getAlias()))
return resolve_identifier_from_storage_or_throw(1 /*identifier_column_qualifier_parts*/);
return tryResolveIdentifierFromStorage(identifier, table_expression_node, table_expression_data, scope, 1 /*identifier_column_qualifier_parts*/);
if (identifier.getPartsSize() == 2)
return {};
const auto & database_name = table_expression_data.database_name;
if (!database_name.empty() && path_start == database_name && identifier[1] == table_name)
return resolve_identifier_from_storage_or_throw(2 /*identifier_column_qualifier_parts*/);
return tryResolveIdentifierFromStorage(identifier, table_expression_node, table_expression_data, scope, 2 /*identifier_column_qualifier_parts*/);
return {};
}

View File

@ -594,7 +594,7 @@ if (ENABLE_TESTS)
target_link_libraries(unit_tests_dbms PRIVATE
ch_contrib::gmock_all
ch_contrib::gtest_all
ch_contrib::gtest
clickhouse_functions
clickhouse_aggregate_functions
clickhouse_parsers

View File

@ -15,7 +15,6 @@
#include <Common/scope_guard_safe.h>
#include <Common/Exception.h>
#include <Common/getNumberOfPhysicalCPUCores.h>
#include <Common/tests/gtest_global_context.h>
#include <Common/typeid_cast.h>
#include <Common/UTF8Helpers.h>
#include <Common/TerminalSize.h>
@ -2020,9 +2019,6 @@ bool ClientBase::executeMultiQuery(const String & all_queries_text)
{
bool echo_query = echo_queries;
/// Test tags are started with "--" so they are interpreted as comments anyway.
/// But if the echo is enabled we have to remove the test tags from `all_queries_text`
/// because we don't want test tags to be echoed.
{
/// disable logs if expects errors
TestHint test_hint(all_queries_text);
@ -2030,6 +2026,9 @@ bool ClientBase::executeMultiQuery(const String & all_queries_text)
processTextAsSingleQuery("SET send_logs_level = 'fatal'");
}
/// Test tags are started with "--" so they are interpreted as comments anyway.
/// But if the echo is enabled we have to remove the test tags from `all_queries_text`
/// because we don't want test tags to be echoed.
size_t test_tags_length = getTestTagsLength(all_queries_text);
/// Several queries separated by ';'.

View File

@ -34,11 +34,13 @@ ConnectionPoolWithFailover::ConnectionPoolWithFailover(
{
const std::string & local_hostname = getFQDNOrHostName();
get_priority_load_balancing.hostname_differences.resize(nested_pools.size());
get_priority_load_balancing.hostname_prefix_distance.resize(nested_pools.size());
get_priority_load_balancing.hostname_levenshtein_distance.resize(nested_pools.size());
for (size_t i = 0; i < nested_pools.size(); ++i)
{
ConnectionPool & connection_pool = dynamic_cast<ConnectionPool &>(*nested_pools[i]);
get_priority_load_balancing.hostname_differences[i] = getHostNameDifference(local_hostname, connection_pool.getHost());
get_priority_load_balancing.hostname_prefix_distance[i] = getHostNamePrefixDistance(local_hostname, connection_pool.getHost());
get_priority_load_balancing.hostname_levenshtein_distance[i] = getHostNameLevenshteinDistance(local_hostname, connection_pool.getHost());
}
}

View File

@ -15,9 +15,14 @@ std::function<Priority(size_t index)> GetPriorityForLoadBalancing::getPriorityFu
switch (load_balance)
{
case LoadBalancing::NEAREST_HOSTNAME:
if (hostname_differences.empty())
throw Exception(ErrorCodes::LOGICAL_ERROR, "It's a bug: hostname_differences is not initialized");
get_priority = [this](size_t i) { return Priority{static_cast<Int64>(hostname_differences[i])}; };
if (hostname_prefix_distance.empty())
throw Exception(ErrorCodes::LOGICAL_ERROR, "It's a bug: hostname_prefix_distance is not initialized");
get_priority = [this](size_t i) { return Priority{static_cast<Int64>(hostname_prefix_distance[i])}; };
break;
case LoadBalancing::HOSTNAME_LEVENSHTEIN_DISTANCE:
if (hostname_levenshtein_distance.empty())
throw Exception(ErrorCodes::LOGICAL_ERROR, "It's a bug: hostname_levenshtein_distance is not initialized");
get_priority = [this](size_t i) { return Priority{static_cast<Int64>(hostname_levenshtein_distance[i])}; };
break;
case LoadBalancing::IN_ORDER:
get_priority = [](size_t i) { return Priority{static_cast<Int64>(i)}; };

View File

@ -13,7 +13,9 @@ public:
bool operator == (const GetPriorityForLoadBalancing & other) const
{
return load_balancing == other.load_balancing && hostname_differences == other.hostname_differences;
return load_balancing == other.load_balancing
&& hostname_prefix_distance == other.hostname_prefix_distance
&& hostname_levenshtein_distance == other.hostname_levenshtein_distance;
}
bool operator != (const GetPriorityForLoadBalancing & other) const
@ -23,7 +25,8 @@ public:
std::function<Priority(size_t index)> getPriorityFunc(LoadBalancing load_balance, size_t offset, size_t pool_size) const;
std::vector<size_t> hostname_differences; /// Distances from name of this host to the names of hosts of pools.
std::vector<size_t> hostname_prefix_distance; /// Prefix distances from name of this host to the names of hosts of pools.
std::vector<size_t> hostname_levenshtein_distance; /// Levenshtein Distances from name of this host to the names of hosts of pools.
LoadBalancing load_balancing = LoadBalancing::RANDOM;

View File

@ -1274,6 +1274,10 @@ public:
return !buf[place_value].isZero(*this);
}
bool ALWAYS_INLINE contains(const Key & x) const
{
return has(x);
}
void write(DB::WriteBuffer & wb) const
{

View File

@ -2,6 +2,7 @@
#include <base/types.h>
#include <Common/PODArray.h>
#include <Common/levenshteinDistance.h>
#include <algorithm>
#include <cctype>
@ -29,31 +30,6 @@ public:
}
private:
static size_t levenshteinDistance(const String & lhs, const String & rhs)
{
size_t m = lhs.size();
size_t n = rhs.size();
PODArrayWithStackMemory<size_t, 64> row(n + 1);
for (size_t i = 1; i <= n; ++i)
row[i] = i;
for (size_t j = 1; j <= m; ++j)
{
row[0] = j;
size_t prev = j - 1;
for (size_t i = 1; i <= n; ++i)
{
size_t old = row[i];
row[i] = std::min(prev + (std::tolower(lhs[j - 1]) != std::tolower(rhs[i - 1])),
std::min(row[i - 1], row[i]) + 1);
prev = old;
}
}
return row[n];
}
static void appendToQueue(size_t ind, const String & name, DistanceIndexQueue & queue, const std::vector<String> & prompting_strings)
{
const String & prompt = prompting_strings[ind];

View File

@ -39,12 +39,14 @@ ZooKeeperArgs::ZooKeeperArgs(const Poco::Util::AbstractConfiguration & config, c
throw KeeperException::fromMessage(Coordination::Error::ZBADARGUMENTS, "Timeout cannot be negative");
/// init get_priority_load_balancing
get_priority_load_balancing.hostname_differences.resize(hosts.size());
get_priority_load_balancing.hostname_prefix_distance.resize(hosts.size());
get_priority_load_balancing.hostname_levenshtein_distance.resize(hosts.size());
const String & local_hostname = getFQDNOrHostName();
for (size_t i = 0; i < hosts.size(); ++i)
{
const String & node_host = hosts[i].substr(0, hosts[i].find_last_of(':'));
get_priority_load_balancing.hostname_differences[i] = DB::getHostNameDifference(local_hostname, node_host);
get_priority_load_balancing.hostname_prefix_distance[i] = DB::getHostNamePrefixDistance(local_hostname, node_host);
get_priority_load_balancing.hostname_levenshtein_distance[i] = DB::getHostNameLevenshteinDistance(local_hostname, node_host);
}
}

View File

@ -5,6 +5,7 @@
#include <optional>
#include <base/types.h>
#include <Common/Exception.h>
#include <Common/levenshteinDistance.h>
#include <Poco/Net/IPAddress.h>
#include <Poco/Net/SocketAddress.h>
@ -121,10 +122,8 @@ bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_
return clickhouse_port == address.port() && isLocalAddress(address.host());
}
size_t getHostNameDifference(const std::string & local_hostname, const std::string & host)
size_t getHostNamePrefixDistance(const std::string & local_hostname, const std::string & host)
{
/// FIXME should we replace it with Levenstein distance? (we already have it in NamePrompter)
size_t hostname_difference = 0;
for (size_t i = 0; i < std::min(local_hostname.length(), host.length()); ++i)
if (local_hostname[i] != host[i])
@ -132,4 +131,9 @@ size_t getHostNameDifference(const std::string & local_hostname, const std::stri
return hostname_difference;
}
size_t getHostNameLevenshteinDistance(const std::string & local_hostname, const std::string & host)
{
return levenshteinDistance(local_hostname, host);
}
}

View File

@ -26,6 +26,8 @@ namespace DB
bool isLocalAddress(const Poco::Net::SocketAddress & address);
bool isLocalAddress(const Poco::Net::IPAddress & address);
/// Returns number of different bytes in hostnames, used for load balancing
size_t getHostNameDifference(const std::string & local_hostname, const std::string & host);
/// Returns host name difference with name prefix, used for load balancing
size_t getHostNamePrefixDistance(const std::string & local_hostname, const std::string & host);
/// Returns host name difference with Levenshtein Distance.
size_t getHostNameLevenshteinDistance(const std::string & local_hostname, const std::string & host);
}

View File

@ -0,0 +1,32 @@
#include <Common/levenshteinDistance.h>
#include <Common/PODArray.h>
namespace DB
{
size_t levenshteinDistance(const String & lhs, const String & rhs)
{
size_t m = lhs.size();
size_t n = rhs.size();
PODArrayWithStackMemory<size_t, 64> row(n + 1);
for (size_t i = 1; i <= n; ++i)
row[i] = i;
for (size_t j = 1; j <= m; ++j)
{
row[0] = j;
size_t prev = j - 1;
for (size_t i = 1; i <= n; ++i)
{
size_t old = row[i];
row[i] = std::min(prev + (std::tolower(lhs[j - 1]) != std::tolower(rhs[i - 1])),
std::min(row[i - 1], row[i]) + 1);
prev = old;
}
}
return row[n];
}
}

View File

@ -0,0 +1,12 @@
#pragma once
#include <base/types.h>
namespace DB
{
/// How many steps if we want to change lhs to rhs.
/// Details in https://en.wikipedia.org/wiki/Levenshtein_distance
size_t levenshteinDistance(const String & lhs, const String & rhs);
}

View File

@ -9,7 +9,6 @@ TEST(EventNotifier, SimpleTest)
using namespace DB;
size_t result = 1;
EventNotifier::init();
auto handler3 = EventNotifier::instance().subscribe(Coordination::Error::ZSESSIONEXPIRED, [&result](){ result *= 3; });

View File

@ -0,0 +1,18 @@
#include <gtest/gtest.h>
#include <Common/tests/gtest_global_context.h>
class ContextEnvironment : public testing::Environment
{
public:
void SetUp() override { getContext(); }
};
int main(int argc, char ** argv)
{
testing::InitGoogleTest(&argc, argv);
testing::AddGlobalTestEnvironment(new ContextEnvironment);
return RUN_ALL_TESTS();
}

View File

@ -71,6 +71,13 @@ protected:
DB::KeeperContextPtr keeper_context = std::make_shared<DB::KeeperContext>(true);
Poco::Logger * log{&Poco::Logger::get("CoordinationTest")};
void SetUp() override
{
Poco::AutoPtr<Poco::ConsoleChannel> channel(new Poco::ConsoleChannel(std::cerr));
Poco::Logger::root().setChannel(channel);
Poco::Logger::root().setLevel("trace");
}
void setLogDirectory(const std::string & path) { keeper_context->setLogDisk(std::make_shared<DB::DiskLocal>("LogDisk", path)); }
void setSnapshotDirectory(const std::string & path)
@ -2911,13 +2918,4 @@ INSTANTIATE_TEST_SUITE_P(CoordinationTestSuite,
CoordinationTest,
::testing::ValuesIn(std::initializer_list<CompressionParam>{CompressionParam{true, ".zstd"}, CompressionParam{false, ""}}));
int main(int argc, char ** argv)
{
Poco::AutoPtr<Poco::ConsoleChannel> channel(new Poco::ConsoleChannel(std::cerr));
Poco::Logger::root().setChannel(channel);
Poco::Logger::root().setLevel("trace");
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#endif

View File

@ -627,7 +627,7 @@ class IColumn;
\
M(Bool, optimize_rewrite_sum_if_to_count_if, false, "Rewrite sumIf() and sum(if()) function countIf() function when logically equivalent", 0) \
M(Bool, optimize_rewrite_aggregate_function_with_if, true, "Rewrite aggregate functions with if expression as argument when logically equivalent. For example, avg(if(cond, col, null)) can be rewritten to avgIf(cond, col)", 0) \
M(Bool, optimize_rewrite_array_exists_to_has, true, "Rewrite arrayExists() functions to has() when logically equivalent. For example, arrayExists(x -> x = 1, arr) can be rewritten to has(arr, 1)", 0) \
M(Bool, optimize_rewrite_array_exists_to_has, false, "Rewrite arrayExists() functions to has() when logically equivalent. For example, arrayExists(x -> x = 1, arr) can be rewritten to has(arr, 1)", 0) \
M(UInt64, insert_shard_id, 0, "If non zero, when insert into a distributed table, the data will be inserted into the shard `insert_shard_id` synchronously. Possible values range from 1 to `shards_number` of corresponding distributed table", 0) \
\
M(Bool, collect_hash_table_stats_during_aggregation, true, "Enable collecting hash table statistics to optimize memory allocation", 0) \
@ -963,6 +963,7 @@ class IColumn;
M(Bool, input_format_values_interpret_expressions, true, "For Values format: if the field could not be parsed by streaming parser, run SQL parser and try to interpret it as SQL expression.", 0) \
M(Bool, input_format_values_deduce_templates_of_expressions, true, "For Values format: if the field could not be parsed by streaming parser, run SQL parser, deduce template of the SQL expression, try to parse all rows using template and then interpret expression for all rows.", 0) \
M(Bool, input_format_values_accurate_types_of_literals, true, "For Values format: when parsing and interpreting expressions using template, check actual type of literal to avoid possible overflow and precision issues.", 0) \
M(Bool, input_format_values_allow_data_after_semicolon, false, "For Values format: allow extra data after semicolon (used by client to interpret comments).", 0) \
M(Bool, input_format_avro_allow_missing_fields, false, "For Avro/AvroConfluent format: when field is not found in schema use default value instead of error", 0) \
/** This setting is obsolete and do nothing, left for compatibility reasons. */ \
M(Bool, input_format_avro_null_as_default, false, "For Avro/AvroConfluent format: insert default in case of null and non Nullable column", 0) \

View File

@ -20,6 +20,7 @@ namespace ErrorCodes
IMPLEMENT_SETTING_ENUM(LoadBalancing, ErrorCodes::UNKNOWN_LOAD_BALANCING,
{{"random", LoadBalancing::RANDOM},
{"nearest_hostname", LoadBalancing::NEAREST_HOSTNAME},
{"hostname_levenshtein_distance", LoadBalancing::HOSTNAME_LEVENSHTEIN_DISTANCE},
{"in_order", LoadBalancing::IN_ORDER},
{"first_or_random", LoadBalancing::FIRST_OR_RANDOM},
{"round_robin", LoadBalancing::ROUND_ROBIN}})

View File

@ -16,8 +16,10 @@ enum class LoadBalancing
/// among replicas with a minimum number of errors selected randomly
RANDOM = 0,
/// a replica is selected among the replicas with the minimum number of errors
/// with the minimum number of distinguished characters in the replica name and local hostname
/// with the minimum number of distinguished characters in the replica name prefix and local hostname prefix
NEAREST_HOSTNAME,
/// just like NEAREST_HOSTNAME, but it count distinguished characters in a levenshtein distance manner
HOSTNAME_LEVENSHTEIN_DISTANCE,
// replicas with the same number of errors are accessed in the same order
// as they are specified in the configuration.
IN_ORDER,

View File

@ -170,6 +170,7 @@ FormatSettings getFormatSettings(ContextPtr context, const Settings & settings)
format_settings.tsv.skip_trailing_empty_lines = settings.input_format_tsv_skip_trailing_empty_lines;
format_settings.tsv.allow_variable_number_of_columns = settings.input_format_tsv_allow_variable_number_of_columns;
format_settings.values.accurate_types_of_literals = settings.input_format_values_accurate_types_of_literals;
format_settings.values.allow_data_after_semicolon = settings.input_format_values_allow_data_after_semicolon;
format_settings.values.deduce_templates_of_expressions = settings.input_format_values_deduce_templates_of_expressions;
format_settings.values.interpret_expressions = settings.input_format_values_interpret_expressions;
format_settings.with_names_use_header = settings.input_format_with_names_use_header;

View File

@ -341,6 +341,7 @@ struct FormatSettings
bool interpret_expressions = true;
bool deduce_templates_of_expressions = true;
bool accurate_types_of_literals = true;
bool allow_data_after_semicolon = false;
} values;
enum class ORCCompression

106
src/Functions/byteSwap.cpp Normal file
View File

@ -0,0 +1,106 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionUnaryArithmetic.h>
namespace DB
{
namespace ErrorCodes
{
extern const int NOT_IMPLEMENTED;
}
namespace
{
template <typename T>
requires std::is_integral_v<T>
T byteSwap(T x)
{
return std::byteswap(x);
}
template <typename T>
requires std::is_same_v<T, UInt128> || std::is_same_v<T, Int128> || std::is_same_v<T, UInt256> || std::is_same_v<T, Int256>
T byteSwap(T x)
{
T dest;
reverseMemcpy(&dest, &x, sizeof(T));
return dest;
}
template <typename T>
T byteSwap(T)
{
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "byteSwap() is not implemented for {} datatype", demangle(typeid(T).name()));
}
template <typename T>
struct ByteSwapImpl
{
using ResultType = T;
static constexpr const bool allow_string_or_fixed_string = false;
static T apply(T x) { return byteSwap<T>(x); }
#if USE_EMBEDDED_COMPILER
static constexpr bool compilable = false;
#endif
};
struct NameByteSwap
{
static constexpr auto name = "byteSwap";
};
using FunctionByteSwap = FunctionUnaryArithmetic<ByteSwapImpl, NameByteSwap, true>;
}
template <>
struct FunctionUnaryArithmeticMonotonicity<NameByteSwap>
{
static bool has() { return false; }
static IFunction::Monotonicity get(const Field &, const Field &) { return {}; }
};
REGISTER_FUNCTION(ByteSwap)
{
factory.registerFunction<FunctionByteSwap>(
FunctionDocumentation{
.description = R"(
Reverses the bytes of an integer, i.e. changes its [endianness](https://en.wikipedia.org/wiki/Endianness).
**Example**
```sql
byteSwap(3351772109)
```
Result:
```result
byteSwap(3351772109)
3455829959
```
The above example can be worked out in the following manner:
1. Convert the base-10 integer to its equivalent hexadecimal format in big-endian format, i.e. 3351772109 -> C7 C7 FB CD (4 bytes)
2. Reverse the bytes, i.e. C7 C7 FB CD -> CD FB C7 C7
3. Convert the result back to an integer assuming big-endian, i.e. CD FB C7 C7 -> 3455829959
One use-case of this function is reversing IPv4s:
```result
toIPv4(byteSwap(toUInt32(toIPv4('205.251.199.199'))))
199.199.251.205
```
)",
.examples{
{"8-bit", "SELECT byteSwap(54)", "54"},
{"16-bit", "SELECT byteSwap(4135)", "10000"},
{"32-bit", "SELECT byteSwap(3351772109)", "3455829959"},
{"64-bit", "SELECT byteSwap(123294967295)", "18439412204227788800"},
},
.categories{"Mathematical", "Arithmetic"}},
FunctionFactory::CaseInsensitive);
}
}

View File

@ -44,7 +44,11 @@ LZMADeflatingWriteBuffer::LZMADeflatingWriteBuffer(
LZMA_VERSION_STRING);
}
LZMADeflatingWriteBuffer::~LZMADeflatingWriteBuffer() = default;
LZMADeflatingWriteBuffer::~LZMADeflatingWriteBuffer()
{
/// It is OK to call deflateEnd() twice (one from the finalizeAfter())
lzma_end(&lstr);
}
void LZMADeflatingWriteBuffer::nextImpl()
{

View File

@ -40,7 +40,11 @@ Lz4DeflatingWriteBuffer::Lz4DeflatingWriteBuffer(
LZ4F_VERSION);
}
Lz4DeflatingWriteBuffer::~Lz4DeflatingWriteBuffer() = default;
Lz4DeflatingWriteBuffer::~Lz4DeflatingWriteBuffer()
{
if (ctx)
LZ4F_freeCompressionContext(ctx);
}
void Lz4DeflatingWriteBuffer::nextImpl()
{
@ -156,6 +160,7 @@ void Lz4DeflatingWriteBuffer::finalizeBefore()
void Lz4DeflatingWriteBuffer::finalizeAfter()
{
LZ4F_freeCompressionContext(ctx);
ctx = nullptr;
}
}

View File

@ -72,7 +72,11 @@ void ZlibDeflatingWriteBuffer::nextImpl()
}
}
ZlibDeflatingWriteBuffer::~ZlibDeflatingWriteBuffer() = default;
ZlibDeflatingWriteBuffer::~ZlibDeflatingWriteBuffer()
{
/// It is OK to call deflateEnd() twice (one from the finalizeAfter() that does the proper error checking)
deflateEnd(&zstr);
}
void ZlibDeflatingWriteBuffer::finalizeBefore()
{

View File

@ -30,7 +30,11 @@ ZstdDeflatingWriteBuffer::ZstdDeflatingWriteBuffer(
output = {nullptr, 0, 0};
}
ZstdDeflatingWriteBuffer::~ZstdDeflatingWriteBuffer() = default;
ZstdDeflatingWriteBuffer::~ZstdDeflatingWriteBuffer()
{
if (cctx)
ZSTD_freeCCtx(cctx);
}
void ZstdDeflatingWriteBuffer::flush(ZSTD_EndDirective mode)
{
@ -88,6 +92,7 @@ void ZstdDeflatingWriteBuffer::finalizeAfter()
try
{
size_t err = ZSTD_freeCCtx(cctx);
cctx = nullptr;
/// This is just in case, since it is impossible to get an error by using this wrapper.
if (unlikely(err))
throw Exception(ErrorCodes::ZSTD_ENCODER_FAILED, "ZSTD_freeCCtx failed: error: '{}'; zstd version: {}",

View File

@ -167,6 +167,9 @@ ZooKeeperPtr DDLWorker::getAndSetZooKeeper()
DDLTaskPtr DDLWorker::initAndCheckTask(const String & entry_name, String & out_reason, const ZooKeeperPtr & zookeeper)
{
if (entries_to_skip.contains(entry_name))
return {};
String node_data;
String entry_path = fs::path(queue_dir) / entry_name;
@ -186,6 +189,12 @@ DDLTaskPtr DDLWorker::initAndCheckTask(const String & entry_name, String & out_r
zookeeper->tryCreate(fs::path(entry_path) / "finished" / host_id, status.serializeText(), zkutil::CreateMode::Persistent);
};
auto add_to_skip_set = [&]()
{
entries_to_skip.insert(entry_name);
return nullptr;
};
try
{
/// Stage 1: parse entry
@ -198,7 +207,7 @@ DDLTaskPtr DDLWorker::initAndCheckTask(const String & entry_name, String & out_r
/// Otherwise, that node will be ignored by DDLQueryStatusSource.
out_reason = "Incorrect task format";
write_error_status(host_fqdn_id, ExecutionStatus::fromCurrentException(), out_reason);
return {};
return add_to_skip_set();
}
/// Stage 2: resolve host_id and check if we should execute query or not
@ -207,7 +216,7 @@ DDLTaskPtr DDLWorker::initAndCheckTask(const String & entry_name, String & out_r
if (!task->findCurrentHostID(context, log))
{
out_reason = "There is no a local address in host list";
return {};
return add_to_skip_set();
}
try
@ -223,13 +232,13 @@ DDLTaskPtr DDLWorker::initAndCheckTask(const String & entry_name, String & out_r
{
out_reason = "Cannot parse query or obtain cluster info";
write_error_status(task->host_id_str, ExecutionStatus::fromCurrentException(), out_reason);
return {};
return add_to_skip_set();
}
if (zookeeper->exists(task->getFinishedNodePath()))
{
out_reason = TASK_PROCESSED_OUT_REASON;
return {};
return add_to_skip_set();
}
/// Now task is ready for execution
@ -955,6 +964,7 @@ void DDLWorker::cleanupQueue(Int64, const ZooKeeperPtr & zookeeper)
continue;
}
zkutil::KeeperMultiException::check(rm_entry_res, ops, res);
entries_to_skip.remove(node_name);
}
catch (...)
{

View File

@ -13,7 +13,9 @@
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <unordered_set>
namespace zkutil
{
@ -79,6 +81,33 @@ public:
ZooKeeperPtr getAndSetZooKeeper();
protected:
class ConcurrentSet
{
public:
bool contains(const String & key) const
{
std::shared_lock lock(mtx);
return set.contains(key);
}
bool insert(const String & key)
{
std::unique_lock lock(mtx);
return set.emplace(key).second;
}
bool remove(const String & key)
{
std::unique_lock lock(mtx);
return set.erase(key);
}
private:
std::unordered_set<String> set;
mutable std::shared_mutex mtx;
};
/// Iterates through queue tasks in ZooKeeper, runs execution of new tasks
void scheduleTasks(bool reinitialized);
@ -160,6 +189,9 @@ protected:
size_t max_tasks_in_queue = 1000;
std::atomic<UInt32> max_id = 0;
ConcurrentSet entries_to_skip;
const CurrentMetrics::Metric * max_entry_metric;
const CurrentMetrics::Metric * max_pushed_entry_metric;
};

View File

@ -4,7 +4,6 @@
#include <Interpreters/DatabaseAndTableWithAlias.h>
#include <Interpreters/InDepthNodeVisitor.h>
#include <Interpreters/QueryAliasesVisitor.h>
#include <Interpreters/getHeaderForProcessingStage.h>
#include <Interpreters/getTableExpressions.h>
namespace DB

View File

@ -1,3 +1,5 @@
#include <Analyzer/QueryNode.h>
#include <Analyzer/Utils.h>
#include <Interpreters/getHeaderForProcessingStage.h>
#include <Interpreters/InterpreterSelectQuery.h>
#include <Interpreters/InterpreterSelectQueryAnalyzer.h>
@ -8,6 +10,7 @@
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Planner/Utils.h>
#include <Processors/Sources/SourceFromSingleChunk.h>
namespace DB
@ -16,7 +19,6 @@ namespace DB
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
extern const int UNSUPPORTED_METHOD;
}
bool hasJoin(const ASTSelectQuery & select)
@ -124,13 +126,27 @@ Block getHeaderForProcessingStage(
ASTPtr query = query_info.query;
if (const auto * select = query_info.query->as<ASTSelectQuery>(); select && hasJoin(*select))
{
/// TODO: Analyzer syntax analyzer result
if (!query_info.syntax_analyzer_result)
throw Exception(ErrorCodes::UNSUPPORTED_METHOD, "getHeaderForProcessingStage is unsupported");
{
if (!query_info.planner_context)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Query is not analyzed: no planner context");
query = query_info.query->clone();
TreeRewriterResult new_rewriter_result = *query_info.syntax_analyzer_result;
removeJoin(*query->as<ASTSelectQuery>(), new_rewriter_result, context);
const auto & query_node = query_info.query_tree->as<QueryNode &>();
const auto & join_tree = query_node.getJoinTree();
auto left_table_expression = extractLeftTableExpression(join_tree);
auto & table_expression_data = query_info.planner_context->getTableExpressionDataOrThrow(left_table_expression);
const auto & query_context = query_info.planner_context->getQueryContext();
auto columns = table_expression_data.getColumns();
auto new_query_node = buildSubqueryToReadColumnsFromTableExpression(columns, left_table_expression, query_context);
query = new_query_node->toAST();
}
else
{
query = query_info.query->clone();
TreeRewriterResult new_rewriter_result = *query_info.syntax_analyzer_result;
removeJoin(*query->as<ASTSelectQuery>(), new_rewriter_result, context);
}
}
Block result;

View File

@ -110,7 +110,7 @@ String IParserKQLFunction::generateUniqueIdentifier()
// This particular random generator hits each number exactly once before looping over.
// Because of this, it's sufficient for queries consisting of up to 2^16 (= 65536) distinct function calls.
// Reference: https://www.pcg-random.org/using-pcg-cpp.html#insecure-generators
static pcg32_once_insecure random_generator;
static thread_local pcg32_once_insecure random_generator;
return std::to_string(random_generator());
}

View File

@ -1248,7 +1248,26 @@ JoinTreeQueryPlan buildQueryPlanForJoinNode(const QueryTreeNodePtr & join_table_
const auto & join_clause = table_join->getOnlyClause();
bool kind_allows_filtering = isInner(join_kind) || isLeft(join_kind) || isRight(join_kind);
if (settings.max_rows_in_set_to_optimize_join > 0 && kind_allows_filtering)
auto has_non_const = [](const Block & block, const auto & keys)
{
for (const auto & key : keys)
{
const auto & column = block.getByName(key).column;
if (column && !isColumnConst(*column))
return true;
}
return false;
};
/// This optimization relies on the sorting that should buffer data from both streams before emitting any rows.
/// Sorting on a stream with const keys can start returning rows immediately and pipeline may stuck.
/// Note: it's also doesn't work with the read-in-order optimization.
/// No checks here because read in order is not applied if we have `CreateSetAndFilterOnTheFlyStep` in the pipeline between the reading and sorting steps.
bool has_non_const_keys = has_non_const(left_plan.getCurrentDataStream().header, join_clause.key_names_left)
&& has_non_const(right_plan.getCurrentDataStream().header, join_clause.key_names_right);
if (settings.max_rows_in_set_to_optimize_join > 0 && kind_allows_filtering && has_non_const_keys)
{
auto * left_set = add_create_set(left_plan, join_clause.key_names_left, JoinTableSide::Left);
auto * right_set = add_create_set(right_plan, join_clause.key_names_right, JoinTableSide::Right);

View File

@ -584,13 +584,17 @@ std::shared_ptr<DirectKeyValueJoin> tryDirectJoin(const std::shared_ptr<TableJoi
const String & key_name = clauses[0].key_names_right[0];
auto & right_table_expression_data = planner_context->getTableExpressionDataOrThrow(right_table_expression);
const auto * table_column_name = right_table_expression_data.getColumnNameOrNull(key_name);
if (!table_column_name)
return {};
const auto & storage_primary_key = storage->getPrimaryKey();
if (storage_primary_key.size() != 1 || storage_primary_key[0] != *table_column_name)
if (const auto * table_column_name = right_table_expression_data.getColumnNameOrNull(key_name))
{
const auto & storage_primary_key = storage->getPrimaryKey();
if (storage_primary_key.size() != 1 || storage_primary_key[0] != *table_column_name)
return {};
}
else
{
return {};
}
/** For right table expression during execution columns have unique name.
* Direct key value join implementation during storage querying must use storage column names.
@ -608,8 +612,8 @@ std::shared_ptr<DirectKeyValueJoin> tryDirectJoin(const std::shared_ptr<TableJoi
for (const auto & right_table_expression_column : right_table_expression_header)
{
const auto * table_column_name_ = right_table_expression_data.getColumnNameOrNull(right_table_expression_column.name);
if (!table_column_name_)
const auto * table_column_name = right_table_expression_data.getColumnNameOrNull(right_table_expression_column.name);
if (!table_column_name)
return {};
auto right_table_expression_column_with_storage_column_name = right_table_expression_column;

View File

@ -17,6 +17,7 @@ static FormatSettings updateFormatSettings(const FormatSettings & settings, cons
updated.skip_unknown_fields = true;
updated.with_names_use_header = true;
updated.date_time_input_format = FormatSettings::DateTimeInputFormat::BestEffort;
updated.defaults_for_omitted_fields = true;
updated.csv.delimiter = updated.hive_text.fields_delimiter;
if (settings.hive_text.input_field_names.empty())
updated.hive_text.input_field_names = header.getNames();

View File

@ -617,10 +617,12 @@ void ValuesBlockInputFormat::readSuffix()
skipWhitespaceIfAny(*buf);
if (buf->hasUnreadData())
throw Exception(ErrorCodes::CANNOT_READ_ALL_DATA, "Cannot read data after semicolon");
if (!format_settings.values.allow_data_after_semicolon && !buf->eof())
throw Exception(ErrorCodes::CANNOT_READ_ALL_DATA, "Cannot read data after semicolon (and input_format_values_allow_data_after_semicolon=0)");
return;
}
if (buf->hasUnreadData())
if (buf->hasUnreadData() || !buf->eof())
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unread data in PeekableReadBuffer will be lost. Most likely it's a bug.");
}

View File

@ -623,7 +623,9 @@ IProcessor::Status AggregatingTransform::prepare()
void AggregatingTransform::work()
{
if (is_consume_finished)
{
initGenerate();
}
else
{
consume(std::move(current_chunk));
@ -676,11 +678,14 @@ void AggregatingTransform::consume(Chunk chunk)
void AggregatingTransform::initGenerate()
{
if (is_generate_initialized)
if (is_generate_initialized.load(std::memory_order_acquire))
return;
std::lock_guard lock(snapshot_mutex);
is_generate_initialized = true;
if (is_generate_initialized.load(std::memory_order_relaxed))
return;
is_generate_initialized.store(true, std::memory_order_release);
/// If there was no data, and we aggregate without keys, and we must return single row with the result of empty aggregation.
/// To do this, we pass a block with zero rows to aggregate.

View File

@ -217,7 +217,7 @@ private:
UInt64 src_rows = 0;
UInt64 src_bytes = 0;
bool is_generate_initialized = false;
std::atomic<bool> is_generate_initialized = false;
bool is_consume_finished = false;
bool is_pipeline_created = false;

View File

@ -75,6 +75,7 @@ void CreatingSetsTransform::work()
try
{
promise_to_build->set_exception(std::current_exception());
promise_to_build.reset();
}
catch (...)
{

View File

@ -20,37 +20,9 @@ GroupingAggregatedTransform::GroupingAggregatedTransform(
, num_inputs(num_inputs_)
, params(std::move(params_))
, last_bucket_number(num_inputs, -1)
, read_from_input(num_inputs, false)
{
}
void GroupingAggregatedTransform::readFromAllInputs()
{
auto in = inputs.begin();
read_from_all_inputs = true;
for (size_t i = 0; i < num_inputs; ++i, ++in)
{
if (in->isFinished())
continue;
if (read_from_input[i])
continue;
in->setNeeded();
if (!in->hasData())
{
read_from_all_inputs = false;
continue;
}
auto chunk = in->pull();
read_from_input[i] = true;
addChunk(std::move(chunk), i);
}
}
void GroupingAggregatedTransform::pushData(Chunks chunks, Int32 bucket, bool is_overflows)
{
auto & output = outputs.front();
@ -119,7 +91,7 @@ bool GroupingAggregatedTransform::tryPushOverflowData()
return true;
}
IProcessor::Status GroupingAggregatedTransform::prepare()
IProcessor::Status GroupingAggregatedTransform::prepare(const PortNumbers & updated_input_ports, const PortNumbers &)
{
/// Check can output.
auto & output = outputs.front();
@ -134,33 +106,16 @@ IProcessor::Status GroupingAggregatedTransform::prepare()
return Status::Finished;
}
/// Read first time from each input to understand if we have two-level aggregation.
if (!read_from_all_inputs)
if (!initialized_index_to_input)
{
readFromAllInputs();
if (!read_from_all_inputs)
return Status::NeedData;
initialized_index_to_input = true;
auto in = inputs.begin();
index_to_input.resize(num_inputs);
for (size_t i = 0; i < num_inputs; ++i, ++in)
index_to_input[i] = in;
}
/// Convert single level to two levels if have two-level input.
if (has_two_level && !single_level_chunks.empty())
return Status::Ready;
/// Check can push (to avoid data caching).
if (!output.canPush())
{
for (auto & input : inputs)
input.setNotNeeded();
return Status::PortFull;
}
bool pushed_to_output = false;
/// Output if has data.
if (has_two_level)
pushed_to_output = tryPushTwoLevelData();
auto need_input = [this](size_t input_num)
{
if (last_bucket_number[input_num] < current_bucket)
@ -169,6 +124,51 @@ IProcessor::Status GroupingAggregatedTransform::prepare()
return expect_several_chunks_for_single_bucket_per_source && last_bucket_number[input_num] == current_bucket;
};
if (!wait_input_ports_numbers.empty())
{
for (const auto & updated_input_port_number : updated_input_ports)
{
if (!wait_input_ports_numbers.contains(updated_input_port_number))
continue;
auto & input = index_to_input[updated_input_port_number];
if (!input->hasData())
{
wait_input_ports_numbers.erase(updated_input_port_number);
continue;
}
auto chunk = input->pull();
addChunk(std::move(chunk), updated_input_port_number);
if (!input->isFinished() && need_input(updated_input_port_number))
continue;
wait_input_ports_numbers.erase(updated_input_port_number);
}
if (!wait_input_ports_numbers.empty())
return Status::NeedData;
}
if (!output.canPush())
{
for (auto & input : inputs)
input.setNotNeeded();
return Status::PortFull;
}
/// Convert single level to two levels if have two-level input.
if (has_two_level && !single_level_chunks.empty())
return Status::Ready;
bool pushed_to_output = false;
/// Output if has data.
if (has_two_level)
pushed_to_output = tryPushTwoLevelData();
/// Read next bucket if can.
for (; ; ++current_bucket)
{
@ -190,6 +190,7 @@ IProcessor::Status GroupingAggregatedTransform::prepare()
if (!in->hasData())
{
wait_input_ports_numbers.insert(input_num);
need_data = true;
continue;
}
@ -197,13 +198,16 @@ IProcessor::Status GroupingAggregatedTransform::prepare()
auto chunk = in->pull();
addChunk(std::move(chunk), input_num);
if (has_two_level && !single_level_chunks.empty())
return Status::Ready;
if (!in->isFinished() && need_input(input_num))
{
wait_input_ports_numbers.insert(input_num);
need_data = true;
}
}
if (has_two_level && !single_level_chunks.empty())
return Status::Ready;
if (finished)
{
all_inputs_finished = true;

View File

@ -1,5 +1,7 @@
#pragma once
#include <Core/SortDescription.h>
#include <Common/HashTable/HashSet.h>
#include <Interpreters/Aggregator.h>
#include <Processors/IProcessor.h>
#include <Processors/ISimpleTransform.h>
@ -67,7 +69,7 @@ public:
void allowSeveralChunksForSingleBucketPerSource() { expect_several_chunks_for_single_bucket_per_source = true; }
protected:
Status prepare() override;
Status prepare(const PortNumbers & updated_input_ports, const PortNumbers &) override;
void work() override;
private:
@ -83,16 +85,15 @@ private:
bool has_two_level = false;
bool all_inputs_finished = false;
bool read_from_all_inputs = false;
std::vector<bool> read_from_input;
bool initialized_index_to_input = false;
std::vector<InputPorts::iterator> index_to_input;
HashSet<uint64_t> wait_input_ports_numbers;
/// If we aggregate partitioned data several chunks might be produced for the same bucket: one for each partition.
bool expect_several_chunks_for_single_bucket_per_source = true;
/// Add chunk read from input to chunks_map, overflow_chunks or single_level_chunks according to it's chunk info.
void addChunk(Chunk chunk, size_t input);
/// Read from all inputs first chunk. It is needed to detect if any source has two-level aggregation.
void readFromAllInputs();
/// Push chunks if all inputs has single level.
bool tryPushSingleLevelData();
/// Push chunks from ready bucket if has one.

View File

@ -2893,12 +2893,12 @@ void MergeTreeData::checkAlterIsPossible(const AlterCommands & commands, Context
queryToString(mutation_commands.ast()));
}
commands.apply(new_metadata, getContext());
if (commands.hasInvertedIndex(new_metadata) && !settings.allow_experimental_inverted_index)
throw Exception(ErrorCodes::SUPPORT_IS_DISABLED,
"Experimental Inverted Index feature is not enabled (turn on setting 'allow_experimental_inverted_index')");
commands.apply(new_metadata, getContext());
/// Set of columns that shouldn't be altered.
NameSet columns_alter_type_forbidden;

View File

@ -166,18 +166,20 @@ SelectPartsDecision MergeTreeDataMergerMutator::selectPartsToMerge(
String best_partition_id_to_optimize = getBestPartitionToOptimizeEntire(info.partitions_info);
if (!best_partition_id_to_optimize.empty())
{
return selectAllPartsToMergeWithinPartition(
future_part,
can_merge_callback,
best_partition_id_to_optimize,
/*final=*/true,
metadata_snapshot,
txn,
out_disable_reason,
/*optimize_skip_merged_partitions=*/true);
return selectAllPartsToMergeWithinPartition(
future_part,
can_merge_callback,
best_partition_id_to_optimize,
/*final=*/true,
metadata_snapshot,
txn,
out_disable_reason,
/*optimize_skip_merged_partitions=*/true);
}
out_disable_reason = "There is no need to merge parts according to merge selector algorithm";
if (!out_disable_reason.empty())
out_disable_reason += ". ";
out_disable_reason += "There is no need to merge parts according to merge selector algorithm";
return SelectPartsDecision::CANNOT_SELECT;
}

View File

@ -206,6 +206,8 @@ struct Settings;
MAKE_OBSOLETE_MERGE_TREE_SETTING(M, MaxThreads, max_part_loading_threads, 0) \
MAKE_OBSOLETE_MERGE_TREE_SETTING(M, MaxThreads, max_part_removal_threads, 0) \
MAKE_OBSOLETE_MERGE_TREE_SETTING(M, Bool, use_metadata_cache, false) \
MAKE_OBSOLETE_MERGE_TREE_SETTING(M, UInt64, merge_tree_enable_clear_old_broken_detached, 0) \
MAKE_OBSOLETE_MERGE_TREE_SETTING(M, UInt64, merge_tree_clear_old_broken_detached_parts_ttl_timeout_seconds, 1ULL * 3600 * 24 * 30) \
/// Settings that should not change after the creation of a table.
/// NOLINTNEXTLINE

View File

@ -157,12 +157,21 @@ void selectWithinPartition(
if (parts_count <= 1)
return;
for (size_t begin = 0; begin < parts_count; ++begin)
{
/// If too many parts, select only from first, to avoid complexity.
if (begin > 1000)
break;
/// If the parts in the parts vector are sorted by block number,
/// it may not be ideal to only select parts for merging from the first N ones.
/// This is because if there are more than N parts in the partition,
/// we will not be able to assign a merge for newly created parts.
/// As a result, the total number of parts within the partition could
/// grow uncontrollably, similar to a snowball effect.
/// To address this we will try to assign a merge taking into consideration
/// only last N parts.
static constexpr size_t parts_threshold = 1000;
size_t begin = 0;
if (parts_count >= parts_threshold)
begin = parts_count - parts_threshold;
for (; begin < parts_count; ++begin)
{
if (!parts[begin].shall_participate_in_merges)
continue;

View File

@ -1,3 +1,4 @@
#include <algorithm>
#include <memory>
#include <Core/NamesAndTypes.h>
#include <Core/TypeId.h>
@ -81,14 +82,33 @@ bool extractFunctions(const ASTPtr & expression, const std::function<bool(const
}
else if (function->name == "or")
{
bool ret = true;
bool ret = false;
ASTs or_args;
for (const auto & child : function->arguments->children)
ret &= extractFunctions(child, is_constant, or_args);
/// We can keep condition only if it still OR condition (i.e. we
/// have dependent conditions for columns at both sides)
if (or_args.size() == 2)
ret |= extractFunctions(child, is_constant, or_args);
if (!or_args.empty())
{
/// In case of there are less number of arguments for which
/// is_constant() == true, we need to add always-true
/// implicitly to avoid breaking AND invariant.
///
/// Consider the following:
///
/// ((value = 10) OR (_table = 'v2')) AND ((_table = 'v1') OR (value = 20))
///
/// Without implicit always-true:
///
/// (_table = 'v2') AND (_table = 'v1')
///
/// With:
///
/// (_table = 'v2' OR 1) AND (_table = 'v1' OR 1) -> (_table = 'v2') OR (_table = 'v1')
///
if (or_args.size() != function->arguments->children.size())
or_args.push_back(std::make_shared<ASTLiteral>(Field(1)));
result.push_back(makeASTForLogicalOr(std::move(or_args)));
}
return ret;
}
}
@ -165,8 +185,10 @@ bool prepareFilterBlockWithQuery(const ASTPtr & query, ContextPtr context, Block
if (!select.where() && !select.prewhere())
return unmodified;
// Provide input columns as constant columns to check if an expression is constant.
std::function<bool(const ASTPtr &)> is_constant = [&block, &context](const ASTPtr & node)
// Provide input columns as constant columns to check if an expression is
// constant and depends on the columns from provided block (the last is
// required to allow skipping some conditions for handling OR).
std::function<bool(const ASTPtr &)> is_constant = [&block, &context](const ASTPtr & expr)
{
auto actions = std::make_shared<ActionsDAG>(block.getColumnsWithTypeAndName());
PreparedSetsPtr prepared_sets = std::make_shared<PreparedSets>();
@ -178,13 +200,26 @@ bool prepareFilterBlockWithQuery(const ASTPtr & query, ContextPtr context, Block
context, SizeLimits{}, 1, source_columns, std::move(actions), prepared_sets, true, true, true,
{ aggregation_keys, grouping_set_keys, GroupByKind::NONE });
ActionsVisitor(visitor_data).visit(node);
ActionsVisitor(visitor_data).visit(expr);
actions = visitor_data.getActions();
auto expr_column_name = expr->getColumnName();
const auto * expr_const_node = actions->tryFindInOutputs(expr_column_name);
if (!expr_const_node)
return false;
auto filter_actions = ActionsDAG::buildFilterActionsDAG({expr_const_node}, {}, context);
const auto & nodes = filter_actions->getNodes();
bool has_dependent_columns = std::any_of(nodes.begin(), nodes.end(), [&](const auto & node)
{
return block.has(node.result_name);
});
if (!has_dependent_columns)
return false;
auto expression_actions = std::make_shared<ExpressionActions>(actions);
auto block_with_constants = block;
expression_actions->execute(block_with_constants);
auto column_name = node->getColumnName();
return block_with_constants.has(column_name) && isColumnConst(*block_with_constants.getByName(column_name).column);
return block_with_constants.has(expr_column_name) && isColumnConst(*block_with_constants.getByName(expr_column_name).column);
};
/// Create an expression that evaluates the expressions in WHERE and PREWHERE, depending only on the existing columns.

View File

@ -1,94 +1,48 @@
test_access_for_functions/test.py::test_access_rights_for_function
test_build_sets_from_multiple_threads/test.py::test_set
test_concurrent_backups_s3/test.py::test_concurrent_backups
test_distributed_ddl/test.py::test_default_database[configs]
test_distributed_ddl/test.py::test_default_database[configs_secure]
test_distributed_ddl/test.py::test_on_server_fail[configs]
test_distributed_ddl/test.py::test_on_server_fail[configs_secure]
test_distributed_insert_backward_compatibility/test.py::test_distributed_in_tuple
test_dictionaries_update_and_reload/test.py::test_reload_after_fail_in_cache_dictionary
test_distributed_backward_compatability/test.py::test_distributed_in_tuple
test_distributed_type_object/test.py::test_distributed_type_object
test_drop_is_lock_free/test.py::test_query_is_lock_free[detach table]
test_executable_table_function/test.py::test_executable_function_input_python
test_mask_sensitive_info/test.py::test_encryption_functions
test_merge_table_over_distributed/test.py::test_global_in
test_merge_table_over_distributed/test.py::test_select_table_name_from_merge_over_distributed
test_merge_tree_s3/test.py::test_heavy_insert_select_check_memory[node]
test_mutations_with_merge_tree/test.py::test_mutations_with_merge_background_task
test_passing_max_partitions_to_read_remotely/test.py::test_default_database_on_cluster
test_row_policy/test.py::test_change_of_users_xml_changes_row_policies
test_row_policy/test.py::test_change_of_users_xml_changes_row_policies
test_row_policy/test.py::test_dcl_introspection
test_row_policy/test.py::test_dcl_introspection
test_row_policy/test.py::test_dcl_management
test_row_policy/test.py::test_dcl_management
test_row_policy/test.py::test_dcl_users_with_policies_from_users_xml
test_row_policy/test.py::test_dcl_users_with_policies_from_users_xml
test_row_policy/test.py::test_grant_create_row_policy
test_row_policy/test.py::test_grant_create_row_policy
test_row_policy/test.py::test_introspection
test_row_policy/test.py::test_introspection
test_row_policy/test.py::test_join
test_row_policy/test.py::test_join
test_row_policy/test.py::test_miscellaneous_engines
test_row_policy/test.py::test_miscellaneous_engines
test_row_policy/test.py::test_policy_from_users_xml_affects_only_user_assigned
test_row_policy/test.py::test_policy_from_users_xml_affects_only_user_assigned
test_row_policy/test.py::test_policy_on_distributed_table_via_role
test_row_policy/test.py::test_policy_on_distributed_table_via_role
test_row_policy/test.py::test_reload_users_xml_by_timer
test_row_policy/test.py::test_reload_users_xml_by_timer
test_row_policy/test.py::test_row_policy_filter_with_subquery
test_row_policy/test.py::test_row_policy_filter_with_subquery
test_row_policy/test.py::test_smoke
test_row_policy/test.py::test_smoke
test_row_policy/test.py::test_some_users_without_policies
test_row_policy/test.py::test_some_users_without_policies
test_row_policy/test.py::test_tags_with_db_and_table_names
test_row_policy/test.py::test_tags_with_db_and_table_names
test_row_policy/test.py::test_throwif_error_in_prewhere_with_same_condition_as_filter
test_row_policy/test.py::test_throwif_error_in_prewhere_with_same_condition_as_filter
test_row_policy/test.py::test_throwif_error_in_where_with_same_condition_as_filter
test_row_policy/test.py::test_throwif_error_in_where_with_same_condition_as_filter
test_row_policy/test.py::test_throwif_in_prewhere_doesnt_expose_restricted_data
test_row_policy/test.py::test_throwif_in_prewhere_doesnt_expose_restricted_data
test_row_policy/test.py::test_throwif_in_where_doesnt_expose_restricted_data
test_row_policy/test.py::test_throwif_in_where_doesnt_expose_restricted_data
test_row_policy/test.py::test_users_xml_is_readonly
test_row_policy/test.py::test_users_xml_is_readonly
test_row_policy/test.py::test_with_prewhere
test_row_policy/test.py::test_with_prewhere
test_settings_constraints_distributed/test.py::test_select_clamps_settings
test_compression_codec_read/test.py::test_default_codec_read
test_dictionaries_update_and_reload/test.py::test_reload_after_fail_in_cache_dictionary
test_distributed_type_object/test.py::test_distributed_type_object
test_materialized_mysql_database/test.py::test_select_without_columns_5_7
test_materialized_mysql_database/test.py::test_select_without_columns_8_0
test_shard_level_const_function/test.py::test_remote
test_storage_postgresql/test.py::test_postgres_select_insert
test_storage_rabbitmq/test.py::test_rabbitmq_materialized_view
test_system_merges/test.py::test_mutation_simple[]
test_system_merges/test.py::test_mutation_simple[replicated]
test_disk_over_web_server/test.py::test_cache[node2]
test_disk_over_web_server/test.py::test_incorrect_usage
test_disk_over_web_server/test.py::test_replicated_database
test_disk_over_web_server/test.py::test_unavailable_server
test_disk_over_web_server/test.py::test_usage[node2]
test_distributed_backward_compatability/test.py::test_distributed_in_tuple
test_executable_table_function/test.py::test_executable_function_input_python
test_settings_profile/test.py::test_show_profiles
test_sql_user_defined_functions_on_cluster/test.py::test_sql_user_defined_functions_on_cluster
test_postgresql_protocol/test.py::test_python_client
test_mysql_database_engine/test.py::test_mysql_ddl_for_mysql_database
test_passing_max_partitions_to_read_remotely/test.py::test_default_database_on_cluster
test_profile_events_s3/test.py::test_profile_events
test_user_defined_object_persistence/test.py::test_persistence
test_settings_profile/test.py::test_show_profiles
test_sql_user_defined_functions_on_cluster/test.py::test_sql_user_defined_functions_on_cluster
test_replicating_constants/test.py::test_different_versions
test_row_policy/test.py::test_change_of_users_xml_changes_row_policies
test_row_policy/test.py::test_dcl_introspection
test_row_policy/test.py::test_dcl_management
test_row_policy/test.py::test_dcl_users_with_policies_from_users_xml
test_row_policy/test.py::test_grant_create_row_policy
test_row_policy/test.py::test_policy_from_users_xml_affects_only_user_assigned
test_row_policy/test.py::test_policy_on_distributed_table_via_role
test_row_policy/test.py::test_reload_users_xml_by_timer
test_row_policy/test.py::test_row_policy_filter_with_subquery
test_row_policy/test.py::test_smoke
test_row_policy/test.py::test_some_users_without_policies
test_row_policy/test.py::test_tags_with_db_and_table_names
test_row_policy/test.py::test_throwif_error_in_prewhere_with_same_condition_as_filter
test_row_policy/test.py::test_throwif_error_in_where_with_same_condition_as_filter
test_row_policy/test.py::test_throwif_in_prewhere_doesnt_expose_restricted_data
test_row_policy/test.py::test_throwif_in_where_doesnt_expose_restricted_data
test_row_policy/test.py::test_users_xml_is_readonly
test_row_policy/test.py::test_with_prewhere
test_select_access_rights/test_main.py::test_alias_columns
test_select_access_rights/test_main.py::test_select_count
test_select_access_rights/test_main.py::test_select_join
test_postgresql_protocol/test.py::test_python_client
test_replicating_constants/test.py::test_different_versions
test_merge_tree_s3/test.py::test_heavy_insert_select_check_memory[node]
test_settings_profile/test.py::test_show_profiles
test_shard_level_const_function/test.py::test_remote
test_sql_user_defined_functions_on_cluster/test.py::test_sql_user_defined_functions_on_cluster
test_storage_rabbitmq/test.py::test_rabbitmq_materialized_view
test_system_merges/test.py::test_mutation_simple[]
test_system_merges/test.py::test_mutation_simple[replicated]
test_user_defined_object_persistence/test.py::test_persistence
test_wrong_db_or_table_name/test.py::test_wrong_table_name
test_drop_is_lock_free/test.py::test_query_is_lock_free[detach table]
test_odbc_interaction/test.py::test_postgres_insert
test_zookeeper_config/test.py::test_chroot_with_different_root
test_zookeeper_config/test.py::test_chroot_with_same_root
test_merge_tree_azure_blob_storage/test.py::test_table_manipulations
test_parallel_replicas_skip_shards/test.py::test_skip_unavailable_shards
test_build_sets_from_multiple_threads/test.py::test_set
test_zookeeper_config/test.py::test_chroot_with_different_root

View File

@ -1,69 +1,46 @@
00223_shard_distributed_aggregation_memory_efficient
00562_in_subquery_merge_tree
00593_union_all_assert_columns_removed
00673_subquery_prepared_set_performance
00717_merge_and_distributed
00725_memory_tracking
00754_distributed_optimize_skip_select_on_unused_shards
00754_distributed_optimize_skip_select_on_unused_shards_with_prewhere
00927_asof_joins
00940_order_by_read_in_order_query_plan
00945_bloom_filter_index
00981_in_subquery_with_tuple
01049_join_low_card_bug_long
01062_pm_all_join_with_block_continuation
01064_incremental_streaming_from_2_src_with_feedback
01071_force_optimize_skip_unused_shards
01072_optimize_skip_unused_shards_const_expr_eval
01083_expressions_in_engine_arguments
01086_odbc_roundtrip
01155_rename_move_materialized_view
01173_transaction_control_queries
01211_optimize_skip_unused_shards_type_mismatch
01213_optimize_skip_unused_shards_DISTINCT
01214_test_storage_merge_aliases_with_where
01231_distributed_aggregation_memory_efficient_mix_levels
01244_optimize_distributed_group_by_sharding_key
01247_optimize_distributed_group_by_sharding_key_dist_on_dist
01268_mv_scalars
01268_shard_avgweighted
01270_optimize_skip_unused_shards_low_cardinality
01319_optimize_skip_unused_shards_nesting
01353_low_cardinality_join_types
01455_shard_leaf_max_rows_bytes_to_read
01495_subqueries_in_with_statement
01504_rocksdb
01526_client_start_and_exit
01527_dist_sharding_key_dictGet_reload
01528_allow_nondeterministic_optimize_skip_unused_shards
01540_verbatim_partition_pruning
01560_merge_distributed_join
01563_distributed_query_finish
01576_alias_column_rewrite
01583_const_column_in_set_index
01584_distributed_buffer_cannot_find_column
01585_use_index_for_global_in
01585_use_index_for_global_in_with_null
01586_columns_pruning
01624_soft_constraints
01651_bugs_from_15889
01656_test_query_log_factories_info
01676_clickhouse_client_autocomplete
01681_bloom_filter_nullable_column
01700_system_zookeeper_path_in
01710_projection_additional_filters
01721_join_implicit_cast_long
01739_index_hint
02880_indexHint__partition_id
01747_join_view_filter_dictionary
01748_partition_id_pruning
01756_optimize_skip_unused_shards_rewrite_in
01757_optimize_skip_unused_shards_limit
01758_optimize_skip_unused_shards_once
01759_optimize_skip_unused_shards_zero_shards
01761_cast_to_enum_nullable
01786_explain_merge_tree
01889_key_condition_function_chains
01890_materialized_distributed_join
01901_in_literal_shard_prune
01925_join_materialized_columns
@ -71,13 +48,9 @@
01930_optimize_skip_unused_shards_rewrite_in
01947_mv_subquery
01952_optimize_distributed_group_by_sharding_key
02000_join_on_const
02001_shard_num_shard_count
02131_used_row_policies_in_query_log
02139_MV_with_scalar_subquery
02174_cte_scalar_cache_mv
02242_join_rocksdb
02267_join_dup_columns_issue36199
02302_s3_file_pruning
02341_global_join_cte
02345_implicit_transaction
@ -85,7 +58,6 @@
02354_annoy
02366_union_decimal_conversion
02375_rocksdb_with_filters
02382_join_and_filtering_set
02402_merge_engine_with_view
02404_memory_bound_merging
02426_orc_bug
@ -97,35 +69,18 @@
02554_fix_grouping_sets_predicate_push_down
02575_merge_prewhere_different_default_kind
02713_array_low_cardinality_string
02707_skip_index_with_in
02241_join_rocksdb_bs
02003_WithMergeableStateAfterAggregationAndLimit_LIMIT_BY_LIMIT_OFFSET
01115_join_with_dictionary
01009_global_array_join_names
00917_multiple_joins_denny_crane
00725_join_on_bug_1
00636_partition_key_parts_pruning
00261_storage_aliases_and_array_join
01825_type_json_multiple_files
01281_group_by_limit_memory_tracking
02723_zookeeper_name
00002_log_and_exception_messages_formatting
01646_rewrite_sum_if_bug
02725_agg_projection_resprect_PK
01019_alter_materialized_view_consistent
01600_parts_states_metrics_long
01600_parts_types_metrics_long
01287_max_execution_speed
02703_row_policy_for_database
02721_url_cluster
02534_s3_cluster_insert_select_schema_inference
02765_parallel_replicas_final_modifier
02784_parallel_replicas_automatic_disabling
02581_share_big_sets_between_mutation_tasks_long
02581_share_big_sets_between_multiple_mutations_tasks_long
00992_system_parts_race_condition_zookeeper_long
02818_parameterized_view_with_cte_multiple_usage
02790_optimize_skip_unused_shards_join
01940_custom_tld_sharding_key
02815_range_dict_no_direct_join
02861_join_on_nullsafe_compare

View File

@ -296,7 +296,7 @@ class CiLogsCredentials:
logging.info("Do not use external logs pushing")
return ""
extra_columns = (
f"{pr_info.number} AS pull_request_number, '{pr_info.sha}' AS commit_sha, "
f"CAST({pr_info.number} AS UInt32) AS pull_request_number, '{pr_info.sha}' AS commit_sha, "
f"toDateTime('{check_start_time}', 'UTC') AS check_start_time, '{check_name}' AS check_name, "
f"'{get_instance_type()}' AS instance_type, '{get_instance_id()}' AS instance_id"
)

View File

@ -8,9 +8,10 @@ import logging
import time
from github import Github
from github.GithubObject import _NotSetType, NotSet as NotSet
from github.Commit import Commit
from github.CommitStatus import CommitStatus
from github.GithubException import GithubException
from github.GithubObject import _NotSetType, NotSet as NotSet
from github.IssueComment import IssueComment
from github.PullRequest import PullRequest
from github.Repository import Repository
@ -336,7 +337,18 @@ def remove_labels(gh: Github, pr_info: PRInfo, labels_names: List[str]) -> None:
repo = get_repo(gh)
pull_request = repo.get_pull(pr_info.number)
for label in labels_names:
pull_request.remove_from_labels(label)
try:
pull_request.remove_from_labels(label)
except GithubException as exc:
if not (
exc.status == 404
and isinstance(exc.data, dict)
and exc.data.get("message", "") == "Label does not exist"
):
raise
logging.warning(
"The label '%s' does not exist in PR #%s", pr_info.number, label
)
pr_info.labels.remove(label)

View File

@ -1,6 +1,6 @@
<clickhouse>
<zookeeper>
<!--<zookeeper_load_balancing>random / in_order / nearest_hostname / first_or_random / round_robin</zookeeper_load_balancing>-->
<!--<zookeeper_load_balancing>random / in_order / nearest_hostname / hostname_levenshtein_distance / first_or_random / round_robin</zookeeper_load_balancing>-->
<zookeeper_load_balancing>random</zookeeper_load_balancing>
<compressed_protocol>true</compressed_protocol>
<node index="1">

View File

@ -140,6 +140,16 @@ def test_load_balancing_nearest_hostname():
assert unique_nodes == set(["n1"])
def test_load_balancing_hostname_levenshtein_distance():
unique_nodes = set()
for _ in range(0, queries):
unique_nodes.add(
get_node(n1, settings={"load_balancing": "hostname_levenshtein_distance"})
)
assert len(unique_nodes) == 1, unique_nodes
assert unique_nodes == set(["n1"])
def test_load_balancing_in_order():
unique_nodes = set()
for _ in range(0, queries):

View File

@ -0,0 +1,11 @@
<clickhouse>
<database_catalog_unused_dir_hide_timeout_sec>0</database_catalog_unused_dir_hide_timeout_sec>
<database_catalog_unused_dir_rm_timeout_sec>60</database_catalog_unused_dir_rm_timeout_sec>
<database_catalog_unused_dir_cleanup_period_sec>1</database_catalog_unused_dir_cleanup_period_sec>
<!-- We don't really need [Zoo]Keeper for this test.
And it makes sense to have at least one test with TestKeeper. -->
<zookeeper>
<implementation>testkeeper</implementation>
</zookeeper>
</clickhouse>

View File

@ -0,0 +1,212 @@
import pytest
from helpers.cluster import ClickHouseCluster
cluster = ClickHouseCluster(__file__)
node1 = cluster.add_instance(
"node1", stay_alive=True, main_configs=["configs/store_cleanup.xml"]
)
path_to_data = "/var/lib/clickhouse/"
@pytest.fixture(scope="module")
def started_cluster():
try:
cluster.start()
yield cluster
finally:
cluster.shutdown()
def test_store_cleanup(started_cluster):
node1.query("CREATE DATABASE db UUID '10000000-1000-4000-8000-000000000001'")
node1.query(
"CREATE TABLE db.log UUID '10000000-1000-4000-8000-000000000002' ENGINE=Log AS SELECT 1"
)
node1.query(
"CREATE TABLE db.mt UUID '10000000-1000-4000-8000-000000000003' ENGINE=MergeTree ORDER BY tuple() AS SELECT 1"
)
node1.query(
"CREATE TABLE db.mem UUID '10000000-1000-4000-8000-000000000004' ENGINE=Memory AS SELECT 1"
)
node1.query("CREATE DATABASE db2 UUID '20000000-1000-4000-8000-000000000001'")
node1.query(
"CREATE TABLE db2.log UUID '20000000-1000-4000-8000-000000000002' ENGINE=Log AS SELECT 1"
)
node1.query("DETACH DATABASE db2")
node1.query("CREATE DATABASE db3 UUID '30000000-1000-4000-8000-000000000001'")
node1.query(
"CREATE TABLE db3.log UUID '30000000-1000-4000-8000-000000000002' ENGINE=Log AS SELECT 1"
)
node1.query(
"CREATE TABLE db3.log2 UUID '30000000-1000-4000-8000-000000000003' ENGINE=Log AS SELECT 1"
)
node1.query("DETACH TABLE db3.log")
node1.query("DETACH TABLE db3.log2 PERMANENTLY")
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store"]
)
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/100"]
)
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/200"]
)
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/300"]
)
node1.stop_clickhouse(kill=True)
# All dirs related to `db` will be removed
node1.exec_in_container(["rm", f"{path_to_data}/metadata/db.sql"])
node1.exec_in_container(["mkdir", f"{path_to_data}/store/kek"])
node1.exec_in_container(["touch", f"{path_to_data}/store/12"])
try:
node1.exec_in_container(["mkdir", f"{path_to_data}/store/456"])
except Exception as e:
print("Failed to create 456/:", str(e))
node1.exec_in_container(["mkdir", f"{path_to_data}/store/456/testgarbage"])
node1.exec_in_container(
["mkdir", f"{path_to_data}/store/456/30000000-1000-4000-8000-000000000003"]
)
node1.exec_in_container(
["touch", f"{path_to_data}/store/456/45600000-1000-4000-8000-000000000003"]
)
node1.exec_in_container(
["mkdir", f"{path_to_data}/store/456/45600000-1000-4000-8000-000000000004"]
)
node1.start_clickhouse()
node1.query("DETACH DATABASE db2")
node1.query("DETACH TABLE db3.log")
node1.wait_for_log_line(
"Removing access rights for unused directory",
timeout=60,
look_behind_lines=1000000,
)
node1.wait_for_log_line(
"directories from store", timeout=60, look_behind_lines=1000000
)
store = node1.exec_in_container(["ls", f"{path_to_data}/store"])
assert "100" in store
assert "200" in store
assert "300" in store
assert "456" in store
assert "kek" in store
assert "12" in store
assert "d---------" in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store"]
)
assert "d---------" in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/456"]
)
# Metadata is removed, so store/100 contains garbage
store100 = node1.exec_in_container(["ls", f"{path_to_data}/store/100"])
assert "10000000-1000-4000-8000-000000000001" in store100
assert "10000000-1000-4000-8000-000000000002" in store100
assert "10000000-1000-4000-8000-000000000003" in store100
assert "d---------" in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/100"]
)
# Database is detached, nothing to clean up
store200 = node1.exec_in_container(["ls", f"{path_to_data}/store/200"])
assert "20000000-1000-4000-8000-000000000001" in store200
assert "20000000-1000-4000-8000-000000000002" in store200
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/200"]
)
# Tables are detached, nothing to clean up
store300 = node1.exec_in_container(["ls", f"{path_to_data}/store/300"])
assert "30000000-1000-4000-8000-000000000001" in store300
assert "30000000-1000-4000-8000-000000000002" in store300
assert "30000000-1000-4000-8000-000000000003" in store300
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/300"]
)
# Manually created garbage
store456 = node1.exec_in_container(["ls", f"{path_to_data}/store/456"])
assert "30000000-1000-4000-8000-000000000003" in store456
assert "45600000-1000-4000-8000-000000000003" in store456
assert "45600000-1000-4000-8000-000000000004" in store456
assert "testgarbage" in store456
assert "----------" in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/456"]
)
node1.wait_for_log_line(
"Removing unused directory", timeout=90, look_behind_lines=1000000
)
node1.wait_for_log_line(
"directories from store", timeout=90, look_behind_lines=1000000
)
node1.wait_for_log_line(
"Nothing to clean up from store/", timeout=90, look_behind_lines=1000000
)
store = node1.exec_in_container(["ls", f"{path_to_data}/store"])
assert "100" in store
assert "200" in store
assert "300" in store
assert "456" in store
assert "kek" not in store # changed
assert "\n12\n" not in store # changed
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store"]
) # changed
# Metadata is removed, so store/100 contains garbage
store100 = node1.exec_in_container(["ls", f"{path_to_data}/store/100"]) # changed
assert "10000000-1000-4000-8000-000000000001" not in store100 # changed
assert "10000000-1000-4000-8000-000000000002" not in store100 # changed
assert "10000000-1000-4000-8000-000000000003" not in store100 # changed
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/100"]
) # changed
# Database is detached, nothing to clean up
store200 = node1.exec_in_container(["ls", f"{path_to_data}/store/200"])
assert "20000000-1000-4000-8000-000000000001" in store200
assert "20000000-1000-4000-8000-000000000002" in store200
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/200"]
)
# Tables are detached, nothing to clean up
store300 = node1.exec_in_container(["ls", f"{path_to_data}/store/300"])
assert "30000000-1000-4000-8000-000000000001" in store300
assert "30000000-1000-4000-8000-000000000002" in store300
assert "30000000-1000-4000-8000-000000000003" in store300
assert "d---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/300"]
)
# Manually created garbage
store456 = node1.exec_in_container(["ls", f"{path_to_data}/store/456"])
assert "30000000-1000-4000-8000-000000000003" not in store456 # changed
assert "45600000-1000-4000-8000-000000000003" not in store456 # changed
assert "45600000-1000-4000-8000-000000000004" not in store456 # changed
assert "testgarbage" not in store456 # changed
assert "---------" not in node1.exec_in_container(
["ls", "-l", f"{path_to_data}/store/456"]
) # changed
node1.query("ATTACH TABLE db3.log2")
node1.query("ATTACH DATABASE db2")
node1.query("ATTACH TABLE db3.log")
assert "1\n" == node1.query("SELECT * FROM db3.log")
assert "1\n" == node1.query("SELECT * FROM db3.log2")
assert "1\n" == node1.query("SELECT * FROM db2.log")

View File

@ -0,0 +1,7 @@
<clickhouse>
<profiles>
<default>
<function_sleep_max_microseconds_per_block>10G</function_sleep_max_microseconds_per_block>
</default>
</profiles>
</clickhouse>

View File

@ -10,6 +10,7 @@ cluster = ClickHouseCluster(__file__)
node1 = cluster.add_instance(
"node1",
main_configs=["configs/logs_config.xml"],
user_configs=["configs/user_overrides.xml"],
with_zookeeper=True,
macros={"shard": 0, "replica": 1},
)
@ -17,6 +18,7 @@ node1 = cluster.add_instance(
node2 = cluster.add_instance(
"node2",
main_configs=["configs/logs_config.xml"],
user_configs=["configs/user_overrides.xml"],
with_zookeeper=True,
macros={"shard": 0, "replica": 2},
)
@ -183,10 +185,10 @@ def test_mutation_simple(started_cluster, replicated):
starting_block, starting_block, starting_block + 1
)
# ALTER will sleep for 3s * 3 (rows) = 9s
# ALTER will sleep for 9s
def alter():
node1.query(
f"ALTER TABLE {name} UPDATE a = 42 WHERE sleep(3) OR 1",
f"ALTER TABLE {name} UPDATE a = 42 WHERE sleep(9) OR 1",
settings=settings,
)

View File

@ -312,6 +312,96 @@ def test_nearest_hostname(started_cluster):
change_balancing("nearest_hostname", "random", reload=False)
def test_hostname_levenshtein_distance(started_cluster):
try:
change_balancing("random", "hostname_levenshtein_distance")
print(
str(
node1.exec_in_container(
[
"bash",
"-c",
"lsof -a -i4 -i6 -itcp -w | grep ':2181' | grep ESTABLISHED",
],
privileged=True,
user="root",
)
)
)
assert (
"1"
== str(
node1.exec_in_container(
[
"bash",
"-c",
"lsof -a -i4 -i6 -itcp -w | grep 'testzookeeperconfigloadbalancing_zoo1_1.*testzookeeperconfigloadbalancing_default:2181' | grep ESTABLISHED | wc -l",
],
privileged=True,
user="root",
)
).strip()
)
print(
str(
node2.exec_in_container(
[
"bash",
"-c",
"lsof -a -i4 -i6 -itcp -w | grep ':2181' | grep ESTABLISHED",
],
privileged=True,
user="root",
)
)
)
assert (
"1"
== str(
node2.exec_in_container(
[
"bash",
"-c",
"lsof -a -i4 -i6 -itcp -w | grep 'testzookeeperconfigloadbalancing_zoo2_1.*testzookeeperconfigloadbalancing_default:2181' | grep ESTABLISHED | wc -l",
],
privileged=True,
user="root",
)
).strip()
)
print(
str(
node3.exec_in_container(
[
"bash",
"-c",
"lsof -a -i4 -i6 -itcp -w | grep ':2181' | grep ESTABLISHED",
],
privileged=True,
user="root",
)
)
)
assert (
"1"
== str(
node3.exec_in_container(
[
"bash",
"-c",
"lsof -a -i4 -i6 -itcp -w | grep 'testzookeeperconfigloadbalancing_zoo3_1.*testzookeeperconfigloadbalancing_default:2181' | grep ESTABLISHED | wc -l",
],
privileged=True,
user="root",
)
).strip()
)
finally:
change_balancing("hostname_levenshtein_distance", "random", reload=False)
def test_round_robin(started_cluster):
pm = PartitionManager()
try:

View File

@ -0,0 +1,10 @@
<test>
<settings>
<max_threads>30</max_threads>
<max_bytes_before_external_group_by>10485760</max_bytes_before_external_group_by>
</settings>
<query>SELECT number, count() FROM numbers_mt(5000000) GROUP BY number FORMAT Null;</query>
<query>SELECT number, count() FROM numbers_mt(15000000) GROUP BY number FORMAT Null;</query>
<query>SELECT number, count() FROM numbers_mt(30000000) GROUP BY number FORMAT Null;</query>
</test>

View File

@ -96,7 +96,7 @@ $CLICKHOUSE_CLIENT --query="DROP TABLE src;"
$CLICKHOUSE_CLIENT --query="CREATE TABLE src (p UInt64, k String, d UInt64) ENGINE = MergeTree PARTITION BY p ORDER BY k;"
$CLICKHOUSE_CLIENT --query="INSERT INTO src VALUES (1, '0', 1);"
$CLICKHOUSE_CLIENT --query="INSERT INTO src VALUES (1, '1', 1);"
$CLICKHOUSE_CLIENT --query="INSERT INTO dst_r1 VALUES (1, '1', 2); -- trash part to be deleted"
$CLICKHOUSE_CLIENT --query="INSERT INTO dst_r1 VALUES (1, '1', 2);" # trash part to be deleted
# Stop replication at the second replica and remove source table to use fetch instead of copying
$CLICKHOUSE_CLIENT --query="SYSTEM STOP REPLICATION QUEUES dst_r2;"
@ -116,7 +116,7 @@ query_with_retry "ALTER TABLE dst_r1 DROP PARTITION 1;"
$CLICKHOUSE_CLIENT --query="CREATE TABLE src (p UInt64, k String, d UInt64) ENGINE = MergeTree PARTITION BY p ORDER BY k;"
$CLICKHOUSE_CLIENT --query="INSERT INTO src VALUES (1, '0', 1);"
$CLICKHOUSE_CLIENT --query="INSERT INTO src VALUES (1, '1', 1);"
$CLICKHOUSE_CLIENT --query="INSERT INTO dst_r1 VALUES (1, '1', 2); -- trash part to be deleted"
$CLICKHOUSE_CLIENT --query="INSERT INTO dst_r1 VALUES (1, '1', 2);" # trash part to be deleted
$CLICKHOUSE_CLIENT --query="SYSTEM STOP MERGES dst_r2;"
$CLICKHOUSE_CLIENT --query="SYSTEM STOP REPLICATION QUEUES dst_r2;"

View File

@ -1,615 +0,0 @@
-- join_algorithm = default, join_use_nulls = 0 --
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
str String
String
str String
str_r String
str String
String
str_l String
str String
str_r String
str_l String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
-- join_algorithm = default, join_use_nulls = 1 --
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
-- join_algorithm = partial_merge, join_use_nulls = 0 --
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
str String
String
str String
str_r String
str String
String
str_l String
str String
str_r String
str_l String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
-- join_algorithm = partial_merge, join_use_nulls = 1 --
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
-- join_algorithm = parallel_hash, join_use_nulls = 0 --
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
str String
String
str String
str_r String
str String
String
str_l String
str String
str_r String
str_l String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
str LowCardinality(String)
LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
-- join_algorithm = parallel_hash, join_use_nulls = 1 --
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
str Nullable(String)
\N Nullable(String)
str Nullable(String)
str_r Nullable(String)
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
--
LowCardinality(String)
str LowCardinality(String)
str
str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
\N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String))

View File

@ -0,0 +1,635 @@
-- { echoOn }
SET allow_experimental_analyzer = 0;
{% for join_algorithm in ['default', 'partial_merge', 'parallel_hash'] -%}
SET join_algorithm = '{{ join_algorithm }}';
SET join_use_nulls = 0;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
--
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
--
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (x) ORDER BY x, lc;
str String
String
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (x) ORDER BY x, lc;
str String
String
str_l String
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
str_l String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
--
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
--
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SET join_use_nulls = 1;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
--
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, lc;
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
--
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
--
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (lc) ORDER BY x, lc;
str LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (lc) ORDER BY x, lc;
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
--
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
{% endfor -%}
SELECT '--';
--
SET join_use_nulls = 0;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY l.lc;
LowCardinality(String)
str LowCardinality(String)
SET join_algorithm = 'partial_merge';
SET join_use_nulls = 1;
SELECT r.lc, materialize(r.lc), toTypeName(r.lc), toTypeName(materialize(r.lc)) FROM l_lc AS l FULL OUTER JOIN r_lc AS r USING (x) ORDER BY r.lc;
str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
\N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
SET allow_experimental_analyzer = 1;
{% for join_algorithm in ['default', 'partial_merge', 'parallel_hash'] -%}
SET join_algorithm = '{{ join_algorithm }}';
SET join_use_nulls = 0;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
str_l LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(String) LowCardinality(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(String) LowCardinality(String)
LowCardinality(String) LowCardinality(String) LowCardinality(String) LowCardinality(String) str_l str_l
--
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
str_l String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str String String str str
String String str_r str_r String String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(String) LowCardinality(String) str str
String String str_r str_r LowCardinality(String) LowCardinality(String)
String String LowCardinality(String) LowCardinality(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str String String str str
String String str_r str_r String String
String String String String str_l str_l
--
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (x) ORDER BY x, lc;
str String
String
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (x) ORDER BY x, lc;
str String
String
str_l String
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
str_l String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str String String str str
String String str_r str_r String String
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str String String str str
LowCardinality(String) LowCardinality(String) str_r str_r String String
LowCardinality(String) LowCardinality(String) String String str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str String String str str
String String str_r str_r String String
String String String String str_l str_l
--
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(String)
LowCardinality(String)
str_l LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
str_l Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(String) LowCardinality(String) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(String) LowCardinality(String)
Nullable(String) Nullable(String) \N \N LowCardinality(String) LowCardinality(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
Nullable(String) Nullable(String) \N \N Nullable(String) Nullable(String) str_l str_l
--
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(String) LowCardinality(String) Nullable(String) Nullable(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) \N \N Nullable(String) Nullable(String) str_l str_l
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
SET join_use_nulls = 1;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(String)
str_r LowCardinality(String)
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, lc;
str LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
str_r LowCardinality(Nullable(String))
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(String) LowCardinality(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
--
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (x) ORDER BY x, r.lc, l.lc;
String String str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
String String str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str Nullable(String) Nullable(String) str str
String String str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) \N \N Nullable(String) Nullable(String) str_l str_l
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
--
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
SELECT lc, toTypeName(lc) FROM l RIGHT JOIN r USING (lc) ORDER BY x, lc;
str String
str_r String
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
SELECT lc, toTypeName(lc) FROM l FULL JOIN r USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
String String str str Nullable(String) Nullable(String) str str
String String str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) \N \N Nullable(String) Nullable(String) str_l str_l
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
--
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc RIGHT JOIN nr USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (x) ORDER BY x, lc;
str LowCardinality(Nullable(String))
\N LowCardinality(Nullable(String))
str_l LowCardinality(Nullable(String))
SELECT lc, toTypeName(lc) FROM l_lc FULL JOIN nr USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l RIGHT JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (x) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str
Nullable(String) Nullable(String) str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N
Nullable(String) Nullable(String) \N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM l_lc AS l FULL JOIN nr AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) \N \N Nullable(String) Nullable(String) str_l str_l
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
--
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
SELECT lc, toTypeName(lc) FROM nl RIGHT JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_r Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (x) ORDER BY x, lc;
str Nullable(String)
\N Nullable(String)
str_l Nullable(String)
SELECT lc, toTypeName(lc) FROM nl FULL JOIN r_lc USING (lc) ORDER BY x, lc;
str Nullable(String)
str_l Nullable(String)
str_r Nullable(String)
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(String) LowCardinality(String) str str Nullable(String) Nullable(String) str str
LowCardinality(String) LowCardinality(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, r.lc, l.lc;
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str str Nullable(String) Nullable(String) str str
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) str_r str_r Nullable(String) Nullable(String) \N \N
LowCardinality(Nullable(String)) LowCardinality(Nullable(String)) \N \N Nullable(String) Nullable(String) str_l str_l
SELECT toTypeName(r.lc), toTypeName(materialize(r.lc)), r.lc, materialize(r.lc), toTypeName(l.lc), toTypeName(materialize(l.lc)), l.lc, materialize(l.lc) FROM nl AS l FULL JOIN r_lc AS r USING (lc) ORDER BY x, r.lc, l.lc;
Nullable(String) Nullable(String) str str Nullable(String) Nullable(String) str str
Nullable(String) Nullable(String) \N \N Nullable(String) Nullable(String) str_l str_l
Nullable(String) Nullable(String) str_r str_r Nullable(String) Nullable(String) \N \N
{% endfor -%}
SELECT '--';
--
SET join_use_nulls = 0;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY l.lc;
LowCardinality(String)
str LowCardinality(String)
SET join_algorithm = 'partial_merge';
SET join_use_nulls = 1;
SELECT r.lc, materialize(r.lc), toTypeName(r.lc), toTypeName(materialize(r.lc)) FROM l_lc AS l FULL OUTER JOIN r_lc AS r USING (x) ORDER BY r.lc;
str str LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
str_r str_r LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
\N \N LowCardinality(Nullable(String)) LowCardinality(Nullable(String))
DROP TABLE l;
DROP TABLE r;
DROP TABLE nl;
DROP TABLE nr;
DROP TABLE l_lc;
DROP TABLE r_lc;

View File

@ -22,15 +22,17 @@ INSERT INTO l VALUES (0, 'str'), (2, 'str_l');
INSERT INTO nl VALUES (0, 'str'), (2, 'str_l');
INSERT INTO l_lc VALUES (0, 'str'), (2, 'str_l');
{% for join_algorithm in [None, 'partial_merge', 'parallel_hash'] -%}
-- { echoOn }
{% for allow_experimental_analyzer in [0, 1] -%}
SET allow_experimental_analyzer = {{ allow_experimental_analyzer }};
{% for join_algorithm in ['default', 'partial_merge', 'parallel_hash'] -%}
SET join_algorithm = '{{ join_algorithm }}';
{% for join_use_nulls in [0, 1] -%}
SELECT '-- join_algorithm = {{ join_algorithm or 'default' }}, join_use_nulls = {{ join_use_nulls }} --';
{% if join_algorithm %}SET join_algorithm = '{{ join_algorithm }}';{% endif -%}
SET join_use_nulls = {{ join_use_nulls }};
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY x, lc;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (lc) ORDER BY x, lc;
SELECT lc, toTypeName(lc) FROM l_lc AS l FULL JOIN r_lc AS r USING (x) ORDER BY x, lc;
@ -98,13 +100,13 @@ SET join_use_nulls = 0;
SELECT lc, toTypeName(lc) FROM l_lc AS l RIGHT JOIN r_lc AS r USING (x) ORDER BY l.lc;
SELECT lowCardinalityKeys(lc.lc) FROM r FULL JOIN l_lc as lc USING (lc) ORDER BY lowCardinalityKeys(lc.lc);
SET join_algorithm = 'partial_merge';
SET join_use_nulls = 1;
SELECT r.lc, materialize(r.lc), toTypeName(r.lc), toTypeName(materialize(r.lc)) FROM l_lc AS l FULL OUTER JOIN r_lc AS r USING (x) ORDER BY r.lc;
{% endfor -%}
DROP TABLE l;
DROP TABLE r;
DROP TABLE nl;

View File

@ -21,20 +21,21 @@ expect ":) "
send -- "DROP TABLE IF EXISTS test_01179\r"
expect "Ok."
send -- "CREATE TABLE test_01179 (date DateTime64(3)) ENGINE=Memory()\r"
send -- "CREATE TABLE test_01179 (val String) ENGINE=Memory()\r"
expect "Ok."
send -- "INSERT INTO test_01179 values ('2020-01-01')\r"
send -- "INSERT INTO test_01179 values ('foo')\r"
expect "Ok."
send -- "INSERT INTO test_01179 values ('2020-01-01'); \r"
send -- "INSERT INTO test_01179 values ('foo'); \r"
expect "Ok."
send -- "INSERT INTO test_01179 values ('2020-01-01 0'); (1) \r"
send -- "INSERT INTO test_01179 values ('foo'); ('bar') \r"
expect "Cannot read data after semicolon"
send -- "SELECT date, count() FROM test_01179 GROUP BY date FORMAT TSV\r"
expect "2020-01-01 00:00:00.000\t2"
send -- "SELECT val, count() FROM test_01179 GROUP BY val FORMAT TSV\r"
expect "foo\t2"
send -- "DROP TABLE test_01179\r"
expect "Ok."

View File

@ -34,3 +34,21 @@ UInt64 LowCardinality(UInt64) LowCardinality(String) String
LowCardinality(UInt64) LowCardinality(UInt64) LowCardinality(String) LowCardinality(String)
LowCardinality(UInt64) LowCardinality(UInt64) LowCardinality(String) LowCardinality(String)
LowCardinality(UInt64) LowCardinality(UInt64) LowCardinality(String) LowCardinality(String)
-
UInt64 UInt64 String LowCardinality(String)
-
UInt64 UInt64 LowCardinality(String) String
-
LowCardinality(UInt64) LowCardinality(UInt64) LowCardinality(String) LowCardinality(String)
-
UInt64 UInt64 String LowCardinality(String)
UInt64 UInt64 String LowCardinality(String)
UInt64 UInt64 String LowCardinality(String)
-
UInt64 UInt64 LowCardinality(String) String
UInt64 UInt64 LowCardinality(String) String
UInt64 UInt64 LowCardinality(String) String
-
LowCardinality(UInt64) LowCardinality(UInt64) LowCardinality(String) LowCardinality(String)
LowCardinality(UInt64) LowCardinality(UInt64) LowCardinality(String) LowCardinality(String)
LowCardinality(UInt64) LowCardinality(UInt64) LowCardinality(String) LowCardinality(String)

View File

@ -1,3 +1,4 @@
SET allow_experimental_analyzer = 0;
set join_algorithm = 'hash';
select '-';
@ -73,3 +74,42 @@ select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeNam
from (select toLowCardinality(number) k, toLowCardinality(toString(number)) s from numbers(2)) as js1
full join (select toLowCardinality(number+1) k, toLowCardinality(toString(number+1)) s from numbers(2)) as js2
using k order by js1.k, js2.k;
SET allow_experimental_analyzer = 1;
set join_algorithm = 'hash';
select '-';
select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeName(materialize(js1.s)), toTypeName(materialize(js2.s))
from (select toLowCardinality(number) k, toString(number) s from numbers(2)) as js1
join (select number+1 k, toLowCardinality(toString(number+1)) s from numbers(2)) as js2
using k order by js1.k, js2.k;
select '-';
select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeName(materialize(js1.s)), toTypeName(materialize(js2.s))
from (select number k, toLowCardinality(toString(number)) s from numbers(2)) as js1
join (select toLowCardinality(number+1) k, toString(number+1) s from numbers(2)) as js2
using k order by js1.k, js2.k;
select '-';
select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeName(materialize(js1.s)), toTypeName(materialize(js2.s))
from (select toLowCardinality(number) k, toLowCardinality(toString(number)) s from numbers(2)) as js1
join (select toLowCardinality(number+1) k, toLowCardinality(toString(number+1)) s from numbers(2)) as js2
using k order by js1.k, js2.k;
select '-';
select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeName(materialize(js1.s)), toTypeName(materialize(js2.s))
from (select toLowCardinality(number) k, toString(number) s from numbers(2)) as js1
full join (select number+1 k, toLowCardinality(toString(number+1)) s from numbers(2)) as js2
using k order by js1.k, js2.k;
select '-';
select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeName(materialize(js1.s)), toTypeName(materialize(js2.s))
from (select number k, toLowCardinality(toString(number)) s from numbers(2)) as js1
full join (select toLowCardinality(number+1) k, toString(number+1) s from numbers(2)) as js2
using k order by js1.k, js2.k;
select '-';
select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeName(materialize(js1.s)), toTypeName(materialize(js2.s))
from (select toLowCardinality(number) k, toLowCardinality(toString(number)) s from numbers(2)) as js1
full join (select toLowCardinality(number+1) k, toLowCardinality(toString(number+1)) s from numbers(2)) as js2
using k order by js1.k, js2.k;

View File

@ -82,6 +82,16 @@
3 3 3
4 4 4
5 5 5
-4 0 -4
-3 0 -3
-2 0 -2
-1 0 -1
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
= inner =
1 1 1
2 2 2
@ -284,6 +294,16 @@
\N \N -2
\N \N -1
\N \N 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
-4 \N -4
-3 \N -3
-2 \N -2
-1 \N -1
0 \N 0
= inner =
1 1 1
2 2 2
@ -402,5 +422,6 @@
1
1
1
1
{% endif -%}
{% endfor -%}

View File

@ -37,7 +37,8 @@ SELECT a, t1.a, t2.a FROM t1 FULL JOIN t2 USING (a) ORDER BY (t1.a, t2.a); {{ is
SELECT '= left =';
SELECT a, t1.a, t2.a FROM t1 LEFT JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
SELECT '= right =';
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a); {{ is_implemented(join_algorithm) }}
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a) SETTINGS allow_experimental_analyzer = 0; {{ is_implemented(join_algorithm) }}
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a) SETTINGS allow_experimental_analyzer = 1; {{ is_implemented(join_algorithm) }}
SELECT '= inner =';
SELECT a, t1.a, t2.a FROM t1 INNER JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
@ -61,10 +62,10 @@ SELECT '= inner =';
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
-- Int64 and UInt64 has no supertype
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT '= agg =';
SELECT sum(a) == 7 FROM t1 FULL JOIN t2 USING (a) WHERE b > 102 AND t2.b <= 204; {{ is_implemented(join_algorithm) }}
@ -118,7 +119,8 @@ SELECT a, t1.a, t2.a FROM t1 FULL JOIN t2 USING (a) ORDER BY (t1.a, t2.a); {{ is
SELECT '= left =';
SELECT a, t1.a, t2.a FROM t1 LEFT JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
SELECT '= right =';
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a); {{ is_implemented(join_algorithm) }}
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a) SETTINGS allow_experimental_analyzer = 0; {{ is_implemented(join_algorithm) }}
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a) SETTINGS allow_experimental_analyzer = 1; {{ is_implemented(join_algorithm) }}
SELECT '= inner =';
SELECT a, t1.a, t2.a FROM t1 INNER JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
@ -142,10 +144,10 @@ SELECT '= inner =';
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
-- Int64 and UInt64 has no supertype
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53,386 }
SELECT '= agg =';
SELECT sum(a) == 7 FROM t1 FULL JOIN t2 USING (a) WHERE b > 102 AND t2.b <= 204; {{ is_implemented(join_algorithm) }}
@ -163,7 +165,10 @@ SELECT a > 0, sum(a), sum(t2.a), sum(b), sum(t2.b) FROM t1 FULL JOIN t2 ON (t1.a
SELECT '= types =';
SELECT any(toTypeName(a)) == 'Nullable(Int32)' AND any(toTypeName(t2.a)) == 'Nullable(Int32)' FROM t1 FULL JOIN t2 USING (a); {{ is_implemented(join_algorithm) }}
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Nullable(Int32)' FROM t1 LEFT JOIN t2 USING (a);
SELECT any(toTypeName(a)) == 'Nullable(Int32)' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 RIGHT JOIN t2 USING (a); {{ is_implemented(join_algorithm) }}
SELECT any(toTypeName(a)) == 'Nullable(Int32)' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 RIGHT JOIN t2 USING (a) SETTINGS allow_experimental_analyzer = 0; {{ is_implemented(join_algorithm) }}
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 RIGHT JOIN t2 USING (a) SETTINGS allow_experimental_analyzer = 1; {{ is_implemented(join_algorithm) }}
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 INNER JOIN t2 USING (a);
SELECT toTypeName(any(a)) == 'Nullable(Int32)' AND toTypeName(any(t2.a)) == 'Nullable(Int32)' FROM t1 FULL JOIN t2 USING (a); {{ is_implemented(join_algorithm) }}

View File

@ -6,3 +6,5 @@
1 1 1 2
2
4
1 1 2
1 1 2

View File

@ -27,6 +27,7 @@ $CLICKHOUSE_CLIENT -nm -q "
select * from test_distributed td asof join $CLICKHOUSE_DATABASE.test_local tl on td.k = tl.k and td.v < tl.v order by tl.v;
select sum(td.v) from test_distributed td asof join $CLICKHOUSE_DATABASE.test_local tl on td.k = tl.k and td.v < tl.v group by tl.k;
select sum(tl.v) from test_distributed td asof join $CLICKHOUSE_DATABASE.test_local tl on td.k = tl.k and td.v < tl.v group by td.k;
select td.k, tl.* from test_distributed td join $CLICKHOUSE_DATABASE.test_local tl on td.k = tl.k;
drop table test_distributed;
drop table test_source;

View File

@ -30,3 +30,27 @@
\N 3
1 \N
2 \N
2 2
2 2
-- { echoOn }
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id AND 1 = 1 SETTINGS allow_experimental_analyzer = 1;
1 0
2 2
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id AND 1 = 1 SETTINGS allow_experimental_analyzer = 1;
2 2
0 3
SELECT * FROM t1 FULL JOIN t2 ON t1.id = t2.id AND 1 = 1 SETTINGS allow_experimental_analyzer = 1;
1 0
2 2
0 3
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id AND 1 = 2 SETTINGS allow_experimental_analyzer = 1;
1 0
2 0
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id AND 1 = 2 SETTINGS allow_experimental_analyzer = 1;
0 2
0 3
SELECT * FROM t1 FULL JOIN t2 ON t1.id = t2.id AND 1 = 2 SETTINGS allow_experimental_analyzer = 1;
1 0
2 0
0 2
0 3

View File

@ -10,23 +10,23 @@ INSERT INTO t2 VALUES (2), (3);
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 JOIN t2 ON 1 = 1;
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 JOIN t2 ON 1;
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 JOIN t2 ON 2 = 2 AND 3 = 3;
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 INNER ANY JOIN t2 ON toNullable(1);
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 INNER ANY JOIN t2 ON toLowCardinality(1);
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 INNER ANY JOIN t2 ON toLowCardinality(toNullable(1));
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 INNER ANY JOIN t2 ON toNullable(toLowCardinality(1));
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 JOIN t2 ON toNullable(1);
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 JOIN t2 ON toLowCardinality(1);
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 JOIN t2 ON toLowCardinality(toNullable(1));
SELECT 70 = 10 * sum(t1.id) + sum(t2.id) AND count() == 4 FROM t1 JOIN t2 ON toNullable(toLowCardinality(1));
SELECT * FROM t1 INNER ANY JOIN t2 ON toUInt16(1); -- { serverError 403 }
SELECT * FROM t1 INNER ANY JOIN t2 ON toInt8(1); -- { serverError 403 }
SELECT * FROM t1 INNER ANY JOIN t2 ON 256; -- { serverError 403 }
SELECT * FROM t1 INNER ANY JOIN t2 ON -1; -- { serverError 403 }
SELECT * FROM t1 INNER ANY JOIN t2 ON toString(1); -- { serverError 403 }
SELECT * FROM t1 JOIN t2 ON toUInt16(1); -- { serverError 403 }
SELECT * FROM t1 JOIN t2 ON toInt8(1); -- { serverError 403 }
SELECT * FROM t1 JOIN t2 ON 256; -- { serverError 403 }
SELECT * FROM t1 JOIN t2 ON -1; -- { serverError 403 }
SELECT * FROM t1 JOIN t2 ON toString(1); -- { serverError 403 }
SELECT '- ON NULL -';
SELECT '- inner -';
SELECT * FROM t1 INNER ANY JOIN t2 ON NULL;
SELECT * FROM t1 INNER ANY JOIN t2 ON 0;
SELECT * FROM t1 INNER ANY JOIN t2 ON 1 = 2;
SELECT * FROM t1 JOIN t2 ON NULL;
SELECT * FROM t1 JOIN t2 ON 0;
SELECT * FROM t1 JOIN t2 ON 1 = 2;
SELECT '- left -';
SELECT * FROM t1 LEFT JOIN t2 ON NULL ORDER BY t1.id, t2.id;
SELECT '- right -';
@ -35,7 +35,7 @@ SELECT '- full -';
SELECT * FROM t1 FULL JOIN t2 ON NULL ORDER BY t1.id, t2.id;
SELECT '- inner -';
SELECT * FROM t1 INNER ANY JOIN t2 ON NULL ORDER BY t1.id NULLS FIRST, t2.id SETTINGS join_use_nulls = 1;
SELECT * FROM t1 JOIN t2 ON NULL ORDER BY t1.id NULLS FIRST, t2.id SETTINGS join_use_nulls = 1;
SELECT '- left -';
SELECT * FROM t1 LEFT JOIN t2 ON NULL ORDER BY t1.id NULLS FIRST, t2.id SETTINGS join_use_nulls = 1;
SELECT '- right -';
@ -43,29 +43,45 @@ SELECT * FROM t1 RIGHT JOIN t2 ON NULL ORDER BY t1.id NULLS FIRST, t2.id SETTING
SELECT '- full -';
SELECT * FROM t1 FULL JOIN t2 ON NULL ORDER BY t1.id NULLS FIRST, t2.id SETTINGS join_use_nulls = 1;
-- in this cases we have AMBIGUOUS_COLUMN_NAME instead of INVALID_JOIN_ON_EXPRESSION
-- in this cases in old analuyzer we have AMBIGUOUS_COLUMN_NAME instead of INVALID_JOIN_ON_EXPRESSION
-- because there's some function in ON expression is not constant itself (result is constant)
SELECT * FROM t1 JOIN t2 ON 1 = 1 SETTINGS join_algorithm = 'full_sorting_merge'; -- { serverError AMBIGUOUS_COLUMN_NAME }
SELECT * FROM t1 JOIN t2 ON 1 = 1 SETTINGS join_algorithm = 'partial_merge'; -- { serverError AMBIGUOUS_COLUMN_NAME }
SELECT * FROM t1 JOIN t2 ON 1 = 1 SETTINGS join_algorithm = 'auto'; -- { serverError AMBIGUOUS_COLUMN_NAME }
SELECT * FROM t1 JOIN t2 ON 1 = 1 SETTINGS join_algorithm = 'full_sorting_merge'; -- { serverError AMBIGUOUS_COLUMN_NAME,NOT_IMPLEMENTED }
SELECT * FROM t1 JOIN t2 ON 1 = 1 SETTINGS join_algorithm = 'partial_merge'; -- { serverError AMBIGUOUS_COLUMN_NAME,NOT_IMPLEMENTED }
SELECT * FROM t1 JOIN t2 ON 1 = 1 SETTINGS join_algorithm = 'auto'; -- { serverError AMBIGUOUS_COLUMN_NAME,NOT_IMPLEMENTED }
SELECT * FROM t1 JOIN t2 ON NULL SETTINGS join_algorithm = 'full_sorting_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON NULL SETTINGS join_algorithm = 'partial_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 LEFT JOIN t2 ON NULL SETTINGS join_algorithm = 'partial_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 RIGHT JOIN t2 ON NULL SETTINGS join_algorithm = 'auto'; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 FULL JOIN t2 ON NULL SETTINGS join_algorithm = 'partial_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON NULL SETTINGS join_algorithm = 'full_sorting_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION,NOT_IMPLEMENTED }
SELECT * FROM t1 JOIN t2 ON NULL SETTINGS join_algorithm = 'partial_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION,NOT_IMPLEMENTED }
SELECT * FROM t1 LEFT JOIN t2 ON NULL SETTINGS join_algorithm = 'partial_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION,NOT_IMPLEMENTED }
SELECT * FROM t1 RIGHT JOIN t2 ON NULL SETTINGS join_algorithm = 'auto'; -- { serverError INVALID_JOIN_ON_EXPRESSION,NOT_IMPLEMENTED }
SELECT * FROM t1 FULL JOIN t2 ON NULL SETTINGS join_algorithm = 'partial_merge'; -- { serverError INVALID_JOIN_ON_EXPRESSION,NOT_IMPLEMENTED }
-- mixing of constant and non-constant expressions in ON is not allowed
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 == 1; -- { serverError AMBIGUOUS_COLUMN_NAME }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 == 2; -- { serverError AMBIGUOUS_COLUMN_NAME }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 == 1 SETTINGS allow_experimental_analyzer = 0; -- { serverError AMBIGUOUS_COLUMN_NAME }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 == 1 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 == 2 SETTINGS allow_experimental_analyzer = 0; -- { serverError AMBIGUOUS_COLUMN_NAME }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 == 2 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 != 1; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 != 1 SETTINGS allow_experimental_analyzer = 0; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 != 1 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND NULL; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 'aaa'; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 'aaa'; -- { serverError INVALID_JOIN_ON_EXPRESSION,ILLEGAL_TYPE_OF_ARGUMENT }
SELECT * FROM t1 JOIN t2 ON 'aaa'; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 0; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 0 SETTINGS allow_experimental_analyzer = 0; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 0 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 SETTINGS allow_experimental_analyzer = 0; -- { serverError INVALID_JOIN_ON_EXPRESSION }
SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND 1 SETTINGS allow_experimental_analyzer = 1;
-- { echoOn }
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id AND 1 = 1 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id AND 1 = 1 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 FULL JOIN t2 ON t1.id = t2.id AND 1 = 1 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id AND 1 = 2 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id AND 1 = 2 SETTINGS allow_experimental_analyzer = 1;
SELECT * FROM t1 FULL JOIN t2 ON t1.id = t2.id AND 1 = 2 SETTINGS allow_experimental_analyzer = 1;
-- { echoOff }
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;

View File

@ -1,5 +1,4 @@
-- Tags: no-tsan, no-asan, no-ubsan, no-msan, no-debug, no-cpu-aarch64, disabled
-- Tag disabled: Parsing inlines may lead to "could not find abbreviation code" (FIXME)
-- Tags: no-tsan, no-asan, no-ubsan, no-msan, no-debug, no-cpu-aarch64
SET allow_introspection_functions = 0;
SELECT addressToLineWithInlines(1); -- { serverError 446 }

View File

@ -45,7 +45,7 @@ SELECT '--- key types';
SELECT * FROM t2 INNER JOIN rdb ON rdb.key == t2.k ORDER BY rdb.key;
-- can't promote right table type
SELECT * FROM (SELECT toUInt64(k) as k FROM t2) as t2 INNER JOIN rdb ON rdb.key == t2.k; -- { serverError TYPE_MISMATCH }
SELECT * FROM (SELECT toUInt64(k) as k FROM t2) as t2 INNER JOIN rdb ON rdb.key == t2.k; -- { serverError NOT_IMPLEMENTED,TYPE_MISMATCH }
-- TODO: support fallcack when right table key type can't be changed
-- SELECT * FROM (SELECT toUInt64(k) as k FROM t2) as t2 INNER JOIN rdb ON rdb.key == t2.k FORMAT Null SETTINGS join_algorithm = 'direct,hash';

View File

@ -12,3 +12,10 @@ y 0 0 1 3
0 0 1 0
y 0 0 1 3
\N 0 \N 10000000000 \N
2 1 1 2
0 1 1 0
0 1 1 0
0 1 1 0
0 0 0 0 1 1 0
y 0 0 0 1 1 3
\N 0 \N \N 10000000000 \N

View File

@ -1,3 +1,5 @@
SET allow_experimental_analyzer = 0;
SET join_algorithm = 'hash';
SELECT * FROM ( SELECT 2 AS x ) AS t1 RIGHT JOIN ( SELECT count('x'), count('y'), 2 AS x ) AS t2 ON t1.x = t2.x;
@ -15,7 +17,18 @@ SELECT * FROM ( SELECT 2 AS x ) AS t1 RIGHT JOIN ( SELECT count('x'), count('y')
SELECT * FROM ( SELECT 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x'), count('y'), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT * FROM ( SELECT 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x') :: Nullable(Int32), count('y'), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT * FROM ( SELECT 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x') :: Nullable(Int32), count('y') :: Nullable(Int32), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT * FROM ( SELECT count('a'), count('b'), count('c'), 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x'), count('y'), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT 'y', * FROM (SELECT count('y'), count('y'), 2 AS x) AS t1 RIGHT JOIN (SELECT count('x'), count('y'), 3 AS x) AS t2 ON t1.x = t2.x;
SELECT * FROM (SELECT arrayJoin([NULL]), 9223372036854775806, arrayJoin([NULL]), NULL AS x) AS t1 RIGHT JOIN (SELECT arrayJoin([arrayJoin([10000000000.])]), NULL AS x) AS t2 ON t1.x = t2.x;
SET allow_experimental_analyzer = 1;
SET join_algorithm = 'hash';
SELECT * FROM ( SELECT 2 AS x ) AS t1 RIGHT JOIN ( SELECT count('x'), count('y'), 2 AS x ) AS t2 ON t1.x = t2.x;
SELECT * FROM ( SELECT 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x'), count('y'), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT * FROM ( SELECT 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x') :: Nullable(Int32), count('y'), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT * FROM ( SELECT 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x') :: Nullable(Int32), count('y') :: Nullable(Int32), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT * FROM ( SELECT count('a'), count('b'), count('c'), 2 AS x ) as t1 RIGHT JOIN ( SELECT count('x'), count('y'), 0 AS x ) AS t2 ON t1.x = t2.x;
SELECT 'y', * FROM (SELECT count('y'), count('y'), 2 AS x) AS t1 RIGHT JOIN (SELECT count('x'), count('y'), 3 AS x) AS t2 ON t1.x = t2.x;

View File

@ -7,8 +7,5 @@
10
bug with constant columns in join keys
a a
a a
a a
a a
1
1

View File

@ -22,20 +22,20 @@ SELECT count() FROM t1 JOIN t2 ON t1.x = t2.x WHERE t1.x % 2 == 0 AND t2.x % 2 =
SELECT 'bug with constant columns in join keys';
SELECT * FROM ( SELECT 'a' AS key ) AS t1
INNER JOIN ( SELECT 'a' AS key GROUP BY ignore(1), ignore(2) WITH CUBE ) AS t2
INNER JOIN ( SELECT 'a' AS key ) AS t2
ON t1.key = t2.key
;
SELECT count() > 1 FROM (EXPLAIN PIPELINE
SELECT * FROM ( SELECT materialize('a') AS key ) AS t1
INNER JOIN ( SELECT materialize('a') AS key GROUP BY ignore(1), ignore(2) WITH CUBE ) AS t2
INNER JOIN ( SELECT materialize('a') AS key ) AS t2
ON t1.key = t2.key
) WHERE explain ilike '%FilterBySetOnTheFlyTransform%'
;
SELECT count() == 0 FROM (EXPLAIN PIPELINE
SELECT * FROM ( SELECT 'a' AS key ) AS t1
INNER JOIN ( SELECT 'a' AS key GROUP BY ignore(1), ignore(2) WITH CUBE ) AS t2
INNER JOIN ( SELECT 'a' AS key ) AS t2
ON t1.key = t2.key
) WHERE explain ilike '%FilterBySetOnTheFlyTransform%'
;

View File

@ -18,6 +18,11 @@ create view v2 as select * from d2;
create table m as v1 engine=Merge(currentDatabase(), '^(v1|v2)$');
{# -- FIXME:
select _table, key from m where (value = 10 and _table = 'v1') or (value = 20 and _table = 'v1') or 0 or 0 settings {{ settings }};
select _table, key from m where (value = 10 and _table = 'v3') or (value = 20 and _table = 'v3') or 0 or 0 settings {{ settings }};
#}
-- avoid reorder
set max_threads=1;
-- { echoOn }

View File

@ -1,4 +1,4 @@
DROP TABLE IF EXISTS t_mutations_subcolumns;
DROP TABLE IF EXISTS t_missed_subcolumns;
SET allow_experimental_object_type = 1;
@ -14,7 +14,7 @@ OPTIMIZE TABLE t_missed_subcolumns FINAL;
SELECT count(), min(id) FROM t_missed_subcolumns;
SELECT * FROM t_missed_subcolumns WHERE obj.k4 = 5 ORDER BY id FORMAT JSONEachRow;
SELECT * FROM t_missed_subcolumns WHERE obj.k4 = 5 ORDER BY id FORMAT JSONEachRow;
SELECT * FROM t_missed_subcolumns WHERE obj.k1.k3 = 'fee' ORDER BY id FORMAT JSONEachRow;

View File

@ -0,0 +1,33 @@
0
1
255
1
10000
4135
65535
256
3455829959
3351772109
4294967295
16777216
18439412204227788800
123294967295
18446744073709551615
0
-1
-128
32767
-9745
128
-8388609
855914552
128
-549755813889
4039370097989451775
128
72057594037927936
-2361183241434822606849
1329227995784915872903807060280344576
-43556142965880123323311949751266331066369
0
1

View File

@ -0,0 +1,61 @@
SELECT byteSwap(0::UInt8);
SELECT byteSwap(1::UInt8);
SELECT byteSwap(255::UInt8);
SELECT byteSwap(256::UInt16);
SELECT byteSwap(4135::UInt16);
SELECT byteSwap(10000::UInt16);
SELECT byteSwap(65535::UInt16);
SELECT byteSwap(65536::UInt32);
SELECT byteSwap(3351772109::UInt32);
SELECT byteSwap(3455829959::UInt32);
SELECT byteSwap(4294967295::UInt32);
SELECT byteSwap(4294967296::UInt64);
SELECT byteSwap(123294967295::UInt64);
SELECT byteSwap(18439412204227788800::UInt64);
SELECT byteSwap(18446744073709551615::UInt64);
SELECT byteSwap(-0::Int8);
SELECT byteSwap(-1::Int8);
SELECT byteSwap(-128::Int8);
SELECT byteSwap(-129::Int16);
SELECT byteSwap(-4135::Int16);
SELECT byteSwap(-32768::Int16);
SELECT byteSwap(-32769::Int32);
SELECT byteSwap(-3351772109::Int32);
SELECT byteSwap(-2147483648::Int32);
SELECT byteSwap(-2147483649::Int64);
SELECT byteSwap(-1242525266376::Int64);
SELECT byteSwap(-9223372036854775808::Int64);
SELECT byteSwap(18446744073709551616::UInt128);
SELECT byteSwap(-9223372036854775809::Int128);
SELECT byteSwap(340282366920938463463374607431768211456::UInt256);
SELECT byteSwap(-170141183460469231731687303715884105729::Int256);
-- Booleans are interpreted as UInt8
SELECT byteSwap(false);
SELECT byteSwap(true);
-- Number of arguments should equal 1
SELECT byteSwap(); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
SELECT byteSwap(128, 129); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
-- Input should be integral
SELECT byteSwap('abc'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(toFixedString('abc', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(toDate('2019-01-01')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(toDate32('2019-01-01')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(toDateTime32(1546300800)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(toDateTime64(1546300800, 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(generateUUIDv4()); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(toDecimal32(2, 4)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT byteSwap(toFloat32(123.456)); -- { serverError NOT_IMPLEMENTED }
SELECT byteSwap(toFloat64(123.456)); -- { serverError NOT_IMPLEMENTED }

View File

@ -50,6 +50,8 @@ in_memory_parts_enable_wal
in_memory_parts_insert_sync
max_part_loading_threads
max_part_removal_threads
merge_tree_clear_old_broken_detached_parts_ttl_timeout_seconds
merge_tree_enable_clear_old_broken_detached
min_bytes_for_compact_part
min_relative_delay_to_yield_leadership
min_rows_for_compact_part

View File

@ -0,0 +1,13 @@
SET allow_experimental_inverted_index = 0;
DROP TABLE IF EXISTS tab;
CREATE TABLE tab
(
`key` UInt64,
`str` String
)
ENGINE = MergeTree
ORDER BY key;
ALTER TABLE tab ADD INDEX inv_idx(str) TYPE inverted(0); -- { serverError SUPPORT_IS_DISABLED }
DROP TABLE tab;

Some files were not shown because too many files have changed in this diff Show More