Merge branch 'master' into read-cgroup-memory-usage-async-metrics

This commit is contained in:
Antonio Andelic 2024-07-26 11:17:54 +02:00
commit 71a5a42f8f
285 changed files with 3811 additions and 3909 deletions

View File

@ -269,7 +269,7 @@ jobs:
- name: Check Workflow results - name: Check Workflow results
run: | run: |
export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json" export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json"
cat >> "$WORKFLOW_RESULT_FILE" << 'EOF' cat > "$WORKFLOW_RESULT_FILE" << 'EOF'
${{ toJson(needs) }} ${{ toJson(needs) }}
EOF EOF
python3 ./tests/ci/ci_buddy.py --check-wf-status python3 ./tests/ci/ci_buddy.py --check-wf-status

View File

@ -9,19 +9,64 @@ on: # yamllint disable-line rule:truthy
- cron: '0 */6 * * *' - cron: '0 */6 * * *'
workflow_dispatch: workflow_dispatch:
jobs: jobs:
RunConfig:
runs-on: [self-hosted, style-checker-aarch64]
outputs:
data: ${{ steps.runconfig.outputs.CI_DATA }}
steps:
- name: DebugInfo
uses: hmarr/debug-action@f7318c783045ac39ed9bb497e22ce835fdafbfe6
- name: Check out repository code
uses: ClickHouse/checkout@v1
with:
clear-repository: true # to ensure correct digests
fetch-depth: 0 # to get version
filter: tree:0
- name: PrepareRunConfig
id: runconfig
run: |
echo "::group::configure CI run"
python3 "$GITHUB_WORKSPACE/tests/ci/ci.py" --configure --workflow "$GITHUB_WORKFLOW" --outfile ${{ runner.temp }}/ci_run_data.json
echo "::endgroup::"
echo "::group::CI run configure results"
python3 -m json.tool ${{ runner.temp }}/ci_run_data.json
echo "::endgroup::"
{
echo 'CI_DATA<<EOF'
cat ${{ runner.temp }}/ci_run_data.json
echo 'EOF'
} >> "$GITHUB_OUTPUT"
KeeperJepsenRelease: KeeperJepsenRelease:
uses: ./.github/workflows/reusable_simple_job.yml needs: [RunConfig]
uses: ./.github/workflows/reusable_test.yml
with: with:
test_name: Jepsen keeper check test_name: ClickHouse Keeper Jepsen
runner_type: style-checker runner_type: style-checker-aarch64
report_required: true data: ${{ needs.RunConfig.outputs.data }}
run_command: | run_command: |
python3 jepsen_check.py keeper python3 jepsen_check.py keeper
# ServerJepsenRelease: ServerJepsenRelease:
# uses: ./.github/workflows/reusable_simple_job.yml if: false # skip for server
# with: needs: [RunConfig]
# test_name: Jepsen server check uses: ./.github/workflows/reusable_test.yml
# runner_type: style-checker with:
# run_command: | test_name: ClickHouse Server Jepsen
# cd "$REPO_COPY/tests/ci" runner_type: style-checker-aarch64
# python3 jepsen_check.py server data: ${{ needs.RunConfig.outputs.data }}
run_command: |
python3 jepsen_check.py server
CheckWorkflow:
if: ${{ !cancelled() }}
needs: [RunConfig, ServerJepsenRelease, KeeperJepsenRelease]
runs-on: [self-hosted, style-checker-aarch64]
steps:
- name: Check out repository code
uses: ClickHouse/checkout@v1
- name: Check Workflow results
run: |
export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json"
cat >> "$WORKFLOW_RESULT_FILE" << 'EOF'
${{ toJson(needs) }}
EOF
python3 ./tests/ci/ci_buddy.py --check-wf-status

View File

@ -135,7 +135,7 @@ jobs:
- name: Check Workflow results - name: Check Workflow results
run: | run: |
export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json" export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json"
cat >> "$WORKFLOW_RESULT_FILE" << 'EOF' cat > "$WORKFLOW_RESULT_FILE" << 'EOF'
${{ toJson(needs) }} ${{ toJson(needs) }}
EOF EOF
python3 ./tests/ci/ci_buddy.py --check-wf-status python3 ./tests/ci/ci_buddy.py --check-wf-status

View File

@ -108,7 +108,7 @@ jobs:
- name: Check Workflow results - name: Check Workflow results
run: | run: |
export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json" export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json"
cat >> "$WORKFLOW_RESULT_FILE" << 'EOF' cat > "$WORKFLOW_RESULT_FILE" << 'EOF'
${{ toJson(needs) }} ${{ toJson(needs) }}
EOF EOF
python3 ./tests/ci/ci_buddy.py --check-wf-status python3 ./tests/ci/ci_buddy.py --check-wf-status

View File

@ -54,7 +54,7 @@ jobs:
- name: Check Workflow results - name: Check Workflow results
run: | run: |
export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json" export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json"
cat >> "$WORKFLOW_RESULT_FILE" << 'EOF' cat > "$WORKFLOW_RESULT_FILE" << 'EOF'
${{ toJson(needs) }} ${{ toJson(needs) }}
EOF EOF
python3 ./tests/ci/ci_buddy.py --check-wf-status python3 ./tests/ci/ci_buddy.py --check-wf-status

View File

@ -152,8 +152,9 @@ jobs:
CheckReadyForMerge: CheckReadyForMerge:
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
# Test_2 or Test_3 must not have jobs required for Mergeable check # Test_2 or Test_3 do not have the jobs required for Mergeable check,
needs: [RunConfig, BuildDockers, StyleCheck, FastTest, Builds_1, Builds_2, Builds_Report, Tests_1] # however, set them as "needs" to get all checks results before the automatic merge occurs.
needs: [RunConfig, BuildDockers, StyleCheck, FastTest, Builds_1, Builds_2, Builds_Report, Tests_1, Tests_2, Tests_3]
runs-on: [self-hosted, style-checker-aarch64] runs-on: [self-hosted, style-checker-aarch64]
steps: steps:
- name: Check out repository code - name: Check out repository code
@ -168,7 +169,7 @@ jobs:
- name: Check Workflow results - name: Check Workflow results
run: | run: |
export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json" export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json"
cat >> "$WORKFLOW_RESULT_FILE" << 'EOF' cat > "$WORKFLOW_RESULT_FILE" << 'EOF'
${{ toJson(needs) }} ${{ toJson(needs) }}
EOF EOF
python3 ./tests/ci/ci_buddy.py --check-wf-status python3 ./tests/ci/ci_buddy.py --check-wf-status

View File

@ -489,7 +489,7 @@ jobs:
- name: Check Workflow results - name: Check Workflow results
run: | run: |
export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json" export WORKFLOW_RESULT_FILE="/tmp/workflow_results.json"
cat >> "$WORKFLOW_RESULT_FILE" << 'EOF' cat > "$WORKFLOW_RESULT_FILE" << 'EOF'
${{ toJson(needs) }} ${{ toJson(needs) }}
EOF EOF

View File

@ -1,4 +1,5 @@
### Table of Contents ### Table of Contents
**[ClickHouse release v24.7, 2024-07-30](#247)**<br/>
**[ClickHouse release v24.6, 2024-07-01](#246)**<br/> **[ClickHouse release v24.6, 2024-07-01](#246)**<br/>
**[ClickHouse release v24.5, 2024-05-30](#245)**<br/> **[ClickHouse release v24.5, 2024-05-30](#245)**<br/>
**[ClickHouse release v24.4, 2024-04-30](#244)**<br/> **[ClickHouse release v24.4, 2024-04-30](#244)**<br/>
@ -9,6 +10,178 @@
# 2024 Changelog # 2024 Changelog
### <a id="247"></a> ClickHouse release 24.7, 2024-07-30
#### Backward Incompatible Change
* Forbid `CRATE MATERIALIZED VIEW ... ENGINE Replicated*MergeTree POPULATE AS SELECT ...` with Replicated databases. [#63963](https://github.com/ClickHouse/ClickHouse/pull/63963) ([vdimir](https://github.com/vdimir)).
* `clickhouse-keeper-client` will only accept paths in string literals, such as `ls '/hello/world'`, not bare strings such as `ls /hello/world`. [#65494](https://github.com/ClickHouse/ClickHouse/pull/65494) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Metric `KeeperOutstandingRequets` was renamed to `KeeperOutstandingRequests`. [#66206](https://github.com/ClickHouse/ClickHouse/pull/66206) ([Robert Schulze](https://github.com/rschu1ze)).
* Remove `is_deterministic` field from the `system.functions` table. [#66630](https://github.com/ClickHouse/ClickHouse/pull/66630) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Function `tuple` will now try to construct named tuples in query (controlled by `enable_named_columns_in_function_tuple`). Introduce function `tupleNames` to extract names from tuples. [#54881](https://github.com/ClickHouse/ClickHouse/pull/54881) ([Amos Bird](https://github.com/amosbird)).
#### New Feature
* Add `ASOF JOIN` support for `full_sorting_join` algorithm. [#55051](https://github.com/ClickHouse/ClickHouse/pull/55051) ([vdimir](https://github.com/vdimir)).
* Add new window function `percent_rank`. [#62747](https://github.com/ClickHouse/ClickHouse/pull/62747) ([lgbo](https://github.com/lgbo-ustc)).
* Support JWT authentication in `clickhouse-client` (will be available only in ClickHouse Cloud). [#62829](https://github.com/ClickHouse/ClickHouse/pull/62829) ([Konstantin Bogdanov](https://github.com/thevar1able)).
* Add SQL functions `changeYear`, `changeMonth`, `changeDay`, `changeHour`, `changeMinute`, `changeSecond`. For example, `SELECT changeMonth(toDate('2024-06-14'), 7)` returns date `2024-07-14`. [#63186](https://github.com/ClickHouse/ClickHouse/pull/63186) ([cucumber95](https://github.com/cucumber95)).
* Introduce startup scripts, which allow the execution of preconfigured queries at the startup stage. [#64889](https://github.com/ClickHouse/ClickHouse/pull/64889) ([pufit](https://github.com/pufit)).
* Support accept_invalid_certificate in client's config in order to allow for client to connect over secure TCP to a server running with self-signed certificate - can be used as a shorthand for corresponding `openSSL` client settings `verificationMode=none` + `invalidCertificateHandler.name=AcceptCertificateHandler`. [#65238](https://github.com/ClickHouse/ClickHouse/pull/65238) ([peacewalker122](https://github.com/peacewalker122)).
* Add system.error_log which contains history of error values from table system.errors, periodically flushed to disk. [#65381](https://github.com/ClickHouse/ClickHouse/pull/65381) ([Pablo Marcos](https://github.com/pamarcos)).
* Add aggregate function `groupConcat`. About the same as `arrayStringConcat( groupArray(column), ',')` Can receive 2 parameters: a string delimiter and the number of elements to be processed. [#65451](https://github.com/ClickHouse/ClickHouse/pull/65451) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
* Add AzureQueue storage. [#65458](https://github.com/ClickHouse/ClickHouse/pull/65458) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Add a new setting to disable/enable writing page index into parquet files. [#65475](https://github.com/ClickHouse/ClickHouse/pull/65475) ([lgbo](https://github.com/lgbo-ustc)).
* Introduce `logger.console_log_level` server config to control the log level to the console (if enabled). [#65559](https://github.com/ClickHouse/ClickHouse/pull/65559) ([Azat Khuzhin](https://github.com/azat)).
* Automatically append a wildcard `*` to the end of a directory path with table function `file`. [#66019](https://github.com/ClickHouse/ClickHouse/pull/66019) ([Zhidong (David) Guo](https://github.com/Gun9niR)).
* Add `--memory-usage` option to client in non interactive mode. [#66393](https://github.com/ClickHouse/ClickHouse/pull/66393) ([vdimir](https://github.com/vdimir)).
* Make an interactive client for clickhouse-disks, add local disk from the local directory. [#64446](https://github.com/ClickHouse/ClickHouse/pull/64446) ([Daniil Ivanik](https://github.com/divanik)).
* When lightweight delete happens on a table with projection(s), users have choices either throw an exception (by default) or drop the projection [#65594](https://github.com/ClickHouse/ClickHouse/pull/65594) ([jsc0218](https://github.com/jsc0218)).
#### Experimental Feature
* Change binary serialization of Variant data type: add `compact` mode to avoid writing the same discriminator multiple times for granules with single variant or with only NULL values. Add MergeTree setting `use_compact_variant_discriminators_serialization` that is enabled by default. Note that Variant type is still experimental and backward-incompatible change in serialization is ok. [#62774](https://github.com/ClickHouse/ClickHouse/pull/62774) ([Kruglov Pavel](https://github.com/Avogar)).
* Support rocksdb as backend storage of keeper. [#56626](https://github.com/ClickHouse/ClickHouse/pull/56626) ([Han Fei](https://github.com/hanfei1991)).
* Refactor JSONExtract functions, support more types including experimental Dynamic type. [#66046](https://github.com/ClickHouse/ClickHouse/pull/66046) ([Kruglov Pavel](https://github.com/Avogar)).
* Support null map subcolumn for Variant and Dynamic subcolumns. [#66178](https://github.com/ClickHouse/ClickHouse/pull/66178) ([Kruglov Pavel](https://github.com/Avogar)).
* Fix reading dynamic subcolumns from altered Memory table. Previously if `max_types` parameter of a Dynamic type was changed in Memory table via alter, further subcolumns reading can return wrong result. [#66066](https://github.com/ClickHouse/ClickHouse/pull/66066) ([Kruglov Pavel](https://github.com/Avogar)).
* Add support for `cluster_for_parallel_replicas` when using custom key parallel replicas. It allows you to use parallel replicas with custom key with MergeTree tables. [#65453](https://github.com/ClickHouse/ClickHouse/pull/65453) ([Antonio Andelic](https://github.com/antonio2368)).
#### Performance Improvement
* Enable `optimize_functions_to_subcolumns` by default. [#58661](https://github.com/ClickHouse/ClickHouse/pull/58661) ([Anton Popov](https://github.com/CurtizJ)).
* Replace int to string algorithm with a faster one (from a modified amdn/itoa to a modified jeaiii/itoa). [#61661](https://github.com/ClickHouse/ClickHouse/pull/61661) ([Raúl Marín](https://github.com/Algunenano)).
* Sizes of hash tables created by join (`parallel_hash` algorithm) is collected and cached now. This information will be used to preallocate space in hash tables for subsequent query executions and save time on hash table resizes. [#64553](https://github.com/ClickHouse/ClickHouse/pull/64553) ([Nikita Taranov](https://github.com/nickitat)).
* Optimized queries with `ORDER BY` primary key and `WHERE` that have a condition with high selectivity by using of buffering. It is controlled by setting `read_in_order_use_buffering` (enabled by default) and can increase memory usage of query. [#64607](https://github.com/ClickHouse/ClickHouse/pull/64607) ([Anton Popov](https://github.com/CurtizJ)).
* Improve performance of loading `plain_rewritable` metadata. [#65634](https://github.com/ClickHouse/ClickHouse/pull/65634) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Attaching tables on read-only disks will use fewer resources by not loading outdated parts. [#65635](https://github.com/ClickHouse/ClickHouse/pull/65635) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Support minmax hyperrectangle for Set indices. [#65676](https://github.com/ClickHouse/ClickHouse/pull/65676) ([AntiTopQuark](https://github.com/AntiTopQuark)).
* Unload primary index of outdated parts to reduce total memory usage. [#65852](https://github.com/ClickHouse/ClickHouse/pull/65852) ([Anton Popov](https://github.com/CurtizJ)).
* Functions `replaceRegexpAll` and `replaceRegexpOne` are now significantly faster if the pattern is trivial, i.e. contains no metacharacters, pattern classes, flags, grouping characters etc. (Thanks to Taiyang Li). [#66185](https://github.com/ClickHouse/ClickHouse/pull/66185) ([Robert Schulze](https://github.com/rschu1ze)).
* s3 requests: Reduce retry time for queries, increase retries count for backups. 8.5 minutes and 100 retires for queries, 1.2 hours and 1000 retries for backup restore. [#65232](https://github.com/ClickHouse/ClickHouse/pull/65232) ([Sema Checherinda](https://github.com/CheSema)).
* Support query plan LIMIT optimization. Support LIMIT pushdown for PostgreSQL storage and table function. [#65454](https://github.com/ClickHouse/ClickHouse/pull/65454) ([Maksim Kita](https://github.com/kitaisreal)).
* Improved ZooKeeper load balancing. The current session doesn't expire until the optimal nodes become available despite `fallback_session_lifetime`. Added support for AZ-aware balancing. [#65570](https://github.com/ClickHouse/ClickHouse/pull/65570) ([Alexander Tokmakov](https://github.com/tavplubix)).
* DatabaseCatalog drops tables faster by using up to database_catalog_drop_table_concurrency threads. [#66065](https://github.com/ClickHouse/ClickHouse/pull/66065) ([Sema Checherinda](https://github.com/CheSema)).
#### Improvement
* The setting `optimize_trivial_insert_select` is disabled by default. In most cases, it should be beneficial. Nevertheless, if you are seeing slower INSERT SELECT or increased memory usage, you can enable it back or `SET compatibility = '24.6'`. [#58970](https://github.com/ClickHouse/ClickHouse/pull/58970) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Print stacktrace and diagnostic info if `clickhouse-client` or `clickhouse-local` crashes. [#61109](https://github.com/ClickHouse/ClickHouse/pull/61109) ([Alexander Tokmakov](https://github.com/tavplubix)).
* The result of `SHOW INDEX | INDEXES | INDICES | KEYS` was previously sorted by the primary key column names. Since this was unintuitive, the result is now sorted by the position of the primary key columns within the primary key. [#61131](https://github.com/ClickHouse/ClickHouse/pull/61131) ([Robert Schulze](https://github.com/rschu1ze)).
* Change how deduplication for Materialized Views works. Fixed a lot of cases like: - on destination table: data is split for 2 or more blocks and that blocks is considered as duplicate when that block is inserted in parallel. - on MV destination table: the equal blocks are deduplicated, that happens when MV often produces equal data as a result for different input data due to performing aggregation. - on MV destination table: the equal blocks which comes from different MV are deduplicated. [#61601](https://github.com/ClickHouse/ClickHouse/pull/61601) ([Sema Checherinda](https://github.com/CheSema)).
* Allow matching column names in a case insensitive manner when reading json files (`input_format_json_ignore_key_case`). [#61750](https://github.com/ClickHouse/ClickHouse/pull/61750) ([kevinyhzou](https://github.com/KevinyhZou)).
* Support reading partitioned data DeltaLake data. Infer DeltaLake schema by reading metadata instead of data. [#63201](https://github.com/ClickHouse/ClickHouse/pull/63201) ([Kseniia Sumarokova](https://github.com/kssenii)).
* In composable protocols TLS layer accepted only `certificateFile` and `privateKeyFile` parameters. https://clickhouse.com/docs/en/operations/settings/composable-protocols. [#63985](https://github.com/ClickHouse/ClickHouse/pull/63985) ([Anton Ivashkin](https://github.com/ianton-ru)).
* Added profile event `SelectQueriesWithPrimaryKeyUsage` which indicates how many SELECT queries use the primary key to evaluate the WHERE clause. [#64492](https://github.com/ClickHouse/ClickHouse/pull/64492) ([0x01f](https://github.com/0xfei)).
* `StorageS3Queue` related fixes and improvements. Deduce a default value of `s3queue_processing_threads_num` according to the number of physical cpu cores on the server (instead of the previous default value as 1). Set default value of `s3queue_loading_retries` to 10. Fix possible vague "Uncaught exception" in exception column of `system.s3queue`. Do not increment retry count on `MEMORY_LIMIT_EXCEEDED` exception. Move files commit to a stage after insertion into table fully finished to avoid files being commited while not inserted. Add settings `s3queue_max_processed_files_before_commit`, `s3queue_max_processed_rows_before_commit`, `s3queue_max_processed_bytes_before_commit`, `s3queue_max_processing_time_sec_before_commit`, to better control commit and flush time. [#65046](https://github.com/ClickHouse/ClickHouse/pull/65046) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Support aliases in parametrized view function (only new analyzer). [#65190](https://github.com/ClickHouse/ClickHouse/pull/65190) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Updated to mask account key in logs in azureBlobStorage. [#65273](https://github.com/ClickHouse/ClickHouse/pull/65273) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
* Partition pruning for `IN` predicates when filter expression is a part of `PARTITION BY` expression. [#65335](https://github.com/ClickHouse/ClickHouse/pull/65335) ([Eduard Karacharov](https://github.com/korowa)).
* Add system tables with main information about all detached tables. [#65400](https://github.com/ClickHouse/ClickHouse/pull/65400) ([Konstantin Morozov](https://github.com/k-morozov)).
* `arrayMin`/`arrayMax` can be applicable to all data types that are comparable. [#65455](https://github.com/ClickHouse/ClickHouse/pull/65455) ([pn](https://github.com/chloro-pn)).
* Improved memory accounting for cgroups v2 to exclude the amount occupied by the page cache. [#65470](https://github.com/ClickHouse/ClickHouse/pull/65470) ([Nikita Taranov](https://github.com/nickitat)).
* Do not create format settings for each row when serializing chunks to insert to EmbeddedRocksDB table. [#65474](https://github.com/ClickHouse/ClickHouse/pull/65474) ([Duc Canh Le](https://github.com/canhld94)).
* Reduce `clickhouse-local` prompt to just `:)`. `getFQDNOrHostName()` takes too long on macOS, and we don't want a hostname in the prompt for `clickhouse-local` anyway. [#65510](https://github.com/ClickHouse/ClickHouse/pull/65510) ([Konstantin Bogdanov](https://github.com/thevar1able)).
* Avoid printing a message from jemalloc about per-CPU arenas on low-end virtual machines. [#65532](https://github.com/ClickHouse/ClickHouse/pull/65532) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Disable filesystem cache background download by default. It will be enabled back when we fix the issue with possible "Memory limit exceeded" because memory deallocation is done outside of query context (while buffer is allocated inside of query context) if we use background download threads. Plus we need to add a separate setting to define max size to download for background workers (currently it is limited by max_file_segment_size, which might be too big). [#65534](https://github.com/ClickHouse/ClickHouse/pull/65534) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Add new option to config `<config_reload_interval_ms>` which allow to specify how often clickhouse will reload config. [#65545](https://github.com/ClickHouse/ClickHouse/pull/65545) ([alesapin](https://github.com/alesapin)).
* Implement binary encoding for ClickHouse data types and add its specification in docs. Use it in Dynamic binary serialization, allow to use it in RowBinaryWithNamesAndTypes and Native formats under settings. [#65546](https://github.com/ClickHouse/ClickHouse/pull/65546) ([Kruglov Pavel](https://github.com/Avogar)).
* Improved ZooKeeper load balancing. The current session doesn't expire until the optimal nodes become available despite `fallback_session_lifetime`. Added support for AZ-aware balancing. [#65570](https://github.com/ClickHouse/ClickHouse/pull/65570) ([Alexander Tokmakov](https://github.com/tavplubix)).
* Server settings `compiled_expression_cache_size` and `compiled_expression_cache_elements_size` are now shown in `system.server_settings`. [#65584](https://github.com/ClickHouse/ClickHouse/pull/65584) ([Robert Schulze](https://github.com/rschu1ze)).
* Add support for user identification based on x509 SubjectAltName extension. [#65626](https://github.com/ClickHouse/ClickHouse/pull/65626) ([Anton Kozlov](https://github.com/tonickkozlov)).
* `clickhouse-local` will respect the `max_server_memory_usage` and `max_server_memory_usage_to_ram_ratio` from the configuration file. It will also set the max memory usage to 90% of the system memory by default, like `clickhouse-server` does. [#65697](https://github.com/ClickHouse/ClickHouse/pull/65697) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Add a script to backup your files to ClickHouse. [#65699](https://github.com/ClickHouse/ClickHouse/pull/65699) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* PostgreSQL source support cancel. [#65722](https://github.com/ClickHouse/ClickHouse/pull/65722) ([Maksim Kita](https://github.com/kitaisreal)).
* Make allow_experimental_analyzer be controlled by the initiator for distributed queries. This ensures compatibility and correctness during operations in mixed version clusters. [#65777](https://github.com/ClickHouse/ClickHouse/pull/65777) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
* Respect cgroup CPU limit in Keeper. [#65819](https://github.com/ClickHouse/ClickHouse/pull/65819) ([Antonio Andelic](https://github.com/antonio2368)).
* Allow to use `concat` function with empty arguments ``` sql :) select concat();. [#65887](https://github.com/ClickHouse/ClickHouse/pull/65887) ([李扬](https://github.com/taiyang-li)).
* Allow controlling named collections in clickhouse-local. [#65973](https://github.com/ClickHouse/ClickHouse/pull/65973) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Improve Azure profile events. [#65999](https://github.com/ClickHouse/ClickHouse/pull/65999) ([alesapin](https://github.com/alesapin)).
* Support ORC file read by writer time zone. [#66025](https://github.com/ClickHouse/ClickHouse/pull/66025) ([kevinyhzou](https://github.com/KevinyhZou)).
* Add settings to control connection to the PostgreSQL. * Setting `postgresql_connection_attempt_timeout` specifies the value passed to `connect_timeout` parameter of connection URL. * Setting `postgresql_connection_pool_retries` specifies the number of retries to establish a connection to the PostgreSQL end-point. [#66232](https://github.com/ClickHouse/ClickHouse/pull/66232) ([Dmitry Novik](https://github.com/novikd)).
* Reduce inaccuracy of input_wait_elapsed_us/input_wait_elapsed_us/elapsed_us. [#66239](https://github.com/ClickHouse/ClickHouse/pull/66239) ([Azat Khuzhin](https://github.com/azat)).
* Improve FilesystemCache ProfileEvents. [#66249](https://github.com/ClickHouse/ClickHouse/pull/66249) ([zhukai](https://github.com/nauu)).
* Add settings to ignore ON CLUSTER clause in queries for named collection management with replicated storage. [#66288](https://github.com/ClickHouse/ClickHouse/pull/66288) ([MikhailBurdukov](https://github.com/MikhailBurdukov)).
* Function `generateSnowflakeID` now allows to specify a machine ID as a parameter to prevent collisions in large clusters. [#66374](https://github.com/ClickHouse/ClickHouse/pull/66374) ([ZAWA_ll](https://github.com/Zawa-ll)).
* Disable suspending on Ctrl+Z in interactive mode. This is a common trap and is not expected behavior for almost all users. I imagine only a few extreme power users could appreciate suspending terminal applications to the background, but I don't know any. [#66511](https://github.com/ClickHouse/ClickHouse/pull/66511) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Add option for validating the Primary key type in Dictionaries. Without this option for simple layouts any column type will be implicitly converted to UInt64. ### Documentation entry for user-facing changes. [#66595](https://github.com/ClickHouse/ClickHouse/pull/66595) ([MikhailBurdukov](https://github.com/MikhailBurdukov)).
#### Bug Fix (user-visible misbehavior in an official stable release)
* Fix unexpected size of low cardinality column in function calls. [#65298](https://github.com/ClickHouse/ClickHouse/pull/65298) ([Raúl Marín](https://github.com/Algunenano)).
* Check cyclic dependencies on CREATE/REPLACE/RENAME/EXCHANGE queries and throw an exception if there is a cyclic dependency. Previously such cyclic dependencies could lead to a deadlock during server startup. Also fix some bugs in dependencies creation. [#65405](https://github.com/ClickHouse/ClickHouse/pull/65405) ([Kruglov Pavel](https://github.com/Avogar)).
* Fix crash in maxIntersections. [#65689](https://github.com/ClickHouse/ClickHouse/pull/65689) ([Raúl Marín](https://github.com/Algunenano)).
* Fix the VALID UNTIL clause in the user definition resetting after a restart. [#66409](https://github.com/ClickHouse/ClickHouse/pull/66409) ([Nikolay Degterinsky](https://github.com/evillique)).
* Fix SHOW MERGES remaining time. [#66735](https://github.com/ClickHouse/ClickHouse/pull/66735) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* `Query was cancelled` might have been printed twice in clickhouse-client. This behaviour is fixed. [#66005](https://github.com/ClickHouse/ClickHouse/pull/66005) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
* Fixed crash while using MaterializedMySQL with TABLE OVERRIDE that maps MySQL NULL field into ClickHouse not NULL field. [#54649](https://github.com/ClickHouse/ClickHouse/pull/54649) ([Filipp Ozinov](https://github.com/bakwc)).
* Fix logical error when PREWHERE expression read no columns and table has no adaptive index granularity (very old table). [#59173](https://github.com/ClickHouse/ClickHouse/pull/59173) ([Alexander Gololobov](https://github.com/davenger)).
* Fix bug with cancellation buffer when canceling a query. [#64478](https://github.com/ClickHouse/ClickHouse/pull/64478) ([Sema Checherinda](https://github.com/CheSema)).
* Fix filling parts columns from metadata (when columns.txt does not exists). [#64757](https://github.com/ClickHouse/ClickHouse/pull/64757) ([Azat Khuzhin](https://github.com/azat)).
* Fix crash for `ALTER TABLE ... ON CLUSTER ... MODIFY SQL SECURITY`. [#64957](https://github.com/ClickHouse/ClickHouse/pull/64957) ([pufit](https://github.com/pufit)).
* Fix crash on destroying AccessControl: add explicit shutdown. [#64993](https://github.com/ClickHouse/ClickHouse/pull/64993) ([Vitaly Baranov](https://github.com/vitlibar)).
* Eliminate injective function in argument of functions `uniq*` recursively. This used to work correctly but was broken in the new analyzer. [#65140](https://github.com/ClickHouse/ClickHouse/pull/65140) ([Duc Canh Le](https://github.com/canhld94)).
* Fix unexpected projection name when query with CTE. [#65267](https://github.com/ClickHouse/ClickHouse/pull/65267) ([wudidapaopao](https://github.com/wudidapaopao)).
* Require `dictGet` privilege when accessing dictionaries via direct query or the `Dictionary` table engine. [#65359](https://github.com/ClickHouse/ClickHouse/pull/65359) ([Joe Lynch](https://github.com/joelynch)).
* Fix user-specific S3 auth with incremental backups. [#65481](https://github.com/ClickHouse/ClickHouse/pull/65481) ([Antonio Andelic](https://github.com/antonio2368)).
* Disable `non-intersecting-parts` optimization for queries with `FINAL` in case of `read-in-order` optimization was enabled. This could lead to an incorrect query result. As a workaround, disable `do_not_merge_across_partitions_select_final` and `split_parts_ranges_into_intersecting_and_non_intersecting_final` before this fix is merged. [#65505](https://github.com/ClickHouse/ClickHouse/pull/65505) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Fix getting exception `Index out of bound for blob metadata` in case all files from list batch were filtered out. [#65523](https://github.com/ClickHouse/ClickHouse/pull/65523) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Fix NOT_FOUND_COLUMN_IN_BLOCK for deduplicate merge of projection. [#65573](https://github.com/ClickHouse/ClickHouse/pull/65573) ([Yakov Olkhovskiy](https://github.com/yakov-olkhovskiy)).
* Fixed bug in MergeJoin. Column in sparse serialisation might be treated as a column of its nested type though the required conversion wasn't performed. [#65632](https://github.com/ClickHouse/ClickHouse/pull/65632) ([Nikita Taranov](https://github.com/nickitat)).
* Fixed a bug that compatibility level '23.4' was not properly applied. [#65737](https://github.com/ClickHouse/ClickHouse/pull/65737) ([cw5121](https://github.com/cw5121)).
* Fix odbc table with nullable fields. [#65738](https://github.com/ClickHouse/ClickHouse/pull/65738) ([Rodolphe Dugé de Bernonville](https://github.com/RodolpheDuge)).
* Fix data race in `TCPHandler`, which could happen on fatal error. [#65744](https://github.com/ClickHouse/ClickHouse/pull/65744) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Fix invalid exceptions in function `parseDateTime` with `%F` and `%D` placeholders. [#65768](https://github.com/ClickHouse/ClickHouse/pull/65768) ([Antonio Andelic](https://github.com/antonio2368)).
* For queries that read from `PostgreSQL`, cancel the internal `PostgreSQL` query if the ClickHouse query is finished. Otherwise, `ClickHouse` query cannot be canceled until the internal `PostgreSQL` query is finished. [#65771](https://github.com/ClickHouse/ClickHouse/pull/65771) ([Maksim Kita](https://github.com/kitaisreal)).
* Fix a bug in short circuit logic when old analyzer and dictGetOrDefault is used. [#65802](https://github.com/ClickHouse/ClickHouse/pull/65802) ([jsc0218](https://github.com/jsc0218)).
* Fix a bug leads to EmbeddedRocksDB with TTL write corrupted SST files. [#65816](https://github.com/ClickHouse/ClickHouse/pull/65816) ([Duc Canh Le](https://github.com/canhld94)).
* Functions `bitTest`, `bitTestAll`, and `bitTestAny` now return an error if the specified bit index is out-of-bounds [#65818](https://github.com/ClickHouse/ClickHouse/pull/65818) ([Pablo Marcos](https://github.com/pamarcos)).
* Setting `join_any_take_last_row` is supported in any query with hash join. [#65820](https://github.com/ClickHouse/ClickHouse/pull/65820) ([vdimir](https://github.com/vdimir)).
* Better handling of join conditions involving `IS NULL` checks (for example `ON (a = b AND (a IS NOT NULL) AND (b IS NOT NULL) ) OR ( (a IS NULL) AND (b IS NULL) )` is rewritten to `ON a <=> b`), fix incorrect optimization when condition other then `IS NULL` are present. [#65835](https://github.com/ClickHouse/ClickHouse/pull/65835) ([vdimir](https://github.com/vdimir)).
* Functions `bitShiftLeft` and `bitShitfRight` return an error for out of bounds shift positions [#65838](https://github.com/ClickHouse/ClickHouse/pull/65838) ([Pablo Marcos](https://github.com/pamarcos)).
* Fix growing memory usage in S3Queue. [#65839](https://github.com/ClickHouse/ClickHouse/pull/65839) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Fix tie handling in `arrayAUC` to match sklearn. [#65840](https://github.com/ClickHouse/ClickHouse/pull/65840) ([gabrielmcg44](https://github.com/gabrielmcg44)).
* Fix possible issues with MySQL server protocol TLS connections. [#65917](https://github.com/ClickHouse/ClickHouse/pull/65917) ([Azat Khuzhin](https://github.com/azat)).
* Fix possible issues with MySQL client protocol TLS connections. [#65938](https://github.com/ClickHouse/ClickHouse/pull/65938) ([Azat Khuzhin](https://github.com/azat)).
* Fix handling of `SSL_ERROR_WANT_READ`/`SSL_ERROR_WANT_WRITE` with zero timeout. [#65941](https://github.com/ClickHouse/ClickHouse/pull/65941) ([Azat Khuzhin](https://github.com/azat)).
* Add missing settings `input_format_csv_skip_first_lines/input_format_tsv_skip_first_lines/input_format_csv_try_infer_numbers_from_strings/input_format_csv_try_infer_strings_from_quoted_tuples` in schema inference cache because they can change the resulting schema. It prevents from incorrect result of schema inference with these settings changed. [#65980](https://github.com/ClickHouse/ClickHouse/pull/65980) ([Kruglov Pavel](https://github.com/Avogar)).
* Column _size in s3 engine and s3 table function denotes the size of a file inside the archive, not a size of the archive itself. [#65993](https://github.com/ClickHouse/ClickHouse/pull/65993) ([Daniil Ivanik](https://github.com/divanik)).
* Fix resolving dynamic subcolumns in analyzer, avoid reading the whole column on dynamic subcolumn reading. [#66004](https://github.com/ClickHouse/ClickHouse/pull/66004) ([Kruglov Pavel](https://github.com/Avogar)).
* Fix config merging for from_env with replace overrides. [#66034](https://github.com/ClickHouse/ClickHouse/pull/66034) ([Azat Khuzhin](https://github.com/azat)).
* Fix a possible hanging in `GRPCServer` during shutdown. [#66061](https://github.com/ClickHouse/ClickHouse/pull/66061) ([Vitaly Baranov](https://github.com/vitlibar)).
* Fixed several cases in function `has` with non-constant `LowCardinality` arguments. [#66088](https://github.com/ClickHouse/ClickHouse/pull/66088) ([Anton Popov](https://github.com/CurtizJ)).
* Fix for `groupArrayIntersect`. It had incorrect behavior in the `merge()` function. Also, fixed behavior in `deserialise()` for numeric and general data. [#66103](https://github.com/ClickHouse/ClickHouse/pull/66103) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
* Fixed buffer overflow bug in `unbin`/`unhex` implementation. [#66106](https://github.com/ClickHouse/ClickHouse/pull/66106) ([Nikita Taranov](https://github.com/nickitat)).
* Disable the `merge-filters` optimization introduced in [#64760](https://github.com/ClickHouse/ClickHouse/issues/64760). It may cause an exception if optimization merges two filter expressions and does not apply a short-circuit evaluation. [#66126](https://github.com/ClickHouse/ClickHouse/pull/66126) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Fixed the issue when the server failed to parse Avro files with negative block size arrays encoded, which is now allowed by the Avro specification. [#66130](https://github.com/ClickHouse/ClickHouse/pull/66130) ([Serge Klochkov](https://github.com/slvrtrn)).
* Fixed a bug in ZooKeeper client: a session could get stuck in unusable state after receiving a hardware error from ZooKeeper. For example, this might happen due to "soft memory limit" in ClickHouse Keeper. [#66140](https://github.com/ClickHouse/ClickHouse/pull/66140) ([Alexander Tokmakov](https://github.com/tavplubix)).
* Fix issue in SumIfToCountIfVisitor and signed integers. [#66146](https://github.com/ClickHouse/ClickHouse/pull/66146) ([Raúl Marín](https://github.com/Algunenano)).
* Fix rare case with missing data in the result of distributed query. [#66174](https://github.com/ClickHouse/ClickHouse/pull/66174) ([vdimir](https://github.com/vdimir)).
* Fix order of parsing metadata fields in StorageDeltaLake. [#66211](https://github.com/ClickHouse/ClickHouse/pull/66211) ([Kseniia Sumarokova](https://github.com/kssenii)).
* Don't throw `TIMEOUT_EXCEEDED` for `none_only_active` mode of `distributed_ddl_output_mode`. [#66218](https://github.com/ClickHouse/ClickHouse/pull/66218) ([Alexander Tokmakov](https://github.com/tavplubix)).
* Fix handling limit for `system.numbers_mt` when no index can be used. [#66231](https://github.com/ClickHouse/ClickHouse/pull/66231) ([János Benjamin Antal](https://github.com/antaljanosbenjamin)).
* Fixed how the ClickHouse server detects the maximum number of usable CPU cores as specified by cgroups v2 if the server runs in a container such as Docker. In more detail, containers often run their process in the root cgroup which has an empty name. In that case, ClickHouse ignored the CPU limits set by cgroups v2. [#66237](https://github.com/ClickHouse/ClickHouse/pull/66237) ([filimonov](https://github.com/filimonov)).
* Fix the `Not-ready set` error when a subquery with `IN` is used in the constraint. [#66261](https://github.com/ClickHouse/ClickHouse/pull/66261) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Fix error reporting while copying to S3 or AzureBlobStorage. [#66295](https://github.com/ClickHouse/ClickHouse/pull/66295) ([Vitaly Baranov](https://github.com/vitlibar)).
* Prevent watchdog from keeping descriptors of unlinked(rotated) log files. [#66334](https://github.com/ClickHouse/ClickHouse/pull/66334) ([Aleksei Filatov](https://github.com/aalexfvk)).
* Fix the bug that logicalexpressionoptimizerpass lost logical type of constant. [#66344](https://github.com/ClickHouse/ClickHouse/pull/66344) ([pn](https://github.com/chloro-pn)).
* Fix `Column identifier is already registered` error with `group_by_use_nulls=true` and new analyzer. [#66400](https://github.com/ClickHouse/ClickHouse/pull/66400) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Fix possible incorrect result for queries joining and filtering table external engine (like PostgreSQL), due to too aggressive filter pushdown. Since now, conditions from where section won't be send to external database in case of outer join with external table. [#66402](https://github.com/ClickHouse/ClickHouse/pull/66402) ([vdimir](https://github.com/vdimir)).
* Added missing column materialization for cross join. [#66413](https://github.com/ClickHouse/ClickHouse/pull/66413) ([lgbo](https://github.com/lgbo-ustc)).
* Fix `Cannot find column` error for queries with constant expression in `GROUP BY` key and new analyzer enabled. [#66433](https://github.com/ClickHouse/ClickHouse/pull/66433) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Avoid possible logical error during import from Npy format in case of bad array nesting level, fix testing of other kinds of errors. [#66461](https://github.com/ClickHouse/ClickHouse/pull/66461) ([Yarik Briukhovetskyi](https://github.com/yariks5s)).
* Fix wrong count() result when there is non-deterministic function in predicate. [#66510](https://github.com/ClickHouse/ClickHouse/pull/66510) ([Duc Canh Le](https://github.com/canhld94)).
* Correctly track memory for `Allocator::realloc`. [#66548](https://github.com/ClickHouse/ClickHouse/pull/66548) ([Antonio Andelic](https://github.com/antonio2368)).
* Fix reading of uninitialized memory when hashing empty tuples. [#66562](https://github.com/ClickHouse/ClickHouse/pull/66562) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Fix an invalid result for queries with `WINDOW`. This could happen when `PARTITION` columns have sparse serialization and window functions are executed in parallel. [#66579](https://github.com/ClickHouse/ClickHouse/pull/66579) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Fix removing named collections in local storage. [#66599](https://github.com/ClickHouse/ClickHouse/pull/66599) ([János Benjamin Antal](https://github.com/antaljanosbenjamin)).
* Fix `column_length` is not updated in `ColumnTuple::insertManyFrom`. [#66626](https://github.com/ClickHouse/ClickHouse/pull/66626) ([lgbo](https://github.com/lgbo-ustc)).
* Fix `Unknown identifier` and `Column is not under aggregate function` errors for queries with the expression `(column IS NULL).` The bug was triggered by [#65088](https://github.com/ClickHouse/ClickHouse/issues/65088), with the disabled analyzer only. [#66654](https://github.com/ClickHouse/ClickHouse/pull/66654) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Fix `Method getResultType is not supported for QUERY query node` error when scalar subquery was used as the first argument of IN (with new analyzer). [#66655](https://github.com/ClickHouse/ClickHouse/pull/66655) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
* Fix possible PARAMETER_OUT_OF_BOUND error during reading variant subcolumn. [#66659](https://github.com/ClickHouse/ClickHouse/pull/66659) ([Kruglov Pavel](https://github.com/Avogar)).
* Fix rare case of stuck merge after drop column. [#66707](https://github.com/ClickHouse/ClickHouse/pull/66707) ([Raúl Marín](https://github.com/Algunenano)).
* Fix assertion `isUniqTypes` when insert select from remote sources. [#66722](https://github.com/ClickHouse/ClickHouse/pull/66722) ([Sema Checherinda](https://github.com/CheSema)).
* Fix logical error in PrometheusRequestHandler. [#66621](https://github.com/ClickHouse/ClickHouse/pull/66621) ([Vitaly Baranov](https://github.com/vitlibar)).
* Fix `indexHint` function case found by fuzzer. [#66286](https://github.com/ClickHouse/ClickHouse/pull/66286) ([Anton Popov](https://github.com/CurtizJ)).
* Fix AST formatting of 'create table b empty as a'. [#64951](https://github.com/ClickHouse/ClickHouse/pull/64951) ([Michael Kolupaev](https://github.com/al13n321)).
#### Build/Testing/Packaging Improvement
* Instantiate template methods ahead in different .cpp files, avoid too large translation units during compiling. [#64818](https://github.com/ClickHouse/ClickHouse/pull/64818) ([lgbo](https://github.com/lgbo-ustc)).
### <a id="246"></a> ClickHouse release 24.6, 2024-07-01 ### <a id="246"></a> ClickHouse release 24.6, 2024-07-01
#### Backward Incompatible Change #### Backward Incompatible Change

2
contrib/libunwind vendored

@ -1 +1 @@
Subproject commit fe854449e24bedfa26e38465b84374312dbd587f Subproject commit a89d904befea07814628c6ce0b44083c4e149c62

View File

@ -23,15 +23,17 @@ RUN apt-get update \
# and MEMORY_LIMIT_EXCEEDED exceptions in Functional tests (total memory limit in Functional tests is ~55.24 GiB). # and MEMORY_LIMIT_EXCEEDED exceptions in Functional tests (total memory limit in Functional tests is ~55.24 GiB).
# TSAN will flush shadow memory when reaching this limit. # TSAN will flush shadow memory when reaching this limit.
# It may cause false-negatives, but it's better than OOM. # It may cause false-negatives, but it's better than OOM.
RUN echo "TSAN_OPTIONS='verbosity=1000 halt_on_error=1 abort_on_error=1 history_size=7 memory_limit_mb=46080 second_deadlock_stack=1'" >> /etc/environment # max_allocation_size_mb is set to 32GB, so we have much bigger chance to run into memory limit than the limitation of the sanitizers
RUN echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment RUN echo "TSAN_OPTIONS='verbosity=1000 halt_on_error=1 abort_on_error=1 history_size=7 memory_limit_mb=46080 second_deadlock_stack=1 max_allocation_size_mb=32768'" >> /etc/environment
RUN echo "MSAN_OPTIONS='abort_on_error=1 poison_in_dtor=1'" >> /etc/environment RUN echo "UBSAN_OPTIONS='print_stacktrace=1 max_allocation_size_mb=32768'" >> /etc/environment
RUN echo "LSAN_OPTIONS='suppressions=/usr/share/clickhouse-test/config/lsan_suppressions.txt'" >> /etc/environment RUN echo "MSAN_OPTIONS='abort_on_error=1 poison_in_dtor=1 max_allocation_size_mb=32768'" >> /etc/environment
RUN echo "LSAN_OPTIONS='suppressions=/usr/share/clickhouse-test/config/lsan_suppressions.txt max_allocation_size_mb=32768'" >> /etc/environment
# Sanitizer options for current shell (not current, but the one that will be spawned on "docker run") # Sanitizer options for current shell (not current, but the one that will be spawned on "docker run")
# (but w/o verbosity for TSAN, otherwise test.reference will not match) # (but w/o verbosity for TSAN, otherwise test.reference will not match)
ENV TSAN_OPTIONS='halt_on_error=1 abort_on_error=1 history_size=7 memory_limit_mb=46080 second_deadlock_stack=1' ENV TSAN_OPTIONS='halt_on_error=1 abort_on_error=1 history_size=7 memory_limit_mb=46080 second_deadlock_stack=1 max_allocation_size_mb=32768'
ENV UBSAN_OPTIONS='print_stacktrace=1' ENV UBSAN_OPTIONS='print_stacktrace=1 max_allocation_size_mb=32768'
ENV MSAN_OPTIONS='abort_on_error=1 poison_in_dtor=1' ENV MSAN_OPTIONS='abort_on_error=1 poison_in_dtor=1 max_allocation_size_mb=32768'
ENV LSAN_OPTIONS='max_allocation_size_mb=32768'
# for external_symbolizer_path # for external_symbolizer_path
RUN ln -s /usr/bin/llvm-symbolizer-${LLVM_VERSION} /usr/bin/llvm-symbolizer RUN ln -s /usr/bin/llvm-symbolizer-${LLVM_VERSION} /usr/bin/llvm-symbolizer

View File

@ -20,7 +20,7 @@
</max_execution_time> </max_execution_time>
<max_memory_usage> <max_memory_usage>
<max>10G</max> <max>5G</max>
</max_memory_usage> </max_memory_usage>
<table_function_remote_max_addresses> <table_function_remote_max_addresses>

View File

@ -208,7 +208,6 @@ handle SIGPIPE nostop noprint pass
handle SIGTERM nostop noprint pass handle SIGTERM nostop noprint pass
handle SIGUSR1 nostop noprint pass handle SIGUSR1 nostop noprint pass
handle SIGUSR2 nostop noprint pass handle SIGUSR2 nostop noprint pass
handle SIGSEGV nostop pass
handle SIG$RTMIN nostop noprint pass handle SIG$RTMIN nostop noprint pass
info signals info signals
continue continue

View File

@ -20,7 +20,6 @@ handle SIGPIPE nostop noprint pass
handle SIGTERM nostop noprint pass handle SIGTERM nostop noprint pass
handle SIGUSR1 nostop noprint pass handle SIGUSR1 nostop noprint pass
handle SIGUSR2 nostop noprint pass handle SIGUSR2 nostop noprint pass
handle SIGSEGV nostop pass
handle SIG$RTMIN nostop noprint pass handle SIG$RTMIN nostop noprint pass
info signals info signals
continue continue

View File

@ -55,7 +55,7 @@ CMPLNT_FR_TM Nullable(String)
``` ```
:::tip :::tip
Most of the time the above command will let you know which fields in the input data are numeric, and which are strings, and which are tuples. This is not always the case. Because ClickHouse is routineley used with datasets containing billions of records there is a default number (100) of rows examined to [infer the schema](/docs/en/integrations/data-ingestion/data-formats/json.md#relying-on-schema-inference) in order to avoid parsing billions of rows to infer the schema. The response below may not match what you see, as the dataset is updated several times each year. Looking at the Data Dictionary you can see that CMPLNT_NUM is specified as text, and not numeric. By overriding the default of 100 rows for inference with the setting `SETTINGS input_format_max_rows_to_read_for_schema_inference=2000` Most of the time the above command will let you know which fields in the input data are numeric, and which are strings, and which are tuples. This is not always the case. Because ClickHouse is routineley used with datasets containing billions of records there is a default number (100) of rows examined to [infer the schema](/en/integrations/data-formats/json/inference) in order to avoid parsing billions of rows to infer the schema. The response below may not match what you see, as the dataset is updated several times each year. Looking at the Data Dictionary you can see that CMPLNT_NUM is specified as text, and not numeric. By overriding the default of 100 rows for inference with the setting `SETTINGS input_format_max_rows_to_read_for_schema_inference=2000`
you can get a better idea of the content. you can get a better idea of the content.
Note: as of version 22.5 the default is now 25,000 rows for inferring the schema, so only change the setting if you are on an older version or if you need more than 25,000 rows to be sampled. Note: as of version 22.5 the default is now 25,000 rows for inferring the schema, so only change the setting if you are on an older version or if you need more than 25,000 rows to be sampled.

View File

@ -7,7 +7,7 @@ keywords: [object, data type]
# Object Data Type (deprecated) # Object Data Type (deprecated)
**This feature is not production-ready and is now deprecated.** If you need to work with JSON documents, consider using [this guide](/docs/en/integrations/data-ingestion/data-formats/json) instead. A new implementation to support JSON object is in progress and can be tracked [here](https://github.com/ClickHouse/ClickHouse/issues/54864). **This feature is not production-ready and is now deprecated.** If you need to work with JSON documents, consider using [this guide](/docs/en/integrations/data-formats/json/overview) instead. A new implementation to support JSON object is in progress and can be tracked [here](https://github.com/ClickHouse/ClickHouse/issues/54864).
<hr /> <hr />

View File

@ -18,10 +18,21 @@ Reloads all dictionaries that have been successfully loaded before.
By default, dictionaries are loaded lazily (see [dictionaries_lazy_load](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-dictionaries_lazy_load)), so instead of being loaded automatically at startup, they are initialized on first access through dictGet function or SELECT from tables with ENGINE = Dictionary. The `SYSTEM RELOAD DICTIONARIES` query reloads such dictionaries (LOADED). By default, dictionaries are loaded lazily (see [dictionaries_lazy_load](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-dictionaries_lazy_load)), so instead of being loaded automatically at startup, they are initialized on first access through dictGet function or SELECT from tables with ENGINE = Dictionary. The `SYSTEM RELOAD DICTIONARIES` query reloads such dictionaries (LOADED).
Always returns `Ok.` regardless of the result of the dictionary update. Always returns `Ok.` regardless of the result of the dictionary update.
**Syntax**
```sql
SYSTEM RELOAD DICTIONARIES [ON CLUSTER cluster_name]
```
## RELOAD DICTIONARY ## RELOAD DICTIONARY
Completely reloads a dictionary `dictionary_name`, regardless of the state of the dictionary (LOADED / NOT_LOADED / FAILED). Completely reloads a dictionary `dictionary_name`, regardless of the state of the dictionary (LOADED / NOT_LOADED / FAILED).
Always returns `Ok.` regardless of the result of updating the dictionary. Always returns `Ok.` regardless of the result of updating the dictionary.
``` sql
SYSTEM RELOAD DICTIONARY [ON CLUSTER cluster_name] dictionary_name
```
The status of the dictionary can be checked by querying the `system.dictionaries` table. The status of the dictionary can be checked by querying the `system.dictionaries` table.
``` sql ``` sql

View File

@ -1,36 +0,0 @@
---
slug: /en/sql-reference/table-functions/fuzzQuery
sidebar_position: 75
sidebar_label: fuzzQuery
---
# fuzzQuery
Perturbs the given query string with random variations.
``` sql
fuzzQuery(query[, max_query_length[, random_seed]])
```
**Arguments**
- `query` (String) - The source query to perform the fuzzing on.
- `max_query_length` (UInt64) - A maximum length the query can get during the fuzzing process.
- `random_seed` (UInt64) - A random seed for producing stable results.
**Returned Value**
A table object with a single column containing perturbed query strings.
## Usage Example
``` sql
SELECT * FROM fuzzQuery('SELECT materialize(\'a\' AS key) GROUP BY key') LIMIT 2;
```
```
┌─query──────────────────────────────────────────────────────────┐
1. │ SELECT 'a' AS key GROUP BY key │
2. │ EXPLAIN PIPELINE compact = true SELECT 'a' AS key GROUP BY key │
└────────────────────────────────────────────────────────────────┘
```

View File

@ -9,10 +9,7 @@ namespace DB
class Client : public ClientBase class Client : public ClientBase
{ {
public: public:
Client() Client() = default;
{
fuzzer = QueryFuzzer(randomSeed(), &std::cout, &std::cerr);
}
void initialize(Poco::Util::Application & self) override; void initialize(Poco::Util::Application & self) override;

View File

@ -1,2 +1,2 @@
clickhouse_add_executable (validate-odbc-connection-string validate-odbc-connection-string.cpp ../validateODBCConnectionString.cpp) clickhouse_add_executable (validate-odbc-connection-string validate-odbc-connection-string.cpp ../validateODBCConnectionString.cpp)
target_link_libraries (validate-odbc-connection-string PRIVATE clickhouse_common_io) target_link_libraries (validate-odbc-connection-string PRIVATE clickhouse_common_io clickhouse_common_config)

View File

@ -49,7 +49,7 @@ enum class QueryTreeNodeType : uint8_t
/// Convert query tree node type to string /// Convert query tree node type to string
const char * toString(QueryTreeNodeType type); const char * toString(QueryTreeNodeType type);
/** Query tree is semantical representation of query. /** Query tree is a semantic representation of query.
* Query tree node represent node in query tree. * Query tree node represent node in query tree.
* IQueryTreeNode is base class for all query tree nodes. * IQueryTreeNode is base class for all query tree nodes.
* *

View File

@ -4124,9 +4124,7 @@ void QueryAnalyzer::resolveInterpolateColumnsNodeList(QueryTreeNodePtr & interpo
auto * column_to_interpolate = interpolate_node_typed.getExpression()->as<IdentifierNode>(); auto * column_to_interpolate = interpolate_node_typed.getExpression()->as<IdentifierNode>();
if (!column_to_interpolate) if (!column_to_interpolate)
throw Exception( throw Exception(ErrorCodes::LOGICAL_ERROR, "INTERPOLATE can work only for indentifiers, but {} is found",
ErrorCodes::LOGICAL_ERROR,
"INTERPOLATE can work only for identifiers, but {} is found",
interpolate_node_typed.getExpression()->formatASTForErrorMessage()); interpolate_node_typed.getExpression()->formatASTForErrorMessage());
auto column_to_interpolate_name = column_to_interpolate->getIdentifier().getFullName(); auto column_to_interpolate_name = column_to_interpolate->getIdentifier().getFullName();

View File

@ -309,9 +309,16 @@ public:
ClientBase::~ClientBase() ClientBase::~ClientBase()
{ {
writeSignalIDtoSignalPipe(SignalListener::StopThread); try
signal_listener_thread.join(); {
HandledSignals::instance().reset(); writeSignalIDtoSignalPipe(SignalListener::StopThread);
signal_listener_thread.join();
HandledSignals::instance().reset();
}
catch (...)
{
tryLogCurrentException(__PRETTY_FUNCTION__);
}
} }
ClientBase::ClientBase( ClientBase::ClientBase(

View File

@ -6,7 +6,6 @@
#include <Common/ProgressIndication.h> #include <Common/ProgressIndication.h>
#include <Common/InterruptListener.h> #include <Common/InterruptListener.h>
#include <Common/ShellCommand.h> #include <Common/ShellCommand.h>
#include <Common/QueryFuzzer.h>
#include <Common/Stopwatch.h> #include <Common/Stopwatch.h>
#include <Common/DNSResolver.h> #include <Common/DNSResolver.h>
#include <Core/ExternalTable.h> #include <Core/ExternalTable.h>
@ -17,6 +16,7 @@
#include <Poco/SplitterChannel.h> #include <Poco/SplitterChannel.h>
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
#include <Client/Suggest.h> #include <Client/Suggest.h>
#include <Client/QueryFuzzer.h>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <Storages/StorageFile.h> #include <Storages/StorageFile.h>
#include <Storages/SelectQueryInfo.h> #include <Storages/SelectQueryInfo.h>

View File

@ -68,21 +68,22 @@ Field QueryFuzzer::getRandomField(int type)
{ {
case 0: case 0:
{ {
return bad_int64_values[fuzz_rand() % std::size(bad_int64_values)]; return bad_int64_values[fuzz_rand() % (sizeof(bad_int64_values)
/ sizeof(*bad_int64_values))];
} }
case 1: case 1:
{ {
static constexpr double values[] static constexpr double values[]
= {NAN, INFINITY, -INFINITY, 0., -0., 0.0001, 0.5, 0.9999, = {NAN, INFINITY, -INFINITY, 0., -0., 0.0001, 0.5, 0.9999,
1., 1.0001, 2., 10.0001, 100.0001, 1000.0001, 1e10, 1e20, 1., 1.0001, 2., 10.0001, 100.0001, 1000.0001, 1e10, 1e20,
FLT_MIN, FLT_MIN + FLT_EPSILON, FLT_MAX, FLT_MAX + FLT_EPSILON}; return values[fuzz_rand() % std::size(values)]; FLT_MIN, FLT_MIN + FLT_EPSILON, FLT_MAX, FLT_MAX + FLT_EPSILON}; return values[fuzz_rand() % (sizeof(values) / sizeof(*values))];
} }
case 2: case 2:
{ {
static constexpr UInt64 scales[] = {0, 1, 2, 10}; static constexpr UInt64 scales[] = {0, 1, 2, 10};
return DecimalField<Decimal64>( return DecimalField<Decimal64>(
bad_int64_values[fuzz_rand() % std::size(bad_int64_values)], bad_int64_values[fuzz_rand() % (sizeof(bad_int64_values) / sizeof(*bad_int64_values))],
static_cast<UInt32>(scales[fuzz_rand() % std::size(scales)]) static_cast<UInt32>(scales[fuzz_rand() % (sizeof(scales) / sizeof(*scales))])
); );
} }
default: default:
@ -164,8 +165,7 @@ Field QueryFuzzer::fuzzField(Field field)
{ {
size_t pos = fuzz_rand() % arr.size(); size_t pos = fuzz_rand() % arr.size();
arr.erase(arr.begin() + pos); arr.erase(arr.begin() + pos);
if (debug_stream) std::cerr << "erased\n";
*debug_stream << "erased\n";
} }
if (fuzz_rand() % 5 == 0) if (fuzz_rand() % 5 == 0)
@ -174,14 +174,12 @@ Field QueryFuzzer::fuzzField(Field field)
{ {
size_t pos = fuzz_rand() % arr.size(); size_t pos = fuzz_rand() % arr.size();
arr.insert(arr.begin() + pos, fuzzField(arr[pos])); arr.insert(arr.begin() + pos, fuzzField(arr[pos]));
if (debug_stream) std::cerr << fmt::format("inserted (pos {})\n", pos);
*debug_stream << fmt::format("inserted (pos {})\n", pos);
} }
else else
{ {
arr.insert(arr.begin(), getRandomField(0)); arr.insert(arr.begin(), getRandomField(0));
if (debug_stream) std::cerr << "inserted (0)\n";
*debug_stream << "inserted (0)\n";
} }
} }
@ -199,9 +197,7 @@ Field QueryFuzzer::fuzzField(Field field)
{ {
size_t pos = fuzz_rand() % arr.size(); size_t pos = fuzz_rand() % arr.size();
arr.erase(arr.begin() + pos); arr.erase(arr.begin() + pos);
std::cerr << "erased\n";
if (debug_stream)
*debug_stream << "erased\n";
} }
if (fuzz_rand() % 5 == 0) if (fuzz_rand() % 5 == 0)
@ -210,16 +206,12 @@ Field QueryFuzzer::fuzzField(Field field)
{ {
size_t pos = fuzz_rand() % arr.size(); size_t pos = fuzz_rand() % arr.size();
arr.insert(arr.begin() + pos, fuzzField(arr[pos])); arr.insert(arr.begin() + pos, fuzzField(arr[pos]));
std::cerr << fmt::format("inserted (pos {})\n", pos);
if (debug_stream)
*debug_stream << fmt::format("inserted (pos {})\n", pos);
} }
else else
{ {
arr.insert(arr.begin(), getRandomField(0)); arr.insert(arr.begin(), getRandomField(0));
std::cerr << "inserted (0)\n";
if (debug_stream)
*debug_stream << "inserted (0)\n";
} }
} }
@ -352,8 +344,7 @@ void QueryFuzzer::fuzzOrderByList(IAST * ast)
} }
else else
{ {
if (debug_stream) std::cerr << "No random column.\n";
*debug_stream << "No random column.\n";
} }
} }
@ -387,8 +378,7 @@ void QueryFuzzer::fuzzColumnLikeExpressionList(IAST * ast)
if (col) if (col)
impl->children.insert(pos, col); impl->children.insert(pos, col);
else else
if (debug_stream) std::cerr << "No random column.\n";
*debug_stream << "No random column.\n";
} }
// We don't have to recurse here to fuzz the children, this is handled by // We don't have to recurse here to fuzz the children, this is handled by
@ -1371,15 +1361,11 @@ void QueryFuzzer::fuzzMain(ASTPtr & ast)
collectFuzzInfoMain(ast); collectFuzzInfoMain(ast);
fuzz(ast); fuzz(ast);
if (out_stream) std::cout << std::endl;
{ WriteBufferFromOStream ast_buf(std::cout, 4096);
*out_stream << std::endl; formatAST(*ast, ast_buf, false /*highlight*/);
ast_buf.finalize();
WriteBufferFromOStream ast_buf(*out_stream, 4096); std::cout << std::endl << std::endl;
formatAST(*ast, ast_buf, false /*highlight*/);
ast_buf.finalize();
*out_stream << std::endl << std::endl;
}
} }
} }

View File

@ -35,31 +35,9 @@ struct ASTWindowDefinition;
* queries, so you want to feed it a lot of queries to get some interesting mix * queries, so you want to feed it a lot of queries to get some interesting mix
* of them. Normally we feed SQL regression tests to it. * of them. Normally we feed SQL regression tests to it.
*/ */
class QueryFuzzer struct QueryFuzzer
{ {
public: pcg64 fuzz_rand{randomSeed()};
explicit QueryFuzzer(pcg64 fuzz_rand_ = randomSeed(), std::ostream * out_stream_ = nullptr, std::ostream * debug_stream_ = nullptr)
: fuzz_rand(fuzz_rand_)
, out_stream(out_stream_)
, debug_stream(debug_stream_)
{
}
// This is the only function you have to call -- it will modify the passed
// ASTPtr to point to new AST with some random changes.
void fuzzMain(ASTPtr & ast);
ASTs getInsertQueriesForFuzzedTables(const String & full_query);
ASTs getDropQueriesForFuzzedTables(const ASTDropQuery & drop_query);
void notifyQueryFailed(ASTPtr ast);
static bool isSuitableForFuzzing(const ASTCreateQuery & create);
private:
pcg64 fuzz_rand;
std::ostream * out_stream = nullptr;
std::ostream * debug_stream = nullptr;
// We add elements to expression lists with fixed probability. Some elements // We add elements to expression lists with fixed probability. Some elements
// are so large, that the expected number of elements we add to them is // are so large, that the expected number of elements we add to them is
@ -88,6 +66,10 @@ private:
std::unordered_map<std::string, size_t> index_of_fuzzed_table; std::unordered_map<std::string, size_t> index_of_fuzzed_table;
std::set<IAST::Hash> created_tables_hashes; std::set<IAST::Hash> created_tables_hashes;
// This is the only function you have to call -- it will modify the passed
// ASTPtr to point to new AST with some random changes.
void fuzzMain(ASTPtr & ast);
// Various helper functions follow, normally you shouldn't have to call them. // Various helper functions follow, normally you shouldn't have to call them.
Field getRandomField(int type); Field getRandomField(int type);
Field fuzzField(Field field); Field fuzzField(Field field);
@ -95,6 +77,9 @@ private:
ASTPtr getRandomExpressionList(); ASTPtr getRandomExpressionList();
DataTypePtr fuzzDataType(DataTypePtr type); DataTypePtr fuzzDataType(DataTypePtr type);
DataTypePtr getRandomType(); DataTypePtr getRandomType();
ASTs getInsertQueriesForFuzzedTables(const String & full_query);
ASTs getDropQueriesForFuzzedTables(const ASTDropQuery & drop_query);
void notifyQueryFailed(ASTPtr ast);
void replaceWithColumnLike(ASTPtr & ast); void replaceWithColumnLike(ASTPtr & ast);
void replaceWithTableLike(ASTPtr & ast); void replaceWithTableLike(ASTPtr & ast);
void fuzzOrderByElement(ASTOrderByElement * elem); void fuzzOrderByElement(ASTOrderByElement * elem);
@ -117,6 +102,8 @@ private:
void addTableLike(ASTPtr ast); void addTableLike(ASTPtr ast);
void addColumnLike(ASTPtr ast); void addColumnLike(ASTPtr ast);
void collectFuzzInfoRecurse(ASTPtr ast); void collectFuzzInfoRecurse(ASTPtr ast);
static bool isSuitableForFuzzing(const ASTCreateQuery & create);
}; };
} }

View File

@ -59,6 +59,7 @@ static struct InitFiu
ONCE(execute_query_calling_empty_set_result_func_on_exception) \ ONCE(execute_query_calling_empty_set_result_func_on_exception) \
ONCE(receive_timeout_on_table_status_response) \ ONCE(receive_timeout_on_table_status_response) \
REGULAR(keepermap_fail_drop_data) \ REGULAR(keepermap_fail_drop_data) \
REGULAR(lazy_pipe_fds_fail_close) \
namespace FailPoints namespace FailPoints

View File

@ -1,19 +1,23 @@
#include <Common/PipeFDs.h> #include <Common/PipeFDs.h>
#include <Common/Exception.h> #include <Common/Exception.h>
#include <Common/formatReadable.h> #include <Common/formatReadable.h>
#include <Common/FailPoint.h>
#include <Common/logger_useful.h> #include <Common/logger_useful.h>
#include <base/errnoToString.h> #include <base/errnoToString.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <string>
#include <algorithm> #include <algorithm>
namespace DB namespace DB
{ {
namespace FailPoints
{
extern const char lazy_pipe_fds_fail_close[];
}
namespace ErrorCodes namespace ErrorCodes
{ {
extern const int CANNOT_PIPE; extern const int CANNOT_PIPE;
@ -42,6 +46,11 @@ void LazyPipeFDs::open()
void LazyPipeFDs::close() void LazyPipeFDs::close()
{ {
fiu_do_on(FailPoints::lazy_pipe_fds_fail_close,
{
throw Exception(ErrorCodes::CANNOT_PIPE, "Manually triggered exception on close");
});
for (int & fd : fds_rw) for (int & fd : fds_rw)
{ {
if (fd < 0) if (fd < 0)

View File

@ -1,8 +1,5 @@
#pragma once #pragma once
#include <cstddef>
namespace DB namespace DB
{ {

View File

@ -605,7 +605,14 @@ void HandledSignals::reset()
HandledSignals::~HandledSignals() HandledSignals::~HandledSignals()
{ {
reset(); try
{
reset();
}
catch (...)
{
tryLogCurrentException(__PRETTY_FUNCTION__);
}
}; };
HandledSignals & HandledSignals::instance() HandledSignals & HandledSignals::instance()

View File

@ -489,11 +489,22 @@ struct CacheEntry
using CacheEntryPtr = std::shared_ptr<CacheEntry>; using CacheEntryPtr = std::shared_ptr<CacheEntry>;
using StackTraceCache = std::map<StackTraceTriple, CacheEntryPtr, std::less<>>; static constinit std::atomic<bool> can_use_cache = false;
using StackTraceCacheBase = std::map<StackTraceTriple, CacheEntryPtr, std::less<>>;
struct StackTraceCache : public StackTraceCacheBase
{
~StackTraceCache()
{
can_use_cache = false;
}
};
static StackTraceCache & cacheInstance() static StackTraceCache & cacheInstance()
{ {
static StackTraceCache cache; static StackTraceCache cache;
can_use_cache = true;
return cache; return cache;
} }
@ -503,6 +514,13 @@ String toStringCached(const StackTrace::FramePointers & pointers, size_t offset,
{ {
const StackTraceRefTriple key{pointers, offset, size}; const StackTraceRefTriple key{pointers, offset, size};
if (!can_use_cache)
{
DB::WriteBufferFromOwnString out;
toStringEveryLineImpl(false, key, [&](std::string_view str) { out << str << '\n'; });
return out.str();
}
/// Calculation of stack trace text is extremely slow. /// Calculation of stack trace text is extremely slow.
/// We use cache because otherwise the server could be overloaded by trash queries. /// We use cache because otherwise the server could be overloaded by trash queries.
/// Note that this cache can grow unconditionally, but practically it should be small. /// Note that this cache can grow unconditionally, but practically it should be small.

View File

@ -1,14 +1,14 @@
clickhouse_add_executable (hashes_test hashes_test.cpp) clickhouse_add_executable (hashes_test hashes_test.cpp)
target_link_libraries (hashes_test PRIVATE clickhouse_common_io ch_contrib::cityhash) target_link_libraries (hashes_test PRIVATE clickhouse_common_io clickhouse_common_config ch_contrib::cityhash)
if (TARGET OpenSSL::Crypto) if (TARGET OpenSSL::Crypto)
target_link_libraries (hashes_test PRIVATE OpenSSL::Crypto) target_link_libraries (hashes_test PRIVATE OpenSSL::Crypto)
endif() endif()
clickhouse_add_executable (sip_hash_perf sip_hash_perf.cpp) clickhouse_add_executable (sip_hash_perf sip_hash_perf.cpp)
target_link_libraries (sip_hash_perf PRIVATE clickhouse_common_io) target_link_libraries (sip_hash_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (small_table small_table.cpp) clickhouse_add_executable (small_table small_table.cpp)
target_link_libraries (small_table PRIVATE clickhouse_common_io) target_link_libraries (small_table PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (parallel_aggregation parallel_aggregation.cpp) clickhouse_add_executable (parallel_aggregation parallel_aggregation.cpp)
target_link_libraries (parallel_aggregation PRIVATE dbms clickhouse_functions) target_link_libraries (parallel_aggregation PRIVATE dbms clickhouse_functions)
@ -17,13 +17,13 @@ clickhouse_add_executable (parallel_aggregation2 parallel_aggregation2.cpp)
target_link_libraries (parallel_aggregation2 PRIVATE dbms clickhouse_functions) target_link_libraries (parallel_aggregation2 PRIVATE dbms clickhouse_functions)
clickhouse_add_executable (int_hashes_perf int_hashes_perf.cpp) clickhouse_add_executable (int_hashes_perf int_hashes_perf.cpp)
target_link_libraries (int_hashes_perf PRIVATE clickhouse_common_io) target_link_libraries (int_hashes_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (compact_array compact_array.cpp) clickhouse_add_executable (compact_array compact_array.cpp)
target_link_libraries (compact_array PRIVATE clickhouse_common_io) target_link_libraries (compact_array PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (radix_sort radix_sort.cpp) clickhouse_add_executable (radix_sort radix_sort.cpp)
target_link_libraries (radix_sort PRIVATE clickhouse_common_io ch_contrib::pdqsort) target_link_libraries (radix_sort PRIVATE clickhouse_common_io clickhouse_common_config ch_contrib::pdqsort)
clickhouse_add_executable (arena_with_free_lists arena_with_free_lists.cpp) clickhouse_add_executable (arena_with_free_lists arena_with_free_lists.cpp)
target_link_libraries (arena_with_free_lists PRIVATE dbms) target_link_libraries (arena_with_free_lists PRIVATE dbms)
@ -33,46 +33,46 @@ target_link_libraries (lru_hash_map_perf PRIVATE dbms)
if (OS_LINUX) if (OS_LINUX)
clickhouse_add_executable (thread_creation_latency thread_creation_latency.cpp) clickhouse_add_executable (thread_creation_latency thread_creation_latency.cpp)
target_link_libraries (thread_creation_latency PRIVATE clickhouse_common_io) target_link_libraries (thread_creation_latency PRIVATE clickhouse_common_io clickhouse_common_config)
endif() endif()
clickhouse_add_executable (array_cache array_cache.cpp) clickhouse_add_executable (array_cache array_cache.cpp)
target_link_libraries (array_cache PRIVATE clickhouse_common_io) target_link_libraries (array_cache PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (space_saving space_saving.cpp) clickhouse_add_executable (space_saving space_saving.cpp)
target_link_libraries (space_saving PRIVATE clickhouse_common_io) target_link_libraries (space_saving PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (integer_hash_tables_benchmark integer_hash_tables_benchmark.cpp) clickhouse_add_executable (integer_hash_tables_benchmark integer_hash_tables_benchmark.cpp)
target_link_libraries (integer_hash_tables_benchmark PRIVATE dbms ch_contrib::abseil_swiss_tables ch_contrib::sparsehash) target_link_libraries (integer_hash_tables_benchmark PRIVATE dbms ch_contrib::abseil_swiss_tables ch_contrib::sparsehash)
clickhouse_add_executable (cow_columns cow_columns.cpp) clickhouse_add_executable (cow_columns cow_columns.cpp)
target_link_libraries (cow_columns PRIVATE clickhouse_common_io) target_link_libraries (cow_columns PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (cow_compositions cow_compositions.cpp) clickhouse_add_executable (cow_compositions cow_compositions.cpp)
target_link_libraries (cow_compositions PRIVATE clickhouse_common_io) target_link_libraries (cow_compositions PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (stopwatch stopwatch.cpp) clickhouse_add_executable (stopwatch stopwatch.cpp)
target_link_libraries (stopwatch PRIVATE clickhouse_common_io) target_link_libraries (stopwatch PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (symbol_index symbol_index.cpp) clickhouse_add_executable (symbol_index symbol_index.cpp)
target_link_libraries (symbol_index PRIVATE clickhouse_common_io) target_link_libraries (symbol_index PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (chaos_sanitizer chaos_sanitizer.cpp) clickhouse_add_executable (chaos_sanitizer chaos_sanitizer.cpp)
target_link_libraries (chaos_sanitizer PRIVATE clickhouse_common_io) target_link_libraries (chaos_sanitizer PRIVATE clickhouse_common_io clickhouse_common_config)
if (OS_LINUX) if (OS_LINUX)
clickhouse_add_executable (memory_statistics_os_perf memory_statistics_os_perf.cpp) clickhouse_add_executable (memory_statistics_os_perf memory_statistics_os_perf.cpp)
target_link_libraries (memory_statistics_os_perf PRIVATE clickhouse_common_io) target_link_libraries (memory_statistics_os_perf PRIVATE clickhouse_common_io clickhouse_common_config)
endif() endif()
clickhouse_add_executable (procfs_metrics_provider_perf procfs_metrics_provider_perf.cpp) clickhouse_add_executable (procfs_metrics_provider_perf procfs_metrics_provider_perf.cpp)
target_link_libraries (procfs_metrics_provider_perf PRIVATE clickhouse_common_io) target_link_libraries (procfs_metrics_provider_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (average average.cpp) clickhouse_add_executable (average average.cpp)
target_link_libraries (average PRIVATE clickhouse_common_io) target_link_libraries (average PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (shell_command_inout shell_command_inout.cpp) clickhouse_add_executable (shell_command_inout shell_command_inout.cpp)
target_link_libraries (shell_command_inout PRIVATE clickhouse_common_io) target_link_libraries (shell_command_inout PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (executable_udf executable_udf.cpp) clickhouse_add_executable (executable_udf executable_udf.cpp)
target_link_libraries (executable_udf PRIVATE dbms) target_link_libraries (executable_udf PRIVATE dbms)
@ -91,4 +91,4 @@ if (ENABLE_SSL)
endif() endif()
clickhouse_add_executable (check_pointer_valid check_pointer_valid.cpp) clickhouse_add_executable (check_pointer_valid check_pointer_valid.cpp)
target_link_libraries (check_pointer_valid PRIVATE clickhouse_common_io) target_link_libraries (check_pointer_valid PRIVATE clickhouse_common_io clickhouse_common_config)

View File

@ -1,2 +1,2 @@
clickhouse_add_executable (mysqlxx_pool_test mysqlxx_pool_test.cpp) clickhouse_add_executable (mysqlxx_pool_test mysqlxx_pool_test.cpp)
target_link_libraries (mysqlxx_pool_test PRIVATE mysqlxx) target_link_libraries (mysqlxx_pool_test PRIVATE mysqlxx clickhouse_common_config)

View File

@ -33,7 +33,7 @@ size_t toMilliseconds(auto duration)
return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(); return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
} }
const auto epsilon = 500us; const auto epsilon = 1ms;
class ResolvePoolMock : public DB::HostResolver class ResolvePoolMock : public DB::HostResolver
{ {
@ -358,53 +358,59 @@ void check_no_failed_address(size_t iteration, auto & resolver, auto & addresses
TEST_F(ResolvePoolTest, BannedForConsiquenceFail) TEST_F(ResolvePoolTest, BannedForConsiquenceFail)
{ {
auto history = 5ms; auto history = 10ms;
auto resolver = make_resolver(toMilliseconds(history)); auto resolver = make_resolver(toMilliseconds(history));
auto failed_addr = resolver->resolve(); auto failed_addr = resolver->resolve();
ASSERT_TRUE(addresses.contains(*failed_addr)); ASSERT_TRUE(addresses.contains(*failed_addr));
auto start_at = now();
failed_addr.setFail(); failed_addr.setFail();
auto start_at = now();
ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count)); ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count));
ASSERT_EQ(1, CurrentMetrics::get(metrics.banned_count)); ASSERT_EQ(1, CurrentMetrics::get(metrics.banned_count));
check_no_failed_address(1, resolver, addresses, failed_addr, metrics, start_at + history - epsilon); check_no_failed_address(1, resolver, addresses, failed_addr, metrics, start_at + history - epsilon);
sleep_until(start_at + history + epsilon); sleep_until(start_at + history + epsilon);
start_at = now();
resolver->update(); resolver->update();
ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count)); ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count));
ASSERT_EQ(0, CurrentMetrics::get(metrics.banned_count)); ASSERT_EQ(0, CurrentMetrics::get(metrics.banned_count));
failed_addr.setFail(); failed_addr.setFail();
start_at = now();
check_no_failed_address(2, resolver, addresses, failed_addr, metrics, start_at + history - epsilon); check_no_failed_address(2, resolver, addresses, failed_addr, metrics, start_at + history - epsilon);
sleep_until(start_at + history + epsilon); sleep_until(start_at + history + epsilon);
start_at = now();
resolver->update(); resolver->update();
// too much time has passed
if (now() > start_at + 2*history - epsilon)
return;
ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count)); ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count));
ASSERT_EQ(1, CurrentMetrics::get(metrics.banned_count)); ASSERT_EQ(1, CurrentMetrics::get(metrics.banned_count));
// ip still banned adter history_ms + update, because it was his second consiquent fail // ip still banned adter history_ms + update, because it was his second consiquent fail
check_no_failed_address(2, resolver, addresses, failed_addr, metrics, start_at + history - epsilon); check_no_failed_address(2, resolver, addresses, failed_addr, metrics, start_at + 2*history - epsilon);
} }
TEST_F(ResolvePoolTest, NoAditionalBannForConcurrentFail) TEST_F(ResolvePoolTest, NoAditionalBannForConcurrentFail)
{ {
auto history = 5ms; auto history = 10ms;
auto resolver = make_resolver(toMilliseconds(history)); auto resolver = make_resolver(toMilliseconds(history));
auto failed_addr = resolver->resolve(); auto failed_addr = resolver->resolve();
ASSERT_TRUE(addresses.contains(*failed_addr)); ASSERT_TRUE(addresses.contains(*failed_addr));
auto start_at = now(); failed_addr.setFail();
failed_addr.setFail();
failed_addr.setFail();
failed_addr.setFail(); auto start_at = now();
failed_addr.setFail();
failed_addr.setFail();
ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count)); ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count));
ASSERT_EQ(1, CurrentMetrics::get(metrics.banned_count)); ASSERT_EQ(1, CurrentMetrics::get(metrics.banned_count));
@ -413,6 +419,7 @@ TEST_F(ResolvePoolTest, NoAditionalBannForConcurrentFail)
sleep_until(start_at + history + epsilon); sleep_until(start_at + history + epsilon);
resolver->update(); resolver->update();
// ip is cleared after just 1 history_ms interval. // ip is cleared after just 1 history_ms interval.
ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count)); ASSERT_EQ(3, CurrentMetrics::get(metrics.active_count));
ASSERT_EQ(0, CurrentMetrics::get(metrics.banned_count)); ASSERT_EQ(0, CurrentMetrics::get(metrics.banned_count));

View File

@ -1,2 +1,2 @@
clickhouse_add_executable (compressed_buffer compressed_buffer.cpp) clickhouse_add_executable (compressed_buffer compressed_buffer.cpp)
target_link_libraries (compressed_buffer PRIVATE clickhouse_common_io clickhouse_compression) target_link_libraries (compressed_buffer PRIVATE clickhouse_common_io clickhouse_common_config clickhouse_compression)

View File

@ -383,7 +383,10 @@ void KeeperServer::launchRaftServer(const Poco::Util::AbstractConfiguration & co
LockMemoryExceptionInThread::removeUniqueLock(); LockMemoryExceptionInThread::removeUniqueLock();
}; };
asio_opts.thread_pool_size_ = getNumberOfPhysicalCPUCores(); /// At least 16 threads for network communication in asio.
/// asio is async framework, so even with 1 thread it should be ok, but
/// still as safeguard it's better to have some redundant capacity here
asio_opts.thread_pool_size_ = std::max(16U, getNumberOfPhysicalCPUCores());
if (state_manager->isSecure()) if (state_manager->isSecure())
{ {

View File

@ -1,5 +1,8 @@
#pragma once #pragma once
/// CLion freezes for a minute on every keypress in any file including this.
#if !defined(__CLION_IDE__)
#include <Common/NamePrompter.h> #include <Common/NamePrompter.h>
#include <Core/BaseSettings.h> #include <Core/BaseSettings.h>
#include <Core/SettingsEnums.h> #include <Core/SettingsEnums.h>
@ -602,7 +605,7 @@ class IColumn;
M(Bool, optimize_if_chain_to_multiif, false, "Replace if(cond1, then1, if(cond2, ...)) chains to multiIf. Currently it's not beneficial for numeric types.", 0) \ M(Bool, optimize_if_chain_to_multiif, false, "Replace if(cond1, then1, if(cond2, ...)) chains to multiIf. Currently it's not beneficial for numeric types.", 0) \
M(Bool, optimize_multiif_to_if, true, "Replace 'multiIf' with only one condition to 'if'.", 0) \ M(Bool, optimize_multiif_to_if, true, "Replace 'multiIf' with only one condition to 'if'.", 0) \
M(Bool, optimize_if_transform_strings_to_enum, false, "Replaces string-type arguments in If and Transform to enum. Disabled by default cause it could make inconsistent change in distributed query that would lead to its fail.", 0) \ M(Bool, optimize_if_transform_strings_to_enum, false, "Replaces string-type arguments in If and Transform to enum. Disabled by default cause it could make inconsistent change in distributed query that would lead to its fail.", 0) \
M(Bool, optimize_functions_to_subcolumns, true, "Transform functions to subcolumns, if possible, to reduce amount of read data. E.g. 'length(arr)' -> 'arr.size0', 'col IS NULL' -> 'col.null' ", 0) \ M(Bool, optimize_functions_to_subcolumns, false, "Transform functions to subcolumns, if possible, to reduce amount of read data. E.g. 'length(arr)' -> 'arr.size0', 'col IS NULL' -> 'col.null' ", 0) \
M(Bool, optimize_using_constraints, false, "Use constraints for query optimization", 0) \ M(Bool, optimize_using_constraints, false, "Use constraints for query optimization", 0) \
M(Bool, optimize_substitute_columns, false, "Use constraints for column substitution", 0) \ M(Bool, optimize_substitute_columns, false, "Use constraints for column substitution", 0) \
M(Bool, optimize_append_index, false, "Use constraints in order to append index condition (indexHint)", 0) \ M(Bool, optimize_append_index, false, "Use constraints in order to append index condition (indexHint)", 0) \
@ -763,7 +766,7 @@ class IColumn;
M(UInt64, merge_tree_min_rows_for_concurrent_read_for_remote_filesystem, (20 * 8192), "If at least as many lines are read from one file, the reading can be parallelized, when reading from remote filesystem.", 0) \ M(UInt64, merge_tree_min_rows_for_concurrent_read_for_remote_filesystem, (20 * 8192), "If at least as many lines are read from one file, the reading can be parallelized, when reading from remote filesystem.", 0) \
M(UInt64, merge_tree_min_bytes_for_concurrent_read_for_remote_filesystem, (24 * 10 * 1024 * 1024), "If at least as many bytes are read from one file, the reading can be parallelized, when reading from remote filesystem.", 0) \ M(UInt64, merge_tree_min_bytes_for_concurrent_read_for_remote_filesystem, (24 * 10 * 1024 * 1024), "If at least as many bytes are read from one file, the reading can be parallelized, when reading from remote filesystem.", 0) \
M(UInt64, remote_read_min_bytes_for_seek, 4 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes required for remote read (url, s3) to do seek, instead of read with ignore.", 0) \ M(UInt64, remote_read_min_bytes_for_seek, 4 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes required for remote read (url, s3) to do seek, instead of read with ignore.", 0) \
M(UInt64, merge_tree_min_bytes_per_task_for_remote_reading, 4 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes to read per task.", 0) \ M(UInt64, merge_tree_min_bytes_per_task_for_remote_reading, 2 * DBMS_DEFAULT_BUFFER_SIZE, "Min bytes to read per task.", 0) ALIAS(filesystem_prefetch_min_bytes_for_single_read_task) \
M(Bool, merge_tree_use_const_size_tasks_for_remote_reading, true, "Whether to use constant size tasks for reading from a remote table.", 0) \ M(Bool, merge_tree_use_const_size_tasks_for_remote_reading, true, "Whether to use constant size tasks for reading from a remote table.", 0) \
M(Bool, merge_tree_determine_task_size_by_prewhere_columns, true, "Whether to use only prewhere columns size to determine reading task size.", 0) \ M(Bool, merge_tree_determine_task_size_by_prewhere_columns, true, "Whether to use only prewhere columns size to determine reading task size.", 0) \
M(UInt64, merge_tree_compact_parts_min_granules_to_multibuffer_read, 16, "Only available in ClickHouse Cloud", 0) \ M(UInt64, merge_tree_compact_parts_min_granules_to_multibuffer_read, 16, "Only available in ClickHouse Cloud", 0) \
@ -805,7 +808,6 @@ class IColumn;
M(UInt64, prefetch_buffer_size, DBMS_DEFAULT_BUFFER_SIZE, "The maximum size of the prefetch buffer to read from the filesystem.", 0) \ M(UInt64, prefetch_buffer_size, DBMS_DEFAULT_BUFFER_SIZE, "The maximum size of the prefetch buffer to read from the filesystem.", 0) \
M(UInt64, filesystem_prefetch_step_bytes, 0, "Prefetch step in bytes. Zero means `auto` - approximately the best prefetch step will be auto deduced, but might not be 100% the best. The actual value might be different because of setting filesystem_prefetch_min_bytes_for_single_read_task", 0) \ M(UInt64, filesystem_prefetch_step_bytes, 0, "Prefetch step in bytes. Zero means `auto` - approximately the best prefetch step will be auto deduced, but might not be 100% the best. The actual value might be different because of setting filesystem_prefetch_min_bytes_for_single_read_task", 0) \
M(UInt64, filesystem_prefetch_step_marks, 0, "Prefetch step in marks. Zero means `auto` - approximately the best prefetch step will be auto deduced, but might not be 100% the best. The actual value might be different because of setting filesystem_prefetch_min_bytes_for_single_read_task", 0) \ M(UInt64, filesystem_prefetch_step_marks, 0, "Prefetch step in marks. Zero means `auto` - approximately the best prefetch step will be auto deduced, but might not be 100% the best. The actual value might be different because of setting filesystem_prefetch_min_bytes_for_single_read_task", 0) \
M(UInt64, filesystem_prefetch_min_bytes_for_single_read_task, "2Mi", "Do not parallelize within one file read less than this amount of bytes. E.g. one reader will not receive a read task of size less than this amount. This setting is recommended to avoid spikes of time for aws getObject requests to aws", 0) \
M(UInt64, filesystem_prefetch_max_memory_usage, "1Gi", "Maximum memory usage for prefetches.", 0) \ M(UInt64, filesystem_prefetch_max_memory_usage, "1Gi", "Maximum memory usage for prefetches.", 0) \
M(UInt64, filesystem_prefetches_limit, 200, "Maximum number of prefetches. Zero means unlimited. A setting `filesystem_prefetches_max_memory_usage` is more recommended if you want to limit the number of prefetches", 0) \ M(UInt64, filesystem_prefetches_limit, 200, "Maximum number of prefetches. Zero means unlimited. A setting `filesystem_prefetches_max_memory_usage` is more recommended if you want to limit the number of prefetches", 0) \
\ \
@ -1348,3 +1350,5 @@ struct FormatFactorySettings : public BaseSettings<FormatFactorySettingsTraits>
}; };
} }
#endif

View File

@ -63,7 +63,6 @@ static std::initializer_list<std::pair<ClickHouseVersion, SettingsChangesHistory
{"output_format_native_encode_types_in_binary_format", false, false, "Added new setting to allow to write type names in binary format in Native output format"}, {"output_format_native_encode_types_in_binary_format", false, false, "Added new setting to allow to write type names in binary format in Native output format"},
{"input_format_native_decode_types_in_binary_format", false, false, "Added new setting to allow to read type names in binary format in Native output format"}, {"input_format_native_decode_types_in_binary_format", false, false, "Added new setting to allow to read type names in binary format in Native output format"},
{"read_in_order_use_buffering", false, true, "Use buffering before merging while reading in order of primary key"}, {"read_in_order_use_buffering", false, true, "Use buffering before merging while reading in order of primary key"},
{"optimize_functions_to_subcolumns", false, true, "Enable optimization by default"},
{"enable_named_columns_in_function_tuple", false, true, "Generate named tuples in function tuple() when all names are unique and can be treated as unquoted identifiers."}, {"enable_named_columns_in_function_tuple", false, true, "Generate named tuples in function tuple() when all names are unique and can be treated as unquoted identifiers."},
{"input_format_json_ignore_key_case", false, false, "Ignore json key case while read json field from string."}, {"input_format_json_ignore_key_case", false, false, "Ignore json key case while read json field from string."},
{"optimize_trivial_insert_select", true, false, "The optimization does not make sense in many cases."}, {"optimize_trivial_insert_select", true, false, "The optimization does not make sense in many cases."},
@ -77,6 +76,7 @@ static std::initializer_list<std::pair<ClickHouseVersion, SettingsChangesHistory
{"azure_sdk_max_retries", 10, 10, "Maximum number of retries in azure sdk"}, {"azure_sdk_max_retries", 10, 10, "Maximum number of retries in azure sdk"},
{"azure_sdk_retry_initial_backoff_ms", 10, 10, "Minimal backoff between retries in azure sdk"}, {"azure_sdk_retry_initial_backoff_ms", 10, 10, "Minimal backoff between retries in azure sdk"},
{"azure_sdk_retry_max_backoff_ms", 1000, 1000, "Maximal backoff between retries in azure sdk"}, {"azure_sdk_retry_max_backoff_ms", 1000, 1000, "Maximal backoff between retries in azure sdk"},
{"merge_tree_min_bytes_per_task_for_remote_reading", 4194304, 2097152, "Value is unified with `filesystem_prefetch_min_bytes_for_single_read_task`"},
{"ignore_on_cluster_for_replicated_named_collections_queries", false, false, "Ignore ON CLUSTER clause for replicated named collections management queries."}, {"ignore_on_cluster_for_replicated_named_collections_queries", false, false, "Ignore ON CLUSTER clause for replicated named collections management queries."},
{"backup_restore_s3_retry_attempts", 1000,1000, "Setting for Aws::Client::RetryStrategy, Aws::Client does retries itself, 0 means no retries. It takes place only for backup/restore."}, {"backup_restore_s3_retry_attempts", 1000,1000, "Setting for Aws::Client::RetryStrategy, Aws::Client does retries itself, 0 means no retries. It takes place only for backup/restore."},
{"postgresql_connection_attempt_timeout", 2, 2, "Allow to control 'connect_timeout' parameter of PostgreSQL connection."}, {"postgresql_connection_attempt_timeout", 2, 2, "Allow to control 'connect_timeout' parameter of PostgreSQL connection."},
@ -147,7 +147,7 @@ static std::initializer_list<std::pair<ClickHouseVersion, SettingsChangesHistory
{"default_table_engine", "None", "MergeTree", "Set default table engine to MergeTree for better usability"}, {"default_table_engine", "None", "MergeTree", "Set default table engine to MergeTree for better usability"},
{"input_format_json_use_string_type_for_ambiguous_paths_in_named_tuples_inference_from_objects", false, false, "Allow to use String type for ambiguous paths during named tuple inference from JSON objects"}, {"input_format_json_use_string_type_for_ambiguous_paths_in_named_tuples_inference_from_objects", false, false, "Allow to use String type for ambiguous paths during named tuple inference from JSON objects"},
{"traverse_shadow_remote_data_paths", false, false, "Traverse shadow directory when query system.remote_data_paths."}, {"traverse_shadow_remote_data_paths", false, false, "Traverse shadow directory when query system.remote_data_paths."},
{"throw_if_deduplication_in_dependent_materialized_views_enabled_with_async_insert", false, true, "Deduplication is dependent materialized view cannot work together with async inserts."}, {"throw_if_deduplication_in_dependent_materialized_views_enabled_with_async_insert", false, true, "Deduplication in dependent materialized view cannot work together with async inserts."},
{"parallel_replicas_allow_in_with_subquery", false, true, "If true, subquery for IN will be executed on every follower replica"}, {"parallel_replicas_allow_in_with_subquery", false, true, "If true, subquery for IN will be executed on every follower replica"},
{"log_processors_profiles", false, true, "Enable by default"}, {"log_processors_profiles", false, true, "Enable by default"},
{"function_locate_has_mysql_compatible_argument_order", false, true, "Increase compatibility with MySQL's locate function."}, {"function_locate_has_mysql_compatible_argument_order", false, true, "Increase compatibility with MySQL's locate function."},

View File

@ -1,8 +1,8 @@
clickhouse_add_executable (string_pool string_pool.cpp) clickhouse_add_executable (string_pool string_pool.cpp)
target_link_libraries (string_pool PRIVATE clickhouse_common_io ch_contrib::sparsehash) target_link_libraries (string_pool PRIVATE clickhouse_common_io clickhouse_common_config ch_contrib::sparsehash)
clickhouse_add_executable (field field.cpp) clickhouse_add_executable (field field.cpp)
target_link_libraries (field PRIVATE dbms) target_link_libraries (field PRIVATE dbms)
clickhouse_add_executable (string_ref_hash string_ref_hash.cpp) clickhouse_add_executable (string_ref_hash string_ref_hash.cpp)
target_link_libraries (string_ref_hash PRIVATE clickhouse_common_io) target_link_libraries (string_ref_hash PRIVATE clickhouse_common_io clickhouse_common_config)

View File

@ -146,10 +146,19 @@ BaseDaemon::BaseDaemon() = default;
BaseDaemon::~BaseDaemon() BaseDaemon::~BaseDaemon()
{ {
writeSignalIDtoSignalPipe(SignalListener::StopThread); try
signal_listener_thread.join(); {
HandledSignals::instance().reset(); writeSignalIDtoSignalPipe(SignalListener::StopThread);
SentryWriter::resetInstance(); signal_listener_thread.join();
HandledSignals::instance().reset();
SentryWriter::resetInstance();
}
catch (...)
{
tryLogCurrentException(&logger());
}
OwnSplitChannel::disableLogging();
} }

View File

@ -125,23 +125,6 @@ DataTypePtr DataTypeFactory::getImpl(const String & family_name_param, const AST
{ {
String family_name = getAliasToOrName(family_name_param); String family_name = getAliasToOrName(family_name_param);
if (endsWith(family_name, "WithDictionary"))
{
ASTPtr low_cardinality_params = std::make_shared<ASTExpressionList>();
String param_name = family_name.substr(0, family_name.size() - strlen("WithDictionary"));
if (parameters)
{
auto func = std::make_shared<ASTFunction>();
func->name = param_name;
func->arguments = parameters;
low_cardinality_params->children.push_back(func);
}
else
low_cardinality_params->children.push_back(std::make_shared<ASTIdentifier>(param_name));
return getImpl<nullptr_on_error>("LowCardinality", low_cardinality_params);
}
const auto * creator = findCreatorByName<nullptr_on_error>(family_name); const auto * creator = findCreatorByName<nullptr_on_error>(family_name);
if constexpr (nullptr_on_error) if constexpr (nullptr_on_error)
{ {

View File

@ -559,8 +559,11 @@ void DatabaseReplicated::createEmptyLogEntry(const ZooKeeperPtr & current_zookee
bool DatabaseReplicated::waitForReplicaToProcessAllEntries(UInt64 timeout_ms) bool DatabaseReplicated::waitForReplicaToProcessAllEntries(UInt64 timeout_ms)
{ {
if (!ddl_worker || is_probably_dropped) {
return false; std::lock_guard lock{ddl_worker_mutex};
if (!ddl_worker || is_probably_dropped)
return false;
}
return ddl_worker->waitForReplicaToProcessAllEntries(timeout_ms); return ddl_worker->waitForReplicaToProcessAllEntries(timeout_ms);
} }
@ -641,7 +644,10 @@ LoadTaskPtr DatabaseReplicated::startupDatabaseAsync(AsyncLoader & async_loader,
if (is_probably_dropped) if (is_probably_dropped)
return; return;
ddl_worker = std::make_unique<DatabaseReplicatedDDLWorker>(this, getContext()); {
std::lock_guard lock{ddl_worker_mutex};
ddl_worker = std::make_unique<DatabaseReplicatedDDLWorker>(this, getContext());
}
ddl_worker->startup(); ddl_worker->startup();
ddl_worker_initialized = true; ddl_worker_initialized = true;
}); });
@ -671,92 +677,96 @@ void DatabaseReplicated::stopLoading()
DatabaseAtomic::stopLoading(); DatabaseAtomic::stopLoading();
} }
bool DatabaseReplicated::checkDigestValid(const ContextPtr & local_context, bool debug_check /* = true */) const void DatabaseReplicated::dumpLocalTablesForDebugOnly(const ContextPtr & local_context) const
{ {
if (debug_check) auto table_names = getAllTableNames(context.lock());
for (const auto & table_name : table_names)
{ {
/// Reduce number of debug checks auto ast_ptr = tryGetCreateTableQuery(table_name, local_context);
if (thread_local_rng() % 16) if (ast_ptr)
return true; LOG_DEBUG(log, "[local] Table {} create query is {}", table_name, queryToString(ast_ptr));
else
LOG_DEBUG(log, "[local] Table {} has no create query", table_name);
} }
LOG_TEST(log, "Current in-memory metadata digest: {}", tables_metadata_digest);
/// Database is probably being dropped
if (!local_context->getZooKeeperMetadataTransaction() && (!ddl_worker || !ddl_worker->isCurrentlyActive()))
return true;
UInt64 local_digest = 0;
{
std::lock_guard lock{mutex};
for (const auto & table : TSA_SUPPRESS_WARNING_FOR_READ(tables))
local_digest += getMetadataHash(table.first);
}
if (local_digest != tables_metadata_digest)
{
LOG_ERROR(log, "Digest of local metadata ({}) is not equal to in-memory digest ({})", local_digest, tables_metadata_digest);
return false;
}
/// Do not check digest in Keeper after internal subquery, it's probably not committed yet
if (local_context->isInternalSubquery())
return true;
/// Check does not make sense to check digest in Keeper during recovering
if (is_recovering)
return true;
String zk_digest = getZooKeeper()->get(replica_path + "/digest");
String local_digest_str = toString(local_digest);
if (zk_digest != local_digest_str)
{
LOG_ERROR(log, "Digest of local metadata ({}) is not equal to digest in Keeper ({})", local_digest_str, zk_digest);
return false;
}
return true;
} }
void DatabaseReplicated::checkQueryValid(const ASTPtr & query, ContextPtr query_context) const void DatabaseReplicated::dumpTablesInZooKeeperForDebugOnly() const
{ {
/// Replicas will set correct name of current database in query context (database name can be different on replicas) UInt32 max_log_ptr;
if (auto * ddl_query = dynamic_cast<ASTQueryWithTableAndOutput *>(query.get())) auto table_name_to_metadata = tryGetConsistentMetadataSnapshot(getZooKeeper(), max_log_ptr);
for (const auto & [table_name, create_table_query] : table_name_to_metadata)
{ {
if (ddl_query->getDatabase() != getDatabaseName()) auto query_ast = parseQueryFromMetadataInZooKeeper(table_name, create_table_query);
throw Exception(ErrorCodes::UNKNOWN_DATABASE, "Database was renamed"); if (query_ast)
ddl_query->database.reset();
if (auto * create = query->as<ASTCreateQuery>())
{ {
if (create->storage) LOG_DEBUG(log, "[zookeeper] Table {} create query is {}", table_name, queryToString(query_ast));
checkTableEngine(*create, *create->storage, query_context); }
else
{
LOG_DEBUG(log, "[zookeeper] Table {} has no create query", table_name);
}
}
}
if (create->targets) void DatabaseReplicated::tryCompareLocalAndZooKeeperTablesAndDumpDiffForDebugOnly(const ContextPtr & local_context) const
{
UInt32 max_log_ptr;
auto table_name_to_metadata_in_zk = tryGetConsistentMetadataSnapshot(getZooKeeper(), max_log_ptr);
auto table_names_local = getAllTableNames(local_context);
if (table_name_to_metadata_in_zk.size() != table_names_local.size())
LOG_DEBUG(log, "Amount of tables in zk {} locally {}", table_name_to_metadata_in_zk.size(), table_names_local.size());
std::unordered_set<std::string> checked_tables;
for (const auto & table_name : table_names_local)
{
auto local_ast_ptr = tryGetCreateTableQuery(table_name, local_context);
if (table_name_to_metadata_in_zk.contains(table_name))
{
checked_tables.insert(table_name);
auto create_table_query_in_zk = table_name_to_metadata_in_zk[table_name];
auto zk_ast_ptr = parseQueryFromMetadataInZooKeeper(table_name, create_table_query_in_zk);
if (local_ast_ptr == nullptr && zk_ast_ptr == nullptr)
{ {
for (const auto & inner_table_engine : create->targets->getInnerEngines()) LOG_DEBUG(log, "AST for table {} is the same (nullptr) in local and ZK", table_name);
checkTableEngine(*create, *inner_table_engine, query_context); }
else if (local_ast_ptr != nullptr && zk_ast_ptr != nullptr && queryToString(local_ast_ptr) != queryToString(zk_ast_ptr))
{
LOG_DEBUG(log, "AST differs for table {}, local {}, in zookeeper {}", table_name, queryToString(local_ast_ptr), queryToString(zk_ast_ptr));
}
else if (local_ast_ptr == nullptr)
{
LOG_DEBUG(log, "AST differs for table {}, local nullptr, in zookeeper {}", table_name, queryToString(zk_ast_ptr));
}
else if (zk_ast_ptr == nullptr)
{
LOG_DEBUG(log, "AST differs for table {}, local {}, in zookeeper nullptr", table_name, queryToString(local_ast_ptr));
}
else
{
LOG_DEBUG(log, "AST for table {} is the same in local and ZK", table_name);
} }
} }
} else
if (const auto * query_alter = query->as<ASTAlterQuery>())
{
for (const auto & command : query_alter->command_list->children)
{ {
if (!isSupportedAlterTypeForOnClusterDDLQuery(command->as<ASTAlterCommand&>().type)) if (local_ast_ptr == nullptr)
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Unsupported type of ALTER query"); LOG_DEBUG(log, "Table {} exists locally, but missing in ZK", table_name);
else
LOG_DEBUG(log, "Table {} exists locally with AST {}, but missing in ZK", table_name, queryToString(local_ast_ptr));
} }
} }
for (const auto & [table_name, table_metadata] : table_name_to_metadata_in_zk)
if (auto * query_drop = query->as<ASTDropQuery>())
{ {
if (query_drop->kind == ASTDropQuery::Kind::Detach && query_context->getSettingsRef().database_replicated_always_detach_permanently) if (!checked_tables.contains(table_name))
query_drop->permanently = true; {
if (query_drop->kind == ASTDropQuery::Kind::Detach && !query_drop->permanently) auto zk_ast_ptr = parseQueryFromMetadataInZooKeeper(table_name, table_metadata);
throw Exception(ErrorCodes::INCORRECT_QUERY, "DETACH TABLE is not allowed for Replicated databases. " if (zk_ast_ptr == nullptr)
"Use DETACH TABLE PERMANENTLY or SYSTEM RESTART REPLICA or set " LOG_DEBUG(log, "Table {} exists in ZK with AST {}, but missing locally", table_name, queryToString(zk_ast_ptr));
"database_replicated_always_detach_permanently to 1"); else
LOG_DEBUG(log, "Table {} exists in ZK, but missing locally", table_name);
}
} }
} }
@ -839,6 +849,107 @@ void DatabaseReplicated::checkTableEngine(const ASTCreateQuery & query, ASTStora
"to distinguish different shards and replicas"); "to distinguish different shards and replicas");
} }
bool DatabaseReplicated::checkDigestValid(const ContextPtr & local_context, bool debug_check /* = true */) const
{
if (debug_check)
{
/// Reduce number of debug checks
if (thread_local_rng() % 16)
return true;
}
LOG_TEST(log, "Current in-memory metadata digest: {}", tables_metadata_digest);
/// Database is probably being dropped
if (!local_context->getZooKeeperMetadataTransaction() && (!ddl_worker || !ddl_worker->isCurrentlyActive()))
return true;
UInt64 local_digest = 0;
{
std::lock_guard lock{mutex};
for (const auto & table : TSA_SUPPRESS_WARNING_FOR_READ(tables))
local_digest += getMetadataHash(table.first);
}
if (local_digest != tables_metadata_digest)
{
LOG_ERROR(log, "Digest of local metadata ({}) is not equal to in-memory digest ({})", local_digest, tables_metadata_digest);
#ifndef NDEBUG
dumpLocalTablesForDebugOnly(local_context);
dumpTablesInZooKeeperForDebugOnly();
tryCompareLocalAndZooKeeperTablesAndDumpDiffForDebugOnly(local_context);
#endif
return false;
}
/// Do not check digest in Keeper after internal subquery, it's probably not committed yet
if (local_context->isInternalSubquery())
return true;
/// Check does not make sense to check digest in Keeper during recovering
if (is_recovering)
return true;
String zk_digest = getZooKeeper()->get(replica_path + "/digest");
String local_digest_str = toString(local_digest);
if (zk_digest != local_digest_str)
{
LOG_ERROR(log, "Digest of local metadata ({}) is not equal to digest in Keeper ({})", local_digest_str, zk_digest);
#ifndef NDEBUG
dumpLocalTablesForDebugOnly(local_context);
dumpTablesInZooKeeperForDebugOnly();
tryCompareLocalAndZooKeeperTablesAndDumpDiffForDebugOnly(local_context);
#endif
return false;
}
return true;
}
void DatabaseReplicated::checkQueryValid(const ASTPtr & query, ContextPtr query_context) const
{
/// Replicas will set correct name of current database in query context (database name can be different on replicas)
if (auto * ddl_query = dynamic_cast<ASTQueryWithTableAndOutput *>(query.get()))
{
if (ddl_query->getDatabase() != getDatabaseName())
throw Exception(ErrorCodes::UNKNOWN_DATABASE, "Database was renamed");
ddl_query->database.reset();
if (auto * create = query->as<ASTCreateQuery>())
{
if (create->storage)
checkTableEngine(*create, *create->storage, query_context);
if (create->targets)
{
for (const auto & inner_table_engine : create->targets->getInnerEngines())
checkTableEngine(*create, *inner_table_engine, query_context);
}
}
}
if (const auto * query_alter = query->as<ASTAlterQuery>())
{
for (const auto & command : query_alter->command_list->children)
{
if (!isSupportedAlterTypeForOnClusterDDLQuery(command->as<ASTAlterCommand&>().type))
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Unsupported type of ALTER query");
}
}
if (auto * query_drop = query->as<ASTDropQuery>())
{
if (query_drop->kind == ASTDropQuery::Kind::Detach && query_context->getSettingsRef().database_replicated_always_detach_permanently)
query_drop->permanently = true;
if (query_drop->kind == ASTDropQuery::Kind::Detach && !query_drop->permanently)
throw Exception(ErrorCodes::INCORRECT_QUERY, "DETACH TABLE is not allowed for Replicated databases. "
"Use DETACH TABLE PERMANENTLY or SYSTEM RESTART REPLICA or set "
"database_replicated_always_detach_permanently to 1");
}
}
BlockIO DatabaseReplicated::tryEnqueueReplicatedDDL(const ASTPtr & query, ContextPtr query_context, QueryFlags flags) BlockIO DatabaseReplicated::tryEnqueueReplicatedDDL(const ASTPtr & query, ContextPtr query_context, QueryFlags flags)
{ {
waitDatabaseStarted(); waitDatabaseStarted();
@ -1253,7 +1364,7 @@ void DatabaseReplicated::recoverLostReplica(const ZooKeeperPtr & current_zookeep
current_zookeeper->set(replica_path + "/digest", toString(tables_metadata_digest)); current_zookeeper->set(replica_path + "/digest", toString(tables_metadata_digest));
} }
std::map<String, String> DatabaseReplicated::tryGetConsistentMetadataSnapshot(const ZooKeeperPtr & zookeeper, UInt32 & max_log_ptr) std::map<String, String> DatabaseReplicated::tryGetConsistentMetadataSnapshot(const ZooKeeperPtr & zookeeper, UInt32 & max_log_ptr) const
{ {
return getConsistentMetadataSnapshotImpl(zookeeper, {}, /* max_retries= */ 10, max_log_ptr); return getConsistentMetadataSnapshotImpl(zookeeper, {}, /* max_retries= */ 10, max_log_ptr);
} }
@ -1314,7 +1425,7 @@ std::map<String, String> DatabaseReplicated::getConsistentMetadataSnapshotImpl(
return table_name_to_metadata; return table_name_to_metadata;
} }
ASTPtr DatabaseReplicated::parseQueryFromMetadataInZooKeeper(const String & node_name, const String & query) ASTPtr DatabaseReplicated::parseQueryFromMetadataInZooKeeper(const String & node_name, const String & query) const
{ {
ParserCreateQuery parser; ParserCreateQuery parser;
String description = "in ZooKeeper " + zookeeper_path + "/metadata/" + node_name; String description = "in ZooKeeper " + zookeeper_path + "/metadata/" + node_name;
@ -1411,6 +1522,7 @@ void DatabaseReplicated::renameDatabase(ContextPtr query_context, const String &
void DatabaseReplicated::stopReplication() void DatabaseReplicated::stopReplication()
{ {
std::lock_guard lock{ddl_worker_mutex};
if (ddl_worker) if (ddl_worker)
ddl_worker->shutdown(); ddl_worker->shutdown();
} }

View File

@ -109,14 +109,15 @@ private:
void checkQueryValid(const ASTPtr & query, ContextPtr query_context) const; void checkQueryValid(const ASTPtr & query, ContextPtr query_context) const;
void checkTableEngine(const ASTCreateQuery & query, ASTStorage & storage, ContextPtr query_context) const; void checkTableEngine(const ASTCreateQuery & query, ASTStorage & storage, ContextPtr query_context) const;
void recoverLostReplica(const ZooKeeperPtr & current_zookeeper, UInt32 our_log_ptr, UInt32 & max_log_ptr); void recoverLostReplica(const ZooKeeperPtr & current_zookeeper, UInt32 our_log_ptr, UInt32 & max_log_ptr);
std::map<String, String> tryGetConsistentMetadataSnapshot(const ZooKeeperPtr & zookeeper, UInt32 & max_log_ptr); std::map<String, String> tryGetConsistentMetadataSnapshot(const ZooKeeperPtr & zookeeper, UInt32 & max_log_ptr) const;
std::map<String, String> getConsistentMetadataSnapshotImpl(const ZooKeeperPtr & zookeeper, const FilterByNameFunction & filter_by_table_name, std::map<String, String> getConsistentMetadataSnapshotImpl(const ZooKeeperPtr & zookeeper, const FilterByNameFunction & filter_by_table_name,
size_t max_retries, UInt32 & max_log_ptr) const; size_t max_retries, UInt32 & max_log_ptr) const;
ASTPtr parseQueryFromMetadataInZooKeeper(const String & node_name, const String & query); ASTPtr parseQueryFromMetadataInZooKeeper(const String & node_name, const String & query) const;
String readMetadataFile(const String & table_name) const; String readMetadataFile(const String & table_name) const;
ClusterPtr getClusterImpl(bool all_groups = false) const; ClusterPtr getClusterImpl(bool all_groups = false) const;
@ -132,6 +133,11 @@ private:
UInt64 getMetadataHash(const String & table_name) const; UInt64 getMetadataHash(const String & table_name) const;
bool checkDigestValid(const ContextPtr & local_context, bool debug_check = true) const TSA_REQUIRES(metadata_mutex); bool checkDigestValid(const ContextPtr & local_context, bool debug_check = true) const TSA_REQUIRES(metadata_mutex);
/// For debug purposes only, don't use in production code
void dumpLocalTablesForDebugOnly(const ContextPtr & local_context) const;
void dumpTablesInZooKeeperForDebugOnly() const;
void tryCompareLocalAndZooKeeperTablesAndDumpDiffForDebugOnly(const ContextPtr & local_context) const;
void waitDatabaseStarted() const override; void waitDatabaseStarted() const override;
void stopLoading() override; void stopLoading() override;
@ -149,6 +155,7 @@ private:
std::atomic_bool is_recovering = false; std::atomic_bool is_recovering = false;
std::atomic_bool ddl_worker_initialized = false; std::atomic_bool ddl_worker_initialized = false;
std::unique_ptr<DatabaseReplicatedDDLWorker> ddl_worker; std::unique_ptr<DatabaseReplicatedDDLWorker> ddl_worker;
std::mutex ddl_worker_mutex;
UInt32 max_log_ptr_at_creation = 0; UInt32 max_log_ptr_at_creation = 0;
/// Usually operation with metadata are single-threaded because of the way replication works, /// Usually operation with metadata are single-threaded because of the way replication works,

View File

@ -289,8 +289,13 @@ StoragePtr DatabaseWithOwnTablesBase::detachTableUnlocked(const String & table_n
tables.erase(it); tables.erase(it);
table_storage->is_detached = true; table_storage->is_detached = true;
if (!table_storage->isSystemStorage() && database_name != DatabaseCatalog::SYSTEM_DATABASE) if (!table_storage->isSystemStorage()
&& database_name != DatabaseCatalog::SYSTEM_DATABASE
&& database_name != DatabaseCatalog::TEMPORARY_DATABASE)
{
LOG_TEST(log, "Counting detached table {} to database {}", table_name, database_name);
CurrentMetrics::sub(getAttachedCounterForStorage(table_storage)); CurrentMetrics::sub(getAttachedCounterForStorage(table_storage));
}
auto table_id = table_storage->getStorageID(); auto table_id = table_storage->getStorageID();
if (table_id.hasUUID()) if (table_id.hasUUID())
@ -334,8 +339,13 @@ void DatabaseWithOwnTablesBase::attachTableUnlocked(const String & table_name, c
/// non-Atomic database the is_detached is set to true before RENAME. /// non-Atomic database the is_detached is set to true before RENAME.
table->is_detached = false; table->is_detached = false;
if (!table->isSystemStorage() && table_id.database_name != DatabaseCatalog::SYSTEM_DATABASE) if (!table->isSystemStorage()
&& database_name != DatabaseCatalog::SYSTEM_DATABASE
&& database_name != DatabaseCatalog::TEMPORARY_DATABASE)
{
LOG_TEST(log, "Counting attached table {} to database {}", table_name, database_name);
CurrentMetrics::add(getAttachedCounterForStorage(table)); CurrentMetrics::add(getAttachedCounterForStorage(table));
}
} }
void DatabaseWithOwnTablesBase::shutdown() void DatabaseWithOwnTablesBase::shutdown()

View File

@ -874,7 +874,9 @@ void DiskObjectStorageTransaction::writeFileUsingBlobWritingFunction(
/// Create metadata (see create_metadata_callback in DiskObjectStorageTransaction::writeFile()). /// Create metadata (see create_metadata_callback in DiskObjectStorageTransaction::writeFile()).
if (mode == WriteMode::Rewrite) if (mode == WriteMode::Rewrite)
{ {
if (!object_storage.isWriteOnce() && metadata_storage.exists(path)) /// Otherwise we will produce lost blobs which nobody points to
/// WriteOnce storages are not affected by the issue
if (!object_storage.isPlain() && metadata_storage.exists(path))
object_storage.removeObjectsIfExist(metadata_storage.getStorageObjects(path)); object_storage.removeObjectsIfExist(metadata_storage.getStorageObjects(path));
metadata_transaction->createMetadataFile(path, std::move(object_key), object_size); metadata_transaction->createMetadataFile(path, std::move(object_key), object_size);

View File

@ -58,7 +58,8 @@ TemporaryFileOnDisk::~TemporaryFileOnDisk()
if (!disk->exists(relative_path)) if (!disk->exists(relative_path))
{ {
LOG_WARNING(getLogger("TemporaryFileOnDisk"), "Temporary path '{}' does not exist in '{}'", relative_path, disk->getPath()); if (show_warning_if_removed)
LOG_WARNING(getLogger("TemporaryFileOnDisk"), "Temporary path '{}' does not exist in '{}'", relative_path, disk->getPath());
return; return;
} }

View File

@ -27,12 +27,19 @@ public:
/// Return relative path (without disk) /// Return relative path (without disk)
const String & getRelativePath() const { return relative_path; } const String & getRelativePath() const { return relative_path; }
/// Sets whether the destructor should show a warning if the temporary file has been already removed.
/// By default a warning is shown.
void setShowWarningIfRemoved(bool show_warning_if_removed_) { show_warning_if_removed = show_warning_if_removed_; }
private: private:
DiskPtr disk; DiskPtr disk;
/// Relative path in disk to the temporary file or directory /// Relative path in disk to the temporary file or directory
String relative_path; String relative_path;
/// Whether the destructor should show a warning if the temporary file has been already removed.
bool show_warning_if_removed = true;
CurrentMetrics::Increment metric_increment; CurrentMetrics::Increment metric_increment;
/// Specified if we know what for file is used (sort/aggregate/join). /// Specified if we know what for file is used (sort/aggregate/join).

View File

@ -18,6 +18,7 @@ namespace ErrorCodes
extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_COLUMN;
extern const int ILLEGAL_TYPE_OF_ARGUMENT; extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int BAD_ARGUMENTS; extern const int BAD_ARGUMENTS;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
} }
struct Base58Encode struct Base58Encode
@ -135,7 +136,7 @@ public:
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
{ {
if (arguments.size() != 1) if (arguments.size() != 1)
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Wrong number of arguments for function {}: 1 expected.", getName()); throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "Wrong number of arguments for function {}: 1 expected.", getName());
if (!isString(arguments[0].type)) if (!isString(arguments[0].type))
throw Exception( throw Exception(

View File

@ -15,6 +15,7 @@ namespace ErrorCodes
{ {
extern const int ILLEGAL_TYPE_OF_ARGUMENT; extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_COLUMN;
extern const int TOO_FEW_ARGUMENTS_FOR_FUNCTION;
} }
class FunctionChar : public IFunction class FunctionChar : public IFunction
@ -36,7 +37,7 @@ public:
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{ {
if (arguments.empty()) if (arguments.empty())
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, throw Exception(ErrorCodes::TOO_FEW_ARGUMENTS_FOR_FUNCTION,
"Number of arguments for function {} can't be {}, should be at least 1", "Number of arguments for function {} can't be {}, should be at least 1",
getName(), arguments.size()); getName(), arguments.size());

View File

@ -59,19 +59,19 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const ColumnPtr column = arguments[0].column; const ColumnPtr column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{ {
auto col_res = ColumnString::create(); auto col_res = ColumnString::create();
Impl::vector(col->getChars(), col->getOffsets(), col_res->getChars(), col_res->getOffsets()); Impl::vector(col->getChars(), col->getOffsets(), col_res->getChars(), col_res->getOffsets(), input_rows_count);
return col_res; return col_res;
} }
else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column.get())) else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column.get()))
{ {
auto col_res = ColumnFixedString::create(col_fixed->getN()); auto col_res = ColumnFixedString::create(col_fixed->getN());
Impl::vectorFixed(col_fixed->getChars(), col_fixed->getN(), col_res->getChars()); Impl::vectorFixed(col_fixed->getChars(), col_fixed->getN(), col_res->getChars(), input_rows_count);
return col_res; return col_res;
} }
else else

View File

@ -739,7 +739,8 @@ public:
{ {
NumberType value; NumberType value;
tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, convert_bool_to_integer, error); if (!tryGetNumericValueFromJSONElement<JSONParser, NumberType>(value, element, convert_bool_to_integer, error))
return false;
auto & col_vec = assert_cast<ColumnVector<NumberType> &>(dest); auto & col_vec = assert_cast<ColumnVector<NumberType> &>(dest);
col_vec.insertValue(value); col_vec.insertValue(value);
return true; return true;

View File

@ -47,85 +47,54 @@ bool allArgumentsAreConstants(const ColumnsWithTypeAndName & args)
return true; return true;
} }
/// Replaces single low cardinality column in a function call by its dictionary
/// This can only happen after the arguments have been adapted in IFunctionOverloadResolver::getReturnType
/// as it's only possible if there is one low cardinality column and, optionally, const columns
ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes( ColumnPtr replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
ColumnsWithTypeAndName & args, bool can_be_executed_on_default_arguments, size_t input_rows_count) ColumnsWithTypeAndName & args, bool can_be_executed_on_default_arguments, size_t input_rows_count)
{ {
/// We return the LC indexes so the LC can be reconstructed with the function result size_t num_rows = input_rows_count;
ColumnPtr indexes; ColumnPtr indexes;
size_t number_low_cardinality_columns = 0; /// Find first LowCardinality column and replace it to nested dictionary.
size_t last_low_cardinality = 0; for (auto & column : args)
size_t number_const_columns = 0;
size_t number_full_columns = 0;
for (size_t i = 0; i < args.size(); i++)
{ {
auto const & arg = args[i]; if (const auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(column.column.get()))
if (checkAndGetColumn<ColumnLowCardinality>(arg.column.get()))
{ {
number_low_cardinality_columns++; /// Single LowCardinality column is supported now.
last_low_cardinality = i; if (indexes)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Expected single dictionary argument for function.");
const auto * low_cardinality_type = checkAndGetDataType<DataTypeLowCardinality>(column.type.get());
if (!low_cardinality_type)
throw Exception(ErrorCodes::LOGICAL_ERROR,
"Incompatible type for LowCardinality column: {}",
column.type->getName());
if (can_be_executed_on_default_arguments)
{
/// Normal case, when function can be executed on values' default.
column.column = low_cardinality_column->getDictionary().getNestedColumn();
indexes = low_cardinality_column->getIndexesPtr();
}
else
{
/// Special case when default value can't be used. Example: 1 % LowCardinality(Int).
/// LowCardinality always contains default, so 1 % 0 will throw exception in normal case.
auto dict_encoded = low_cardinality_column->getMinimalDictionaryEncodedColumn(0, low_cardinality_column->size());
column.column = dict_encoded.dictionary;
indexes = dict_encoded.indexes;
}
num_rows = column.column->size();
column.type = low_cardinality_type->getDictionaryType();
} }
else if (checkAndGetColumn<ColumnConst>(arg.column.get()))
number_const_columns++;
else
number_full_columns++;
} }
if (!number_low_cardinality_columns && !number_const_columns) /// Change size of constants.
return nullptr;
if (number_full_columns > 0 || number_low_cardinality_columns > 1)
{
/// This should not be possible but currently there are multiple tests in CI failing because of it
/// TODO: Fix those cases, then enable this exception
#if 0
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unexpected low cardinality types found. Low cardinality: {}. Full {}. Const {}",
number_low_cardinality_columns, number_full_columns, number_const_columns);
#else
return nullptr;
#endif
}
else if (number_low_cardinality_columns == 1)
{
auto & lc_arg = args[last_low_cardinality];
const auto * low_cardinality_type = checkAndGetDataType<DataTypeLowCardinality>(lc_arg.type.get());
if (!low_cardinality_type)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Incompatible type for LowCardinality column: {}", lc_arg.type->getName());
const auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(lc_arg.column.get());
chassert(low_cardinality_column);
if (can_be_executed_on_default_arguments)
{
/// Normal case, when function can be executed on values' default.
lc_arg.column = low_cardinality_column->getDictionary().getNestedColumn();
indexes = low_cardinality_column->getIndexesPtr();
}
else
{
/// Special case when default value can't be used. Example: 1 % LowCardinality(Int).
/// LowCardinality always contains default, so 1 % 0 will throw exception in normal case.
auto dict_encoded = low_cardinality_column->getMinimalDictionaryEncodedColumn(0, low_cardinality_column->size());
lc_arg.column = dict_encoded.dictionary;
indexes = dict_encoded.indexes;
}
/// The new column will have a different number of rows, normally less but occasionally it might be more (NULL)
input_rows_count = lc_arg.column->size();
lc_arg.type = low_cardinality_type->getDictionaryType();
}
/// Change size of constants
for (auto & column : args) for (auto & column : args)
{ {
if (const auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get())) if (const auto * column_const = checkAndGetColumn<ColumnConst>(column.column.get()))
{ {
column.column = ColumnConst::create(recursiveRemoveLowCardinality(column_const->getDataColumnPtr()), input_rows_count); column.column = ColumnConst::create(recursiveRemoveLowCardinality(column_const->getDataColumnPtr()), num_rows);
column.type = recursiveRemoveLowCardinality(column.type); column.type = recursiveRemoveLowCardinality(column.type);
} }
} }
@ -301,8 +270,6 @@ ColumnPtr IExecutableFunction::executeWithoutSparseColumns(const ColumnsWithType
bool can_be_executed_on_default_arguments = canBeExecutedOnDefaultArguments(); bool can_be_executed_on_default_arguments = canBeExecutedOnDefaultArguments();
const auto & dictionary_type = res_low_cardinality_type->getDictionaryType(); const auto & dictionary_type = res_low_cardinality_type->getDictionaryType();
/// The arguments should have been adapted in IFunctionOverloadResolver::getReturnType
/// So there is only one low cardinality column (and optionally some const columns) and no full column
ColumnPtr indexes = replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes( ColumnPtr indexes = replaceLowCardinalityColumnsByNestedAndGetDictionaryIndexes(
columns_without_low_cardinality, can_be_executed_on_default_arguments, input_rows_count); columns_without_low_cardinality, can_be_executed_on_default_arguments, input_rows_count);

View File

@ -8,17 +8,19 @@ namespace DB
template <char not_case_lower_bound, char not_case_upper_bound> template <char not_case_lower_bound, char not_case_upper_bound>
struct LowerUpperImpl struct LowerUpperImpl
{ {
static void vector(const ColumnString::Chars & data, static void vector(
const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t /*input_rows_count*/)
{ {
res_data.resize_exact(data.size()); res_data.resize_exact(data.size());
res_offsets.assign(offsets); res_offsets.assign(offsets);
array(data.data(), data.data() + data.size(), res_data.data()); array(data.data(), data.data() + data.size(), res_data.data());
} }
static void vectorFixed(const ColumnString::Chars & data, size_t /*n*/, ColumnString::Chars & res_data) static void vectorFixed(const ColumnString::Chars & data, size_t /*n*/, ColumnString::Chars & res_data, size_t /*input_rows_count*/)
{ {
res_data.resize_exact(data.size()); res_data.resize_exact(data.size());
array(data.data(), data.data() + data.size(), res_data.data()); array(data.data(), data.data() + data.size(), res_data.data());

View File

@ -90,7 +90,8 @@ struct LowerUpperUTF8Impl
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
if (data.empty()) if (data.empty())
return; return;
@ -98,7 +99,7 @@ struct LowerUpperUTF8Impl
bool all_ascii = isAllASCII(data.data(), data.size()); bool all_ascii = isAllASCII(data.data(), data.size());
if (all_ascii) if (all_ascii)
{ {
LowerUpperImpl<not_case_lower_bound, not_case_upper_bound>::vector(data, offsets, res_data, res_offsets); LowerUpperImpl<not_case_lower_bound, not_case_upper_bound>::vector(data, offsets, res_data, res_offsets, input_rows_count);
return; return;
} }
@ -107,7 +108,7 @@ struct LowerUpperUTF8Impl
array(data.data(), data.data() + data.size(), offsets, res_data.data()); array(data.data(), data.data() + data.size(), offsets, res_data.data());
} }
static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Functions lowerUTF8 and upperUTF8 cannot work with FixedString argument"); throw Exception(ErrorCodes::BAD_ARGUMENTS, "Functions lowerUTF8 and upperUTF8 cannot work with FixedString argument");
} }

View File

@ -62,12 +62,13 @@ using Pos = const char *;
template <typename Extractor> template <typename Extractor>
struct ExtractSubstringImpl struct ExtractSubstringImpl
{ {
static void vector(const ColumnString::Chars & data, const ColumnString::Offsets & offsets, static void vector(
ColumnString::Chars & res_data, ColumnString::Offsets & res_offsets) const ColumnString::Chars & data, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size); res_data.reserve(input_rows_count * Extractor::getReserveLengthForElement());
res_data.reserve(size * Extractor::getReserveLengthForElement());
size_t prev_offset = 0; size_t prev_offset = 0;
size_t res_offset = 0; size_t res_offset = 0;
@ -76,7 +77,7 @@ struct ExtractSubstringImpl
Pos start; Pos start;
size_t length; size_t length;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
Extractor::execute(reinterpret_cast<const char *>(&data[prev_offset]), offsets[i] - prev_offset - 1, start, length); Extractor::execute(reinterpret_cast<const char *>(&data[prev_offset]), offsets[i] - prev_offset - 1, start, length);
@ -99,7 +100,7 @@ struct ExtractSubstringImpl
res_data.assign(start, length); res_data.assign(start, length);
} }
static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by this function"); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by this function");
} }
@ -111,12 +112,13 @@ struct ExtractSubstringImpl
template <typename Extractor> template <typename Extractor>
struct CutSubstringImpl struct CutSubstringImpl
{ {
static void vector(const ColumnString::Chars & data, const ColumnString::Offsets & offsets, static void vector(
ColumnString::Chars & res_data, ColumnString::Offsets & res_offsets) const ColumnString::Chars & data, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
res_data.reserve(data.size()); res_data.reserve(data.size());
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
size_t prev_offset = 0; size_t prev_offset = 0;
size_t res_offset = 0; size_t res_offset = 0;
@ -125,7 +127,7 @@ struct CutSubstringImpl
Pos start; Pos start;
size_t length; size_t length;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const char * current = reinterpret_cast<const char *>(&data[prev_offset]); const char * current = reinterpret_cast<const char *>(&data[prev_offset]);
Extractor::execute(current, offsets[i] - prev_offset - 1, start, length); Extractor::execute(current, offsets[i] - prev_offset - 1, start, length);
@ -154,7 +156,7 @@ struct CutSubstringImpl
res_data.append(start + length, data.data() + data.size()); res_data.append(start + length, data.data() + data.size());
} }
static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by this function"); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by this function");
} }

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <base/find_symbols.h> #include <base/find_symbols.h>
#include "domain.h" #include <Functions/URL/domain.h>
#include "tldLookup.h" #include <Functions/URL/tldLookup.h>
#include <Common/TLDListsHolder.h> /// TLDType #include <Common/TLDListsHolder.h> /// TLDType
namespace DB namespace DB

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include "fragment.h"
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include <Functions/URL/fragment.h>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include "queryString.h"
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include <Functions/URL/queryString.h>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include "queryStringAndFragment.h"
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include <Functions/URL/queryStringAndFragment.h>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "ExtractFirstSignificantSubdomain.h" #include <Functions/URL/ExtractFirstSignificantSubdomain.h>
namespace DB namespace DB

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include "ExtractFirstSignificantSubdomain.h" #include <Functions/URL/ExtractFirstSignificantSubdomain.h>
#include "FirstSignificantSubdomainCustomImpl.h" #include <Functions/URL/FirstSignificantSubdomainCustomImpl.h>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "protocol.h" #include <Functions/URL/protocol.h>
#include <base/find_symbols.h> #include <base/find_symbols.h>

View File

@ -1,7 +1,7 @@
#include <base/hex.h>
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include <base/find_symbols.h> #include <base/find_symbols.h>
#include <base/hex.h>
namespace DB namespace DB
@ -121,8 +121,10 @@ enum URLCodeStrategy
template <URLCodeStrategy code_strategy, bool space_as_plus> template <URLCodeStrategy code_strategy, bool space_as_plus>
struct CodeURLComponentImpl struct CodeURLComponentImpl
{ {
static void vector(const ColumnString::Chars & data, const ColumnString::Offsets & offsets, static void vector(
ColumnString::Chars & res_data, ColumnString::Offsets & res_offsets) const ColumnString::Chars & data, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
if (code_strategy == encode) if (code_strategy == encode)
{ {
@ -134,13 +136,12 @@ struct CodeURLComponentImpl
res_data.resize(data.size()); res_data.resize(data.size());
} }
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
size_t prev_offset = 0; size_t prev_offset = 0;
size_t res_offset = 0; size_t res_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]); const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]);
size_t src_size = offsets[i] - prev_offset; size_t src_size = offsets[i] - prev_offset;
@ -165,7 +166,7 @@ struct CodeURLComponentImpl
res_data.resize(res_offset); res_data.resize(res_offset);
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by URL functions"); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by URL functions");
} }

View File

@ -1,5 +1,4 @@
#include "domain.h" #include <Functions/URL/domain.h>
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "protocol.h"
#include <base/find_symbols.h>
#include <cstring>
#include <Common/StringUtils.h> #include <Common/StringUtils.h>
#include <Functions/URL/protocol.h>
#include <base/find_symbols.h>
#include <cstring>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "domain.h" #include <Functions/URL/domain.h>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "ExtractFirstSignificantSubdomain.h" #include <Functions/URL/ExtractFirstSignificantSubdomain.h>
namespace DB namespace DB

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include "ExtractFirstSignificantSubdomain.h" #include <Functions/URL/ExtractFirstSignificantSubdomain.h>
#include "FirstSignificantSubdomainCustomImpl.h" #include <Functions/URL/FirstSignificantSubdomainCustomImpl.h>
namespace DB namespace DB

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "fragment.h" #include <Functions/URL/fragment.h>
namespace DB namespace DB
{ {

View File

@ -1,7 +1,7 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include <Functions/StringHelpers.h> #include <Functions/StringHelpers.h>
#include "path.h" #include <Functions/URL/path.h>
#include <base/find_symbols.h> #include <base/find_symbols.h>

View File

@ -1,7 +1,7 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include <Functions/StringHelpers.h> #include <Functions/StringHelpers.h>
#include "path.h" #include <Functions/URL/path.h>
#include <base/find_symbols.h> #include <base/find_symbols.h>
namespace DB namespace DB

View File

@ -5,7 +5,7 @@
#include <Columns/ColumnsNumber.h> #include <Columns/ColumnsNumber.h>
#include <Columns/ColumnArray.h> #include <Columns/ColumnArray.h>
#include <Columns/ColumnConst.h> #include <Columns/ColumnConst.h>
#include "domain.h" #include <Functions/URL/domain.h>
namespace DB namespace DB

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "protocol.h" #include <Functions/URL/protocol.h>
namespace DB namespace DB

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "queryString.h" #include <Functions/URL/queryString.h>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "queryStringAndFragment.h" #include <Functions/URL/queryStringAndFragment.h>
namespace DB namespace DB
{ {

View File

@ -1,6 +1,6 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
#include "domain.h" #include <Functions/URL/domain.h>
namespace DB namespace DB
{ {

View File

@ -28,20 +28,20 @@ namespace
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
/// The size of result is always not more than the size of source. /// The size of result is always not more than the size of source.
/// Because entities decodes to the shorter byte sequence. /// Because entities decodes to the shorter byte sequence.
/// Example: &#xx... &#xx... will decode to UTF-8 byte sequence not longer than 4 bytes. /// Example: &#xx... &#xx... will decode to UTF-8 byte sequence not longer than 4 bytes.
res_data.resize(data.size()); res_data.resize(data.size());
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
size_t prev_offset = 0; size_t prev_offset = 0;
size_t res_offset = 0; size_t res_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]); const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]);
size_t src_size = offsets[i] - prev_offset; size_t src_size = offsets[i] - prev_offset;
@ -55,7 +55,7 @@ namespace
res_data.resize(res_offset); res_data.resize(res_offset);
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Function decodeHTMLComponent cannot work with FixedString argument"); throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Function decodeHTMLComponent cannot work with FixedString argument");
} }
@ -64,7 +64,6 @@ namespace
static const int max_legal_unicode_value = 0x10FFFF; static const int max_legal_unicode_value = 0x10FFFF;
static const int max_decimal_length_of_unicode_point = 7; /// 1114111 static const int max_decimal_length_of_unicode_point = 7; /// 1114111
static size_t execute(const char * src, size_t src_size, char * dst) static size_t execute(const char * src, size_t src_size, char * dst)
{ {
const char * src_pos = src; const char * src_pos = src;

View File

@ -27,20 +27,20 @@ namespace
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
/// The size of result is always not more than the size of source. /// The size of result is always not more than the size of source.
/// Because entities decodes to the shorter byte sequence. /// Because entities decodes to the shorter byte sequence.
/// Example: &#xx... &#xx... will decode to UTF-8 byte sequence not longer than 4 bytes. /// Example: &#xx... &#xx... will decode to UTF-8 byte sequence not longer than 4 bytes.
res_data.resize(data.size()); res_data.resize(data.size());
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
size_t prev_offset = 0; size_t prev_offset = 0;
size_t res_offset = 0; size_t res_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]); const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]);
size_t src_size = offsets[i] - prev_offset; size_t src_size = offsets[i] - prev_offset;
@ -54,7 +54,7 @@ namespace
res_data.resize(res_offset); res_data.resize(res_offset);
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Function decodeXMLComponent cannot work with FixedString argument"); throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Function decodeXMLComponent cannot work with FixedString argument");
} }

View File

@ -25,17 +25,17 @@ namespace
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
/// 6 is the maximum size amplification (the maximum length of encoded entity: &quot;) /// 6 is the maximum size amplification (the maximum length of encoded entity: &quot;)
res_data.resize(data.size() * 6); res_data.resize(data.size() * 6);
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
size_t prev_offset = 0; size_t prev_offset = 0;
size_t res_offset = 0; size_t res_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]); const char * src_data = reinterpret_cast<const char *>(&data[prev_offset]);
size_t src_size = offsets[i] - prev_offset; size_t src_size = offsets[i] - prev_offset;
@ -49,7 +49,7 @@ namespace
res_data.resize(res_offset); res_data.resize(res_offset);
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Function encodeXML cannot work with FixedString argument"); throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Function encodeXML cannot work with FixedString argument");
} }

View File

@ -11,8 +11,8 @@ namespace DB
namespace ErrorCodes namespace ErrorCodes
{ {
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int ARGUMENT_OUT_OF_BOUND; extern const int ARGUMENT_OUT_OF_BOUND;
extern const int TOO_MANY_ARGUMENTS_FOR_FUNCTION;
} }
@ -87,7 +87,7 @@ public:
return col_res; return col_res;
} }
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, throw Exception(ErrorCodes::TOO_MANY_ARGUMENTS_FOR_FUNCTION,
"Illegal number of UInt arguments of function {}: should be not more than 2 dimensions", "Illegal number of UInt arguments of function {}: should be not more than 2 dimensions",
getName()); getName());
} }

View File

@ -44,15 +44,15 @@ struct IdnaEncode
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
const size_t rows = offsets.size();
res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII
res_offsets.reserve(rows); res_offsets.reserve(input_rows_count);
size_t prev_offset = 0; size_t prev_offset = 0;
std::string ascii; std::string ascii;
for (size_t row = 0; row < rows; ++row) for (size_t row = 0; row < input_rows_count; ++row)
{ {
const char * value = reinterpret_cast<const char *>(&data[prev_offset]); const char * value = reinterpret_cast<const char *>(&data[prev_offset]);
const size_t value_length = offsets[row] - prev_offset - 1; const size_t value_length = offsets[row] - prev_offset - 1;
@ -85,7 +85,7 @@ struct IdnaEncode
} }
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed"); throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed");
} }
@ -99,15 +99,15 @@ struct IdnaDecode
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
const size_t rows = offsets.size();
res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII
res_offsets.reserve(rows); res_offsets.reserve(input_rows_count);
size_t prev_offset = 0; size_t prev_offset = 0;
std::string unicode; std::string unicode;
for (size_t row = 0; row < rows; ++row) for (size_t row = 0; row < input_rows_count; ++row)
{ {
const char * ascii = reinterpret_cast<const char *>(&data[prev_offset]); const char * ascii = reinterpret_cast<const char *>(&data[prev_offset]);
const size_t ascii_length = offsets[row] - prev_offset - 1; const size_t ascii_length = offsets[row] - prev_offset - 1;
@ -124,7 +124,7 @@ struct IdnaDecode
} }
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed"); throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed");
} }

View File

@ -9,10 +9,12 @@ namespace
struct InitcapImpl struct InitcapImpl
{ {
static void vector(const ColumnString::Chars & data, static void vector(
const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t /*input_rows_count*/)
{ {
if (data.empty()) if (data.empty())
return; return;
@ -21,7 +23,7 @@ struct InitcapImpl
array(data.data(), data.data() + data.size(), res_data.data()); array(data.data(), data.data() + data.size(), res_data.data());
} }
static void vectorFixed(const ColumnString::Chars & data, size_t /*n*/, ColumnString::Chars & res_data) static void vectorFixed(const ColumnString::Chars & data, size_t /*n*/, ColumnString::Chars & res_data, size_t)
{ {
res_data.resize(data.size()); res_data.resize(data.size());
array(data.data(), data.data() + data.size(), res_data.data()); array(data.data(), data.data() + data.size(), res_data.data());

View File

@ -22,7 +22,8 @@ struct InitcapUTF8Impl
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t /*input_rows_count*/)
{ {
if (data.empty()) if (data.empty())
return; return;
@ -31,7 +32,7 @@ struct InitcapUTF8Impl
array(data.data(), data.data() + data.size(), offsets, res_data.data()); array(data.data(), data.data() + data.size(), offsets, res_data.data());
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Function initcapUTF8 cannot work with FixedString argument"); throw Exception(ErrorCodes::BAD_ARGUMENTS, "Function initcapUTF8 cannot work with FixedString argument");
} }

View File

@ -16,8 +16,8 @@ namespace DB
namespace ErrorCodes namespace ErrorCodes
{ {
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int ARGUMENT_OUT_OF_BOUND; extern const int ARGUMENT_OUT_OF_BOUND;
extern const int TOO_MANY_ARGUMENTS_FOR_FUNCTION;
} }
#define EXTRACT_VECTOR(INDEX) \ #define EXTRACT_VECTOR(INDEX) \
@ -130,7 +130,7 @@ namespace ErrorCodes
MASK(8, 6, col6->getUInt(i)), \ MASK(8, 6, col6->getUInt(i)), \
MASK(8, 7, col7->getUInt(i))) \ MASK(8, 7, col7->getUInt(i))) \
\ \
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, \ throw Exception(ErrorCodes::TOO_MANY_ARGUMENTS_FOR_FUNCTION, \
"Illegal number of UInt arguments of function {}, max: 8", \ "Illegal number of UInt arguments of function {}, max: 8", \
getName()); \ getName()); \

View File

@ -19,17 +19,19 @@ template <bool keep_names>
struct Impl struct Impl
{ {
static constexpr auto name = keep_names ? "normalizeQueryKeepNames" : "normalizeQuery"; static constexpr auto name = keep_names ? "normalizeQueryKeepNames" : "normalizeQuery";
static void vector(const ColumnString::Chars & data,
static void vector(
const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
res_data.reserve(data.size()); res_data.reserve(data.size());
ColumnString::Offset prev_src_offset = 0; ColumnString::Offset prev_src_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
ColumnString::Offset curr_src_offset = offsets[i]; ColumnString::Offset curr_src_offset = offsets[i];
@ -43,7 +45,7 @@ struct Impl
} }
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Cannot apply function normalizeQuery to fixed string."); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Cannot apply function normalizeQuery to fixed string.");
} }

View File

@ -84,7 +84,8 @@ struct NormalizeUTF8Impl
static void vector(const ColumnString::Chars & data, static void vector(const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
UErrorCode err = U_ZERO_ERROR; UErrorCode err = U_ZERO_ERROR;
@ -92,8 +93,7 @@ struct NormalizeUTF8Impl
if (U_FAILURE(err)) if (U_FAILURE(err))
throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed (getNormalizer): {}", u_errorName(err)); throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed (getNormalizer): {}", u_errorName(err));
size_t size = offsets.size(); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
res_data.reserve(data.size() * 2); res_data.reserve(data.size() * 2);
@ -103,7 +103,7 @@ struct NormalizeUTF8Impl
PODArray<UChar> from_uchars; PODArray<UChar> from_uchars;
PODArray<UChar> to_uchars; PODArray<UChar> to_uchars;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
size_t from_size = offsets[i] - current_from_offset - 1; size_t from_size = offsets[i] - current_from_offset - 1;
@ -157,7 +157,7 @@ struct NormalizeUTF8Impl
res_data.resize(current_to_offset); res_data.resize(current_to_offset);
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Cannot apply function normalizeUTF8 to fixed string."); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Cannot apply function normalizeUTF8 to fixed string.");
} }

View File

@ -27,13 +27,13 @@ struct Impl
static void vector( static void vector(
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
PaddedPODArray<UInt64> & res_data) PaddedPODArray<UInt64> & res_data,
size_t input_rows_count)
{ {
size_t size = offsets.size(); res_data.resize(input_rows_count);
res_data.resize(size);
ColumnString::Offset prev_src_offset = 0; ColumnString::Offset prev_src_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
ColumnString::Offset curr_src_offset = offsets[i]; ColumnString::Offset curr_src_offset = offsets[i];
res_data[i] = normalizedQueryHash( res_data[i] = normalizedQueryHash(
@ -77,15 +77,15 @@ public:
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; } bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const ColumnPtr column = arguments[0].column; const ColumnPtr column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{ {
auto col_res = ColumnUInt64::create(); auto col_res = ColumnUInt64::create();
typename ColumnUInt64::Container & vec_res = col_res->getData(); typename ColumnUInt64::Container & vec_res = col_res->getData();
vec_res.resize(col->size()); vec_res.resize(input_rows_count);
Impl<keep_names>::vector(col->getChars(), col->getOffsets(), vec_res); Impl<keep_names>::vector(col->getChars(), col->getOffsets(), vec_res, input_rows_count);
return col_res; return col_res;
} }
else else

View File

@ -91,8 +91,6 @@ private:
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const auto size = input_rows_count;
/// Prepare array of ellipses. /// Prepare array of ellipses.
size_t ellipses_count = (arguments.size() - 2) / 4; size_t ellipses_count = (arguments.size() - 2) / 4;
std::vector<Ellipse> ellipses(ellipses_count); std::vector<Ellipse> ellipses(ellipses_count);
@ -141,13 +139,11 @@ private:
auto dst = ColumnVector<UInt8>::create(); auto dst = ColumnVector<UInt8>::create();
auto & dst_data = dst->getData(); auto & dst_data = dst->getData();
dst_data.resize(size); dst_data.resize(input_rows_count);
size_t start_index = 0; size_t start_index = 0;
for (const auto row : collections::range(0, size)) for (size_t row = 0; row < input_rows_count; ++row)
{
dst_data[row] = isPointInEllipses(col_vec_x->getData()[row], col_vec_y->getData()[row], ellipses.data(), ellipses_count, start_index); dst_data[row] = isPointInEllipses(col_vec_x->getData()[row], col_vec_y->getData()[row], ellipses.data(), ellipses_count, start_index);
}
return dst; return dst;
} }
@ -157,7 +153,7 @@ private:
const auto * col_const_y = assert_cast<const ColumnConst *> (col_y); const auto * col_const_y = assert_cast<const ColumnConst *> (col_y);
size_t start_index = 0; size_t start_index = 0;
UInt8 res = isPointInEllipses(col_const_x->getValue<Float64>(), col_const_y->getValue<Float64>(), ellipses.data(), ellipses_count, start_index); UInt8 res = isPointInEllipses(col_const_x->getValue<Float64>(), col_const_y->getValue<Float64>(), ellipses.data(), ellipses_count, start_index);
return DataTypeUInt8().createColumnConst(size, res); return DataTypeUInt8().createColumnConst(input_rows_count, res);
} }
else else
{ {

View File

@ -6,11 +6,11 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h> #include <Functions/FunctionStringToString.h>
# pragma clang diagnostic push #pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wnewline-eof" #pragma clang diagnostic ignored "-Wnewline-eof"
# include <ada/idna/punycode.h> #include <ada/idna/punycode.h>
# include <ada/idna/unicode_transcoding.h> #include <ada/idna/unicode_transcoding.h>
# pragma clang diagnostic pop #pragma clang diagnostic pop
namespace DB namespace DB
{ {
@ -38,16 +38,16 @@ struct PunycodeEncode
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
const size_t rows = offsets.size();
res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII
res_offsets.reserve(rows); res_offsets.reserve(input_rows_count);
size_t prev_offset = 0; size_t prev_offset = 0;
std::u32string value_utf32; std::u32string value_utf32;
std::string value_puny; std::string value_puny;
for (size_t row = 0; row < rows; ++row) for (size_t row = 0; row < input_rows_count; ++row)
{ {
const char * value = reinterpret_cast<const char *>(&data[prev_offset]); const char * value = reinterpret_cast<const char *>(&data[prev_offset]);
const size_t value_length = offsets[row] - prev_offset - 1; const size_t value_length = offsets[row] - prev_offset - 1;
@ -72,7 +72,7 @@ struct PunycodeEncode
} }
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed"); throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed");
} }
@ -86,16 +86,16 @@ struct PunycodeDecode
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
const size_t rows = offsets.size();
res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII res_data.reserve(data.size()); /// just a guess, assuming the input is all-ASCII
res_offsets.reserve(rows); res_offsets.reserve(input_rows_count);
size_t prev_offset = 0; size_t prev_offset = 0;
std::u32string value_utf32; std::u32string value_utf32;
std::string value_utf8; std::string value_utf8;
for (size_t row = 0; row < rows; ++row) for (size_t row = 0; row < input_rows_count; ++row)
{ {
const char * value = reinterpret_cast<const char *>(&data[prev_offset]); const char * value = reinterpret_cast<const char *>(&data[prev_offset]);
const size_t value_length = offsets[row] - prev_offset - 1; const size_t value_length = offsets[row] - prev_offset - 1;
@ -129,7 +129,7 @@ struct PunycodeDecode
} }
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed"); throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Arguments of type FixedString are not allowed");
} }

View File

@ -24,6 +24,7 @@ namespace ErrorCodes
extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_COLUMN;
extern const int BAD_ARGUMENTS; extern const int BAD_ARGUMENTS;
extern const int LOGICAL_ERROR; extern const int LOGICAL_ERROR;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
} }
namespace namespace
@ -246,7 +247,7 @@ public:
{ {
auto desired = Distribution::getNumberOfArguments(); auto desired = Distribution::getNumberOfArguments();
if (arguments.size() != desired && arguments.size() != desired + 1) if (arguments.size() != desired && arguments.size() != desired + 1)
throw Exception(ErrorCodes::BAD_ARGUMENTS, throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
"Wrong number of arguments for function {}. Should be {} or {}", "Wrong number of arguments for function {}. Should be {} or {}",
getName(), desired, desired + 1); getName(), desired, desired + 1);

View File

@ -55,19 +55,19 @@ public:
bool useDefaultImplementationForConstants() const override { return true; } bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const override ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{ {
const ColumnPtr column = arguments[0].column; const ColumnPtr column = arguments[0].column;
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get())) if (const ColumnString * col = checkAndGetColumn<ColumnString>(column.get()))
{ {
auto col_res = ColumnString::create(); auto col_res = ColumnString::create();
ReverseImpl::vector(col->getChars(), col->getOffsets(), col_res->getChars(), col_res->getOffsets()); ReverseImpl::vector(col->getChars(), col->getOffsets(), col_res->getChars(), col_res->getOffsets(), input_rows_count);
return col_res; return col_res;
} }
else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column.get())) else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column.get()))
{ {
auto col_res = ColumnFixedString::create(col_fixed->getN()); auto col_res = ColumnFixedString::create(col_fixed->getN());
ReverseImpl::vectorFixed(col_fixed->getChars(), col_fixed->getN(), col_res->getChars()); ReverseImpl::vectorFixed(col_fixed->getChars(), col_fixed->getN(), col_res->getChars(), input_rows_count);
return col_res; return col_res;
} }
else else

View File

@ -9,17 +9,18 @@ namespace DB
*/ */
struct ReverseImpl struct ReverseImpl
{ {
static void vector(const ColumnString::Chars & data, static void vector(
const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
res_data.resize_exact(data.size()); res_data.resize_exact(data.size());
res_offsets.assign(offsets); res_offsets.assign(offsets);
size_t size = offsets.size();
ColumnString::Offset prev_offset = 0; ColumnString::Offset prev_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
for (size_t j = prev_offset; j < offsets[i] - 1; ++j) for (size_t j = prev_offset; j < offsets[i] - 1; ++j)
res_data[j] = data[offsets[i] + prev_offset - 2 - j]; res_data[j] = data[offsets[i] + prev_offset - 2 - j];
@ -28,12 +29,15 @@ struct ReverseImpl
} }
} }
static void vectorFixed(const ColumnString::Chars & data, size_t n, ColumnString::Chars & res_data) static void vectorFixed(
const ColumnString::Chars & data,
size_t n,
ColumnString::Chars & res_data,
size_t input_rows_count)
{ {
res_data.resize_exact(data.size()); res_data.resize_exact(data.size());
size_t size = data.size() / n;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
for (size_t j = i * n; j < (i + 1) * n; ++j) for (size_t j = i * n; j < (i + 1) * n; ++j)
res_data[j] = data[(i * 2 + 1) * n - j - 1]; res_data[j] = data[(i * 2 + 1) * n - j - 1];
} }

View File

@ -23,25 +23,25 @@ namespace
*/ */
struct ReverseUTF8Impl struct ReverseUTF8Impl
{ {
static void vector(const ColumnString::Chars & data, static void vector(
const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
bool all_ascii = isAllASCII(data.data(), data.size()); bool all_ascii = isAllASCII(data.data(), data.size());
if (all_ascii) if (all_ascii)
{ {
ReverseImpl::vector(data, offsets, res_data, res_offsets); ReverseImpl::vector(data, offsets, res_data, res_offsets, input_rows_count);
return; return;
} }
res_data.resize(data.size()); res_data.resize(data.size());
res_offsets.assign(offsets); res_offsets.assign(offsets);
size_t size = offsets.size();
ColumnString::Offset prev_offset = 0; ColumnString::Offset prev_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
ColumnString::Offset j = prev_offset; ColumnString::Offset j = prev_offset;
while (j < offsets[i] - 1) while (j < offsets[i] - 1)
@ -73,7 +73,7 @@ struct ReverseUTF8Impl
} }
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Cannot apply function reverseUTF8 to fixed string."); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Cannot apply function reverseUTF8 to fixed string.");
} }

View File

@ -79,14 +79,14 @@ struct SoundexImpl
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
const size_t size = offsets.size(); res_data.resize(input_rows_count * (length + 1));
res_data.resize(size * (length + 1)); res_offsets.resize(input_rows_count);
res_offsets.resize(size);
size_t prev_offset = 0; size_t prev_offset = 0;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const char * value = reinterpret_cast<const char *>(&data[prev_offset]); const char * value = reinterpret_cast<const char *>(&data[prev_offset]);
const size_t value_length = offsets[i] - prev_offset - 1; const size_t value_length = offsets[i] - prev_offset - 1;
@ -98,7 +98,7 @@ struct SoundexImpl
} }
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by soundex function"); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by soundex function");
} }

View File

@ -128,16 +128,16 @@ struct ToValidUTF8Impl
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
const size_t offsets_size = offsets.size();
/// It can be larger than that, but we believe it is unlikely to happen. /// It can be larger than that, but we believe it is unlikely to happen.
res_data.resize(data.size()); res_data.resize(data.size());
res_offsets.resize(offsets_size); res_offsets.resize(input_rows_count);
size_t prev_offset = 0; size_t prev_offset = 0;
WriteBufferFromVector<ColumnString::Chars> write_buffer(res_data); WriteBufferFromVector<ColumnString::Chars> write_buffer(res_data);
for (size_t i = 0; i < offsets_size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
const char * haystack_data = reinterpret_cast<const char *>(&data[prev_offset]); const char * haystack_data = reinterpret_cast<const char *>(&data[prev_offset]);
const size_t haystack_size = offsets[i] - prev_offset - 1; const size_t haystack_size = offsets[i] - prev_offset - 1;
@ -149,7 +149,7 @@ struct ToValidUTF8Impl
write_buffer.finalize(); write_buffer.finalize();
} }
[[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by toValidUTF8 function"); throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Column of type FixedString is not supported by toValidUTF8 function");
} }

View File

@ -43,10 +43,10 @@ public:
const ColumnString::Chars & data, const ColumnString::Chars & data,
const ColumnString::Offsets & offsets, const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data, ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets) ColumnString::Offsets & res_offsets,
size_t input_rows_count)
{ {
size_t size = offsets.size(); res_offsets.resize_exact(input_rows_count);
res_offsets.resize_exact(size);
res_data.reserve_exact(data.size()); res_data.reserve_exact(data.size());
size_t prev_offset = 0; size_t prev_offset = 0;
@ -55,7 +55,7 @@ public:
const UInt8 * start; const UInt8 * start;
size_t length; size_t length;
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < input_rows_count; ++i)
{ {
execute(reinterpret_cast<const UInt8 *>(&data[prev_offset]), offsets[i] - prev_offset - 1, start, length); execute(reinterpret_cast<const UInt8 *>(&data[prev_offset]), offsets[i] - prev_offset - 1, start, length);
@ -69,7 +69,7 @@ public:
} }
} }
static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &, size_t)
{ {
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Functions trimLeft, trimRight and trimBoth cannot work with FixedString argument"); throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Functions trimLeft, trimRight and trimBoth cannot work with FixedString argument");
} }

View File

@ -1,77 +1,77 @@
clickhouse_add_executable (read_buffer read_buffer.cpp) clickhouse_add_executable (read_buffer read_buffer.cpp)
target_link_libraries (read_buffer PRIVATE clickhouse_common_io) target_link_libraries (read_buffer PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (read_buffer_perf read_buffer_perf.cpp) clickhouse_add_executable (read_buffer_perf read_buffer_perf.cpp)
target_link_libraries (read_buffer_perf PRIVATE clickhouse_common_io) target_link_libraries (read_buffer_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (read_float_perf read_float_perf.cpp) clickhouse_add_executable (read_float_perf read_float_perf.cpp)
target_link_libraries (read_float_perf PRIVATE clickhouse_common_io) target_link_libraries (read_float_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (write_buffer write_buffer.cpp) clickhouse_add_executable (write_buffer write_buffer.cpp)
target_link_libraries (write_buffer PRIVATE clickhouse_common_io) target_link_libraries (write_buffer PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (write_buffer_perf write_buffer_perf.cpp) clickhouse_add_executable (write_buffer_perf write_buffer_perf.cpp)
target_link_libraries (write_buffer_perf PRIVATE clickhouse_common_io) target_link_libraries (write_buffer_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (valid_utf8_perf valid_utf8_perf.cpp) clickhouse_add_executable (valid_utf8_perf valid_utf8_perf.cpp)
target_link_libraries (valid_utf8_perf PRIVATE clickhouse_common_io) target_link_libraries (valid_utf8_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (valid_utf8 valid_utf8.cpp) clickhouse_add_executable (valid_utf8 valid_utf8.cpp)
target_link_libraries (valid_utf8 PRIVATE clickhouse_common_io) target_link_libraries (valid_utf8 PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (var_uint var_uint.cpp) clickhouse_add_executable (var_uint var_uint.cpp)
target_link_libraries (var_uint PRIVATE clickhouse_common_io) target_link_libraries (var_uint PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (read_escaped_string read_escaped_string.cpp) clickhouse_add_executable (read_escaped_string read_escaped_string.cpp)
target_link_libraries (read_escaped_string PRIVATE clickhouse_common_io) target_link_libraries (read_escaped_string PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (parse_int_perf parse_int_perf.cpp) clickhouse_add_executable (parse_int_perf parse_int_perf.cpp)
target_link_libraries (parse_int_perf PRIVATE clickhouse_common_io) target_link_libraries (parse_int_perf PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (parse_int_perf2 parse_int_perf2.cpp) clickhouse_add_executable (parse_int_perf2 parse_int_perf2.cpp)
target_link_libraries (parse_int_perf2 PRIVATE clickhouse_common_io) target_link_libraries (parse_int_perf2 PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (read_write_int read_write_int.cpp) clickhouse_add_executable (read_write_int read_write_int.cpp)
target_link_libraries (read_write_int PRIVATE clickhouse_common_io) target_link_libraries (read_write_int PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (o_direct_and_dirty_pages o_direct_and_dirty_pages.cpp) clickhouse_add_executable (o_direct_and_dirty_pages o_direct_and_dirty_pages.cpp)
target_link_libraries (o_direct_and_dirty_pages PRIVATE clickhouse_common_io) target_link_libraries (o_direct_and_dirty_pages PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (io_operators io_operators.cpp) clickhouse_add_executable (io_operators io_operators.cpp)
target_link_libraries (io_operators PRIVATE clickhouse_common_io) target_link_libraries (io_operators PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (write_int write_int.cpp) clickhouse_add_executable (write_int write_int.cpp)
target_link_libraries (write_int PRIVATE clickhouse_common_io) target_link_libraries (write_int PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (zlib_buffers zlib_buffers.cpp) clickhouse_add_executable (zlib_buffers zlib_buffers.cpp)
target_link_libraries (zlib_buffers PRIVATE clickhouse_common_io) target_link_libraries (zlib_buffers PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (lzma_buffers lzma_buffers.cpp) clickhouse_add_executable (lzma_buffers lzma_buffers.cpp)
target_link_libraries (lzma_buffers PRIVATE clickhouse_common_io) target_link_libraries (lzma_buffers PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (limit_read_buffer limit_read_buffer.cpp) clickhouse_add_executable (limit_read_buffer limit_read_buffer.cpp)
target_link_libraries (limit_read_buffer PRIVATE clickhouse_common_io) target_link_libraries (limit_read_buffer PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (limit_read_buffer2 limit_read_buffer2.cpp) clickhouse_add_executable (limit_read_buffer2 limit_read_buffer2.cpp)
target_link_libraries (limit_read_buffer2 PRIVATE clickhouse_common_io) target_link_libraries (limit_read_buffer2 PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (parse_date_time_best_effort parse_date_time_best_effort.cpp) clickhouse_add_executable (parse_date_time_best_effort parse_date_time_best_effort.cpp)
target_link_libraries (parse_date_time_best_effort PRIVATE clickhouse_common_io) target_link_libraries (parse_date_time_best_effort PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (zlib_ng_bug zlib_ng_bug.cpp) clickhouse_add_executable (zlib_ng_bug zlib_ng_bug.cpp)
target_link_libraries (zlib_ng_bug PRIVATE ch_contrib::zlib clickhouse_common_io) target_link_libraries (zlib_ng_bug PRIVATE ch_contrib::zlib clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (dragonbox_test dragonbox_test.cpp) clickhouse_add_executable (dragonbox_test dragonbox_test.cpp)
target_link_libraries (dragonbox_test PRIVATE ch_contrib::dragonbox_to_chars clickhouse_common_io) target_link_libraries (dragonbox_test PRIVATE ch_contrib::dragonbox_to_chars clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (zstd_buffers zstd_buffers.cpp) clickhouse_add_executable (zstd_buffers zstd_buffers.cpp)
target_link_libraries (zstd_buffers PRIVATE clickhouse_common_io) target_link_libraries (zstd_buffers PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (snappy_read_buffer snappy_read_buffer.cpp) clickhouse_add_executable (snappy_read_buffer snappy_read_buffer.cpp)
target_link_libraries (snappy_read_buffer PRIVATE clickhouse_common_io) target_link_libraries (snappy_read_buffer PRIVATE clickhouse_common_io clickhouse_common_config)
clickhouse_add_executable (hadoop_snappy_read_buffer hadoop_snappy_read_buffer.cpp) clickhouse_add_executable (hadoop_snappy_read_buffer hadoop_snappy_read_buffer.cpp)
target_link_libraries (hadoop_snappy_read_buffer PRIVATE clickhouse_common_io) target_link_libraries (hadoop_snappy_read_buffer PRIVATE clickhouse_common_io clickhouse_common_config)
if (TARGET ch_contrib::hdfs) if (TARGET ch_contrib::hdfs)
clickhouse_add_executable (read_buffer_from_hdfs read_buffer_from_hdfs.cpp) clickhouse_add_executable (read_buffer_from_hdfs read_buffer_from_hdfs.cpp)

View File

@ -24,7 +24,6 @@
#include <Processors/Sources/NullSource.h> #include <Processors/Sources/NullSource.h>
#include <QueryPipeline/Pipe.h> #include <QueryPipeline/Pipe.h>
#include <Storages/Distributed/DistributedSettings.h> #include <Storages/Distributed/DistributedSettings.h>
#include <Storages/MergeTree/ParallelReplicasReadingCoordinator.h>
#include <Storages/SelectQueryInfo.h> #include <Storages/SelectQueryInfo.h>
#include <Storages/StorageReplicatedMergeTree.h> #include <Storages/StorageReplicatedMergeTree.h>
#include <Storages/StorageSnapshot.h> #include <Storages/StorageSnapshot.h>
@ -517,14 +516,11 @@ void executeQueryWithParallelReplicas(
"`cluster_for_parallel_replicas` setting refers to cluster with several shards. Expected a cluster with one shard"); "`cluster_for_parallel_replicas` setting refers to cluster with several shards. Expected a cluster with one shard");
} }
auto coordinator = std::make_shared<ParallelReplicasReadingCoordinator>(
new_cluster->getShardsInfo().begin()->getAllNodeCount(), settings.parallel_replicas_mark_segment_size);
auto external_tables = new_context->getExternalTables(); auto external_tables = new_context->getExternalTables();
auto read_from_remote = std::make_unique<ReadFromParallelRemoteReplicasStep>( auto read_from_remote = std::make_unique<ReadFromParallelRemoteReplicasStep>(
query_ast, query_ast,
new_cluster, new_cluster,
storage_id, storage_id,
std::move(coordinator),
header, header,
processed_stage, processed_stage,
new_context, new_context,

View File

@ -17,13 +17,19 @@
namespace DB namespace DB
{ {
IInterpreterUnionOrSelectQuery::IInterpreterUnionOrSelectQuery(const DB::ASTPtr& query_ptr_, IInterpreterUnionOrSelectQuery::IInterpreterUnionOrSelectQuery(const ASTPtr & query_ptr_,
const DB::ContextMutablePtr& context_, const DB::SelectQueryOptions& options_) const ContextMutablePtr & context_, const SelectQueryOptions & options_)
: query_ptr(query_ptr_) : query_ptr(query_ptr_)
, context(context_) , context(context_)
, options(options_) , options(options_)
, max_streams(context->getSettingsRef().max_threads) , max_streams(context->getSettingsRef().max_threads)
{ {
/// FIXME All code here will work with the old analyzer, however for views over Distributed tables
/// it's possible that new analyzer will be enabled in ::getQueryProcessingStage method
/// of the underlying storage when all other parts of infrastructure are not ready for it
/// (built with old analyzer).
context->setSetting("allow_experimental_analyzer", false);
if (options.shard_num) if (options.shard_num)
context->addSpecialScalar( context->addSpecialScalar(
"_shard_num", "_shard_num",

View File

@ -75,7 +75,6 @@
#include <Storages/MergeTree/MergeTreeWhereOptimizer.h> #include <Storages/MergeTree/MergeTreeWhereOptimizer.h>
#include <Storages/StorageDistributed.h> #include <Storages/StorageDistributed.h>
#include <Storages/StorageDummy.h>
#include <Storages/StorageMerge.h> #include <Storages/StorageMerge.h>
#include <Storages/StorageValues.h> #include <Storages/StorageValues.h>
#include <Storages/StorageView.h> #include <Storages/StorageView.h>
@ -214,11 +213,11 @@ InterpreterSelectQuery::InterpreterSelectQuery(
{} {}
InterpreterSelectQuery::InterpreterSelectQuery( InterpreterSelectQuery::InterpreterSelectQuery(
const ASTPtr & query_ptr_, const ASTPtr & query_ptr_,
const ContextPtr & context_, const ContextPtr & context_,
Pipe input_pipe_, Pipe input_pipe_,
const SelectQueryOptions & options_) const SelectQueryOptions & options_)
: InterpreterSelectQuery(query_ptr_, context_, std::move(input_pipe_), nullptr, options_.copy().noSubquery()) : InterpreterSelectQuery(query_ptr_, context_, std::move(input_pipe_), nullptr, options_.copy().noSubquery())
{} {}
InterpreterSelectQuery::InterpreterSelectQuery( InterpreterSelectQuery::InterpreterSelectQuery(
@ -227,18 +226,15 @@ InterpreterSelectQuery::InterpreterSelectQuery(
const StoragePtr & storage_, const StoragePtr & storage_,
const StorageMetadataPtr & metadata_snapshot_, const StorageMetadataPtr & metadata_snapshot_,
const SelectQueryOptions & options_) const SelectQueryOptions & options_)
: InterpreterSelectQuery( : InterpreterSelectQuery(query_ptr_, context_, std::nullopt, storage_, options_.copy().noSubquery(), {}, metadata_snapshot_)
query_ptr_, context_, std::nullopt, storage_, options_.copy().noSubquery(), {}, metadata_snapshot_) {}
{
}
InterpreterSelectQuery::InterpreterSelectQuery( InterpreterSelectQuery::InterpreterSelectQuery(
const ASTPtr & query_ptr_, const ASTPtr & query_ptr_,
const ContextPtr & context_, const ContextPtr & context_,
const SelectQueryOptions & options_, const SelectQueryOptions & options_,
PreparedSetsPtr prepared_sets_) PreparedSetsPtr prepared_sets_)
: InterpreterSelectQuery( : InterpreterSelectQuery(query_ptr_, context_, std::nullopt, nullptr, options_, {}, {}, prepared_sets_)
query_ptr_, context_, std::nullopt, nullptr, options_, {}, {}, prepared_sets_)
{} {}
InterpreterSelectQuery::~InterpreterSelectQuery() = default; InterpreterSelectQuery::~InterpreterSelectQuery() = default;

View File

@ -26,7 +26,6 @@ class Logger;
namespace DB namespace DB
{ {
class SubqueryForSet;
class InterpreterSelectWithUnionQuery; class InterpreterSelectWithUnionQuery;
class Context; class Context;
class QueryPlan; class QueryPlan;

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