diff --git a/.github/ISSUE_TEMPLATE/10_question.md b/.github/ISSUE_TEMPLATE/10_question.md
index 5b3d00a3180..0992bf06217 100644
--- a/.github/ISSUE_TEMPLATE/10_question.md
+++ b/.github/ISSUE_TEMPLATE/10_question.md
@@ -7,6 +7,6 @@ assignees: ''
---
-> Make sure to check documentation https://clickhouse.com/docs/en/ first. If the question is concise and probably has a short answer, asking it in Telegram chat https://telegram.me/clickhouse_en is probably the fastest way to find the answer. For more complicated questions, consider asking them on StackOverflow with "clickhouse" tag https://stackoverflow.com/questions/tagged/clickhouse
+> Make sure to check documentation https://clickhouse.com/docs/en/ first. If the question is concise and probably has a short answer, asking it in [community Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-1gh9ds7f4-PgDhJAaF8ad5RbWBAAjzFg) is probably the fastest way to find the answer. For more complicated questions, consider asking them on StackOverflow with "clickhouse" tag https://stackoverflow.com/questions/tagged/clickhouse
> If you still prefer GitHub issues, remove all this text and ask your question here.
diff --git a/.github/workflows/docs_check.yml b/.github/workflows/docs_check.yml
index 7a15e77becb..5c912ebd359 100644
--- a/.github/workflows/docs_check.yml
+++ b/.github/workflows/docs_check.yml
@@ -16,6 +16,7 @@ on: # yamllint disable-line rule:truthy
- 'docker/docs/**'
- 'docs/**'
- 'website/**'
+ - 'utils/check-style/aspell-ignore/**'
jobs:
CheckLabels:
runs-on: [self-hosted, style-checker]
diff --git a/.github/workflows/docs_release.yml b/.github/workflows/docs_release.yml
index da67edd4aa1..1b43138852b 100644
--- a/.github/workflows/docs_release.yml
+++ b/.github/workflows/docs_release.yml
@@ -17,6 +17,7 @@ concurrency:
- 'docs/**'
- 'utils/list-versions/version_date.tsv'
- 'website/**'
+ - 'utils/check-style/aspell-ignore/**'
workflow_dispatch:
jobs:
DockerHubPushAarch64:
diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index f3d672136ef..3eca97441f5 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -842,7 +842,7 @@ jobs:
docker ps --quiet | xargs --no-run-if-empty docker kill ||:
docker ps --all --quiet | xargs --no-run-if-empty docker rm -f ||:
sudo rm -fr "$TEMP_PATH" "$CACHES_PATH"
- BuilderBinAmd64SSE2:
+ BuilderBinAmd64Compat:
needs: [DockerHubPush]
runs-on: [self-hosted, builder]
steps:
@@ -853,7 +853,7 @@ jobs:
IMAGES_PATH=${{runner.temp}}/images_path
REPO_COPY=${{runner.temp}}/build_check/ClickHouse
CACHES_PATH=${{runner.temp}}/../ccaches
- BUILD_NAME=binary_amd64sse2
+ BUILD_NAME=binary_amd64_compat
EOF
- name: Download changed images
uses: actions/download-artifact@v2
@@ -1017,7 +1017,7 @@ jobs:
- BuilderBinFreeBSD
# - BuilderBinGCC
- BuilderBinPPC64
- - BuilderBinAmd64SSE2
+ - BuilderBinAmd64Compat
- BuilderBinAarch64V80Compat
- BuilderBinClangTidy
- BuilderDebShared
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
index 857e2c7f604..a81f52a9371 100644
--- a/.github/workflows/pull_request.yml
+++ b/.github/workflows/pull_request.yml
@@ -16,6 +16,7 @@ on: # yamllint disable-line rule:truthy
- 'docker/docs/**'
- 'docs/**'
- 'website/**'
+ - 'utils/check-style/aspell-ignore/**'
##########################################################################################
##################################### SMALL CHECKS #######################################
##########################################################################################
@@ -900,7 +901,7 @@ jobs:
docker ps --quiet | xargs --no-run-if-empty docker kill ||:
docker ps --all --quiet | xargs --no-run-if-empty docker rm -f ||:
sudo rm -fr "$TEMP_PATH" "$CACHES_PATH"
- BuilderBinAmd64SSE2:
+ BuilderBinAmd64Compat:
needs: [DockerHubPush, FastTest, StyleCheck]
runs-on: [self-hosted, builder]
steps:
@@ -911,7 +912,7 @@ jobs:
IMAGES_PATH=${{runner.temp}}/images_path
REPO_COPY=${{runner.temp}}/build_check/ClickHouse
CACHES_PATH=${{runner.temp}}/../ccaches
- BUILD_NAME=binary_amd64sse2
+ BUILD_NAME=binary_amd64_compat
EOF
- name: Download changed images
uses: actions/download-artifact@v2
@@ -1070,7 +1071,7 @@ jobs:
- BuilderBinFreeBSD
# - BuilderBinGCC
- BuilderBinPPC64
- - BuilderBinAmd64SSE2
+ - BuilderBinAmd64Compat
- BuilderBinAarch64V80Compat
- BuilderBinClangTidy
- BuilderDebShared
diff --git a/.gitignore b/.gitignore
index 6d94cade384..7d915186dcc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -158,3 +158,9 @@ website/package-lock.json
# temporary test files
tests/queries/0_stateless/test_*
tests/queries/0_stateless/*.binary
+tests/queries/0_stateless/*.generated-expect
+
+# rust
+/rust/**/target
+# It is autogenerated from *.in
+/rust/**/.cargo/config.toml
diff --git a/.gitmodules b/.gitmodules
index 070109eb32d..0805b6d5492 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -269,9 +269,6 @@
[submodule "contrib/vectorscan"]
path = contrib/vectorscan
url = https://github.com/VectorCamp/vectorscan.git
-[submodule "contrib/liburing"]
- path = contrib/liburing
- url = https://github.com/axboe/liburing.git
[submodule "contrib/c-ares"]
path = contrib/c-ares
url = https://github.com/ClickHouse/c-ares
@@ -294,3 +291,6 @@
[submodule "contrib/google-benchmark"]
path = contrib/google-benchmark
url = https://github.com/google/benchmark.git
+[submodule "contrib/libdivide"]
+ path = contrib/libdivide
+ url = https://github.com/ridiculousfish/libdivide.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e41894b8bd..ddc10c1eb2f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
### Table of Contents
+**[ClickHouse release v22.12, 2022-12-15](#2212)**
**[ClickHouse release v22.11, 2022-11-17](#2211)**
**[ClickHouse release v22.10, 2022-10-25](#2210)**
**[ClickHouse release v22.9, 2022-09-22](#229)**
@@ -12,6 +13,124 @@
**[ClickHouse release v22.1, 2022-01-18](#221)**
**[Changelog for 2021](https://clickhouse.com/docs/en/whats-new/changelog/2021/)**
+# 2022 Changelog
+
+### ClickHouse release 22.12, 2022-12-15
+
+#### Backward Incompatible Change
+* Add `GROUP BY ALL` syntax: [#37631](https://github.com/ClickHouse/ClickHouse/issues/37631). [#42265](https://github.com/ClickHouse/ClickHouse/pull/42265) ([刘陶峰](https://github.com/taofengliu)). If you have a column or an alias named `all` and doing `GROUP BY all` without the intention to group by all the columns, the query will have a different semantic. To keep the old semantic, put `all` into backticks or double quotes `"all"` to make it an identifier instead of a keyword.
+
+#### Upgrade Notes
+* Fixed backward incompatibility in (de)serialization of states of `min`, `max`, `any*`, `argMin`, `argMax` aggregate functions with `String` argument. The incompatibility affects 22.9, 22.10 and 22.11 branches (fixed since 22.9.6, 22.10.4 and 22.11.2 correspondingly). Some minor releases of 22.3, 22.7 and 22.8 branches are also affected: 22.3.13...22.3.14 (fixed since 22.3.15), 22.8.6...22.8.9 (fixed since 22.8.10), 22.7.6 and newer (will not be fixed in 22.7, we recommend upgrading from 22.7.* to 22.8.10 or newer). This release note does not concern users that have never used affected versions. Incompatible versions append an extra `'\0'` to strings when reading states of the aggregate functions mentioned above. For example, if an older version saved state of `anyState('foobar')` to `state_column` then the incompatible version will print `'foobar\0'` on `anyMerge(state_column)`. Also incompatible versions write states of the aggregate functions without trailing `'\0'`. Newer versions (that have the fix) can correctly read data written by all versions including incompatible versions, except one corner case. If an incompatible version saved a state with a string that actually ends with null character, then newer version will trim trailing `'\0'` when reading state of affected aggregate function. For example, if an incompatible version saved state of `anyState('abrac\0dabra\0')` to `state_column` then newer versions will print `'abrac\0dabra'` on `anyMerge(state_column)`. The issue also affects distributed queries when an incompatible version works in a cluster together with older or newer versions. [#43038](https://github.com/ClickHouse/ClickHouse/pull/43038) ([Alexander Tokmakov](https://github.com/tavplubix), [Raúl Marín](https://github.com/Algunenano)). Note: all the official ClickHouse builds already include the patches. This is not necessarily true for unofficial third-party builds that should be avoided.
+
+#### New Feature
+* Add `BSONEachRow` input/output format. In this format, ClickHouse formats/parses each row as a separate BSON document and each column is formatted/parsed as a single BSON field with the column name as the key. [#42033](https://github.com/ClickHouse/ClickHouse/pull/42033) ([mark-polokhov](https://github.com/mark-polokhov)).
+* Add `grace_hash` JOIN algorithm, it can be enabled with `SET join_algorithm = 'grace_hash'`. [#38191](https://github.com/ClickHouse/ClickHouse/pull/38191) ([BigRedEye](https://github.com/BigRedEye), [Vladimir C](https://github.com/vdimir)).
+* Allow configuring password complexity rules and checks for creating and changing users. [#43719](https://github.com/ClickHouse/ClickHouse/pull/43719) ([Nikolay Degterinsky](https://github.com/evillique)).
+* Mask sensitive information in logs; mask secret parts in the output of queries `SHOW CREATE TABLE` and `SELECT FROM system.tables`. Also resolves [#41418](https://github.com/ClickHouse/ClickHouse/issues/41418). [#43227](https://github.com/ClickHouse/ClickHouse/pull/43227) ([Vitaly Baranov](https://github.com/vitlibar)).
+* Add `GROUP BY ALL` syntax: [#37631](https://github.com/ClickHouse/ClickHouse/issues/37631). [#42265](https://github.com/ClickHouse/ClickHouse/pull/42265) ([刘陶峰](https://github.com/taofengliu)).
+* Add `FROM table SELECT column` syntax. [#41095](https://github.com/ClickHouse/ClickHouse/pull/41095) ([Nikolay Degterinsky](https://github.com/evillique)).
+* Added function `concatWithSeparator` and `concat_ws` as an alias for Spark SQL compatibility. A function `concatWithSeparatorAssumeInjective` added as a variant to enable GROUP BY optimization, similarly to `concatAssumeInjective`. [#43749](https://github.com/ClickHouse/ClickHouse/pull/43749) ([李扬](https://github.com/taiyang-li)).
+* Added `multiplyDecimal` and `divideDecimal` functions for decimal operations with fixed precision. [#42438](https://github.com/ClickHouse/ClickHouse/pull/42438) ([Andrey Zvonov](https://github.com/zvonand)).
+* Added `system.moves` table with list of currently moving parts. [#42660](https://github.com/ClickHouse/ClickHouse/pull/42660) ([Sergei Trifonov](https://github.com/serxa)).
+* Add support for embedded Prometheus endpoint for ClickHouse Keeper. [#43087](https://github.com/ClickHouse/ClickHouse/pull/43087) ([Antonio Andelic](https://github.com/antonio2368)).
+* Support numeric literals with `_` as the separator, for example, `1_000_000`. [#43925](https://github.com/ClickHouse/ClickHouse/pull/43925) ([jh0x](https://github.com/jh0x)).
+* Added possibility to use an array as a second parameter for `cutURLParameter` function. It will cut multiple parameters. Close [#6827](https://github.com/ClickHouse/ClickHouse/issues/6827). [#43788](https://github.com/ClickHouse/ClickHouse/pull/43788) ([Roman Vasin](https://github.com/rvasin)).
+* Add a column with the expression of the index in the `system.data_skipping_indices` table. [#43308](https://github.com/ClickHouse/ClickHouse/pull/43308) ([Guillaume Tassery](https://github.com/YiuRULE)).
+* Add column `engine_full` to system table `databases` so that users can access the entire engine definition of a database via system tables. [#43468](https://github.com/ClickHouse/ClickHouse/pull/43468) ([凌涛](https://github.com/lingtaolf)).
+* New hash function [xxh3](https://github.com/Cyan4973/xxHash) added. Also, the performance of `xxHash32` and `xxHash64` are improved on ARM thanks to a library update. [#43411](https://github.com/ClickHouse/ClickHouse/pull/43411) ([Nikita Taranov](https://github.com/nickitat)).
+* Added support to define constraints for merge tree settings. For example you can forbid overriding the `storage_policy` by users. [#43903](https://github.com/ClickHouse/ClickHouse/pull/43903) ([Sergei Trifonov](https://github.com/serxa)).
+* Add a new setting `input_format_json_read_objects_as_strings` that allows the parsing of nested JSON objects into Strings in all JSON input formats. This setting is disabled by default. [#44052](https://github.com/ClickHouse/ClickHouse/pull/44052) ([Kruglov Pavel](https://github.com/Avogar)).
+
+#### Experimental Feature
+* Support deduplication for asynchronous inserts. Before this change, async inserts did not support deduplication, because multiple small inserts coexisted in one inserted batch. Closes [#38075](https://github.com/ClickHouse/ClickHouse/issues/38075). [#43304](https://github.com/ClickHouse/ClickHouse/pull/43304) ([Han Fei](https://github.com/hanfei1991)).
+* Add support for cosine distance for the experimental Annoy (vector similarity search) index. [#42778](https://github.com/ClickHouse/ClickHouse/pull/42778) ([Filatenkov Artur](https://github.com/FArthur-cmd)).
+* Add `CREATE / ALTER / DROP NAMED COLLECTION` queries. [#43252](https://github.com/ClickHouse/ClickHouse/pull/43252) ([Kseniia Sumarokova](https://github.com/kssenii)). This feature is under development and the queries are not effective as of version 22.12. This changelog entry is added only to avoid confusion. Restrict default access to named collections to the user defined in config. This requires that `show_named_collections = 1` is set to be able to see them. [#43325](https://github.com/ClickHouse/ClickHouse/pull/43325) ([Kseniia Sumarokova](https://github.com/kssenii)). The `system.named_collections` table is introduced [#43147](https://github.com/ClickHouse/ClickHouse/pull/43147) ([Kseniia Sumarokova](https://github.com/kssenii)).
+
+#### Performance Improvement
+* Add settings `max_streams_for_merge_tree_reading` and `allow_asynchronous_read_from_io_pool_for_merge_tree`. Setting `max_streams_for_merge_tree_reading` limits the number of reading streams for MergeTree tables. Setting `allow_asynchronous_read_from_io_pool_for_merge_tree` enables a background I/O pool to read from `MergeTree` tables. This may increase performance for I/O bound queries if used together with `max_streams_to_max_threads_ratio` or `max_streams_for_merge_tree_reading`. [#43260](https://github.com/ClickHouse/ClickHouse/pull/43260) ([Nikolai Kochetov](https://github.com/KochetovNicolai)). This improves performance up to 100 times in case of high latency storage, low number of CPU and high number of data parts.
+* Settings `merge_tree_min_rows_for_concurrent_read_for_remote_filesystem/merge_tree_min_bytes_for_concurrent_read_for_remote_filesystem` did not respect adaptive granularity. Fat rows did not decrease the number of read rows (as it was done for `merge_tree_min_rows_for_concurrent_read/merge_tree_min_bytes_for_concurrent_read`, which could lead to high memory usage when using remote filesystems. [#43965](https://github.com/ClickHouse/ClickHouse/pull/43965) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
+* Optimized the number of list requests to ZooKeeper or ClickHouse Keeper when selecting a part to merge. Previously it could produce thousands of requests in some cases. Fixes [#43647](https://github.com/ClickHouse/ClickHouse/issues/43647). [#43675](https://github.com/ClickHouse/ClickHouse/pull/43675) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Optimization is getting skipped now if `max_size_to_preallocate_for_aggregation` has too small a value. The default value of this setting increased to `10^8`. [#43945](https://github.com/ClickHouse/ClickHouse/pull/43945) ([Nikita Taranov](https://github.com/nickitat)).
+* Speed-up server shutdown by avoiding cleaning up of old data parts. Because it is unnecessary after https://github.com/ClickHouse/ClickHouse/pull/41145. [#43760](https://github.com/ClickHouse/ClickHouse/pull/43760) ([Sema Checherinda](https://github.com/CheSema)).
+* Merging on initiator now uses the same memory bound approach as merging of local aggregation results if `enable_memory_bound_merging_of_aggregation_results` is set. [#40879](https://github.com/ClickHouse/ClickHouse/pull/40879) ([Nikita Taranov](https://github.com/nickitat)).
+* Keeper improvement: try syncing logs to disk in parallel with replication. [#43450](https://github.com/ClickHouse/ClickHouse/pull/43450) ([Antonio Andelic](https://github.com/antonio2368)).
+* Keeper improvement: requests are batched more often. The batching can be controlled with the new setting `max_requests_quick_batch_size`. [#43686](https://github.com/ClickHouse/ClickHouse/pull/43686) ([Antonio Andelic](https://github.com/antonio2368)).
+
+#### Improvement
+* Implement referential dependencies and use them to create tables in the correct order while restoring from a backup. [#43834](https://github.com/ClickHouse/ClickHouse/pull/43834) ([Vitaly Baranov](https://github.com/vitlibar)).
+* Substitute UDFs in `CREATE` query to avoid failures during loading at startup. Additionally, UDFs can now be used as `DEFAULT` expressions for columns. [#43539](https://github.com/ClickHouse/ClickHouse/pull/43539) ([Antonio Andelic](https://github.com/antonio2368)).
+* Change how the following queries delete parts: TRUNCATE TABLE, ALTER TABLE DROP PART, ALTER TABLE DROP PARTITION. Now, these queries make empty parts which cover the old parts. This makes the TRUNCATE query work without a followedexclusive lock which means concurrent reads aren't locked. Also achieved durability in all those queries. If the request succeeds, then no resurrected parts appear later. Note that atomicity is achieved only with transaction scope. [#41145](https://github.com/ClickHouse/ClickHouse/pull/41145) ([Sema Checherinda](https://github.com/CheSema)).
+* `SET param_x` query no longer requires manual string serialization for the value of the parameter. For example, query `SET param_a = '[\'a\', \'b\']'` can now be written like `SET param_a = ['a', 'b']`. [#41874](https://github.com/ClickHouse/ClickHouse/pull/41874) ([Nikolay Degterinsky](https://github.com/evillique)).
+* Show read rows in the progress indication while reading from STDIN from client. Closes [#43423](https://github.com/ClickHouse/ClickHouse/issues/43423). [#43442](https://github.com/ClickHouse/ClickHouse/pull/43442) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Show progress bar while reading from s3 table function / engine. [#43454](https://github.com/ClickHouse/ClickHouse/pull/43454) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* `filesystemAvailable` and related functions support one optional argument with disk name, and change `filesystemFree` to `filesystemUnreserved`. Closes [#35076](https://github.com/ClickHouse/ClickHouse/issues/35076). [#42064](https://github.com/ClickHouse/ClickHouse/pull/42064) ([flynn](https://github.com/ucasfl)).
+* Integration with LDAP: increased the default value of search_limit to 256, and added LDAP server config option to change that to an arbitrary value. Closes: [#42276](https://github.com/ClickHouse/ClickHouse/issues/42276). [#42461](https://github.com/ClickHouse/ClickHouse/pull/42461) ([Vasily Nemkov](https://github.com/Enmk)).
+* Allow the removal of sensitive information (see the `query_masking_rules` in the configuration file) from the exception messages as well. Resolves [#41418](https://github.com/ClickHouse/ClickHouse/issues/41418). [#42940](https://github.com/ClickHouse/ClickHouse/pull/42940) ([filimonov](https://github.com/filimonov)).
+* Support queries like `SHOW FULL TABLES ...` for MySQL compatibility. [#43910](https://github.com/ClickHouse/ClickHouse/pull/43910) ([Filatenkov Artur](https://github.com/FArthur-cmd)).
+* Keeper improvement: Add 4lw command `rqld` which can manually assign a node as leader. [#43026](https://github.com/ClickHouse/ClickHouse/pull/43026) ([JackyWoo](https://github.com/JackyWoo)).
+* Apply connection timeout settings for Distributed async INSERT from the query. [#43156](https://github.com/ClickHouse/ClickHouse/pull/43156) ([Azat Khuzhin](https://github.com/azat)).
+* The `unhex` function now supports `FixedString` arguments. [issue42369](https://github.com/ClickHouse/ClickHouse/issues/42369). [#43207](https://github.com/ClickHouse/ClickHouse/pull/43207) ([DR](https://github.com/freedomDR)).
+* Priority is given to deleting completely expired parts according to the TTL rules, see [#42869](https://github.com/ClickHouse/ClickHouse/issues/42869). [#43222](https://github.com/ClickHouse/ClickHouse/pull/43222) ([zhongyuankai](https://github.com/zhongyuankai)).
+* More precise and reactive CPU load indication in clickhouse-client. [#43307](https://github.com/ClickHouse/ClickHouse/pull/43307) ([Sergei Trifonov](https://github.com/serxa)).
+* Support reading of subcolumns of nested types from storage `S3` and table function `s3` with formats `Parquet`, `Arrow` and `ORC`. [#43329](https://github.com/ClickHouse/ClickHouse/pull/43329) ([chen](https://github.com/xiedeyantu)).
+* Add `table_uuid` column to the `system.parts` table. [#43404](https://github.com/ClickHouse/ClickHouse/pull/43404) ([Azat Khuzhin](https://github.com/azat)).
+* Added client option to display the number of locally processed rows in non-interactive mode (`--print-num-processed-rows`). [#43407](https://github.com/ClickHouse/ClickHouse/pull/43407) ([jh0x](https://github.com/jh0x)).
+* Implement `aggregation-in-order` optimization on top of a query plan. It is enabled by default (but works only together with `optimize_aggregation_in_order`, which is disabled by default). Set `query_plan_aggregation_in_order = 0` to use the previous AST-based version. [#43592](https://github.com/ClickHouse/ClickHouse/pull/43592) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
+* Allow to collect profile events with `trace_type = 'ProfileEvent'` to `system.trace_log` on each increment with current stack, profile event name and value of the increment. It can be enabled by the setting `trace_profile_events` and used to investigate performance of queries. [#43639](https://github.com/ClickHouse/ClickHouse/pull/43639) ([Anton Popov](https://github.com/CurtizJ)).
+* Add a new setting `input_format_max_binary_string_size` to limit string size in RowBinary format. [#43842](https://github.com/ClickHouse/ClickHouse/pull/43842) ([Kruglov Pavel](https://github.com/Avogar)).
+* When ClickHouse requests a remote HTTP server, and it returns an error, the numeric HTTP code was not displayed correctly in the exception message. Closes [#43919](https://github.com/ClickHouse/ClickHouse/issues/43919). [#43920](https://github.com/ClickHouse/ClickHouse/pull/43920) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Correctly report errors in queries even when multiple JOINs optimization is taking place. [#43583](https://github.com/ClickHouse/ClickHouse/pull/43583) ([Salvatore](https://github.com/tbsal)).
+
+#### Build/Testing/Packaging Improvement
+
+* Systemd integration now correctly notifies systemd that the service is really started and is ready to serve requests. [#43400](https://github.com/ClickHouse/ClickHouse/pull/43400) ([Коренберг Марк](https://github.com/socketpair)).
+* Added the option to build ClickHouse with OpenSSL using the [OpenSSL FIPS Module](https://www.openssl.org/docs/man3.0/man7/fips_module.html). This build type has not been tested to validate security and is not supported. [#43991](https://github.com/ClickHouse/ClickHouse/pull/43991) ([Boris Kuschel](https://github.com/bkuschel)).
+* Upgrade to the new `DeflateQpl` compression codec which has been implemented in a previous PR (details: https://github.com/ClickHouse/ClickHouse/pull/39494). This patch improves codec on below aspects: 1. QPL v0.2.0 to QPL v0.3.0 [Intel® Query Processing Library (QPL)](https://github.com/intel/qpl) 2. Improve CMake file for fixing QPL build issues for QPL v0.3.0. 3. Link the QPL library with libaccel-config at build time instead of runtime loading on QPL v0.2.0 (dlopen) 4. Fixed log print issue in CompressionCodecDeflateQpl.cpp. [#44024](https://github.com/ClickHouse/ClickHouse/pull/44024) ([jasperzhu](https://github.com/jinjunzh)).
+
+#### Bug Fix (user-visible misbehavior in official stable or prestable release)
+
+* Fixed bug which could lead to deadlock while using asynchronous inserts. [#43233](https://github.com/ClickHouse/ClickHouse/pull/43233) ([Anton Popov](https://github.com/CurtizJ)).
+* Fix some incorrect logic in AST level optimization `optimize_normalize_count_variants`. [#43873](https://github.com/ClickHouse/ClickHouse/pull/43873) ([Duc Canh Le](https://github.com/canhld94)).
+* Fix a case when mutations are not making progress when checksums do not match between replicas (e.g. caused by a change in data format on an upgrade). [#36877](https://github.com/ClickHouse/ClickHouse/pull/36877) ([nvartolomei](https://github.com/nvartolomei)).
+* Fix the `skip_unavailable_shards` optimization which did not work with the `hdfsCluster` table function. [#43236](https://github.com/ClickHouse/ClickHouse/pull/43236) ([chen](https://github.com/xiedeyantu)).
+* Fix `s3` support for the `?` wildcard. Closes [#42731](https://github.com/ClickHouse/ClickHouse/issues/42731). [#43253](https://github.com/ClickHouse/ClickHouse/pull/43253) ([chen](https://github.com/xiedeyantu)).
+* Fix functions `arrayFirstOrNull` and `arrayLastOrNull` or null when the array contains `Nullable` elements. [#43274](https://github.com/ClickHouse/ClickHouse/pull/43274) ([Duc Canh Le](https://github.com/canhld94)).
+* Fix incorrect `UserTimeMicroseconds`/`SystemTimeMicroseconds` accounting related to Kafka tables. [#42791](https://github.com/ClickHouse/ClickHouse/pull/42791) ([Azat Khuzhin](https://github.com/azat)).
+* Do not suppress exceptions in `web` disks. Fix retries for the `web` disk. [#42800](https://github.com/ClickHouse/ClickHouse/pull/42800) ([Azat Khuzhin](https://github.com/azat)).
+* Fixed (logical) race condition between inserts and dropping materialized views. A race condition happened when a Materialized View was dropped at the same time as an INSERT, where the MVs were present as a dependency of the insert at the begining of the execution, but the table has been dropped by the time the insert chain tries to access it, producing either an `UNKNOWN_TABLE` or `TABLE_IS_DROPPED` exception, and stopping the insertion. After this change, we avoid these exceptions and just continue with the insert if the dependency is gone. [#43161](https://github.com/ClickHouse/ClickHouse/pull/43161) ([AlfVII](https://github.com/AlfVII)).
+* Fix undefined behavior in the `quantiles` function, which might lead to uninitialized memory. Found by fuzzer. This closes [#44066](https://github.com/ClickHouse/ClickHouse/issues/44066). [#44067](https://github.com/ClickHouse/ClickHouse/pull/44067) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Additional check on zero uncompressed size is added to `CompressionCodecDelta`. [#43255](https://github.com/ClickHouse/ClickHouse/pull/43255) ([Nikita Taranov](https://github.com/nickitat)).
+* Flatten arrays from Parquet to avoid an issue with inconsistent data in arrays. These incorrect files can be generated by Apache Iceberg. [#43297](https://github.com/ClickHouse/ClickHouse/pull/43297) ([Arthur Passos](https://github.com/arthurpassos)).
+* Fix bad cast from `LowCardinality` column when using short circuit function execution. [#43311](https://github.com/ClickHouse/ClickHouse/pull/43311) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fixed queries with `SAMPLE BY` with prewhere optimization on tables using `Merge` engine. [#43315](https://github.com/ClickHouse/ClickHouse/pull/43315) ([Antonio Andelic](https://github.com/antonio2368)).
+* Check and compare the content of the `format_version` file in `MergeTreeData` so that tables can be loaded even if the storage policy was changed. [#43328](https://github.com/ClickHouse/ClickHouse/pull/43328) ([Antonio Andelic](https://github.com/antonio2368)).
+* Fix possible (very unlikely) "No column to rollback" logical error during INSERT into `Buffer` tables. [#43336](https://github.com/ClickHouse/ClickHouse/pull/43336) ([Azat Khuzhin](https://github.com/azat)).
+* Fix a bug that allowed the parser to parse an unlimited amount of round brackets into one function if `allow_function_parameters` is set. [#43350](https://github.com/ClickHouse/ClickHouse/pull/43350) ([Nikolay Degterinsky](https://github.com/evillique)).
+* `MaterializeMySQL` (experimental feature) support DDL: `drop table t1, t2` and compatible with most of MySQL DROP DDL. [#43366](https://github.com/ClickHouse/ClickHouse/pull/43366) ([zzsmdfj](https://github.com/zzsmdfj)).
+* `session_log` (experimental feature): Fixed the inability to log in (because of failure to create the session_log entry) in a very rare case of messed up setting profiles. [#42641](https://github.com/ClickHouse/ClickHouse/pull/42641) ([Vasily Nemkov](https://github.com/Enmk)).
+* Fix possible `Cannot create non-empty column with type Nothing` in functions `if`/`multiIf`. Closes [#43356](https://github.com/ClickHouse/ClickHouse/issues/43356). [#43368](https://github.com/ClickHouse/ClickHouse/pull/43368) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fix a bug when a row level filter uses the default value of a column. [#43387](https://github.com/ClickHouse/ClickHouse/pull/43387) ([Alexander Gololobov](https://github.com/davenger)).
+* Query with `DISTINCT` + `LIMIT BY` + `LIMIT` can return fewer rows than expected. Fixes [#43377](https://github.com/ClickHouse/ClickHouse/issues/43377). [#43410](https://github.com/ClickHouse/ClickHouse/pull/43410) ([Igor Nikonov](https://github.com/devcrafter)).
+* Fix `sumMap` for `Nullable(Decimal(...))`. [#43414](https://github.com/ClickHouse/ClickHouse/pull/43414) ([Azat Khuzhin](https://github.com/azat)).
+* Fix `date_diff` for hour/minute on macOS. Close [#42742](https://github.com/ClickHouse/ClickHouse/issues/42742). [#43466](https://github.com/ClickHouse/ClickHouse/pull/43466) ([zzsmdfj](https://github.com/zzsmdfj)).
+* Fix incorrect memory accounting because of merges/mutations. [#43516](https://github.com/ClickHouse/ClickHouse/pull/43516) ([Azat Khuzhin](https://github.com/azat)).
+* Fixed primary key analysis with conditions involving `toString(enum)`. [#43596](https://github.com/ClickHouse/ClickHouse/pull/43596) ([Nikita Taranov](https://github.com/nickitat)). This error has been found by @tisonkun.
+* Ensure consistency when `clickhouse-copier` updates status and `attach_is_done` in Keeper after partition attach is done. [#43602](https://github.com/ClickHouse/ClickHouse/pull/43602) ([lzydmxy](https://github.com/lzydmxy)).
+* During the recovery of a lost replica of a `Replicated` database (experimental feature), there could a situation where we need to atomically swap two table names (use EXCHANGE). Previously we tried to use two RENAME queries, which was obviously failing and moreover, failed the whole recovery process of the database replica. [#43628](https://github.com/ClickHouse/ClickHouse/pull/43628) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
+* Fix the case when the `s3Cluster` function throws `NOT_FOUND_COLUMN_IN_BLOCK` error. Closes [#43534](https://github.com/ClickHouse/ClickHouse/issues/43534). [#43629](https://github.com/ClickHouse/ClickHouse/pull/43629) ([chen](https://github.com/xiedeyantu)).
+* Fix possible logical error `Array sizes mismatched` while parsing JSON object with arrays with same key names but with different nesting level. Closes [#43569](https://github.com/ClickHouse/ClickHouse/issues/43569). [#43693](https://github.com/ClickHouse/ClickHouse/pull/43693) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fixed possible exception in the case of distributed `GROUP BY` with an `ALIAS` column among aggregation keys. [#43709](https://github.com/ClickHouse/ClickHouse/pull/43709) ([Nikita Taranov](https://github.com/nickitat)).
+* Fix bug which can lead to broken projections if zero-copy replication (experimental feature) is enabled and used. [#43764](https://github.com/ClickHouse/ClickHouse/pull/43764) ([alesapin](https://github.com/alesapin)).
+* Fix using multipart upload for very large S3 objects in AWS S3. [#43824](https://github.com/ClickHouse/ClickHouse/pull/43824) ([ianton-ru](https://github.com/ianton-ru)).
+* Fixed `ALTER ... RESET SETTING` with `ON CLUSTER`. It could have been applied to one replica only. Fixes [#43843](https://github.com/ClickHouse/ClickHouse/issues/43843). [#43848](https://github.com/ClickHouse/ClickHouse/pull/43848) ([Elena Torró](https://github.com/elenatorro)).
+* Fix a logical error in JOIN with `Join` table engine at right hand side, if `USING` is being used. [#43963](https://github.com/ClickHouse/ClickHouse/pull/43963) ([Vladimir C](https://github.com/vdimir)). Fix a bug with wrong order of keys in `Join` table engine. [#44012](https://github.com/ClickHouse/ClickHouse/pull/44012) ([Vladimir C](https://github.com/vdimir)).
+* Keeper fix: throw if the interserver port for Raft is already in use. [#43984](https://github.com/ClickHouse/ClickHouse/pull/43984) ([Antonio Andelic](https://github.com/antonio2368)).
+* Fix ORDER BY positional argument (example: `ORDER BY 1, 2`) in case of unneeded columns pruning from subqueries. Closes [#43964](https://github.com/ClickHouse/ClickHouse/issues/43964). [#43987](https://github.com/ClickHouse/ClickHouse/pull/43987) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Fixed exception when a subquery contains HAVING but doesn't contain an actual aggregation. [#44051](https://github.com/ClickHouse/ClickHouse/pull/44051) ([Nikita Taranov](https://github.com/nickitat)).
+* Fix race in s3 multipart upload. This race could cause the error `Part number must be an integer between 1 and 10000, inclusive. (S3_ERROR)` while restoring from a backup. [#44065](https://github.com/ClickHouse/ClickHouse/pull/44065) ([Vitaly Baranov](https://github.com/vitlibar)).
+
+
### ClickHouse release 22.11, 2022-11-17
#### Backward Incompatible Change
@@ -534,30 +653,30 @@
* Add counters (ProfileEvents) for cases when query complexity limitation has been set and has reached (a separate counter for `overflow_mode` = `break` and `throw`). For example, if you have set up `max_rows_to_read` with `read_overflow_mode = 'break'`, looking at the value of `OverflowBreak` counter will allow distinguishing incomplete results. [#40205](https://github.com/ClickHouse/ClickHouse/pull/40205) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Fix memory accounting in case of "Memory limit exceeded" errors (previously [peak] memory usage was takes failed allocations into account). [#40249](https://github.com/ClickHouse/ClickHouse/pull/40249) ([Azat Khuzhin](https://github.com/azat)).
* Add metrics for filesystem cache: `FilesystemCacheSize` and `FilesystemCacheElements`. [#40260](https://github.com/ClickHouse/ClickHouse/pull/40260) ([Kseniia Sumarokova](https://github.com/kssenii)).
-* Support hadoop secure RPC transfer (hadoop.rpc.protection=privacy and hadoop.rpc.protection=integrity). [#39411](https://github.com/ClickHouse/ClickHouse/pull/39411) ([michael1589](https://github.com/michael1589)).
+* Support Hadoop secure RPC transfer (hadoop.rpc.protection=privacy and hadoop.rpc.protection=integrity). [#39411](https://github.com/ClickHouse/ClickHouse/pull/39411) ([michael1589](https://github.com/michael1589)).
* Avoid continuously growing memory consumption of pattern cache when using functions multi(Fuzzy)Match(Any|AllIndices|AnyIndex)(). [#40264](https://github.com/ClickHouse/ClickHouse/pull/40264) ([Robert Schulze](https://github.com/rschu1ze)).
-* Add cache for schema inference for file/s3/hdfs/url table functions. Now, schema inference will be performed only on the first query to the file, all subsequent queries to the same file will use the schema from cache if data wasn't changed. Add system table system.schema_inference_cache with all current schemas in cache and system queries SYSTEM DROP SCHEMA CACHE [FOR FILE/S3/HDFS/URL] to drop schemas from cache. [#38286](https://github.com/ClickHouse/ClickHouse/pull/38286) ([Kruglov Pavel](https://github.com/Avogar)).
+* Add cache for schema inference for file/s3/hdfs/url table functions. Now, schema inference will be performed only on the first query to the file, all subsequent queries to the same file will use the schema from the cache if data has not changed. Add system table system.schema_inference_cache with all current schemas in cache and system queries SYSTEM DROP SCHEMA CACHE [FOR FILE/S3/HDFS/URL] to drop schemas from cache. [#38286](https://github.com/ClickHouse/ClickHouse/pull/38286) ([Kruglov Pavel](https://github.com/Avogar)).
* Add support for LARGE_BINARY/LARGE_STRING with Arrow (Closes [#32401](https://github.com/ClickHouse/ClickHouse/issues/32401)). [#40293](https://github.com/ClickHouse/ClickHouse/pull/40293) ([Josh Taylor](https://github.com/joshuataylor)).
#### Build/Testing/Packaging Improvement
* [ClickFiddle](https://fiddle.clickhouse.com/): A new tool for testing ClickHouse versions in read/write mode (**Igor Baliuk**).
* ClickHouse binary is made self-extracting [#35775](https://github.com/ClickHouse/ClickHouse/pull/35775) ([Yakov Olkhovskiy, Arthur Filatenkov](https://github.com/yakov-olkhovskiy)).
-* Update tzdata to 2022b to support the new timezone changes. See https://github.com/google/cctz/pull/226. Chile's 2022 DST start is delayed from September 4 to September 11. Iran plans to stop observing DST permanently, after it falls back on 2022-09-21. There are corrections of the historical time zone of Asia/Tehran in the year 1977: Iran adopted standard time in 1935, not 1946. In 1977 it observed DST from 03-21 23:00 to 10-20 24:00; its 1978 transitions were on 03-24 and 08-05, not 03-20 and 10-20; and its spring 1979 transition was on 05-27, not 03-21 (https://data.iana.org/time-zones/tzdb/NEWS). ([Alexey Milovidov](https://github.com/alexey-milovidov)).
-* Former packages used to install systemd.service file to `/etc`. The files there are marked as `conf` and are not cleaned out, and not updated automatically. This PR cleans them out. [#39323](https://github.com/ClickHouse/ClickHouse/pull/39323) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Update `tzdata` to 2022b to support the new timezone changes. See https://github.com/google/cctz/pull/226. Chile's 2022 DST start is delayed from September 4 to September 11. Iran plans to stop observing DST permanently after it falls back on 2022-09-21. There are corrections to the historical time zone of Asia/Tehran in the year 1977: Iran adopted standard time in 1935, not 1946. In 1977 it observed DST from 03-21 23:00 to 10-20 24:00; its 1978 transitions were on 03-24 and 08-05, not 03-20 and 10-20; and its spring 1979 transition was on 05-27, not 03-21 (https://data.iana.org/time-zones/tzdb/NEWS). ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Former packages used to install systemd.service file to `/etc`. The files there are marked as `conf` and are not cleaned out, and are not updated automatically. This PR cleans them out. [#39323](https://github.com/ClickHouse/ClickHouse/pull/39323) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
* Ensure LSan is effective. [#39430](https://github.com/ClickHouse/ClickHouse/pull/39430) ([Azat Khuzhin](https://github.com/azat)).
* TSAN has issues with clang-14 (https://github.com/google/sanitizers/issues/1552, https://github.com/google/sanitizers/issues/1540), so here we build the TSAN binaries with clang-15. [#39450](https://github.com/ClickHouse/ClickHouse/pull/39450) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
* Remove the option to build ClickHouse tools as separate executable programs. This fixes [#37847](https://github.com/ClickHouse/ClickHouse/issues/37847). [#39520](https://github.com/ClickHouse/ClickHouse/pull/39520) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
-* Small preparations for build on s390x (which is big-endian). [#39627](https://github.com/ClickHouse/ClickHouse/pull/39627) ([Harry Lee](https://github.com/HarryLeeIBM)). [#39656](https://github.com/ClickHouse/ClickHouse/pull/39656) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed Endian issue in BitHelpers for s390x. [#39656](https://github.com/ClickHouse/ClickHouse/pull/39656) ([Harry Lee](https://github.com/HarryLeeIBM)). Implement a piece of code related to SipHash for s390x architecture (which is not supported by ClickHouse). [#39732](https://github.com/ClickHouse/ClickHouse/pull/39732) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed an Endian issue in Coordination snapshot code for s390x architecture (which is not supported by ClickHouse). [#39931](https://github.com/ClickHouse/ClickHouse/pull/39931) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed Endian issues in Codec code for s390x architecture (which is not supported by ClickHouse). [#40008](https://github.com/ClickHouse/ClickHouse/pull/40008) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed Endian issues in reading/writing BigEndian binary data in ReadHelpers and WriteHelpers code for s390x architecture (which is not supported by ClickHouse). [#40179](https://github.com/ClickHouse/ClickHouse/pull/40179) ([Harry Lee](https://github.com/HarryLeeIBM)).
+* Small preparations for build on s390x (which is big-endian). [#39627](https://github.com/ClickHouse/ClickHouse/pull/39627) ([Harry Lee](https://github.com/HarryLeeIBM)). [#39656](https://github.com/ClickHouse/ClickHouse/pull/39656) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed Endian issue in BitHelpers for s390x. [#39656](https://github.com/ClickHouse/ClickHouse/pull/39656) ([Harry Lee](https://github.com/HarryLeeIBM)). Implement a piece of code related to SipHash for s390x architecture (which is not supported by ClickHouse). [#39732](https://github.com/ClickHouse/ClickHouse/pull/39732) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed an Endian issue in the Coordination snapshot code for s390x architecture (which is not supported by ClickHouse). [#39931](https://github.com/ClickHouse/ClickHouse/pull/39931) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed Endian issues in Codec code for s390x architecture (which is not supported by ClickHouse). [#40008](https://github.com/ClickHouse/ClickHouse/pull/40008) ([Harry Lee](https://github.com/HarryLeeIBM)). Fixed Endian issues in reading/writing BigEndian binary data in ReadHelpers and WriteHelpers code for s390x architecture (which is not supported by ClickHouse). [#40179](https://github.com/ClickHouse/ClickHouse/pull/40179) ([Harry Lee](https://github.com/HarryLeeIBM)).
* Support build with `clang-16` (trunk). This closes [#39949](https://github.com/ClickHouse/ClickHouse/issues/39949). [#40181](https://github.com/ClickHouse/ClickHouse/pull/40181) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Prepare RISC-V 64 build to run in CI. This is for [#40141](https://github.com/ClickHouse/ClickHouse/issues/40141). [#40197](https://github.com/ClickHouse/ClickHouse/pull/40197) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Simplified function registration macro interface (`FUNCTION_REGISTER*`) to eliminate the step to add and call an extern function in the registerFunctions.cpp, it also makes incremental builds of a new function faster. [#38615](https://github.com/ClickHouse/ClickHouse/pull/38615) ([Li Yin](https://github.com/liyinsg)).
-* Docker: Now entrypoint.sh in docker image creates and executes chown for all folders it found in config for multidisk setup [#17717](https://github.com/ClickHouse/ClickHouse/issues/17717). [#39121](https://github.com/ClickHouse/ClickHouse/pull/39121) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
+* Docker: Now entrypoint.sh in docker image creates and executes chown for all folders it finds in the config for multidisk setup [#17717](https://github.com/ClickHouse/ClickHouse/issues/17717). [#39121](https://github.com/ClickHouse/ClickHouse/pull/39121) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
#### Bug Fix
-* Fix possible segfault in `CapnProto` input format. This bug was found and send through ClickHouse bug-bounty [program](https://github.com/ClickHouse/ClickHouse/issues/38986) by *kiojj*. [#40241](https://github.com/ClickHouse/ClickHouse/pull/40241) ([Kruglov Pavel](https://github.com/Avogar)).
-* Fix a very rare case of incorrect behavior of array subscript operator. This closes [#28720](https://github.com/ClickHouse/ClickHouse/issues/28720). [#40185](https://github.com/ClickHouse/ClickHouse/pull/40185) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Fix possible segfault in `CapnProto` input format. This bug was found and sent in through the ClickHouse bug-bounty [program](https://github.com/ClickHouse/ClickHouse/issues/38986) by *kiojj*. [#40241](https://github.com/ClickHouse/ClickHouse/pull/40241) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fix a very rare case of incorrect behavior of the array subscript operator. This closes [#28720](https://github.com/ClickHouse/ClickHouse/issues/28720). [#40185](https://github.com/ClickHouse/ClickHouse/pull/40185) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Fix insufficient argument check for encryption functions (found by query fuzzer). This closes [#39987](https://github.com/ClickHouse/ClickHouse/issues/39987). [#40194](https://github.com/ClickHouse/ClickHouse/pull/40194) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Fix the case when the order of columns can be incorrect if the `IN` operator is used with a table with `ENGINE = Set` containing multiple columns. This fixes [#13014](https://github.com/ClickHouse/ClickHouse/issues/13014). [#40225](https://github.com/ClickHouse/ClickHouse/pull/40225) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
* Fix seeking while reading from encrypted disk. This PR fixes [#38381](https://github.com/ClickHouse/ClickHouse/issues/38381). [#39687](https://github.com/ClickHouse/ClickHouse/pull/39687) ([Vitaly Baranov](https://github.com/vitlibar)).
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f96148567da..99997db96a1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -448,12 +448,7 @@ else()
link_libraries(global-group)
endif ()
-if (NOT (OS_LINUX OR OS_DARWIN))
- # Using system libs can cause a lot of warnings in includes (on macro expansion).
- option(WERROR "Enable -Werror compiler option" OFF)
-else ()
- option(WERROR "Enable -Werror compiler option" ON)
-endif ()
+option(WERROR "Enable -Werror compiler option" ON)
if (WERROR)
# Don't pollute CMAKE_CXX_FLAGS with -Werror as it will break some CMake checks.
@@ -614,6 +609,8 @@ if (NATIVE_BUILD_TARGETS
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DENABLE_CCACHE=${ENABLE_CCACHE}"
+ # Avoid overriding .cargo/config.toml with native toolchain.
+ "-DENABLE_RUST=OFF"
"-DENABLE_CLICKHOUSE_SELF_EXTRACTING=${ENABLE_CLICKHOUSE_SELF_EXTRACTING}"
${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY "${NATIVE_BUILD_DIR}"
diff --git a/README.md b/README.md
index 59c9c180c90..35580369fd0 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,6 @@ ClickHouse® is an open-source column-oriented database management system that a
* [Contacts](https://clickhouse.com/company/contact) can help to get your questions answered if there are any.
## Upcoming events
-* [**v22.12 Release Webinar**](https://clickhouse.com/company/events/v22-12-release-webinar) Original creator, co-founder, and CTO of ClickHouse Alexey Milovidov will walk us through the highlights of the release, provide live demos, and share vision into what is coming in the roadmap.
+* [**v22.12 Release Webinar**](https://clickhouse.com/company/events/v22-12-release-webinar) 22.12 is the ClickHouse Christmas release. There are plenty of gifts (a new JOIN algorithm among them) and we adopted something from MongoDB. Original creator, co-founder, and CTO of ClickHouse Alexey Milovidov will walk us through the highlights of the release.
* [**ClickHouse Meetup at the CHEQ office in Tel Aviv**](https://www.meetup.com/clickhouse-tel-aviv-user-group/events/289599423/) - Jan 16 - We are very excited to be holding our next in-person ClickHouse meetup at the CHEQ office in Tel Aviv! Hear from CHEQ, ServiceNow and Contentsquare, as well as a deep dive presentation from ClickHouse CTO Alexey Milovidov. Join us for a fun evening of talks, food and discussion!
-* **ClickHouse Meetup in Seattle* - Keep an eye on this space as we will be announcing a January meetup in Seattle soon!
+* [**ClickHouse Meetup at Microsoft Office in Seattle**](https://www.meetup.com/clickhouse-seattle-user-group/events/290310025/) - Jan 18 - Keep an eye on this space as we will be announcing speakers soon!
diff --git a/SECURITY.md b/SECURITY.md
index a4f431d7552..3dcdc5db009 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -13,9 +13,10 @@ The following versions of ClickHouse server are currently being supported with s
| Version | Supported |
|:-|:-|
+| 22.12 | ✔️ |
| 22.11 | ✔️ |
| 22.10 | ✔️ |
-| 22.9 | ✔️ |
+| 22.9 | ❌ |
| 22.8 | ✔️ |
| 22.7 | ❌ |
| 22.6 | ❌ |
diff --git a/base/base/CMakeLists.txt b/base/base/CMakeLists.txt
index 175a4836e64..d788bd6f092 100644
--- a/base/base/CMakeLists.txt
+++ b/base/base/CMakeLists.txt
@@ -40,6 +40,11 @@ else ()
target_compile_definitions(common PUBLIC WITH_COVERAGE=0)
endif ()
+# FIXME: move libraries for line reading out from base
+if (TARGET ch_rust::skim)
+ target_link_libraries(common PUBLIC ch_rust::skim)
+endif()
+
target_include_directories(common PUBLIC .. "${CMAKE_CURRENT_BINARY_DIR}/..")
if (OS_DARWIN AND NOT USE_STATIC_LIBRARIES)
diff --git a/base/base/ReplxxLineReader.cpp b/base/base/ReplxxLineReader.cpp
index b86746365b7..9e29f7744fa 100644
--- a/base/base/ReplxxLineReader.cpp
+++ b/base/base/ReplxxLineReader.cpp
@@ -16,9 +16,11 @@
#include
#include
#include
-#include
-#include
-#include /// is_any_of
+#include "config.h" // USE_SKIM
+
+#if USE_SKIM
+#include
+#endif
namespace
{
@@ -39,36 +41,6 @@ std::string getEditor()
return editor;
}
-std::pair getFuzzyFinder()
-{
- const char * env_path = std::getenv("PATH"); // NOLINT(concurrency-mt-unsafe)
-
- if (!env_path || !*env_path)
- return {};
-
- std::vector paths;
- boost::split(paths, env_path, boost::is_any_of(":"));
- for (const auto & path_str : paths)
- {
- std::filesystem::path path(path_str);
- std::filesystem::path sk_bin_path = path / "sk";
- if (!access(sk_bin_path.c_str(), X_OK))
- return {sk_bin_path, FUZZY_FINDER_SKIM};
-
- std::filesystem::path fzf_bin_path = path / "fzf";
- if (!access(fzf_bin_path.c_str(), X_OK))
- return {fzf_bin_path, FUZZY_FINDER_FZF};
- }
-
- return {"", FUZZY_FINDER_NONE};
-}
-
-String escapeShellArgument(std::string arg)
-{
- boost::replace_all(arg, "'", "'\\''");
- return fmt::format("'{}'", arg);
-}
-
/// See comments in ShellCommand::executeImpl()
/// (for the vfork via dlsym())
int executeCommand(char * const argv[])
@@ -316,8 +288,6 @@ ReplxxLineReader::ReplxxLineReader(
using namespace std::placeholders;
using Replxx = replxx::Replxx;
- std::tie(fuzzy_finder, fuzzy_finder_type) = getFuzzyFinder();
-
if (!history_file_path.empty())
{
history_file_fd = open(history_file_path.c_str(), O_RDWR);
@@ -422,17 +392,48 @@ ReplxxLineReader::ReplxxLineReader(
};
rx.bind_key(Replxx::KEY::meta('#'), insert_comment_action);
- /// interactive search in history (requires fzf/sk)
- if (fuzzy_finder_type != FUZZY_FINDER_NONE)
+#if USE_SKIM
+ auto interactive_history_search = [this](char32_t code)
{
- auto interactive_history_search = [this](char32_t code)
+ std::vector words;
{
- openInteractiveHistorySearch();
- rx.invoke(Replxx::ACTION::CLEAR_SELF, code);
- return rx.invoke(Replxx::ACTION::REPAINT, code);
- };
- rx.bind_key(Replxx::KEY::control('R'), interactive_history_search);
- }
+ auto hs(rx.history_scan());
+ while (hs.next())
+ words.push_back(hs.get().text());
+ }
+
+ std::string new_query;
+ try
+ {
+ new_query = std::string(skim(words));
+ }
+ catch (const std::exception & e)
+ {
+ rx.print("skim failed: %s (consider using Ctrl-T for a regular non-fuzzy reverse search)\n", e.what());
+ }
+ if (!new_query.empty())
+ rx.set_state(replxx::Replxx::State(new_query.c_str(), static_cast(new_query.size())));
+
+ if (bracketed_paste_enabled)
+ enableBracketedPaste();
+
+ rx.invoke(Replxx::ACTION::CLEAR_SELF, code);
+ return rx.invoke(Replxx::ACTION::REPAINT, code);
+ };
+
+ rx.bind_key(Replxx::KEY::control('R'), interactive_history_search);
+
+ /// Rebind regular incremental search to C-T.
+ ///
+ /// NOTE: C-T by default this is a binding to swap adjustent chars
+ /// (TRANSPOSE_CHARACTERS), but for SQL it sounds pretty useless.
+ rx.bind_key(Replxx::KEY::control('T'), [this](char32_t)
+ {
+ /// Reverse search is detected by C-R.
+ uint32_t reverse_search = Replxx::KEY::control('R');
+ return rx.invoke(Replxx::ACTION::HISTORY_INCREMENTAL_SEARCH, reverse_search);
+ });
+#endif
}
ReplxxLineReader::~ReplxxLineReader()
@@ -501,65 +502,6 @@ void ReplxxLineReader::openEditor()
enableBracketedPaste();
}
-void ReplxxLineReader::openInteractiveHistorySearch()
-{
- assert(!fuzzy_finder.empty());
- TemporaryFile history_file("clickhouse_client_history_in_XXXXXX.bin");
- auto hs(rx.history_scan());
- while (hs.next())
- {
- history_file.write(hs.get().text());
- history_file.write(std::string(1, '\0'));
- }
- history_file.close();
-
- TemporaryFile output_file("clickhouse_client_history_out_XXXXXX.sql");
- output_file.close();
-
- char sh[] = "sh";
- char sh_c[] = "-c";
- /// NOTE: You can use one of the following to configure the behaviour additionally:
- /// - SKIM_DEFAULT_OPTIONS
- /// - FZF_DEFAULT_OPTS
- ///
- /// And also note, that fzf and skim is 95% compatible (at least option
- /// that is used here)
- std::string fuzzy_finder_command = fmt::format("{} --read0 --height=30%", fuzzy_finder);
- switch (fuzzy_finder_type)
- {
- case FUZZY_FINDER_SKIM:
- fuzzy_finder_command += " --tac --tiebreak=-score";
- break;
- case FUZZY_FINDER_FZF:
- fuzzy_finder_command += " --tac --tiebreak=index";
- break;
- case FUZZY_FINDER_NONE:
- /// assertion for !fuzzy_finder.empty() is enough
- break;
- }
- fuzzy_finder_command += fmt::format(" < {} > {}",
- escapeShellArgument(history_file.getPath()),
- escapeShellArgument(output_file.getPath()));
- char * const argv[] = {sh, sh_c, fuzzy_finder_command.data(), nullptr};
-
- try
- {
- if (executeCommand(argv) == 0)
- {
- std::string new_query = readFile(output_file.getPath());
- rightTrim(new_query);
- rx.set_state(replxx::Replxx::State(new_query.c_str(), static_cast(new_query.size())));
- }
- }
- catch (const std::runtime_error & e)
- {
- rx.print(e.what());
- }
-
- if (bracketed_paste_enabled)
- enableBracketedPaste();
-}
-
void ReplxxLineReader::enableBracketedPaste()
{
bracketed_paste_enabled = true;
diff --git a/base/base/ReplxxLineReader.h b/base/base/ReplxxLineReader.h
index 9be3b3aa993..428fbf144c3 100644
--- a/base/base/ReplxxLineReader.h
+++ b/base/base/ReplxxLineReader.h
@@ -4,15 +4,6 @@
#include
-enum FuzzyFinderType
-{
- FUZZY_FINDER_NONE,
- /// Use https://github.com/junegunn/fzf
- FUZZY_FINDER_FZF,
- /// Use https://github.com/lotabout/skim
- FUZZY_FINDER_SKIM,
-};
-
class ReplxxLineReader : public LineReader
{
public:
@@ -35,7 +26,6 @@ private:
void addToHistory(const String & line) override;
int executeEditor(const std::string & path);
void openEditor();
- void openInteractiveHistorySearch();
replxx::Replxx rx;
replxx::Replxx::highlighter_callback_t highlighter;
@@ -45,6 +35,4 @@ private:
bool bracketed_paste_enabled = false;
std::string editor;
- std::string fuzzy_finder;
- FuzzyFinderType fuzzy_finder_type = FUZZY_FINDER_NONE;
};
diff --git a/base/readpassphrase/readpassphrase.c b/base/readpassphrase/readpassphrase.c
index b8707770e6c..a84ec43767c 100644
--- a/base/readpassphrase/readpassphrase.c
+++ b/base/readpassphrase/readpassphrase.c
@@ -153,7 +153,7 @@ restart:
/* Restore old terminal settings and signals. */
if (memcmp(&term, &oterm, sizeof(term)) != 0) {
- const int sigttou = signo[SIGTTOU];
+ const int sigttou = (int)signo[SIGTTOU];
/* Ignore SIGTTOU generated when we are not the fg pgrp. */
while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
diff --git a/cmake/autogenerated_versions.txt b/cmake/autogenerated_versions.txt
index d06d3918612..87b11c46f45 100644
--- a/cmake/autogenerated_versions.txt
+++ b/cmake/autogenerated_versions.txt
@@ -2,11 +2,11 @@
# NOTE: has nothing common with DBMS_TCP_PROTOCOL_VERSION,
# only DBMS_TCP_PROTOCOL_VERSION should be incremented on protocol changes.
-SET(VERSION_REVISION 54469)
+SET(VERSION_REVISION 54470)
SET(VERSION_MAJOR 22)
-SET(VERSION_MINOR 12)
+SET(VERSION_MINOR 13)
SET(VERSION_PATCH 1)
-SET(VERSION_GITHASH 0d211ed19849fe44b0e43fdebe2c15d76d560a77)
-SET(VERSION_DESCRIBE v22.12.1.1-testing)
-SET(VERSION_STRING 22.12.1.1)
+SET(VERSION_GITHASH 688e488e930c83eefeac4f87c4cc029cc5b231e3)
+SET(VERSION_DESCRIBE v22.13.1.1-testing)
+SET(VERSION_STRING 22.13.1.1)
# end of autochange
diff --git a/cmake/darwin/toolchain-aarch64.cmake b/cmake/darwin/toolchain-aarch64.cmake
index 81398111495..569b02bb642 100644
--- a/cmake/darwin/toolchain-aarch64.cmake
+++ b/cmake/darwin/toolchain-aarch64.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_SYSTEM_NAME "Darwin")
set (CMAKE_SYSTEM_PROCESSOR "aarch64")
set (CMAKE_C_COMPILER_TARGET "aarch64-apple-darwin")
diff --git a/cmake/darwin/toolchain-x86_64.cmake b/cmake/darwin/toolchain-x86_64.cmake
index 0be81dfa753..c4527d2fc0d 100644
--- a/cmake/darwin/toolchain-x86_64.cmake
+++ b/cmake/darwin/toolchain-x86_64.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_SYSTEM_NAME "Darwin")
set (CMAKE_SYSTEM_PROCESSOR "x86_64")
set (CMAKE_C_COMPILER_TARGET "x86_64-apple-darwin")
diff --git a/cmake/freebsd/toolchain-aarch64.cmake b/cmake/freebsd/toolchain-aarch64.cmake
index eeec635cc06..8a8da00f3be 100644
--- a/cmake/freebsd/toolchain-aarch64.cmake
+++ b/cmake/freebsd/toolchain-aarch64.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_SYSTEM_NAME "FreeBSD")
set (CMAKE_SYSTEM_PROCESSOR "aarch64")
set (CMAKE_C_COMPILER_TARGET "aarch64-unknown-freebsd12")
diff --git a/cmake/freebsd/toolchain-ppc64le.cmake b/cmake/freebsd/toolchain-ppc64le.cmake
index d6007befb67..c3f6594204d 100644
--- a/cmake/freebsd/toolchain-ppc64le.cmake
+++ b/cmake/freebsd/toolchain-ppc64le.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_SYSTEM_NAME "FreeBSD")
set (CMAKE_SYSTEM_PROCESSOR "ppc64le")
set (CMAKE_C_COMPILER_TARGET "powerpc64le-unknown-freebsd13")
diff --git a/cmake/freebsd/toolchain-x86_64.cmake b/cmake/freebsd/toolchain-x86_64.cmake
index 80cbeba549f..460de6a7d39 100644
--- a/cmake/freebsd/toolchain-x86_64.cmake
+++ b/cmake/freebsd/toolchain-x86_64.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_SYSTEM_NAME "FreeBSD")
set (CMAKE_SYSTEM_PROCESSOR "x86_64")
set (CMAKE_C_COMPILER_TARGET "x86_64-pc-freebsd11")
diff --git a/cmake/linux/toolchain-aarch64.cmake b/cmake/linux/toolchain-aarch64.cmake
index 5db71aecf9a..2dedef8859f 100644
--- a/cmake/linux/toolchain-aarch64.cmake
+++ b/cmake/linux/toolchain-aarch64.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set (CMAKE_SYSTEM_NAME "Linux")
diff --git a/cmake/linux/toolchain-ppc64le.cmake b/cmake/linux/toolchain-ppc64le.cmake
index 345de208234..8eb2aab34e9 100644
--- a/cmake/linux/toolchain-ppc64le.cmake
+++ b/cmake/linux/toolchain-ppc64le.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set (CMAKE_SYSTEM_NAME "Linux")
diff --git a/cmake/linux/toolchain-riscv64.cmake b/cmake/linux/toolchain-riscv64.cmake
index 02c3d0c97fc..49a036c2972 100644
--- a/cmake/linux/toolchain-riscv64.cmake
+++ b/cmake/linux/toolchain-riscv64.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set (CMAKE_SYSTEM_NAME "Linux")
diff --git a/cmake/linux/toolchain-x86_64-musl.cmake b/cmake/linux/toolchain-x86_64-musl.cmake
index 3eb2077db2b..bc327e5ac25 100644
--- a/cmake/linux/toolchain-x86_64-musl.cmake
+++ b/cmake/linux/toolchain-x86_64-musl.cmake
@@ -1,3 +1,6 @@
+# See linux/toolchain-x86_64.cmake for details about multiple load of toolchain file.
+include_guard(GLOBAL)
+
set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set (CMAKE_SYSTEM_NAME "Linux")
diff --git a/cmake/linux/toolchain-x86_64.cmake b/cmake/linux/toolchain-x86_64.cmake
index bdcfcfa013a..e73d779284a 100644
--- a/cmake/linux/toolchain-x86_64.cmake
+++ b/cmake/linux/toolchain-x86_64.cmake
@@ -1,18 +1,15 @@
-if (_CLICKHOUSE_TOOLCHAIN_FILE_LOADED)
- # During first run of cmake the toolchain file will be loaded twice,
- # - /usr/share/cmake-3.23/Modules/CMakeDetermineSystem.cmake
- # - /bld/CMakeFiles/3.23.2/CMakeSystem.cmake
- #
- # But once you already have non-empty cmake cache it will be loaded only
- # once:
- # - /bld/CMakeFiles/3.23.2/CMakeSystem.cmake
- #
- # This has no harm except for double load of toolchain will add
- # --gcc-toolchain multiple times that will not allow ccache to reuse the
- # cache.
- return()
-endif()
-set (_CLICKHOUSE_TOOLCHAIN_FILE_LOADED ON)
+# During first run of cmake the toolchain file will be loaded twice,
+# - /usr/share/cmake-3.23/Modules/CMakeDetermineSystem.cmake
+# - /bld/CMakeFiles/3.23.2/CMakeSystem.cmake
+#
+# But once you already have non-empty cmake cache it will be loaded only
+# once:
+# - /bld/CMakeFiles/3.23.2/CMakeSystem.cmake
+#
+# This has no harm except for double load of toolchain will add
+# --gcc-toolchain multiple times that will not allow ccache to reuse the
+# cache.
+include_guard(GLOBAL)
set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
index 2e05b318b8f..6f80059498e 100644
--- a/contrib/CMakeLists.txt
+++ b/contrib/CMakeLists.txt
@@ -65,7 +65,7 @@ add_contrib (dragonbox-cmake dragonbox)
add_contrib (vectorscan-cmake vectorscan)
add_contrib (jemalloc-cmake jemalloc)
add_contrib (libcpuid-cmake libcpuid)
-add_contrib (libdivide)
+add_contrib (libdivide-cmake)
add_contrib (libmetrohash)
add_contrib (lz4-cmake lz4)
add_contrib (murmurhash)
diff --git a/contrib/corrosion-cmake/CMakeLists.txt b/contrib/corrosion-cmake/CMakeLists.txt
index ef810182a40..ea8f191564d 100644
--- a/contrib/corrosion-cmake/CMakeLists.txt
+++ b/contrib/corrosion-cmake/CMakeLists.txt
@@ -10,9 +10,6 @@ else()
endif()
option(ENABLE_RUST "Enable rust" ${DEFAULT_ENABLE_RUST})
-
-message(STATUS ${ENABLE_RUST})
-
if(NOT ENABLE_RUST)
message(STATUS "Not using rust")
return()
@@ -42,5 +39,7 @@ endif()
message(STATUS "Switched Rust target to ${Rust_CARGO_TARGET}")
+# FindRust.cmake
+list(APPEND CMAKE_MODULE_PATH "${ClickHouse_SOURCE_DIR}/contrib/corrosion/cmake")
# Define function corrosion_import_crate()
include ("${ClickHouse_SOURCE_DIR}/contrib/corrosion/cmake/Corrosion.cmake")
diff --git a/contrib/libdivide b/contrib/libdivide
new file mode 160000
index 00000000000..3bd34388573
--- /dev/null
+++ b/contrib/libdivide
@@ -0,0 +1 @@
+Subproject commit 3bd34388573681ce563348cdf04fe15d24770d04
diff --git a/contrib/libdivide-cmake/CMakeLists.txt b/contrib/libdivide-cmake/CMakeLists.txt
new file mode 100644
index 00000000000..3174808bc23
--- /dev/null
+++ b/contrib/libdivide-cmake/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(LIBDIVIDE_SOURCE_DIR "${ClickHouse_SOURCE_DIR}/contrib/libdivide")
+add_library (_libdivide INTERFACE)
+# for libdivide.h
+target_include_directories (_libdivide SYSTEM BEFORE INTERFACE ${LIBDIVIDE_SOURCE_DIR})
+# for libdivide-config.h
+target_include_directories (_libdivide SYSTEM BEFORE INTERFACE .)
+add_library (ch_contrib::libdivide ALIAS _libdivide)
diff --git a/contrib/libdivide-cmake/libdivide-config.h b/contrib/libdivide-cmake/libdivide-config.h
new file mode 100644
index 00000000000..8ef001fb97b
--- /dev/null
+++ b/contrib/libdivide-cmake/libdivide-config.h
@@ -0,0 +1,9 @@
+#if defined(__SSE2__)
+# define LIBDIVIDE_SSE2
+#elif defined(__AVX512F__) || defined(__AVX512BW__) || defined(__AVX512VL__)
+# define LIBDIVIDE_AVX512
+#elif defined(__AVX2__)
+# define LIBDIVIDE_AVX2
+#elif defined(__aarch64__) && defined(__ARM_NEON)
+# define LIBDIVIDE_NEON
+#endif
diff --git a/contrib/libdivide/CMakeLists.txt b/contrib/libdivide/CMakeLists.txt
deleted file mode 100644
index 45cbc0a584b..00000000000
--- a/contrib/libdivide/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_library (_libdivide INTERFACE)
-target_include_directories (_libdivide SYSTEM BEFORE INTERFACE .)
-add_library (ch_contrib::libdivide ALIAS _libdivide)
diff --git a/contrib/libdivide/LICENSE.txt b/contrib/libdivide/LICENSE.txt
deleted file mode 100644
index d056b847bba..00000000000
--- a/contrib/libdivide/LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
- libdivide
- Copyright (C) 2010 ridiculous_fish
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- libdivide@ridiculousfish.com
diff --git a/contrib/libdivide/README.txt b/contrib/libdivide/README.txt
deleted file mode 100644
index 2d17a68e4c2..00000000000
--- a/contrib/libdivide/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-https://github.com/ridiculousfish/libdivide
-http://libdivide.com/
diff --git a/contrib/libdivide/libdivide.h b/contrib/libdivide/libdivide.h
deleted file mode 100644
index 33d210310a1..00000000000
--- a/contrib/libdivide/libdivide.h
+++ /dev/null
@@ -1,2503 +0,0 @@
-// libdivide.h - Optimized integer division
-// https://libdivide.com
-//
-// Copyright (C) 2010 - 2019 ridiculous_fish,
-// Copyright (C) 2016 - 2019 Kim Walisch,
-//
-// libdivide is dual-licensed under the Boost or zlib licenses.
-// You may use libdivide under the terms of either of these.
-// See LICENSE.txt for more details.
-
-#ifndef LIBDIVIDE_H
-#define LIBDIVIDE_H
-
-#define LIBDIVIDE_VERSION "3.0"
-#define LIBDIVIDE_VERSION_MAJOR 3
-#define LIBDIVIDE_VERSION_MINOR 0
-
-#include
-
-#if defined(__cplusplus)
-#include
-#include
-#include
-#else
-#include
-#include
-#endif
-
-#if defined(LIBDIVIDE_SSE2)
-#include
-#endif
-#if defined(LIBDIVIDE_AVX2) || defined(LIBDIVIDE_AVX512)
-#include
-#endif
-#if defined(LIBDIVIDE_NEON)
-#include
-#endif
-
-#if defined(_MSC_VER)
-#include
-// disable warning C4146: unary minus operator applied
-// to unsigned type, result still unsigned
-#pragma warning(disable : 4146)
-#define LIBDIVIDE_VC
-#endif
-
-#if !defined(__has_builtin)
-#define __has_builtin(x) 0
-#endif
-
-#if defined(__SIZEOF_INT128__)
-#define HAS_INT128_T
-// clang-cl on Windows does not yet support 128-bit division
-#if !(defined(__clang__) && defined(LIBDIVIDE_VC))
-#define HAS_INT128_DIV
-#endif
-#endif
-
-#if defined(__x86_64__) || defined(_M_X64)
-#define LIBDIVIDE_X86_64
-#endif
-
-#if defined(__i386__)
-#define LIBDIVIDE_i386
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
-#define LIBDIVIDE_GCC_STYLE_ASM
-#endif
-
-#if defined(__cplusplus) || defined(LIBDIVIDE_VC)
-#define LIBDIVIDE_FUNCTION __FUNCTION__
-#else
-#define LIBDIVIDE_FUNCTION __func__
-#endif
-
-#define LIBDIVIDE_ERROR(msg) \
- do { \
- fprintf(stderr, "libdivide.h:%d: %s(): Error: %s\n", __LINE__, LIBDIVIDE_FUNCTION, msg); \
- abort(); \
- } while (0)
-
-#if defined(LIBDIVIDE_ASSERTIONS_ON)
-#define LIBDIVIDE_ASSERT(x) \
- do { \
- if (!(x)) { \
- fprintf(stderr, "libdivide.h:%d: %s(): Assertion failed: %s\n", __LINE__, \
- LIBDIVIDE_FUNCTION, #x); \
- abort(); \
- } \
- } while (0)
-#else
-#define LIBDIVIDE_ASSERT(x)
-#endif
-
-#ifdef __cplusplus
-namespace libdivide {
-#endif
-
-// pack divider structs to prevent compilers from padding.
-// This reduces memory usage by up to 43% when using a large
-// array of libdivide dividers and improves performance
-// by up to 10% because of reduced memory bandwidth.
-#pragma pack(push, 1)
-
-struct libdivide_u32_t {
- uint32_t magic;
- uint8_t more;
-};
-
-struct libdivide_s32_t {
- int32_t magic;
- uint8_t more;
-};
-
-struct libdivide_u64_t {
- uint64_t magic;
- uint8_t more;
-};
-
-struct libdivide_s64_t {
- int64_t magic;
- uint8_t more;
-};
-
-struct libdivide_u32_branchfree_t {
- uint32_t magic;
- uint8_t more;
-};
-
-struct libdivide_s32_branchfree_t {
- int32_t magic;
- uint8_t more;
-};
-
-struct libdivide_u64_branchfree_t {
- uint64_t magic;
- uint8_t more;
-};
-
-struct libdivide_s64_branchfree_t {
- int64_t magic;
- uint8_t more;
-};
-
-#pragma pack(pop)
-
-// Explanation of the "more" field:
-//
-// * Bits 0-5 is the shift value (for shift path or mult path).
-// * Bit 6 is the add indicator for mult path.
-// * Bit 7 is set if the divisor is negative. We use bit 7 as the negative
-// divisor indicator so that we can efficiently use sign extension to
-// create a bitmask with all bits set to 1 (if the divisor is negative)
-// or 0 (if the divisor is positive).
-//
-// u32: [0-4] shift value
-// [5] ignored
-// [6] add indicator
-// magic number of 0 indicates shift path
-//
-// s32: [0-4] shift value
-// [5] ignored
-// [6] add indicator
-// [7] indicates negative divisor
-// magic number of 0 indicates shift path
-//
-// u64: [0-5] shift value
-// [6] add indicator
-// magic number of 0 indicates shift path
-//
-// s64: [0-5] shift value
-// [6] add indicator
-// [7] indicates negative divisor
-// magic number of 0 indicates shift path
-//
-// In s32 and s64 branchfree modes, the magic number is negated according to
-// whether the divisor is negated. In branchfree strategy, it is not negated.
-
-enum {
- LIBDIVIDE_32_SHIFT_MASK = 0x1F,
- LIBDIVIDE_64_SHIFT_MASK = 0x3F,
- LIBDIVIDE_ADD_MARKER = 0x40,
- LIBDIVIDE_NEGATIVE_DIVISOR = 0x80
-};
-
-static inline struct libdivide_s32_t libdivide_s32_gen(int32_t d);
-static inline struct libdivide_u32_t libdivide_u32_gen(uint32_t d);
-static inline struct libdivide_s64_t libdivide_s64_gen(int64_t d);
-static inline struct libdivide_u64_t libdivide_u64_gen(uint64_t d);
-
-static inline struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d);
-static inline struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d);
-static inline struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d);
-static inline struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d);
-
-static inline int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom);
-static inline uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom);
-static inline int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom);
-static inline uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom);
-
-static inline int32_t libdivide_s32_branchfree_do(
- int32_t numer, const struct libdivide_s32_branchfree_t *denom);
-static inline uint32_t libdivide_u32_branchfree_do(
- uint32_t numer, const struct libdivide_u32_branchfree_t *denom);
-static inline int64_t libdivide_s64_branchfree_do(
- int64_t numer, const struct libdivide_s64_branchfree_t *denom);
-static inline uint64_t libdivide_u64_branchfree_do(
- uint64_t numer, const struct libdivide_u64_branchfree_t *denom);
-
-static inline int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom);
-static inline uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom);
-static inline int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom);
-static inline uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom);
-
-static inline int32_t libdivide_s32_branchfree_recover(
- const struct libdivide_s32_branchfree_t *denom);
-static inline uint32_t libdivide_u32_branchfree_recover(
- const struct libdivide_u32_branchfree_t *denom);
-static inline int64_t libdivide_s64_branchfree_recover(
- const struct libdivide_s64_branchfree_t *denom);
-static inline uint64_t libdivide_u64_branchfree_recover(
- const struct libdivide_u64_branchfree_t *denom);
-
-//////// Internal Utility Functions
-
-static inline uint32_t libdivide_mullhi_u32(uint32_t x, uint32_t y) {
- uint64_t xl = x, yl = y;
- uint64_t rl = xl * yl;
- return (uint32_t)(rl >> 32);
-}
-
-static inline int32_t libdivide_mullhi_s32(int32_t x, int32_t y) {
- int64_t xl = x, yl = y;
- int64_t rl = xl * yl;
- // needs to be arithmetic shift
- return (int32_t)(rl >> 32);
-}
-
-static inline uint64_t libdivide_mullhi_u64(uint64_t x, uint64_t y) {
-#if defined(LIBDIVIDE_VC) && defined(LIBDIVIDE_X86_64)
- return __umulh(x, y);
-#elif defined(HAS_INT128_T)
- __uint128_t xl = x, yl = y;
- __uint128_t rl = xl * yl;
- return (uint64_t)(rl >> 64);
-#else
- // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64)
- uint32_t mask = 0xFFFFFFFF;
- uint32_t x0 = (uint32_t)(x & mask);
- uint32_t x1 = (uint32_t)(x >> 32);
- uint32_t y0 = (uint32_t)(y & mask);
- uint32_t y1 = (uint32_t)(y >> 32);
- uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0);
- uint64_t x0y1 = x0 * (uint64_t)y1;
- uint64_t x1y0 = x1 * (uint64_t)y0;
- uint64_t x1y1 = x1 * (uint64_t)y1;
- uint64_t temp = x1y0 + x0y0_hi;
- uint64_t temp_lo = temp & mask;
- uint64_t temp_hi = temp >> 32;
-
- return x1y1 + temp_hi + ((temp_lo + x0y1) >> 32);
-#endif
-}
-
-static inline int64_t libdivide_mullhi_s64(int64_t x, int64_t y) {
-#if defined(LIBDIVIDE_VC) && defined(LIBDIVIDE_X86_64)
- return __mulh(x, y);
-#elif defined(HAS_INT128_T)
- __int128_t xl = x, yl = y;
- __int128_t rl = xl * yl;
- return (int64_t)(rl >> 64);
-#else
- // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64)
- uint32_t mask = 0xFFFFFFFF;
- uint32_t x0 = (uint32_t)(x & mask);
- uint32_t y0 = (uint32_t)(y & mask);
- int32_t x1 = (int32_t)(x >> 32);
- int32_t y1 = (int32_t)(y >> 32);
- uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0);
- int64_t t = x1 * (int64_t)y0 + x0y0_hi;
- int64_t w1 = x0 * (int64_t)y1 + (t & mask);
-
- return x1 * (int64_t)y1 + (t >> 32) + (w1 >> 32);
-#endif
-}
-
-static inline int32_t libdivide_count_leading_zeros32(uint32_t val) {
-#if defined(__GNUC__) || __has_builtin(__builtin_clz)
- // Fast way to count leading zeros
- return __builtin_clz(val);
-#elif defined(LIBDIVIDE_VC)
- unsigned long result;
- if (_BitScanReverse(&result, val)) {
- return 31 - result;
- }
- return 0;
-#else
- if (val == 0) return 32;
- int32_t result = 8;
- uint32_t hi = 0xFFU << 24;
- while ((val & hi) == 0) {
- hi >>= 8;
- result += 8;
- }
- while (val & hi) {
- result -= 1;
- hi <<= 1;
- }
- return result;
-#endif
-}
-
-static inline int32_t libdivide_count_leading_zeros64(uint64_t val) {
-#if defined(__GNUC__) || __has_builtin(__builtin_clzll)
- // Fast way to count leading zeros
- return __builtin_clzll(val);
-#elif defined(LIBDIVIDE_VC) && defined(_WIN64)
- unsigned long result;
- if (_BitScanReverse64(&result, val)) {
- return 63 - result;
- }
- return 0;
-#else
- uint32_t hi = val >> 32;
- uint32_t lo = val & 0xFFFFFFFF;
- if (hi != 0) return libdivide_count_leading_zeros32(hi);
- return 32 + libdivide_count_leading_zeros32(lo);
-#endif
-}
-
-// libdivide_64_div_32_to_32: divides a 64-bit uint {u1, u0} by a 32-bit
-// uint {v}. The result must fit in 32 bits.
-// Returns the quotient directly and the remainder in *r
-static inline uint32_t libdivide_64_div_32_to_32(
- uint32_t u1, uint32_t u0, uint32_t v, uint32_t *r) {
-#if (defined(LIBDIVIDE_i386) || defined(LIBDIVIDE_X86_64)) && defined(LIBDIVIDE_GCC_STYLE_ASM)
- uint32_t result;
- __asm__("divl %[v]" : "=a"(result), "=d"(*r) : [v] "r"(v), "a"(u0), "d"(u1));
- return result;
-#else
- uint64_t n = ((uint64_t)u1 << 32) | u0;
- uint32_t result = (uint32_t)(n / v);
- *r = (uint32_t)(n - result * (uint64_t)v);
- return result;
-#endif
-}
-
-// libdivide_128_div_64_to_64: divides a 128-bit uint {u1, u0} by a 64-bit
-// uint {v}. The result must fit in 64 bits.
-// Returns the quotient directly and the remainder in *r
-static uint64_t libdivide_128_div_64_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t *r) {
- // N.B. resist the temptation to use __uint128_t here.
- // In LLVM compiler-rt, it performs a 128/128 -> 128 division which is many times slower than
- // necessary. In gcc it's better but still slower than the divlu implementation, perhaps because
- // it's not inlined.
-#if defined(LIBDIVIDE_X86_64) && defined(LIBDIVIDE_GCC_STYLE_ASM)
- uint64_t result;
- __asm__("divq %[v]" : "=a"(result), "=d"(*r) : [v] "r"(v), "a"(u0), "d"(u1));
- return result;
-#else
- // Code taken from Hacker's Delight:
- // http://www.hackersdelight.org/HDcode/divlu.c.
- // License permits inclusion here per:
- // http://www.hackersdelight.org/permissions.htm
-
- const uint64_t b = (1ULL << 32); // Number base (32 bits)
- uint64_t un1, un0; // Norm. dividend LSD's
- uint64_t vn1, vn0; // Norm. divisor digits
- uint64_t q1, q0; // Quotient digits
- uint64_t un64, un21, un10; // Dividend digit pairs
- uint64_t rhat; // A remainder
- int32_t s; // Shift amount for norm
-
- // If overflow, set rem. to an impossible value,
- // and return the largest possible quotient
- if (u1 >= v) {
- *r = (uint64_t)-1;
- return (uint64_t)-1;
- }
-
- // count leading zeros
- s = libdivide_count_leading_zeros64(v);
- if (s > 0) {
- // Normalize divisor
- v = v << s;
- un64 = (u1 << s) | (u0 >> (64 - s));
- un10 = u0 << s; // Shift dividend left
- } else {
- // Avoid undefined behavior of (u0 >> 64).
- // The behavior is undefined if the right operand is
- // negative, or greater than or equal to the length
- // in bits of the promoted left operand.
- un64 = u1;
- un10 = u0;
- }
-
- // Break divisor up into two 32-bit digits
- vn1 = v >> 32;
- vn0 = v & 0xFFFFFFFF;
-
- // Break right half of dividend into two digits
- un1 = un10 >> 32;
- un0 = un10 & 0xFFFFFFFF;
-
- // Compute the first quotient digit, q1
- q1 = un64 / vn1;
- rhat = un64 - q1 * vn1;
-
- while (q1 >= b || q1 * vn0 > b * rhat + un1) {
- q1 = q1 - 1;
- rhat = rhat + vn1;
- if (rhat >= b) break;
- }
-
- // Multiply and subtract
- un21 = un64 * b + un1 - q1 * v;
-
- // Compute the second quotient digit
- q0 = un21 / vn1;
- rhat = un21 - q0 * vn1;
-
- while (q0 >= b || q0 * vn0 > b * rhat + un0) {
- q0 = q0 - 1;
- rhat = rhat + vn1;
- if (rhat >= b) break;
- }
-
- *r = (un21 * b + un0 - q0 * v) >> s;
- return q1 * b + q0;
-#endif
-}
-
-// Bitshift a u128 in place, left (signed_shift > 0) or right (signed_shift < 0)
-static inline void libdivide_u128_shift(uint64_t *u1, uint64_t *u0, int32_t signed_shift) {
- if (signed_shift > 0) {
- uint32_t shift = signed_shift;
- *u1 <<= shift;
- *u1 |= *u0 >> (64 - shift);
- *u0 <<= shift;
- } else if (signed_shift < 0) {
- uint32_t shift = -signed_shift;
- *u0 >>= shift;
- *u0 |= *u1 << (64 - shift);
- *u1 >>= shift;
- }
-}
-
-// Computes a 128 / 128 -> 64 bit division, with a 128 bit remainder.
-static uint64_t libdivide_128_div_128_to_64(
- uint64_t u_hi, uint64_t u_lo, uint64_t v_hi, uint64_t v_lo, uint64_t *r_hi, uint64_t *r_lo) {
-#if defined(HAS_INT128_T) && defined(HAS_INT128_DIV)
- __uint128_t ufull = u_hi;
- __uint128_t vfull = v_hi;
- ufull = (ufull << 64) | u_lo;
- vfull = (vfull << 64) | v_lo;
- uint64_t res = (uint64_t)(ufull / vfull);
- __uint128_t remainder = ufull - (vfull * res);
- *r_lo = (uint64_t)remainder;
- *r_hi = (uint64_t)(remainder >> 64);
- return res;
-#else
- // Adapted from "Unsigned Doubleword Division" in Hacker's Delight
- // We want to compute u / v
- typedef struct {
- uint64_t hi;
- uint64_t lo;
- } u128_t;
- u128_t u = {u_hi, u_lo};
- u128_t v = {v_hi, v_lo};
-
- if (v.hi == 0) {
- // divisor v is a 64 bit value, so we just need one 128/64 division
- // Note that we are simpler than Hacker's Delight here, because we know
- // the quotient fits in 64 bits whereas Hacker's Delight demands a full
- // 128 bit quotient
- *r_hi = 0;
- return libdivide_128_div_64_to_64(u.hi, u.lo, v.lo, r_lo);
- }
- // Here v >= 2**64
- // We know that v.hi != 0, so count leading zeros is OK
- // We have 0 <= n <= 63
- uint32_t n = libdivide_count_leading_zeros64(v.hi);
-
- // Normalize the divisor so its MSB is 1
- u128_t v1t = v;
- libdivide_u128_shift(&v1t.hi, &v1t.lo, n);
- uint64_t v1 = v1t.hi; // i.e. v1 = v1t >> 64
-
- // To ensure no overflow
- u128_t u1 = u;
- libdivide_u128_shift(&u1.hi, &u1.lo, -1);
-
- // Get quotient from divide unsigned insn.
- uint64_t rem_ignored;
- uint64_t q1 = libdivide_128_div_64_to_64(u1.hi, u1.lo, v1, &rem_ignored);
-
- // Undo normalization and division of u by 2.
- u128_t q0 = {0, q1};
- libdivide_u128_shift(&q0.hi, &q0.lo, n);
- libdivide_u128_shift(&q0.hi, &q0.lo, -63);
-
- // Make q0 correct or too small by 1
- // Equivalent to `if (q0 != 0) q0 = q0 - 1;`
- if (q0.hi != 0 || q0.lo != 0) {
- q0.hi -= (q0.lo == 0); // borrow
- q0.lo -= 1;
- }
-
- // Now q0 is correct.
- // Compute q0 * v as q0v
- // = (q0.hi << 64 + q0.lo) * (v.hi << 64 + v.lo)
- // = (q0.hi * v.hi << 128) + (q0.hi * v.lo << 64) +
- // (q0.lo * v.hi << 64) + q0.lo * v.lo)
- // Each term is 128 bit
- // High half of full product (upper 128 bits!) are dropped
- u128_t q0v = {0, 0};
- q0v.hi = q0.hi * v.lo + q0.lo * v.hi + libdivide_mullhi_u64(q0.lo, v.lo);
- q0v.lo = q0.lo * v.lo;
-
- // Compute u - q0v as u_q0v
- // This is the remainder
- u128_t u_q0v = u;
- u_q0v.hi -= q0v.hi + (u.lo < q0v.lo); // second term is borrow
- u_q0v.lo -= q0v.lo;
-
- // Check if u_q0v >= v
- // This checks if our remainder is larger than the divisor
- if ((u_q0v.hi > v.hi) || (u_q0v.hi == v.hi && u_q0v.lo >= v.lo)) {
- // Increment q0
- q0.lo += 1;
- q0.hi += (q0.lo == 0); // carry
-
- // Subtract v from remainder
- u_q0v.hi -= v.hi + (u_q0v.lo < v.lo);
- u_q0v.lo -= v.lo;
- }
-
- *r_hi = u_q0v.hi;
- *r_lo = u_q0v.lo;
-
- LIBDIVIDE_ASSERT(q0.hi == 0);
- return q0.lo;
-#endif
-}
-
-////////// UINT32
-
-static inline struct libdivide_u32_t libdivide_internal_u32_gen(uint32_t d, int branchfree) {
- if (d == 0) {
- LIBDIVIDE_ERROR("divider must be != 0");
- }
-
- struct libdivide_u32_t result;
- uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(d);
-
- // Power of 2
- if ((d & (d - 1)) == 0) {
- // We need to subtract 1 from the shift value in case of an unsigned
- // branchfree divider because there is a hardcoded right shift by 1
- // in its division algorithm. Because of this we also need to add back
- // 1 in its recovery algorithm.
- result.magic = 0;
- result.more = (uint8_t)(floor_log_2_d - (branchfree != 0));
- } else {
- uint8_t more;
- uint32_t rem, proposed_m;
- proposed_m = libdivide_64_div_32_to_32(1U << floor_log_2_d, 0, d, &rem);
-
- LIBDIVIDE_ASSERT(rem > 0 && rem < d);
- const uint32_t e = d - rem;
-
- // This power works if e < 2**floor_log_2_d.
- if (!branchfree && (e < (1U << floor_log_2_d))) {
- // This power works
- more = floor_log_2_d;
- } else {
- // We have to use the general 33-bit algorithm. We need to compute
- // (2**power) / d. However, we already have (2**(power-1))/d and
- // its remainder. By doubling both, and then correcting the
- // remainder, we can compute the larger division.
- // don't care about overflow here - in fact, we expect it
- proposed_m += proposed_m;
- const uint32_t twice_rem = rem + rem;
- if (twice_rem >= d || twice_rem < rem) proposed_m += 1;
- more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
- }
- result.magic = 1 + proposed_m;
- result.more = more;
- // result.more's shift should in general be ceil_log_2_d. But if we
- // used the smaller power, we subtract one from the shift because we're
- // using the smaller power. If we're using the larger power, we
- // subtract one from the shift because it's taken care of by the add
- // indicator. So floor_log_2_d happens to be correct in both cases.
- }
- return result;
-}
-
-struct libdivide_u32_t libdivide_u32_gen(uint32_t d) {
- return libdivide_internal_u32_gen(d, 0);
-}
-
-struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d) {
- if (d == 1) {
- LIBDIVIDE_ERROR("branchfree divider must be != 1");
- }
- struct libdivide_u32_t tmp = libdivide_internal_u32_gen(d, 1);
- struct libdivide_u32_branchfree_t ret = {
- tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_32_SHIFT_MASK)};
- return ret;
-}
-
-uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return numer >> more;
- } else {
- uint32_t q = libdivide_mullhi_u32(denom->magic, numer);
- if (more & LIBDIVIDE_ADD_MARKER) {
- uint32_t t = ((numer - q) >> 1) + q;
- return t >> (more & LIBDIVIDE_32_SHIFT_MASK);
- } else {
- // All upper bits are 0,
- // don't need to mask them off.
- return q >> more;
- }
- }
-}
-
-uint32_t libdivide_u32_branchfree_do(
- uint32_t numer, const struct libdivide_u32_branchfree_t *denom) {
- uint32_t q = libdivide_mullhi_u32(denom->magic, numer);
- uint32_t t = ((numer - q) >> 1) + q;
- return t >> denom->more;
-}
-
-uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
-
- if (!denom->magic) {
- return 1U << shift;
- } else if (!(more & LIBDIVIDE_ADD_MARKER)) {
- // We compute q = n/d = n*m / 2^(32 + shift)
- // Therefore we have d = 2^(32 + shift) / m
- // We need to ceil it.
- // We know d is not a power of 2, so m is not a power of 2,
- // so we can just add 1 to the floor
- uint32_t hi_dividend = 1U << shift;
- uint32_t rem_ignored;
- return 1 + libdivide_64_div_32_to_32(hi_dividend, 0, denom->magic, &rem_ignored);
- } else {
- // Here we wish to compute d = 2^(32+shift+1)/(m+2^32).
- // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now
- // Also note that shift may be as high as 31, so shift + 1 will
- // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and
- // then double the quotient and remainder.
- uint64_t half_n = 1ULL << (32 + shift);
- uint64_t d = (1ULL << 32) | denom->magic;
- // Note that the quotient is guaranteed <= 32 bits, but the remainder
- // may need 33!
- uint32_t half_q = (uint32_t)(half_n / d);
- uint64_t rem = half_n % d;
- // We computed 2^(32+shift)/(m+2^32)
- // Need to double it, and then add 1 to the quotient if doubling th
- // remainder would increase the quotient.
- // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits
- uint32_t full_q = half_q + half_q + ((rem << 1) >= d);
-
- // We rounded down in gen (hence +1)
- return full_q + 1;
- }
-}
-
-uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
-
- if (!denom->magic) {
- return 1U << (shift + 1);
- } else {
- // Here we wish to compute d = 2^(32+shift+1)/(m+2^32).
- // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now
- // Also note that shift may be as high as 31, so shift + 1 will
- // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and
- // then double the quotient and remainder.
- uint64_t half_n = 1ULL << (32 + shift);
- uint64_t d = (1ULL << 32) | denom->magic;
- // Note that the quotient is guaranteed <= 32 bits, but the remainder
- // may need 33!
- uint32_t half_q = (uint32_t)(half_n / d);
- uint64_t rem = half_n % d;
- // We computed 2^(32+shift)/(m+2^32)
- // Need to double it, and then add 1 to the quotient if doubling th
- // remainder would increase the quotient.
- // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits
- uint32_t full_q = half_q + half_q + ((rem << 1) >= d);
-
- // We rounded down in gen (hence +1)
- return full_q + 1;
- }
-}
-
-/////////// UINT64
-
-static inline struct libdivide_u64_t libdivide_internal_u64_gen(uint64_t d, int branchfree) {
- if (d == 0) {
- LIBDIVIDE_ERROR("divider must be != 0");
- }
-
- struct libdivide_u64_t result;
- uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(d);
-
- // Power of 2
- if ((d & (d - 1)) == 0) {
- // We need to subtract 1 from the shift value in case of an unsigned
- // branchfree divider because there is a hardcoded right shift by 1
- // in its division algorithm. Because of this we also need to add back
- // 1 in its recovery algorithm.
- result.magic = 0;
- result.more = (uint8_t)(floor_log_2_d - (branchfree != 0));
- } else {
- uint64_t proposed_m, rem;
- uint8_t more;
- // (1 << (64 + floor_log_2_d)) / d
- proposed_m = libdivide_128_div_64_to_64(1ULL << floor_log_2_d, 0, d, &rem);
-
- LIBDIVIDE_ASSERT(rem > 0 && rem < d);
- const uint64_t e = d - rem;
-
- // This power works if e < 2**floor_log_2_d.
- if (!branchfree && e < (1ULL << floor_log_2_d)) {
- // This power works
- more = floor_log_2_d;
- } else {
- // We have to use the general 65-bit algorithm. We need to compute
- // (2**power) / d. However, we already have (2**(power-1))/d and
- // its remainder. By doubling both, and then correcting the
- // remainder, we can compute the larger division.
- // don't care about overflow here - in fact, we expect it
- proposed_m += proposed_m;
- const uint64_t twice_rem = rem + rem;
- if (twice_rem >= d || twice_rem < rem) proposed_m += 1;
- more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
- }
- result.magic = 1 + proposed_m;
- result.more = more;
- // result.more's shift should in general be ceil_log_2_d. But if we
- // used the smaller power, we subtract one from the shift because we're
- // using the smaller power. If we're using the larger power, we
- // subtract one from the shift because it's taken care of by the add
- // indicator. So floor_log_2_d happens to be correct in both cases,
- // which is why we do it outside of the if statement.
- }
- return result;
-}
-
-struct libdivide_u64_t libdivide_u64_gen(uint64_t d) {
- return libdivide_internal_u64_gen(d, 0);
-}
-
-struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d) {
- if (d == 1) {
- LIBDIVIDE_ERROR("branchfree divider must be != 1");
- }
- struct libdivide_u64_t tmp = libdivide_internal_u64_gen(d, 1);
- struct libdivide_u64_branchfree_t ret = {
- tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_64_SHIFT_MASK)};
- return ret;
-}
-
-uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return numer >> more;
- } else {
- uint64_t q = libdivide_mullhi_u64(denom->magic, numer);
- if (more & LIBDIVIDE_ADD_MARKER) {
- uint64_t t = ((numer - q) >> 1) + q;
- return t >> (more & LIBDIVIDE_64_SHIFT_MASK);
- } else {
- // All upper bits are 0,
- // don't need to mask them off.
- return q >> more;
- }
- }
-}
-
-uint64_t libdivide_u64_branchfree_do(
- uint64_t numer, const struct libdivide_u64_branchfree_t *denom) {
- uint64_t q = libdivide_mullhi_u64(denom->magic, numer);
- uint64_t t = ((numer - q) >> 1) + q;
- return t >> denom->more;
-}
-
-uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
-
- if (!denom->magic) {
- return 1ULL << shift;
- } else if (!(more & LIBDIVIDE_ADD_MARKER)) {
- // We compute q = n/d = n*m / 2^(64 + shift)
- // Therefore we have d = 2^(64 + shift) / m
- // We need to ceil it.
- // We know d is not a power of 2, so m is not a power of 2,
- // so we can just add 1 to the floor
- uint64_t hi_dividend = 1ULL << shift;
- uint64_t rem_ignored;
- return 1 + libdivide_128_div_64_to_64(hi_dividend, 0, denom->magic, &rem_ignored);
- } else {
- // Here we wish to compute d = 2^(64+shift+1)/(m+2^64).
- // Notice (m + 2^64) is a 65 bit number. This gets hairy. See
- // libdivide_u32_recover for more on what we do here.
- // TODO: do something better than 128 bit math
-
- // Full n is a (potentially) 129 bit value
- // half_n is a 128 bit value
- // Compute the hi half of half_n. Low half is 0.
- uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0;
- // d is a 65 bit value. The high bit is always set to 1.
- const uint64_t d_hi = 1, d_lo = denom->magic;
- // Note that the quotient is guaranteed <= 64 bits,
- // but the remainder may need 65!
- uint64_t r_hi, r_lo;
- uint64_t half_q =
- libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo);
- // We computed 2^(64+shift)/(m+2^64)
- // Double the remainder ('dr') and check if that is larger than d
- // Note that d is a 65 bit value, so r1 is small and so r1 + r1
- // cannot overflow
- uint64_t dr_lo = r_lo + r_lo;
- uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry
- int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo);
- uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0);
- return full_q + 1;
- }
-}
-
-uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
-
- if (!denom->magic) {
- return 1ULL << (shift + 1);
- } else {
- // Here we wish to compute d = 2^(64+shift+1)/(m+2^64).
- // Notice (m + 2^64) is a 65 bit number. This gets hairy. See
- // libdivide_u32_recover for more on what we do here.
- // TODO: do something better than 128 bit math
-
- // Full n is a (potentially) 129 bit value
- // half_n is a 128 bit value
- // Compute the hi half of half_n. Low half is 0.
- uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0;
- // d is a 65 bit value. The high bit is always set to 1.
- const uint64_t d_hi = 1, d_lo = denom->magic;
- // Note that the quotient is guaranteed <= 64 bits,
- // but the remainder may need 65!
- uint64_t r_hi, r_lo;
- uint64_t half_q =
- libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo);
- // We computed 2^(64+shift)/(m+2^64)
- // Double the remainder ('dr') and check if that is larger than d
- // Note that d is a 65 bit value, so r1 is small and so r1 + r1
- // cannot overflow
- uint64_t dr_lo = r_lo + r_lo;
- uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry
- int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo);
- uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0);
- return full_q + 1;
- }
-}
-
-/////////// SINT32
-
-static inline struct libdivide_s32_t libdivide_internal_s32_gen(int32_t d, int branchfree) {
- if (d == 0) {
- LIBDIVIDE_ERROR("divider must be != 0");
- }
-
- struct libdivide_s32_t result;
-
- // If d is a power of 2, or negative a power of 2, we have to use a shift.
- // This is especially important because the magic algorithm fails for -1.
- // To check if d is a power of 2 or its inverse, it suffices to check
- // whether its absolute value has exactly one bit set. This works even for
- // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set
- // and is a power of 2.
- uint32_t ud = (uint32_t)d;
- uint32_t absD = (d < 0) ? -ud : ud;
- uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(absD);
- // check if exactly one bit is set,
- // don't care if absD is 0 since that's divide by zero
- if ((absD & (absD - 1)) == 0) {
- // Branchfree and normal paths are exactly the same
- result.magic = 0;
- result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0);
- } else {
- LIBDIVIDE_ASSERT(floor_log_2_d >= 1);
-
- uint8_t more;
- // the dividend here is 2**(floor_log_2_d + 31), so the low 32 bit word
- // is 0 and the high word is floor_log_2_d - 1
- uint32_t rem, proposed_m;
- proposed_m = libdivide_64_div_32_to_32(1U << (floor_log_2_d - 1), 0, absD, &rem);
- const uint32_t e = absD - rem;
-
- // We are going to start with a power of floor_log_2_d - 1.
- // This works if works if e < 2**floor_log_2_d.
- if (!branchfree && e < (1U << floor_log_2_d)) {
- // This power works
- more = floor_log_2_d - 1;
- } else {
- // We need to go one higher. This should not make proposed_m
- // overflow, but it will make it negative when interpreted as an
- // int32_t.
- proposed_m += proposed_m;
- const uint32_t twice_rem = rem + rem;
- if (twice_rem >= absD || twice_rem < rem) proposed_m += 1;
- more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
- }
-
- proposed_m += 1;
- int32_t magic = (int32_t)proposed_m;
-
- // Mark if we are negative. Note we only negate the magic number in the
- // branchfull case.
- if (d < 0) {
- more |= LIBDIVIDE_NEGATIVE_DIVISOR;
- if (!branchfree) {
- magic = -magic;
- }
- }
-
- result.more = more;
- result.magic = magic;
- }
- return result;
-}
-
-struct libdivide_s32_t libdivide_s32_gen(int32_t d) {
- return libdivide_internal_s32_gen(d, 0);
-}
-
-struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d) {
- struct libdivide_s32_t tmp = libdivide_internal_s32_gen(d, 1);
- struct libdivide_s32_branchfree_t result = {tmp.magic, tmp.more};
- return result;
-}
-
-int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
-
- if (!denom->magic) {
- uint32_t sign = (int8_t)more >> 7;
- uint32_t mask = (1U << shift) - 1;
- uint32_t uq = numer + ((numer >> 31) & mask);
- int32_t q = (int32_t)uq;
- q >>= shift;
- q = (q ^ sign) - sign;
- return q;
- } else {
- uint32_t uq = (uint32_t)libdivide_mullhi_s32(denom->magic, numer);
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift and then sign extend
- int32_t sign = (int8_t)more >> 7;
- // q += (more < 0 ? -numer : numer)
- // cast required to avoid UB
- uq += ((uint32_t)numer ^ sign) - sign;
- }
- int32_t q = (int32_t)uq;
- q >>= shift;
- q += (q < 0);
- return q;
- }
-}
-
-int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- // must be arithmetic shift and then sign extend
- int32_t sign = (int8_t)more >> 7;
- int32_t magic = denom->magic;
- int32_t q = libdivide_mullhi_s32(magic, numer);
- q += numer;
-
- // If q is non-negative, we have nothing to do
- // If q is negative, we want to add either (2**shift)-1 if d is a power of
- // 2, or (2**shift) if it is not a power of 2
- uint32_t is_power_of_2 = (magic == 0);
- uint32_t q_sign = (uint32_t)(q >> 31);
- q += q_sign & ((1U << shift) - is_power_of_2);
-
- // Now arithmetic right shift
- q >>= shift;
- // Negate if needed
- q = (q ^ sign) - sign;
-
- return q;
-}
-
-int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- if (!denom->magic) {
- uint32_t absD = 1U << shift;
- if (more & LIBDIVIDE_NEGATIVE_DIVISOR) {
- absD = -absD;
- }
- return (int32_t)absD;
- } else {
- // Unsigned math is much easier
- // We negate the magic number only in the branchfull case, and we don't
- // know which case we're in. However we have enough information to
- // determine the correct sign of the magic number. The divisor was
- // negative if LIBDIVIDE_NEGATIVE_DIVISOR is set. If ADD_MARKER is set,
- // the magic number's sign is opposite that of the divisor.
- // We want to compute the positive magic number.
- int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR);
- int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER) ? denom->magic > 0 : denom->magic < 0;
-
- // Handle the power of 2 case (including branchfree)
- if (denom->magic == 0) {
- int32_t result = 1U << shift;
- return negative_divisor ? -result : result;
- }
-
- uint32_t d = (uint32_t)(magic_was_negated ? -denom->magic : denom->magic);
- uint64_t n = 1ULL << (32 + shift); // this shift cannot exceed 30
- uint32_t q = (uint32_t)(n / d);
- int32_t result = (int32_t)q;
- result += 1;
- return negative_divisor ? -result : result;
- }
-}
-
-int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom) {
- return libdivide_s32_recover((const struct libdivide_s32_t *)denom);
-}
-
-///////////// SINT64
-
-static inline struct libdivide_s64_t libdivide_internal_s64_gen(int64_t d, int branchfree) {
- if (d == 0) {
- LIBDIVIDE_ERROR("divider must be != 0");
- }
-
- struct libdivide_s64_t result;
-
- // If d is a power of 2, or negative a power of 2, we have to use a shift.
- // This is especially important because the magic algorithm fails for -1.
- // To check if d is a power of 2 or its inverse, it suffices to check
- // whether its absolute value has exactly one bit set. This works even for
- // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set
- // and is a power of 2.
- uint64_t ud = (uint64_t)d;
- uint64_t absD = (d < 0) ? -ud : ud;
- uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(absD);
- // check if exactly one bit is set,
- // don't care if absD is 0 since that's divide by zero
- if ((absD & (absD - 1)) == 0) {
- // Branchfree and non-branchfree cases are the same
- result.magic = 0;
- result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0);
- } else {
- // the dividend here is 2**(floor_log_2_d + 63), so the low 64 bit word
- // is 0 and the high word is floor_log_2_d - 1
- uint8_t more;
- uint64_t rem, proposed_m;
- proposed_m = libdivide_128_div_64_to_64(1ULL << (floor_log_2_d - 1), 0, absD, &rem);
- const uint64_t e = absD - rem;
-
- // We are going to start with a power of floor_log_2_d - 1.
- // This works if works if e < 2**floor_log_2_d.
- if (!branchfree && e < (1ULL << floor_log_2_d)) {
- // This power works
- more = floor_log_2_d - 1;
- } else {
- // We need to go one higher. This should not make proposed_m
- // overflow, but it will make it negative when interpreted as an
- // int32_t.
- proposed_m += proposed_m;
- const uint64_t twice_rem = rem + rem;
- if (twice_rem >= absD || twice_rem < rem) proposed_m += 1;
- // note that we only set the LIBDIVIDE_NEGATIVE_DIVISOR bit if we
- // also set ADD_MARKER this is an annoying optimization that
- // enables algorithm #4 to avoid the mask. However we always set it
- // in the branchfree case
- more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
- }
- proposed_m += 1;
- int64_t magic = (int64_t)proposed_m;
-
- // Mark if we are negative
- if (d < 0) {
- more |= LIBDIVIDE_NEGATIVE_DIVISOR;
- if (!branchfree) {
- magic = -magic;
- }
- }
-
- result.more = more;
- result.magic = magic;
- }
- return result;
-}
-
-struct libdivide_s64_t libdivide_s64_gen(int64_t d) {
- return libdivide_internal_s64_gen(d, 0);
-}
-
-struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d) {
- struct libdivide_s64_t tmp = libdivide_internal_s64_gen(d, 1);
- struct libdivide_s64_branchfree_t ret = {tmp.magic, tmp.more};
- return ret;
-}
-
-int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
-
- if (!denom->magic) { // shift path
- uint64_t mask = (1ULL << shift) - 1;
- uint64_t uq = numer + ((numer >> 63) & mask);
- int64_t q = (int64_t)uq;
- q >>= shift;
- // must be arithmetic shift and then sign-extend
- int64_t sign = (int8_t)more >> 7;
- q = (q ^ sign) - sign;
- return q;
- } else {
- uint64_t uq = (uint64_t)libdivide_mullhi_s64(denom->magic, numer);
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift and then sign extend
- int64_t sign = (int8_t)more >> 7;
- // q += (more < 0 ? -numer : numer)
- // cast required to avoid UB
- uq += ((uint64_t)numer ^ sign) - sign;
- }
- int64_t q = (int64_t)uq;
- q >>= shift;
- q += (q < 0);
- return q;
- }
-}
-
-int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- // must be arithmetic shift and then sign extend
- int64_t sign = (int8_t)more >> 7;
- int64_t magic = denom->magic;
- int64_t q = libdivide_mullhi_s64(magic, numer);
- q += numer;
-
- // If q is non-negative, we have nothing to do.
- // If q is negative, we want to add either (2**shift)-1 if d is a power of
- // 2, or (2**shift) if it is not a power of 2.
- uint64_t is_power_of_2 = (magic == 0);
- uint64_t q_sign = (uint64_t)(q >> 63);
- q += q_sign & ((1ULL << shift) - is_power_of_2);
-
- // Arithmetic right shift
- q >>= shift;
- // Negate if needed
- q = (q ^ sign) - sign;
-
- return q;
-}
-
-int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom) {
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- if (denom->magic == 0) { // shift path
- uint64_t absD = 1ULL << shift;
- if (more & LIBDIVIDE_NEGATIVE_DIVISOR) {
- absD = -absD;
- }
- return (int64_t)absD;
- } else {
- // Unsigned math is much easier
- int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR);
- int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER) ? denom->magic > 0 : denom->magic < 0;
-
- uint64_t d = (uint64_t)(magic_was_negated ? -denom->magic : denom->magic);
- uint64_t n_hi = 1ULL << shift, n_lo = 0;
- uint64_t rem_ignored;
- uint64_t q = libdivide_128_div_64_to_64(n_hi, n_lo, d, &rem_ignored);
- int64_t result = (int64_t)(q + 1);
- if (negative_divisor) {
- result = -result;
- }
- return result;
- }
-}
-
-int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom) {
- return libdivide_s64_recover((const struct libdivide_s64_t *)denom);
-}
-
-#if defined(LIBDIVIDE_NEON)
-
-static inline uint32x4_t libdivide_u32_do_vec128(
- uint32x4_t numers, const struct libdivide_u32_t *denom);
-static inline int32x4_t libdivide_s32_do_vec128(
- int32x4_t numers, const struct libdivide_s32_t *denom);
-static inline uint64x2_t libdivide_u64_do_vec128(
- uint64x2_t numers, const struct libdivide_u64_t *denom);
-static inline int64x2_t libdivide_s64_do_vec128(
- int64x2_t numers, const struct libdivide_s64_t *denom);
-
-static inline uint32x4_t libdivide_u32_branchfree_do_vec128(
- uint32x4_t numers, const struct libdivide_u32_branchfree_t *denom);
-static inline int32x4_t libdivide_s32_branchfree_do_vec128(
- int32x4_t numers, const struct libdivide_s32_branchfree_t *denom);
-static inline uint64x2_t libdivide_u64_branchfree_do_vec128(
- uint64x2_t numers, const struct libdivide_u64_branchfree_t *denom);
-static inline int64x2_t libdivide_s64_branchfree_do_vec128(
- int64x2_t numers, const struct libdivide_s64_branchfree_t *denom);
-
-//////// Internal Utility Functions
-
-// Logical right shift by runtime value.
-// NEON implements right shift as left shits by negative values.
-static inline uint32x4_t libdivide_u32_neon_srl(uint32x4_t v, uint8_t amt) {
- int32_t wamt = static_cast(amt);
- return vshlq_u32(v, vdupq_n_s32(-wamt));
-}
-
-static inline uint64x2_t libdivide_u64_neon_srl(uint64x2_t v, uint8_t amt) {
- int64_t wamt = static_cast(amt);
- return vshlq_u64(v, vdupq_n_s64(-wamt));
-}
-
-// Arithmetic right shift by runtime value.
-static inline int32x4_t libdivide_s32_neon_sra(int32x4_t v, uint8_t amt) {
- int32_t wamt = static_cast(amt);
- return vshlq_s32(v, vdupq_n_s32(-wamt));
-}
-
-static inline int64x2_t libdivide_s64_neon_sra(int64x2_t v, uint8_t amt) {
- int64_t wamt = static_cast(amt);
- return vshlq_s64(v, vdupq_n_s64(-wamt));
-}
-
-static inline int64x2_t libdivide_s64_signbits(int64x2_t v) { return vshrq_n_s64(v, 63); }
-
-static inline uint32x4_t libdivide_mullhi_u32_vec128(uint32x4_t a, uint32_t b) {
- // Desire is [x0, x1, x2, x3]
- uint32x4_t w1 = vreinterpretq_u32_u64(vmull_n_u32(vget_low_u32(a), b)); // [_, x0, _, x1]
- uint32x4_t w2 = vreinterpretq_u32_u64(vmull_high_n_u32(a, b)); //[_, x2, _, x3]
- return vuzp2q_u32(w1, w2); // [x0, x1, x2, x3]
-}
-
-static inline int32x4_t libdivide_mullhi_s32_vec128(int32x4_t a, int32_t b) {
- int32x4_t w1 = vreinterpretq_s32_s64(vmull_n_s32(vget_low_s32(a), b)); // [_, x0, _, x1]
- int32x4_t w2 = vreinterpretq_s32_s64(vmull_high_n_s32(a, b)); //[_, x2, _, x3]
- return vuzp2q_s32(w1, w2); // [x0, x1, x2, x3]
-}
-
-static inline uint64x2_t libdivide_mullhi_u64_vec128(uint64x2_t x, uint64_t sy) {
- // full 128 bits product is:
- // x0*y0 + (x0*y1 << 32) + (x1*y0 << 32) + (x1*y1 << 64)
- // Note x0,y0,x1,y1 are all conceptually uint32, products are 32x32->64.
-
- // Get low and high words. x0 contains low 32 bits, x1 is high 32 bits.
- uint64x2_t y = vdupq_n_u64(sy);
- uint32x2_t x0 = vmovn_u64(x);
- uint32x2_t y0 = vmovn_u64(y);
- uint32x2_t x1 = vshrn_n_u64(x, 32);
- uint32x2_t y1 = vshrn_n_u64(y, 32);
-
- // Compute x0*y0.
- uint64x2_t x0y0 = vmull_u32(x0, y0);
- uint64x2_t x0y0_hi = vshrq_n_u64(x0y0, 32);
-
- // Compute other intermediate products.
- uint64x2_t temp = vmlal_u32(x0y0_hi, x1, y0); // temp = x0y0_hi + x1*y0;
- // We want to split temp into its low 32 bits and high 32 bits, both
- // in the low half of 64 bit registers.
- // Use shifts to avoid needing a reg for the mask.
- uint64x2_t temp_lo = vshrq_n_u64(vshlq_n_u64(temp, 32), 32); // temp_lo = temp & 0xFFFFFFFF;
- uint64x2_t temp_hi = vshrq_n_u64(temp, 32); // temp_hi = temp >> 32;
-
- temp_lo = vmlal_u32(temp_lo, x0, y1); // temp_lo += x0*y0
- temp_lo = vshrq_n_u64(temp_lo, 32); // temp_lo >>= 32
- temp_hi = vmlal_u32(temp_hi, x1, y1); // temp_hi += x1*y1
- uint64x2_t result = vaddq_u64(temp_hi, temp_lo);
- return result;
-}
-
-static inline int64x2_t libdivide_mullhi_s64_vec128(int64x2_t x, int64_t sy) {
- int64x2_t p = vreinterpretq_s64_u64(
- libdivide_mullhi_u64_vec128(vreinterpretq_u64_s64(x), static_cast(sy)));
- int64x2_t y = vdupq_n_s64(sy);
- int64x2_t t1 = vandq_s64(libdivide_s64_signbits(x), y);
- int64x2_t t2 = vandq_s64(libdivide_s64_signbits(y), x);
- p = vsubq_s64(p, t1);
- p = vsubq_s64(p, t2);
- return p;
-}
-
-////////// UINT32
-
-uint32x4_t libdivide_u32_do_vec128(uint32x4_t numers, const struct libdivide_u32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return libdivide_u32_neon_srl(numers, more);
- } else {
- uint32x4_t q = libdivide_mullhi_u32_vec128(numers, denom->magic);
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- // Note we can use halving-subtract to avoid the shift.
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- uint32x4_t t = vaddq_u32(vhsubq_u32(numers, q), q);
- return libdivide_u32_neon_srl(t, shift);
- } else {
- return libdivide_u32_neon_srl(q, more);
- }
- }
-}
-
-uint32x4_t libdivide_u32_branchfree_do_vec128(
- uint32x4_t numers, const struct libdivide_u32_branchfree_t *denom) {
- uint32x4_t q = libdivide_mullhi_u32_vec128(numers, denom->magic);
- uint32x4_t t = vaddq_u32(vhsubq_u32(numers, q), q);
- return libdivide_u32_neon_srl(t, denom->more);
-}
-
-////////// UINT64
-
-uint64x2_t libdivide_u64_do_vec128(uint64x2_t numers, const struct libdivide_u64_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return libdivide_u64_neon_srl(numers, more);
- } else {
- uint64x2_t q = libdivide_mullhi_u64_vec128(numers, denom->magic);
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- // No 64-bit halving subtracts in NEON :(
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- uint64x2_t t = vaddq_u64(vshrq_n_u64(vsubq_u64(numers, q), 1), q);
- return libdivide_u64_neon_srl(t, shift);
- } else {
- return libdivide_u64_neon_srl(q, more);
- }
- }
-}
-
-uint64x2_t libdivide_u64_branchfree_do_vec128(
- uint64x2_t numers, const struct libdivide_u64_branchfree_t *denom) {
- uint64x2_t q = libdivide_mullhi_u64_vec128(numers, denom->magic);
- uint64x2_t t = vaddq_u64(vshrq_n_u64(vsubq_u64(numers, q), 1), q);
- return libdivide_u64_neon_srl(t, denom->more);
-}
-
-////////// SINT32
-
-int32x4_t libdivide_s32_do_vec128(int32x4_t numers, const struct libdivide_s32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- uint32_t mask = (1U << shift) - 1;
- int32x4_t roundToZeroTweak = vdupq_n_s32((int)mask);
- // q = numer + ((numer >> 31) & roundToZeroTweak);
- int32x4_t q = vaddq_s32(numers, vandq_s32(vshrq_n_s32(numers, 31), roundToZeroTweak));
- q = libdivide_s32_neon_sra(q, shift);
- int32x4_t sign = vdupq_n_s32((int8_t)more >> 7);
- // q = (q ^ sign) - sign;
- q = vsubq_s32(veorq_s32(q, sign), sign);
- return q;
- } else {
- int32x4_t q = libdivide_mullhi_s32_vec128(numers, denom->magic);
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- int32x4_t sign = vdupq_n_s32((int8_t)more >> 7);
- // q += ((numer ^ sign) - sign);
- q = vaddq_s32(q, vsubq_s32(veorq_s32(numers, sign), sign));
- }
- // q >>= shift
- q = libdivide_s32_neon_sra(q, more & LIBDIVIDE_32_SHIFT_MASK);
- q = vaddq_s32(
- q, vreinterpretq_s32_u32(vshrq_n_u32(vreinterpretq_u32_s32(q), 31))); // q += (q < 0)
- return q;
- }
-}
-
-int32x4_t libdivide_s32_branchfree_do_vec128(
- int32x4_t numers, const struct libdivide_s32_branchfree_t *denom) {
- int32_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- // must be arithmetic shift
- int32x4_t sign = vdupq_n_s32((int8_t)more >> 7);
- int32x4_t q = libdivide_mullhi_s32_vec128(numers, magic);
- q = vaddq_s32(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2
- uint32_t is_power_of_2 = (magic == 0);
- int32x4_t q_sign = vshrq_n_s32(q, 31); // q_sign = q >> 31
- int32x4_t mask = vdupq_n_s32((1U << shift) - is_power_of_2);
- q = vaddq_s32(q, vandq_s32(q_sign, mask)); // q = q + (q_sign & mask)
- q = libdivide_s32_neon_sra(q, shift); // q >>= shift
- q = vsubq_s32(veorq_s32(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-////////// SINT64
-
-int64x2_t libdivide_s64_do_vec128(int64x2_t numers, const struct libdivide_s64_t *denom) {
- uint8_t more = denom->more;
- int64_t magic = denom->magic;
- if (magic == 0) { // shift path
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- uint64_t mask = (1ULL << shift) - 1;
- int64x2_t roundToZeroTweak = vdupq_n_s64(mask); // TODO: no need to sign extend
- // q = numer + ((numer >> 63) & roundToZeroTweak);
- int64x2_t q =
- vaddq_s64(numers, vandq_s64(libdivide_s64_signbits(numers), roundToZeroTweak));
- q = libdivide_s64_neon_sra(q, shift);
- // q = (q ^ sign) - sign;
- int64x2_t sign = vreinterpretq_s64_s8(vdupq_n_s8((int8_t)more >> 7));
- q = vsubq_s64(veorq_s64(q, sign), sign);
- return q;
- } else {
- int64x2_t q = libdivide_mullhi_s64_vec128(numers, magic);
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- int64x2_t sign = vdupq_n_s64((int8_t)more >> 7); // TODO: no need to widen
- // q += ((numer ^ sign) - sign);
- q = vaddq_s64(q, vsubq_s64(veorq_s64(numers, sign), sign));
- }
- // q >>= denom->mult_path.shift
- q = libdivide_s64_neon_sra(q, more & LIBDIVIDE_64_SHIFT_MASK);
- q = vaddq_s64(
- q, vreinterpretq_s64_u64(vshrq_n_u64(vreinterpretq_u64_s64(q), 63))); // q += (q < 0)
- return q;
- }
-}
-
-int64x2_t libdivide_s64_branchfree_do_vec128(
- int64x2_t numers, const struct libdivide_s64_branchfree_t *denom) {
- int64_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- // must be arithmetic shift
- int64x2_t sign = vdupq_n_s64((int8_t)more >> 7); // TODO: avoid sign extend
-
- // libdivide_mullhi_s64(numers, magic);
- int64x2_t q = libdivide_mullhi_s64_vec128(numers, magic);
- q = vaddq_s64(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do.
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2.
- uint32_t is_power_of_2 = (magic == 0);
- int64x2_t q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63
- int64x2_t mask = vdupq_n_s64((1ULL << shift) - is_power_of_2);
- q = vaddq_s64(q, vandq_s64(q_sign, mask)); // q = q + (q_sign & mask)
- q = libdivide_s64_neon_sra(q, shift); // q >>= shift
- q = vsubq_s64(veorq_s64(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-#endif
-
-#if defined(LIBDIVIDE_AVX512)
-
-static inline __m512i libdivide_u32_do_vec512(__m512i numers, const struct libdivide_u32_t *denom);
-static inline __m512i libdivide_s32_do_vec512(__m512i numers, const struct libdivide_s32_t *denom);
-static inline __m512i libdivide_u64_do_vec512(__m512i numers, const struct libdivide_u64_t *denom);
-static inline __m512i libdivide_s64_do_vec512(__m512i numers, const struct libdivide_s64_t *denom);
-
-static inline __m512i libdivide_u32_branchfree_do_vec512(
- __m512i numers, const struct libdivide_u32_branchfree_t *denom);
-static inline __m512i libdivide_s32_branchfree_do_vec512(
- __m512i numers, const struct libdivide_s32_branchfree_t *denom);
-static inline __m512i libdivide_u64_branchfree_do_vec512(
- __m512i numers, const struct libdivide_u64_branchfree_t *denom);
-static inline __m512i libdivide_s64_branchfree_do_vec512(
- __m512i numers, const struct libdivide_s64_branchfree_t *denom);
-
-//////// Internal Utility Functions
-
-static inline __m512i libdivide_s64_signbits(__m512i v) {
- ;
- return _mm512_srai_epi64(v, 63);
-}
-
-static inline __m512i libdivide_s64_shift_right_vec512(__m512i v, int amt) {
- return _mm512_srai_epi64(v, amt);
-}
-
-// Here, b is assumed to contain one 32-bit value repeated.
-static inline __m512i libdivide_mullhi_u32_vec512(__m512i a, __m512i b) {
- __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epu32(a, b), 32);
- __m512i a1X3X = _mm512_srli_epi64(a, 32);
- __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0);
- __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epu32(a1X3X, b), mask);
- return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3);
-}
-
-// b is one 32-bit value repeated.
-static inline __m512i libdivide_mullhi_s32_vec512(__m512i a, __m512i b) {
- __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epi32(a, b), 32);
- __m512i a1X3X = _mm512_srli_epi64(a, 32);
- __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0);
- __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epi32(a1X3X, b), mask);
- return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3);
-}
-
-// Here, y is assumed to contain one 64-bit value repeated.
-static inline __m512i libdivide_mullhi_u64_vec512(__m512i x, __m512i y) {
- // see m128i variant for comments.
- __m512i x0y0 = _mm512_mul_epu32(x, y);
- __m512i x0y0_hi = _mm512_srli_epi64(x0y0, 32);
-
- __m512i x1 = _mm512_shuffle_epi32(x, (_MM_PERM_ENUM)_MM_SHUFFLE(3, 3, 1, 1));
- __m512i y1 = _mm512_shuffle_epi32(y, (_MM_PERM_ENUM)_MM_SHUFFLE(3, 3, 1, 1));
-
- __m512i x0y1 = _mm512_mul_epu32(x, y1);
- __m512i x1y0 = _mm512_mul_epu32(x1, y);
- __m512i x1y1 = _mm512_mul_epu32(x1, y1);
-
- __m512i mask = _mm512_set1_epi64(0xFFFFFFFF);
- __m512i temp = _mm512_add_epi64(x1y0, x0y0_hi);
- __m512i temp_lo = _mm512_and_si512(temp, mask);
- __m512i temp_hi = _mm512_srli_epi64(temp, 32);
-
- temp_lo = _mm512_srli_epi64(_mm512_add_epi64(temp_lo, x0y1), 32);
- temp_hi = _mm512_add_epi64(x1y1, temp_hi);
- return _mm512_add_epi64(temp_lo, temp_hi);
-}
-
-// y is one 64-bit value repeated.
-static inline __m512i libdivide_mullhi_s64_vec512(__m512i x, __m512i y) {
- __m512i p = libdivide_mullhi_u64_vec512(x, y);
- __m512i t1 = _mm512_and_si512(libdivide_s64_signbits(x), y);
- __m512i t2 = _mm512_and_si512(libdivide_s64_signbits(y), x);
- p = _mm512_sub_epi64(p, t1);
- p = _mm512_sub_epi64(p, t2);
- return p;
-}
-
-////////// UINT32
-
-__m512i libdivide_u32_do_vec512(__m512i numers, const struct libdivide_u32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return _mm512_srli_epi32(numers, more);
- } else {
- __m512i q = libdivide_mullhi_u32_vec512(numers, _mm512_set1_epi32(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q);
- return _mm512_srli_epi32(t, shift);
- } else {
- return _mm512_srli_epi32(q, more);
- }
- }
-}
-
-__m512i libdivide_u32_branchfree_do_vec512(
- __m512i numers, const struct libdivide_u32_branchfree_t *denom) {
- __m512i q = libdivide_mullhi_u32_vec512(numers, _mm512_set1_epi32(denom->magic));
- __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q);
- return _mm512_srli_epi32(t, denom->more);
-}
-
-////////// UINT64
-
-__m512i libdivide_u64_do_vec512(__m512i numers, const struct libdivide_u64_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return _mm512_srli_epi64(numers, more);
- } else {
- __m512i q = libdivide_mullhi_u64_vec512(numers, _mm512_set1_epi64(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q);
- return _mm512_srli_epi64(t, shift);
- } else {
- return _mm512_srli_epi64(q, more);
- }
- }
-}
-
-__m512i libdivide_u64_branchfree_do_vec512(
- __m512i numers, const struct libdivide_u64_branchfree_t *denom) {
- __m512i q = libdivide_mullhi_u64_vec512(numers, _mm512_set1_epi64(denom->magic));
- __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q);
- return _mm512_srli_epi64(t, denom->more);
-}
-
-////////// SINT32
-
-__m512i libdivide_s32_do_vec512(__m512i numers, const struct libdivide_s32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- uint32_t mask = (1U << shift) - 1;
- __m512i roundToZeroTweak = _mm512_set1_epi32(mask);
- // q = numer + ((numer >> 31) & roundToZeroTweak);
- __m512i q = _mm512_add_epi32(
- numers, _mm512_and_si512(_mm512_srai_epi32(numers, 31), roundToZeroTweak));
- q = _mm512_srai_epi32(q, shift);
- __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
- // q = (q ^ sign) - sign;
- q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign);
- return q;
- } else {
- __m512i q = libdivide_mullhi_s32_vec512(numers, _mm512_set1_epi32(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
- // q += ((numer ^ sign) - sign);
- q = _mm512_add_epi32(q, _mm512_sub_epi32(_mm512_xor_si512(numers, sign), sign));
- }
- // q >>= shift
- q = _mm512_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK);
- q = _mm512_add_epi32(q, _mm512_srli_epi32(q, 31)); // q += (q < 0)
- return q;
- }
-}
-
-__m512i libdivide_s32_branchfree_do_vec512(
- __m512i numers, const struct libdivide_s32_branchfree_t *denom) {
- int32_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- // must be arithmetic shift
- __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
- __m512i q = libdivide_mullhi_s32_vec512(numers, _mm512_set1_epi32(magic));
- q = _mm512_add_epi32(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2
- uint32_t is_power_of_2 = (magic == 0);
- __m512i q_sign = _mm512_srai_epi32(q, 31); // q_sign = q >> 31
- __m512i mask = _mm512_set1_epi32((1U << shift) - is_power_of_2);
- q = _mm512_add_epi32(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask)
- q = _mm512_srai_epi32(q, shift); // q >>= shift
- q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-////////// SINT64
-
-__m512i libdivide_s64_do_vec512(__m512i numers, const struct libdivide_s64_t *denom) {
- uint8_t more = denom->more;
- int64_t magic = denom->magic;
- if (magic == 0) { // shift path
- uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- uint64_t mask = (1ULL << shift) - 1;
- __m512i roundToZeroTweak = _mm512_set1_epi64(mask);
- // q = numer + ((numer >> 63) & roundToZeroTweak);
- __m512i q = _mm512_add_epi64(
- numers, _mm512_and_si512(libdivide_s64_signbits(numers), roundToZeroTweak));
- q = libdivide_s64_shift_right_vec512(q, shift);
- __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
- // q = (q ^ sign) - sign;
- q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign);
- return q;
- } else {
- __m512i q = libdivide_mullhi_s64_vec512(numers, _mm512_set1_epi64(magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
- // q += ((numer ^ sign) - sign);
- q = _mm512_add_epi64(q, _mm512_sub_epi64(_mm512_xor_si512(numers, sign), sign));
- }
- // q >>= denom->mult_path.shift
- q = libdivide_s64_shift_right_vec512(q, more & LIBDIVIDE_64_SHIFT_MASK);
- q = _mm512_add_epi64(q, _mm512_srli_epi64(q, 63)); // q += (q < 0)
- return q;
- }
-}
-
-__m512i libdivide_s64_branchfree_do_vec512(
- __m512i numers, const struct libdivide_s64_branchfree_t *denom) {
- int64_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- // must be arithmetic shift
- __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
-
- // libdivide_mullhi_s64(numers, magic);
- __m512i q = libdivide_mullhi_s64_vec512(numers, _mm512_set1_epi64(magic));
- q = _mm512_add_epi64(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do.
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2.
- uint32_t is_power_of_2 = (magic == 0);
- __m512i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63
- __m512i mask = _mm512_set1_epi64((1ULL << shift) - is_power_of_2);
- q = _mm512_add_epi64(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask)
- q = libdivide_s64_shift_right_vec512(q, shift); // q >>= shift
- q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-#endif
-
-#if defined(LIBDIVIDE_AVX2)
-
-static inline __m256i libdivide_u32_do_vec256(__m256i numers, const struct libdivide_u32_t *denom);
-static inline __m256i libdivide_s32_do_vec256(__m256i numers, const struct libdivide_s32_t *denom);
-static inline __m256i libdivide_u64_do_vec256(__m256i numers, const struct libdivide_u64_t *denom);
-static inline __m256i libdivide_s64_do_vec256(__m256i numers, const struct libdivide_s64_t *denom);
-
-static inline __m256i libdivide_u32_branchfree_do_vec256(
- __m256i numers, const struct libdivide_u32_branchfree_t *denom);
-static inline __m256i libdivide_s32_branchfree_do_vec256(
- __m256i numers, const struct libdivide_s32_branchfree_t *denom);
-static inline __m256i libdivide_u64_branchfree_do_vec256(
- __m256i numers, const struct libdivide_u64_branchfree_t *denom);
-static inline __m256i libdivide_s64_branchfree_do_vec256(
- __m256i numers, const struct libdivide_s64_branchfree_t *denom);
-
-//////// Internal Utility Functions
-
-// Implementation of _mm256_srai_epi64(v, 63) (from AVX512).
-static inline __m256i libdivide_s64_signbits(__m256i v) {
- __m256i hiBitsDuped = _mm256_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1));
- __m256i signBits = _mm256_srai_epi32(hiBitsDuped, 31);
- return signBits;
-}
-
-// Implementation of _mm256_srai_epi64 (from AVX512).
-static inline __m256i libdivide_s64_shift_right_vec256(__m256i v, int amt) {
- const int b = 64 - amt;
- __m256i m = _mm256_set1_epi64x(1ULL << (b - 1));
- __m256i x = _mm256_srli_epi64(v, amt);
- __m256i result = _mm256_sub_epi64(_mm256_xor_si256(x, m), m);
- return result;
-}
-
-// Here, b is assumed to contain one 32-bit value repeated.
-static inline __m256i libdivide_mullhi_u32_vec256(__m256i a, __m256i b) {
- __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epu32(a, b), 32);
- __m256i a1X3X = _mm256_srli_epi64(a, 32);
- __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0);
- __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epu32(a1X3X, b), mask);
- return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3);
-}
-
-// b is one 32-bit value repeated.
-static inline __m256i libdivide_mullhi_s32_vec256(__m256i a, __m256i b) {
- __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epi32(a, b), 32);
- __m256i a1X3X = _mm256_srli_epi64(a, 32);
- __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0);
- __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epi32(a1X3X, b), mask);
- return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3);
-}
-
-// Here, y is assumed to contain one 64-bit value repeated.
-static inline __m256i libdivide_mullhi_u64_vec256(__m256i x, __m256i y) {
- // see m128i variant for comments.
- __m256i x0y0 = _mm256_mul_epu32(x, y);
- __m256i x0y0_hi = _mm256_srli_epi64(x0y0, 32);
-
- __m256i x1 = _mm256_shuffle_epi32(x, _MM_SHUFFLE(3, 3, 1, 1));
- __m256i y1 = _mm256_shuffle_epi32(y, _MM_SHUFFLE(3, 3, 1, 1));
-
- __m256i x0y1 = _mm256_mul_epu32(x, y1);
- __m256i x1y0 = _mm256_mul_epu32(x1, y);
- __m256i x1y1 = _mm256_mul_epu32(x1, y1);
-
- __m256i mask = _mm256_set1_epi64x(0xFFFFFFFF);
- __m256i temp = _mm256_add_epi64(x1y0, x0y0_hi);
- __m256i temp_lo = _mm256_and_si256(temp, mask);
- __m256i temp_hi = _mm256_srli_epi64(temp, 32);
-
- temp_lo = _mm256_srli_epi64(_mm256_add_epi64(temp_lo, x0y1), 32);
- temp_hi = _mm256_add_epi64(x1y1, temp_hi);
- return _mm256_add_epi64(temp_lo, temp_hi);
-}
-
-// y is one 64-bit value repeated.
-static inline __m256i libdivide_mullhi_s64_vec256(__m256i x, __m256i y) {
- __m256i p = libdivide_mullhi_u64_vec256(x, y);
- __m256i t1 = _mm256_and_si256(libdivide_s64_signbits(x), y);
- __m256i t2 = _mm256_and_si256(libdivide_s64_signbits(y), x);
- p = _mm256_sub_epi64(p, t1);
- p = _mm256_sub_epi64(p, t2);
- return p;
-}
-
-////////// UINT32
-
-__m256i libdivide_u32_do_vec256(__m256i numers, const struct libdivide_u32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return _mm256_srli_epi32(numers, more);
- } else {
- __m256i q = libdivide_mullhi_u32_vec256(numers, _mm256_set1_epi32(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q);
- return _mm256_srli_epi32(t, shift);
- } else {
- return _mm256_srli_epi32(q, more);
- }
- }
-}
-
-__m256i libdivide_u32_branchfree_do_vec256(
- __m256i numers, const struct libdivide_u32_branchfree_t *denom) {
- __m256i q = libdivide_mullhi_u32_vec256(numers, _mm256_set1_epi32(denom->magic));
- __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q);
- return _mm256_srli_epi32(t, denom->more);
-}
-
-////////// UINT64
-
-__m256i libdivide_u64_do_vec256(__m256i numers, const struct libdivide_u64_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return _mm256_srli_epi64(numers, more);
- } else {
- __m256i q = libdivide_mullhi_u64_vec256(numers, _mm256_set1_epi64x(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q);
- return _mm256_srli_epi64(t, shift);
- } else {
- return _mm256_srli_epi64(q, more);
- }
- }
-}
-
-__m256i libdivide_u64_branchfree_do_vec256(
- __m256i numers, const struct libdivide_u64_branchfree_t *denom) {
- __m256i q = libdivide_mullhi_u64_vec256(numers, _mm256_set1_epi64x(denom->magic));
- __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q);
- return _mm256_srli_epi64(t, denom->more);
-}
-
-////////// SINT32
-
-__m256i libdivide_s32_do_vec256(__m256i numers, const struct libdivide_s32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- uint32_t mask = (1U << shift) - 1;
- __m256i roundToZeroTweak = _mm256_set1_epi32(mask);
- // q = numer + ((numer >> 31) & roundToZeroTweak);
- __m256i q = _mm256_add_epi32(
- numers, _mm256_and_si256(_mm256_srai_epi32(numers, 31), roundToZeroTweak));
- q = _mm256_srai_epi32(q, shift);
- __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
- // q = (q ^ sign) - sign;
- q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign);
- return q;
- } else {
- __m256i q = libdivide_mullhi_s32_vec256(numers, _mm256_set1_epi32(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
- // q += ((numer ^ sign) - sign);
- q = _mm256_add_epi32(q, _mm256_sub_epi32(_mm256_xor_si256(numers, sign), sign));
- }
- // q >>= shift
- q = _mm256_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK);
- q = _mm256_add_epi32(q, _mm256_srli_epi32(q, 31)); // q += (q < 0)
- return q;
- }
-}
-
-__m256i libdivide_s32_branchfree_do_vec256(
- __m256i numers, const struct libdivide_s32_branchfree_t *denom) {
- int32_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- // must be arithmetic shift
- __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
- __m256i q = libdivide_mullhi_s32_vec256(numers, _mm256_set1_epi32(magic));
- q = _mm256_add_epi32(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2
- uint32_t is_power_of_2 = (magic == 0);
- __m256i q_sign = _mm256_srai_epi32(q, 31); // q_sign = q >> 31
- __m256i mask = _mm256_set1_epi32((1U << shift) - is_power_of_2);
- q = _mm256_add_epi32(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask)
- q = _mm256_srai_epi32(q, shift); // q >>= shift
- q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-////////// SINT64
-
-__m256i libdivide_s64_do_vec256(__m256i numers, const struct libdivide_s64_t *denom) {
- uint8_t more = denom->more;
- int64_t magic = denom->magic;
- if (magic == 0) { // shift path
- uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- uint64_t mask = (1ULL << shift) - 1;
- __m256i roundToZeroTweak = _mm256_set1_epi64x(mask);
- // q = numer + ((numer >> 63) & roundToZeroTweak);
- __m256i q = _mm256_add_epi64(
- numers, _mm256_and_si256(libdivide_s64_signbits(numers), roundToZeroTweak));
- q = libdivide_s64_shift_right_vec256(q, shift);
- __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
- // q = (q ^ sign) - sign;
- q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign);
- return q;
- } else {
- __m256i q = libdivide_mullhi_s64_vec256(numers, _mm256_set1_epi64x(magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
- // q += ((numer ^ sign) - sign);
- q = _mm256_add_epi64(q, _mm256_sub_epi64(_mm256_xor_si256(numers, sign), sign));
- }
- // q >>= denom->mult_path.shift
- q = libdivide_s64_shift_right_vec256(q, more & LIBDIVIDE_64_SHIFT_MASK);
- q = _mm256_add_epi64(q, _mm256_srli_epi64(q, 63)); // q += (q < 0)
- return q;
- }
-}
-
-__m256i libdivide_s64_branchfree_do_vec256(
- __m256i numers, const struct libdivide_s64_branchfree_t *denom) {
- int64_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- // must be arithmetic shift
- __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
-
- // libdivide_mullhi_s64(numers, magic);
- __m256i q = libdivide_mullhi_s64_vec256(numers, _mm256_set1_epi64x(magic));
- q = _mm256_add_epi64(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do.
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2.
- uint32_t is_power_of_2 = (magic == 0);
- __m256i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63
- __m256i mask = _mm256_set1_epi64x((1ULL << shift) - is_power_of_2);
- q = _mm256_add_epi64(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask)
- q = libdivide_s64_shift_right_vec256(q, shift); // q >>= shift
- q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-#endif
-
-#if defined(LIBDIVIDE_SSE2)
-
-static inline __m128i libdivide_u32_do_vec128(__m128i numers, const struct libdivide_u32_t *denom);
-static inline __m128i libdivide_s32_do_vec128(__m128i numers, const struct libdivide_s32_t *denom);
-static inline __m128i libdivide_u64_do_vec128(__m128i numers, const struct libdivide_u64_t *denom);
-static inline __m128i libdivide_s64_do_vec128(__m128i numers, const struct libdivide_s64_t *denom);
-
-static inline __m128i libdivide_u32_branchfree_do_vec128(
- __m128i numers, const struct libdivide_u32_branchfree_t *denom);
-static inline __m128i libdivide_s32_branchfree_do_vec128(
- __m128i numers, const struct libdivide_s32_branchfree_t *denom);
-static inline __m128i libdivide_u64_branchfree_do_vec128(
- __m128i numers, const struct libdivide_u64_branchfree_t *denom);
-static inline __m128i libdivide_s64_branchfree_do_vec128(
- __m128i numers, const struct libdivide_s64_branchfree_t *denom);
-
-//////// Internal Utility Functions
-
-// Implementation of _mm_srai_epi64(v, 63) (from AVX512).
-static inline __m128i libdivide_s64_signbits(__m128i v) {
- __m128i hiBitsDuped = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1));
- __m128i signBits = _mm_srai_epi32(hiBitsDuped, 31);
- return signBits;
-}
-
-// Implementation of _mm_srai_epi64 (from AVX512).
-static inline __m128i libdivide_s64_shift_right_vec128(__m128i v, int amt) {
- const int b = 64 - amt;
- __m128i m = _mm_set1_epi64x(1ULL << (b - 1));
- __m128i x = _mm_srli_epi64(v, amt);
- __m128i result = _mm_sub_epi64(_mm_xor_si128(x, m), m);
- return result;
-}
-
-// Here, b is assumed to contain one 32-bit value repeated.
-static inline __m128i libdivide_mullhi_u32_vec128(__m128i a, __m128i b) {
- __m128i hi_product_0Z2Z = _mm_srli_epi64(_mm_mul_epu32(a, b), 32);
- __m128i a1X3X = _mm_srli_epi64(a, 32);
- __m128i mask = _mm_set_epi32(-1, 0, -1, 0);
- __m128i hi_product_Z1Z3 = _mm_and_si128(_mm_mul_epu32(a1X3X, b), mask);
- return _mm_or_si128(hi_product_0Z2Z, hi_product_Z1Z3);
-}
-
-// SSE2 does not have a signed multiplication instruction, but we can convert
-// unsigned to signed pretty efficiently. Again, b is just a 32 bit value
-// repeated four times.
-static inline __m128i libdivide_mullhi_s32_vec128(__m128i a, __m128i b) {
- __m128i p = libdivide_mullhi_u32_vec128(a, b);
- // t1 = (a >> 31) & y, arithmetic shift
- __m128i t1 = _mm_and_si128(_mm_srai_epi32(a, 31), b);
- __m128i t2 = _mm_and_si128(_mm_srai_epi32(b, 31), a);
- p = _mm_sub_epi32(p, t1);
- p = _mm_sub_epi32(p, t2);
- return p;
-}
-
-// Here, y is assumed to contain one 64-bit value repeated.
-static inline __m128i libdivide_mullhi_u64_vec128(__m128i x, __m128i y) {
- // full 128 bits product is:
- // x0*y0 + (x0*y1 << 32) + (x1*y0 << 32) + (x1*y1 << 64)
- // Note x0,y0,x1,y1 are all conceptually uint32, products are 32x32->64.
-
- // Compute x0*y0.
- // Note x1, y1 are ignored by mul_epu32.
- __m128i x0y0 = _mm_mul_epu32(x, y);
- __m128i x0y0_hi = _mm_srli_epi64(x0y0, 32);
-
- // Get x1, y1 in the low bits.
- // We could shuffle or right shift. Shuffles are preferred as they preserve
- // the source register for the next computation.
- __m128i x1 = _mm_shuffle_epi32(x, _MM_SHUFFLE(3, 3, 1, 1));
- __m128i y1 = _mm_shuffle_epi32(y, _MM_SHUFFLE(3, 3, 1, 1));
-
- // No need to mask off top 32 bits for mul_epu32.
- __m128i x0y1 = _mm_mul_epu32(x, y1);
- __m128i x1y0 = _mm_mul_epu32(x1, y);
- __m128i x1y1 = _mm_mul_epu32(x1, y1);
-
- // Mask here selects low bits only.
- __m128i mask = _mm_set1_epi64x(0xFFFFFFFF);
- __m128i temp = _mm_add_epi64(x1y0, x0y0_hi);
- __m128i temp_lo = _mm_and_si128(temp, mask);
- __m128i temp_hi = _mm_srli_epi64(temp, 32);
-
- temp_lo = _mm_srli_epi64(_mm_add_epi64(temp_lo, x0y1), 32);
- temp_hi = _mm_add_epi64(x1y1, temp_hi);
- return _mm_add_epi64(temp_lo, temp_hi);
-}
-
-// y is one 64-bit value repeated.
-static inline __m128i libdivide_mullhi_s64_vec128(__m128i x, __m128i y) {
- __m128i p = libdivide_mullhi_u64_vec128(x, y);
- __m128i t1 = _mm_and_si128(libdivide_s64_signbits(x), y);
- __m128i t2 = _mm_and_si128(libdivide_s64_signbits(y), x);
- p = _mm_sub_epi64(p, t1);
- p = _mm_sub_epi64(p, t2);
- return p;
-}
-
-////////// UINT32
-
-__m128i libdivide_u32_do_vec128(__m128i numers, const struct libdivide_u32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return _mm_srli_epi32(numers, more);
- } else {
- __m128i q = libdivide_mullhi_u32_vec128(numers, _mm_set1_epi32(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q);
- return _mm_srli_epi32(t, shift);
- } else {
- return _mm_srli_epi32(q, more);
- }
- }
-}
-
-__m128i libdivide_u32_branchfree_do_vec128(
- __m128i numers, const struct libdivide_u32_branchfree_t *denom) {
- __m128i q = libdivide_mullhi_u32_vec128(numers, _mm_set1_epi32(denom->magic));
- __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q);
- return _mm_srli_epi32(t, denom->more);
-}
-
-////////// UINT64
-
-__m128i libdivide_u64_do_vec128(__m128i numers, const struct libdivide_u64_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- return _mm_srli_epi64(numers, more);
- } else {
- __m128i q = libdivide_mullhi_u64_vec128(numers, _mm_set1_epi64x(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // uint32_t t = ((numer - q) >> 1) + q;
- // return t >> denom->shift;
- uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q);
- return _mm_srli_epi64(t, shift);
- } else {
- return _mm_srli_epi64(q, more);
- }
- }
-}
-
-__m128i libdivide_u64_branchfree_do_vec128(
- __m128i numers, const struct libdivide_u64_branchfree_t *denom) {
- __m128i q = libdivide_mullhi_u64_vec128(numers, _mm_set1_epi64x(denom->magic));
- __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q);
- return _mm_srli_epi64(t, denom->more);
-}
-
-////////// SINT32
-
-__m128i libdivide_s32_do_vec128(__m128i numers, const struct libdivide_s32_t *denom) {
- uint8_t more = denom->more;
- if (!denom->magic) {
- uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- uint32_t mask = (1U << shift) - 1;
- __m128i roundToZeroTweak = _mm_set1_epi32(mask);
- // q = numer + ((numer >> 31) & roundToZeroTweak);
- __m128i q =
- _mm_add_epi32(numers, _mm_and_si128(_mm_srai_epi32(numers, 31), roundToZeroTweak));
- q = _mm_srai_epi32(q, shift);
- __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
- // q = (q ^ sign) - sign;
- q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign);
- return q;
- } else {
- __m128i q = libdivide_mullhi_s32_vec128(numers, _mm_set1_epi32(denom->magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
- // q += ((numer ^ sign) - sign);
- q = _mm_add_epi32(q, _mm_sub_epi32(_mm_xor_si128(numers, sign), sign));
- }
- // q >>= shift
- q = _mm_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK);
- q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); // q += (q < 0)
- return q;
- }
-}
-
-__m128i libdivide_s32_branchfree_do_vec128(
- __m128i numers, const struct libdivide_s32_branchfree_t *denom) {
- int32_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
- // must be arithmetic shift
- __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
- __m128i q = libdivide_mullhi_s32_vec128(numers, _mm_set1_epi32(magic));
- q = _mm_add_epi32(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2
- uint32_t is_power_of_2 = (magic == 0);
- __m128i q_sign = _mm_srai_epi32(q, 31); // q_sign = q >> 31
- __m128i mask = _mm_set1_epi32((1U << shift) - is_power_of_2);
- q = _mm_add_epi32(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask)
- q = _mm_srai_epi32(q, shift); // q >>= shift
- q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-////////// SINT64
-
-__m128i libdivide_s64_do_vec128(__m128i numers, const struct libdivide_s64_t *denom) {
- uint8_t more = denom->more;
- int64_t magic = denom->magic;
- if (magic == 0) { // shift path
- uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- uint64_t mask = (1ULL << shift) - 1;
- __m128i roundToZeroTweak = _mm_set1_epi64x(mask);
- // q = numer + ((numer >> 63) & roundToZeroTweak);
- __m128i q =
- _mm_add_epi64(numers, _mm_and_si128(libdivide_s64_signbits(numers), roundToZeroTweak));
- q = libdivide_s64_shift_right_vec128(q, shift);
- __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
- // q = (q ^ sign) - sign;
- q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign);
- return q;
- } else {
- __m128i q = libdivide_mullhi_s64_vec128(numers, _mm_set1_epi64x(magic));
- if (more & LIBDIVIDE_ADD_MARKER) {
- // must be arithmetic shift
- __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
- // q += ((numer ^ sign) - sign);
- q = _mm_add_epi64(q, _mm_sub_epi64(_mm_xor_si128(numers, sign), sign));
- }
- // q >>= denom->mult_path.shift
- q = libdivide_s64_shift_right_vec128(q, more & LIBDIVIDE_64_SHIFT_MASK);
- q = _mm_add_epi64(q, _mm_srli_epi64(q, 63)); // q += (q < 0)
- return q;
- }
-}
-
-__m128i libdivide_s64_branchfree_do_vec128(
- __m128i numers, const struct libdivide_s64_branchfree_t *denom) {
- int64_t magic = denom->magic;
- uint8_t more = denom->more;
- uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
- // must be arithmetic shift
- __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
-
- // libdivide_mullhi_s64(numers, magic);
- __m128i q = libdivide_mullhi_s64_vec128(numers, _mm_set1_epi64x(magic));
- q = _mm_add_epi64(q, numers); // q += numers
-
- // If q is non-negative, we have nothing to do.
- // If q is negative, we want to add either (2**shift)-1 if d is
- // a power of 2, or (2**shift) if it is not a power of 2.
- uint32_t is_power_of_2 = (magic == 0);
- __m128i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63
- __m128i mask = _mm_set1_epi64x((1ULL << shift) - is_power_of_2);
- q = _mm_add_epi64(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask)
- q = libdivide_s64_shift_right_vec128(q, shift); // q >>= shift
- q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign
- return q;
-}
-
-#endif
-
-/////////// C++ stuff
-
-#ifdef __cplusplus
-
-enum Branching {
- BRANCHFULL, // use branching algorithms
- BRANCHFREE // use branchfree algorithms
-};
-
-#if defined(LIBDIVIDE_NEON)
-// Helper to deduce NEON vector type for integral type.
-template
-struct NeonVecFor {};
-
-template <>
-struct NeonVecFor {
- typedef uint32x4_t type;
-};
-
-template <>
-struct NeonVecFor {
- typedef int32x4_t type;
-};
-
-template <>
-struct NeonVecFor {
- typedef uint64x2_t type;
-};
-
-template <>
-struct NeonVecFor {
- typedef int64x2_t type;
-};
-#endif
-
-// Versions of our algorithms for SIMD.
-#if defined(LIBDIVIDE_NEON)
-#define LIBDIVIDE_DIVIDE_NEON(ALGO, INT_TYPE) \
- typename NeonVecFor::type divide(typename NeonVecFor::type n) const { \
- return libdivide_##ALGO##_do_vec128(n, &denom); \
- }
-#else
-#define LIBDIVIDE_DIVIDE_NEON(ALGO, INT_TYPE)
-#endif
-#if defined(LIBDIVIDE_SSE2)
-#define LIBDIVIDE_DIVIDE_SSE2(ALGO) \
- __m128i divide(__m128i n) const { return libdivide_##ALGO##_do_vec128(n, &denom); }
-#else
-#define LIBDIVIDE_DIVIDE_SSE2(ALGO)
-#endif
-
-#if defined(LIBDIVIDE_AVX2)
-#define LIBDIVIDE_DIVIDE_AVX2(ALGO) \
- __m256i divide(__m256i n) const { return libdivide_##ALGO##_do_vec256(n, &denom); }
-#else
-#define LIBDIVIDE_DIVIDE_AVX2(ALGO)
-#endif
-
-#if defined(LIBDIVIDE_AVX512)
-#define LIBDIVIDE_DIVIDE_AVX512(ALGO) \
- __m512i divide(__m512i n) const { return libdivide_##ALGO##_do_vec512(n, &denom); }
-#else
-#define LIBDIVIDE_DIVIDE_AVX512(ALGO)
-#endif
-
-// The DISPATCHER_GEN() macro generates C++ methods (for the given integer
-// and algorithm types) that redirect to libdivide's C API.
-#define DISPATCHER_GEN(T, ALGO) \
- libdivide_##ALGO##_t denom; \
- dispatcher() {} \
- dispatcher(T d) : denom(libdivide_##ALGO##_gen(d)) {} \
- T divide(T n) const { return libdivide_##ALGO##_do(n, &denom); } \
- T recover() const { return libdivide_##ALGO##_recover(&denom); } \
- LIBDIVIDE_DIVIDE_NEON(ALGO, T) \
- LIBDIVIDE_DIVIDE_SSE2(ALGO) \
- LIBDIVIDE_DIVIDE_AVX2(ALGO) \
- LIBDIVIDE_DIVIDE_AVX512(ALGO)
-
-// The dispatcher selects a specific division algorithm for a given
-// type and ALGO using partial template specialization.
-template
-struct dispatcher {};
-
-template <>
-struct dispatcher {
- DISPATCHER_GEN(int32_t, s32)
-};
-template <>
-struct dispatcher {
- DISPATCHER_GEN(int32_t, s32_branchfree)
-};
-template <>
-struct dispatcher {
- DISPATCHER_GEN(uint32_t, u32)
-};
-template <>
-struct dispatcher {
- DISPATCHER_GEN(uint32_t, u32_branchfree)
-};
-template <>
-struct dispatcher {
- DISPATCHER_GEN(int64_t, s64)
-};
-template <>
-struct dispatcher {
- DISPATCHER_GEN(int64_t, s64_branchfree)
-};
-template <>
-struct dispatcher {
- DISPATCHER_GEN(uint64_t, u64)
-};
-template <>
-struct dispatcher {
- DISPATCHER_GEN(uint64_t, u64_branchfree)
-};
-
-// This is the main divider class for use by the user (C++ API).
-// The actual division algorithm is selected using the dispatcher struct
-// based on the integer and algorithm template parameters.
-template
-class divider {
- public:
- // We leave the default constructor empty so that creating
- // an array of dividers and then initializing them
- // later doesn't slow us down.
- divider() {}
-
- // Constructor that takes the divisor as a parameter
- divider(T d) : div(d) {}
-
- // Divides n by the divisor
- T divide(T n) const { return div.divide(n); }
-
- // Recovers the divisor, returns the value that was
- // used to initialize this divider object.
- T recover() const { return div.recover(); }
-
- bool operator==(const divider &other) const {
- return div.denom.magic == other.denom.magic && div.denom.more == other.denom.more;
- }
-
- bool operator!=(const divider &other) const { return !(*this == other); }
-
- // Vector variants treat the input as packed integer values with the same type as the divider
- // (e.g. s32, u32, s64, u64) and divides each of them by the divider, returning the packed
- // quotients.
-#if defined(LIBDIVIDE_SSE2)
- __m128i divide(__m128i n) const { return div.divide(n); }
-#endif
-#if defined(LIBDIVIDE_AVX2)
- __m256i divide(__m256i n) const { return div.divide(n); }
-#endif
-#if defined(LIBDIVIDE_AVX512)
- __m512i divide(__m512i n) const { return div.divide(n); }
-#endif
-#if defined(LIBDIVIDE_NEON)
- typename NeonVecFor::type divide(typename NeonVecFor::type n) const {
- return div.divide(n);
- }
-#endif
-
- private:
- // Storage for the actual divisor
- dispatcher::value, std::is_signed::value, sizeof(T), ALGO> div;
-};
-
-// Overload of operator / for scalar division
-template
-T operator/(T n, const divider &div) {
- return div.divide(n);
-}
-
-// Overload of operator /= for scalar division
-template
-T &operator/=(T &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-
-// Overloads for vector types.
-#if defined(LIBDIVIDE_SSE2)
-template
-__m128i operator/(__m128i n, const divider &div) {
- return div.divide(n);
-}
-
-template
-__m128i operator/=(__m128i &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-#endif
-#if defined(LIBDIVIDE_AVX2)
-template
-__m256i operator/(__m256i n, const divider &div) {
- return div.divide(n);
-}
-
-template
-__m256i operator/=(__m256i &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-#endif
-#if defined(LIBDIVIDE_AVX512)
-template
-__m512i operator/(__m512i n, const divider &div) {
- return div.divide(n);
-}
-
-template
-__m512i operator/=(__m512i &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-#endif
-
-#if defined(LIBDIVIDE_NEON)
-template
-uint32x4_t operator/(uint32x4_t n, const divider &div) {
- return div.divide(n);
-}
-
-template
-int32x4_t operator/(int32x4_t n, const divider &div) {
- return div.divide(n);
-}
-
-template
-uint64x2_t operator/(uint64x2_t n, const divider &div) {
- return div.divide(n);
-}
-
-template
-int64x2_t operator/(int64x2_t n, const divider &div) {
- return div.divide(n);
-}
-
-template
-uint32x4_t operator/=(uint32x4_t &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-
-template
-int32x4_t operator/=(int32x4_t &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-
-template
-uint64x2_t operator/=(uint64x2_t &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-
-template
-int64x2_t operator/=(int64x2_t &n, const divider &div) {
- n = div.divide(n);
- return n;
-}
-#endif
-
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
-// libdivide::branchfree_divider
-template
-using branchfree_divider = divider;
-#endif
-
-} // namespace libdivide
-
-#endif // __cplusplus
-
-#endif // LIBDIVIDE_H
diff --git a/docker/packager/binary/build.sh b/docker/packager/binary/build.sh
index c2de0e33d82..436fcbe921c 100755
--- a/docker/packager/binary/build.sh
+++ b/docker/packager/binary/build.sh
@@ -55,7 +55,8 @@ ccache --zero-stats ||:
if [ "$BUILD_MUSL_KEEPER" == "1" ]
then
# build keeper with musl separately
- cmake --debug-trycompile -DBUILD_STANDALONE_KEEPER=1 -DENABLE_CLICKHOUSE_KEEPER=1 -DCMAKE_VERBOSE_MAKEFILE=1 -DUSE_MUSL=1 -LA -DCMAKE_TOOLCHAIN_FILE=/build/cmake/linux/toolchain-x86_64-musl.cmake "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" "-DSANITIZE=$SANITIZER" -DENABLE_CHECK_HEAVY_BUILDS=1 "${CMAKE_FLAGS[@]}" ..
+ # and without rust bindings
+ cmake --debug-trycompile -DENABLE_RUST=OFF -DBUILD_STANDALONE_KEEPER=1 -DENABLE_CLICKHOUSE_KEEPER=1 -DCMAKE_VERBOSE_MAKEFILE=1 -DUSE_MUSL=1 -LA -DCMAKE_TOOLCHAIN_FILE=/build/cmake/linux/toolchain-x86_64-musl.cmake "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" "-DSANITIZE=$SANITIZER" -DENABLE_CHECK_HEAVY_BUILDS=1 "${CMAKE_FLAGS[@]}" ..
# shellcheck disable=SC2086 # No quotes because I want it to expand to nothing if empty.
ninja $NINJA_FLAGS clickhouse-keeper
diff --git a/docker/packager/packager b/docker/packager/packager
index 7f6bd8818fb..716071fcac6 100755
--- a/docker/packager/packager
+++ b/docker/packager/packager
@@ -131,7 +131,7 @@ def parse_env_variables(
ARM_V80COMPAT_SUFFIX = "-aarch64-v80compat"
FREEBSD_SUFFIX = "-freebsd"
PPC_SUFFIX = "-ppc64le"
- AMD64_SSE2_SUFFIX = "-amd64sse2"
+ AMD64_COMPAT_SUFFIX = "-amd64-compat"
result = []
result.append("OUTPUT_DIR=/output")
@@ -144,7 +144,7 @@ def parse_env_variables(
is_cross_arm_v80compat = compiler.endswith(ARM_V80COMPAT_SUFFIX)
is_cross_ppc = compiler.endswith(PPC_SUFFIX)
is_cross_freebsd = compiler.endswith(FREEBSD_SUFFIX)
- is_amd64_sse2 = compiler.endswith(AMD64_SSE2_SUFFIX)
+ is_amd64_compat = compiler.endswith(AMD64_COMPAT_SUFFIX)
if is_cross_darwin:
cc = compiler[: -len(DARWIN_SUFFIX)]
@@ -197,8 +197,8 @@ def parse_env_variables(
cmake_flags.append(
"-DCMAKE_TOOLCHAIN_FILE=/build/cmake/linux/toolchain-ppc64le.cmake"
)
- elif is_amd64_sse2:
- cc = compiler[: -len(AMD64_SSE2_SUFFIX)]
+ elif is_amd64_compat:
+ cc = compiler[: -len(AMD64_COMPAT_SUFFIX)]
result.append("DEB_ARCH=amd64")
cmake_flags.append("-DNO_SSE3_OR_HIGHER=1")
else:
@@ -358,7 +358,7 @@ if __name__ == "__main__":
"clang-15-aarch64",
"clang-15-aarch64-v80compat",
"clang-15-ppc64le",
- "clang-15-amd64sse2",
+ "clang-15-amd64-compat",
"clang-15-freebsd",
"gcc-11",
),
diff --git a/docker/server/Dockerfile.alpine b/docker/server/Dockerfile.alpine
index 305fc279414..22d6282d71c 100644
--- a/docker/server/Dockerfile.alpine
+++ b/docker/server/Dockerfile.alpine
@@ -33,7 +33,7 @@ RUN arch=${TARGETARCH:-amd64} \
# lts / testing / prestable / etc
ARG REPO_CHANNEL="stable"
ARG REPOSITORY="https://packages.clickhouse.com/tgz/${REPO_CHANNEL}"
-ARG VERSION="22.11.2.30"
+ARG VERSION="22.12.1.1752"
ARG PACKAGES="clickhouse-client clickhouse-server clickhouse-common-static"
# user/group precreated explicitly with fixed uid/gid on purpose.
diff --git a/docker/server/Dockerfile.ubuntu b/docker/server/Dockerfile.ubuntu
index f1c4dd097aa..3135ec508de 100644
--- a/docker/server/Dockerfile.ubuntu
+++ b/docker/server/Dockerfile.ubuntu
@@ -21,7 +21,7 @@ RUN sed -i "s|http://archive.ubuntu.com|${apt_archive}|g" /etc/apt/sources.list
ARG REPO_CHANNEL="stable"
ARG REPOSITORY="deb https://packages.clickhouse.com/deb ${REPO_CHANNEL} main"
-ARG VERSION="22.11.2.30"
+ARG VERSION="22.12.1.1752"
ARG PACKAGES="clickhouse-client clickhouse-server clickhouse-common-static"
# set non-empty deb_location_url url to create a docker image
diff --git a/docker/test/fasttest/run.sh b/docker/test/fasttest/run.sh
index 7359e0a9402..bf6f9bc9e49 100755
--- a/docker/test/fasttest/run.sh
+++ b/docker/test/fasttest/run.sh
@@ -116,6 +116,7 @@ function clone_submodules
contrib/base64
contrib/cctz
contrib/libcpuid
+ contrib/libdivide
contrib/double-conversion
contrib/llvm-project
contrib/lz4
diff --git a/docker/test/integration/runner/dockerd-entrypoint.sh b/docker/test/integration/runner/dockerd-entrypoint.sh
index 5ae880ddf36..c16b2bf1087 100755
--- a/docker/test/integration/runner/dockerd-entrypoint.sh
+++ b/docker/test/integration/runner/dockerd-entrypoint.sh
@@ -12,6 +12,10 @@ echo '{
"registry-mirrors" : ["http://dockerhub-proxy.dockerhub-proxy-zone:5000"]
}' | dd of=/etc/docker/daemon.json 2>/dev/null
+# In case of test hung it is convenient to use pytest --pdb to debug it,
+# and on hung you can simply press Ctrl-C and it will spawn a python pdb,
+# but on SIGINT dockerd will exit, so ignore it to preserve the daemon.
+trap '' INT
dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --default-address-pool base=172.17.0.0/12,size=24 &>/ClickHouse/tests/integration/dockerd.log &
set +e
diff --git a/docker/test/stateful/Dockerfile b/docker/test/stateful/Dockerfile
index 234d0861f8b..b67a638188c 100644
--- a/docker/test/stateful/Dockerfile
+++ b/docker/test/stateful/Dockerfile
@@ -17,6 +17,7 @@ ENV S3_URL="https://clickhouse-datasets.s3.amazonaws.com"
ENV DATASETS="hits visits"
RUN npm install -g azurite
+RUN npm install tslib
COPY run.sh /
CMD ["/bin/bash", "/run.sh"]
diff --git a/docker/test/stateless/Dockerfile b/docker/test/stateless/Dockerfile
index a497d3443b0..40109255a7e 100644
--- a/docker/test/stateless/Dockerfile
+++ b/docker/test/stateless/Dockerfile
@@ -80,6 +80,7 @@ ENV MINIO_ROOT_PASSWORD="clickhouse"
ENV EXPORT_S3_STORAGE_POLICIES=1
RUN npm install -g azurite
+RUN npm install tslib
COPY run.sh /
COPY setup_minio.sh /
diff --git a/docker/test/stress/run.sh b/docker/test/stress/run.sh
index 5cb27d90b62..01e0f5b4897 100644
--- a/docker/test/stress/run.sh
+++ b/docker/test/stress/run.sh
@@ -131,19 +131,20 @@ function stop()
# Preserve the pid, since the server can hung after the PID will be deleted.
pid="$(cat /var/run/clickhouse-server/clickhouse-server.pid)"
- # --max-tries is supported only since 22.12
- if dpkg --compare-versions "$(clickhouse local -q 'select version()')" ge "22.12"; then
- # Increase default waiting timeout for sanitizers and debug builds
- clickhouse stop --max-tries 180 --do-not-kill && return
- else
- clickhouse stop --do-not-kill && return
+ clickhouse stop $max_tries --do-not-kill && return
+
+ if [ -n "$1" ]
+ then
+ # temporarily disable it in BC check
+ clickhouse stop --force
+ return
fi
# We failed to stop the server with SIGTERM. Maybe it hang, let's collect stacktraces.
kill -TERM "$(pidof gdb)" ||:
sleep 5
echo "thread apply all backtrace (on stop)" >> /test_output/gdb.log
- gdb -batch -ex 'thread apply all backtrace' -p "$pid" | ts '%Y-%m-%d %H:%M:%S' >> /test_output/gdb.log
+ timeout 30m gdb -batch -ex 'thread apply all backtrace' -p "$pid" | ts '%Y-%m-%d %H:%M:%S' >> /test_output/gdb.log
clickhouse stop --force
}
@@ -431,7 +432,7 @@ else
clickhouse-client --query="SELECT 'Tables count:', count() FROM system.tables"
- stop
+ stop 1
mv /var/log/clickhouse-server/clickhouse-server.log /var/log/clickhouse-server/clickhouse-server.backward.stress.log
# Start new server
@@ -497,6 +498,7 @@ else
-e "Coordination::Exception: Connection loss" \
-e "MutateFromLogEntryTask" \
-e "No connection to ZooKeeper, cannot get shared table ID" \
+ -e "Session expired" \
/var/log/clickhouse-server/clickhouse-server.backward.clean.log | zgrep -Fa "" > /test_output/bc_check_error_messages.txt \
&& echo -e 'Backward compatibility check: Error message in clickhouse-server.log (see bc_check_error_messages.txt)\tFAIL' >> /test_output/test_results.tsv \
|| echo -e 'Backward compatibility check: No Error messages in clickhouse-server.log\tOK' >> /test_output/test_results.tsv
diff --git a/docker/test/style/process_style_check_result.py b/docker/test/style/process_style_check_result.py
index 6dc3d05d051..2edf6ba3591 100755
--- a/docker/test/style/process_style_check_result.py
+++ b/docker/test/style/process_style_check_result.py
@@ -19,6 +19,7 @@ def process_result(result_folder):
"typos",
"whitespaces",
"workflows",
+ "submodules",
"docs spelling",
)
diff --git a/docker/test/style/run.sh b/docker/test/style/run.sh
index 80911bf8627..315efb9e6c4 100755
--- a/docker/test/style/run.sh
+++ b/docker/test/style/run.sh
@@ -10,7 +10,7 @@ echo "Check style" | ts
echo "Check python formatting with black" | ts
./check-black -n |& tee /test_output/black_output.txt
echo "Check python type hinting with mypy" | ts
-./check-mypy -n |& tee /test_output/mypy_output.txt
+./check-mypy -n |& tee /test_output/mypy_output.txt
echo "Check typos" | ts
./check-typos |& tee /test_output/typos_output.txt
echo "Check docs spelling" | ts
@@ -19,6 +19,8 @@ echo "Check whitespaces" | ts
./check-whitespaces -n |& tee /test_output/whitespaces_output.txt
echo "Check workflows" | ts
./check-workflows |& tee /test_output/workflows_output.txt
+echo "Check submodules" | ts
+./check-submodules |& tee /test_output/submodules_output.txt
echo "Check shell scripts with shellcheck" | ts
./shellcheck-run.sh |& tee /test_output/shellcheck_output.txt
/process_style_check_result.py || echo -e "failure\tCannot parse results" > /test_output/check_status.tsv
diff --git a/docker/test/testflows/runner/dockerd-entrypoint.sh b/docker/test/testflows/runner/dockerd-entrypoint.sh
index 0e15396082a..d310ee583bf 100755
--- a/docker/test/testflows/runner/dockerd-entrypoint.sh
+++ b/docker/test/testflows/runner/dockerd-entrypoint.sh
@@ -10,6 +10,10 @@ cat > /etc/docker/daemon.json << EOF
}
EOF
+# In case of test hung it is convenient to use pytest --pdb to debug it,
+# and on hung you can simply press Ctrl-C and it will spawn a python pdb,
+# but on SIGINT dockerd will exit, so ignore it to preserve the daemon.
+trap '' INT
dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 &>/var/log/somefile &
set +e
diff --git a/docs/_includes/install/universal.sh b/docs/_includes/install/universal.sh
index 30766cb6052..de34897a6f6 100755
--- a/docs/_includes/install/universal.sh
+++ b/docs/_includes/install/universal.sh
@@ -9,14 +9,22 @@ if [ "${OS}" = "Linux" ]
then
if [ "${ARCH}" = "x86_64" -o "${ARCH}" = "amd64" ]
then
- DIR="amd64"
+ # Require at least x86-64 + SSE4.2 (introduced in 2006). On older hardware fall back to plain x86-64 (introduced in 1999) which
+ # guarantees at least SSE2. The caveat is that plain x86-64 builds are much less tested than SSE 4.2 builds.
+ HAS_SSE42=$(grep sse4_2 /proc/cpuinfo)
+ if [ "${HAS_SSE42}" ]
+ then
+ DIR="amd64"
+ else
+ DIR="amd64compat"
+ fi
elif [ "${ARCH}" = "aarch64" -o "${ARCH}" = "arm64" ]
then
# If the system has >=ARMv8.2 (https://en.wikipedia.org/wiki/AArch64), choose the corresponding build, else fall back to a v8.0
# compat build. Unfortunately, the ARM ISA level cannot be read directly, we need to guess from the "features" in /proc/cpuinfo.
# Also, the flags in /proc/cpuinfo are named differently than the flags passed to the compiler (cmake/cpu_features.cmake).
- ARMV82=$(grep -m 1 'Features' /proc/cpuinfo | awk '/asimd/ && /sha1/ && /aes/ && /atomics/ && /lrcpc/')
- if [ "${ARMV82}" ]
+ HAS_ARMV82=$(grep -m 1 'Features' /proc/cpuinfo | awk '/asimd/ && /sha1/ && /aes/ && /atomics/ && /lrcpc/')
+ if [ "${HAS_ARMV82}" ]
then
DIR="aarch64"
else
diff --git a/docs/changelogs/v22.12.1.1752-stable.md b/docs/changelogs/v22.12.1.1752-stable.md
new file mode 100644
index 00000000000..9b3d2379277
--- /dev/null
+++ b/docs/changelogs/v22.12.1.1752-stable.md
@@ -0,0 +1,320 @@
+---
+sidebar_position: 1
+sidebar_label: 2022
+---
+
+# 2022 Changelog
+
+### ClickHouse release v22.12.1.1752-stable (688e488e930) FIXME as compared to v22.11.1.1360-stable (0d211ed1984)
+
+#### Backward Incompatible Change
+* Fixed backward incompatibility in (de)serialization of states of `min`, `max`, `any*`, `argMin`, `argMax` aggregate functions with `String` argument. The incompatibility was introduced in https://github.com/ClickHouse/ClickHouse/pull/41431 and affects 22.9, 22.10 and 22.11 branches (fixed since 22.9.6, 22.10.4 and 22.11.2 correspondingly). Some minor releases of 22.3, 22.7 and 22.8 branches are also affected: 22.3.13...22.3.14 (fixed since 22.3.15), 22.8.6...22.8.9 (fixed since 22.8.10), 22.7.6 and newer (will not be fixed in 22.7, we recommend to upgrade from 22.7.* to 22.8.10 or newer). This release note does not concern users that have never used affected versions. Incompatible versions append extra `'\0'` to strings when reading states of the aggregate functions mentioned above. For example, if an older version saved state of `anyState('foobar')` to `state_column` then incompatible version will print `'foobar\0'` on `anyMerge(state_column)`. Also incompatible versions write states of the aggregate functions without trailing `'\0'`. Newer versions (that have the fix) can correctly read data written by all versions including incompatible versions, except one corner case. If an incompatible version saved a state with a string that actually ends with null character, then newer version will trim trailing `'\0'` when reading state of affected aggregate function. For example, if an incompatible version saved state of `anyState('abrac\0dabra\0')` to `state_column` then newer versions will print `'abrac\0dabra'` on `anyMerge(state_column)`. The issue also affects distributed queries when an incompatible version works in a cluster together with older or newer versions. [#43038](https://github.com/ClickHouse/ClickHouse/pull/43038) ([Raúl Marín](https://github.com/Algunenano)).
+
+#### New Feature
+* Add "grace_hash" join_algorithm. [#38191](https://github.com/ClickHouse/ClickHouse/pull/38191) ([BigRedEye](https://github.com/BigRedEye)).
+* Merging on initiator now uses the same memory bound approach as merging of local aggregation results if `enable_memory_bound_merging_of_aggregation_results` is set. [#40879](https://github.com/ClickHouse/ClickHouse/pull/40879) ([Nikita Taranov](https://github.com/nickitat)).
+* Add BSONEachRow input/output format. In this format, ClickHouse formats/parses each row as a separated BSON Document and each column is formatted/parsed as a single BSON field with column name as a key. [#42033](https://github.com/ClickHouse/ClickHouse/pull/42033) ([mark-polokhov](https://github.com/mark-polokhov)).
+* close: [#37631](https://github.com/ClickHouse/ClickHouse/issues/37631). [#42265](https://github.com/ClickHouse/ClickHouse/pull/42265) ([刘陶峰](https://github.com/taofengliu)).
+* Added `multiplyDecimal` and `divideDecimal` functions for decimal operations with fixed precision. [#42438](https://github.com/ClickHouse/ClickHouse/pull/42438) ([Andrey Zvonov](https://github.com/zvonand)).
+* Added `system.moves` table with list of currently moving parts. [#42660](https://github.com/ClickHouse/ClickHouse/pull/42660) ([Sergei Trifonov](https://github.com/serxa)).
+* Keeper feature: add support for embedded Prometheus endpoint. [#43087](https://github.com/ClickHouse/ClickHouse/pull/43087) ([Antonio Andelic](https://github.com/antonio2368)).
+* Added age function to calculate difference between two dates or dates with time values expressed as number of full units. Close [#41115](https://github.com/ClickHouse/ClickHouse/issues/41115). [#43123](https://github.com/ClickHouse/ClickHouse/pull/43123) ([Roman Vasin](https://github.com/rvasin)).
+* Add settings `max_streams_for_merge_tree_reading` and `allow_asynchronous_read_from_io_pool_for_merge_tree`. Setting `max_streams_for_merge_tree_reading` limits the number of reading streams for MergeTree tables. Setting `allow_asynchronous_read_from_io_pool_for_merge_tree` enables background I/O pool to read from `MergeTree` tables. This may increase performance for I/O bound queries if used together with `max_streams_to_max_threads_ratio` or `max_streams_for_merge_tree_reading`. [#43260](https://github.com/ClickHouse/ClickHouse/pull/43260) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
+* Add the expression of the index on `data_skipping_indices` system table. [#43308](https://github.com/ClickHouse/ClickHouse/pull/43308) ([Guillaume Tassery](https://github.com/YiuRULE)).
+* New hash function [xxh3](https://github.com/Cyan4973/xxHash) added. Also performance of `xxHash32` and `xxHash64` improved on arm thanks to library update. [#43411](https://github.com/ClickHouse/ClickHouse/pull/43411) ([Nikita Taranov](https://github.com/nickitat)).
+* - Temporary data (for external sorting, aggregation, and JOINs) can share storage with the filesystem cache for remote disks and evict it, close [#42158](https://github.com/ClickHouse/ClickHouse/issues/42158). [#43457](https://github.com/ClickHouse/ClickHouse/pull/43457) ([Vladimir C](https://github.com/vdimir)).
+* Add column `engine_full` to system table `databases` so that users can access whole engine definition of database via system tables. [#43468](https://github.com/ClickHouse/ClickHouse/pull/43468) ([凌涛](https://github.com/lingtaolf)).
+* Add password complexity rules and checks for creating a new user. [#43719](https://github.com/ClickHouse/ClickHouse/pull/43719) ([Nikolay Degterinsky](https://github.com/evillique)).
+* Add function concatWithSeparator , like concat_ws in spark. [#43749](https://github.com/ClickHouse/ClickHouse/pull/43749) ([李扬](https://github.com/taiyang-li)).
+* Added constraints for merge tree settings. [#43903](https://github.com/ClickHouse/ClickHouse/pull/43903) ([Sergei Trifonov](https://github.com/serxa)).
+* Support numeric literals with _ as separator. [#43925](https://github.com/ClickHouse/ClickHouse/pull/43925) ([jh0x](https://github.com/jh0x)).
+* Add a new setting `input_format_json_read_objects_as_strings` that allows to parse nested JSON objects into Strings in all JSON input formats. This setting is disable by default. [#44052](https://github.com/ClickHouse/ClickHouse/pull/44052) ([Kruglov Pavel](https://github.com/Avogar)).
+
+#### Performance Improvement
+* Optimisation is getting skipped now if `max_size_to_preallocate_for_aggregation` has too small value. Default value of this setting increased to `10^8`. [#43945](https://github.com/ClickHouse/ClickHouse/pull/43945) ([Nikita Taranov](https://github.com/nickitat)).
+
+#### Improvement
+* Support numeric literals with underscores. closes [#28967](https://github.com/ClickHouse/ClickHouse/issues/28967). [#39129](https://github.com/ClickHouse/ClickHouse/pull/39129) ([unbyte](https://github.com/unbyte)).
+* Add `FROM table SELECT column` syntax. [#41095](https://github.com/ClickHouse/ClickHouse/pull/41095) ([Nikolay Degterinsky](https://github.com/evillique)).
+* This PR changes how followed queries delete parts: truncate table, alter table drop part, alter table drop partition. Now these queries make empty parts which cover old parts. This makes truncate query works without exclusive lock which means concurrent reads aren't locked. Also achieved durability in all those queries. If request is succeeded then no resurrected pars appear later. Note that atomicity is achieved only with transaction scope. [#41145](https://github.com/ClickHouse/ClickHouse/pull/41145) ([Sema Checherinda](https://github.com/CheSema)).
+* `SET param_x` query no longer requires manual string serialization for the value of the parameter. For example, query `SET param_a = '[\'a\', \'b\']'` can now be written like `SET param_a = ['a', 'b']`. [#41874](https://github.com/ClickHouse/ClickHouse/pull/41874) ([Nikolay Degterinsky](https://github.com/evillique)).
+* `filesystemAvailable` and related functions support one optional argument with disk name, and change `filesystemFree` to `filesystemUnreserved`. Closes [#35076](https://github.com/ClickHouse/ClickHouse/issues/35076). [#42064](https://github.com/ClickHouse/ClickHouse/pull/42064) ([flynn](https://github.com/ucasfl)).
+* Increased the default value of search_limit to 256, and added LDAP server config option to change that to an arbitrary value. Closes: [#42276](https://github.com/ClickHouse/ClickHouse/issues/42276). [#42461](https://github.com/ClickHouse/ClickHouse/pull/42461) ([Vasily Nemkov](https://github.com/Enmk)).
+* Add cosine distance for annoy. [#42778](https://github.com/ClickHouse/ClickHouse/pull/42778) ([Filatenkov Artur](https://github.com/FArthur-cmd)).
+* Allow to remove sensitive information from the exception messages also. Resolves [#41418](https://github.com/ClickHouse/ClickHouse/issues/41418). [#42940](https://github.com/ClickHouse/ClickHouse/pull/42940) ([filimonov](https://github.com/filimonov)).
+* Keeper improvement: Add 4lw command `rqld` which can manually assign a node as leader. [#43026](https://github.com/ClickHouse/ClickHouse/pull/43026) ([JackyWoo](https://github.com/JackyWoo)).
+* Apply connection timeouts settings for Distributed async INSERT from the query. [#43156](https://github.com/ClickHouse/ClickHouse/pull/43156) ([Azat Khuzhin](https://github.com/azat)).
+* unhex function support FixedString arguments. [issue42369](https://github.com/ClickHouse/ClickHouse/issues/42369). [#43207](https://github.com/ClickHouse/ClickHouse/pull/43207) ([DR](https://github.com/freedomDR)).
+* Priority is given to deleting completely expired Parts,related [#42869](https://github.com/ClickHouse/ClickHouse/issues/42869). [#43222](https://github.com/ClickHouse/ClickHouse/pull/43222) ([zhongyuankai](https://github.com/zhongyuankai)).
+* Follow-up to https://github.com/ClickHouse/ClickHouse/pull/42484. Mask sensitive information in logs better; mask secret parts in the output of queries `SHOW CREATE TABLE` and `SELECT FROM system.tables`. Also resolves [#41418](https://github.com/ClickHouse/ClickHouse/issues/41418). [#43227](https://github.com/ClickHouse/ClickHouse/pull/43227) ([Vitaly Baranov](https://github.com/vitlibar)).
+* Enable compress marks and primary key. [#43288](https://github.com/ClickHouse/ClickHouse/pull/43288) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
+* resolve issue [#38075](https://github.com/ClickHouse/ClickHouse/issues/38075) . Right now async insert doesn't support deduplication, because multiple small inserts will coexist in one part, which corespond multiple `block id`s. This solution is straitfoward: The change involves: 1. mark offsets for every inserts in every chunk 2. calculate multiple `block_id`s when sinker receive a chunk 3. get block number lock by these `block_id`s 3.1. if fails, remove the dup insert(s) and dup `block_id`(s) from block and recalculate `offsets` agian. 3.2. if succeeds, commit `block_id`'s and other items into keeper a. if fails, do 3.1 b. if succeeds, everything succeeds. [#43304](https://github.com/ClickHouse/ClickHouse/pull/43304) ([Han Fei](https://github.com/hanfei1991)).
+* More precise and reactive CPU load indication on client. [#43307](https://github.com/ClickHouse/ClickHouse/pull/43307) ([Sergei Trifonov](https://github.com/serxa)).
+* Restrict default access to named collections for user defined in config. It must have explicit `show_named_collections=1` to be able to see them. [#43325](https://github.com/ClickHouse/ClickHouse/pull/43325) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Support reading of subcolumns of nested types from storage `S3` and table function `s3` with formats `Parquet`, `Arrow` and `ORC`. [#43329](https://github.com/ClickHouse/ClickHouse/pull/43329) ([chen](https://github.com/xiedeyantu)).
+* - Systemd integration now correctly notifies systemd that service is really started and is ready to server requests. [#43400](https://github.com/ClickHouse/ClickHouse/pull/43400) ([Коренберг Марк](https://github.com/socketpair)).
+* Add table_uuid to system.parts. [#43404](https://github.com/ClickHouse/ClickHouse/pull/43404) ([Azat Khuzhin](https://github.com/azat)).
+* Added client option to display the number of locally processed rows in non-interactive mode (--print-num-processed-rows). [#43407](https://github.com/ClickHouse/ClickHouse/pull/43407) ([jh0x](https://github.com/jh0x)).
+* Show read rows while reading from stdin from client. Closes [#43423](https://github.com/ClickHouse/ClickHouse/issues/43423). [#43442](https://github.com/ClickHouse/ClickHouse/pull/43442) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Keeper improvement: try syncing logs to disk in parallel with replication. [#43450](https://github.com/ClickHouse/ClickHouse/pull/43450) ([Antonio Andelic](https://github.com/antonio2368)).
+* Show progress bar while reading from s3 table function / engine. [#43454](https://github.com/ClickHouse/ClickHouse/pull/43454) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Progress bar will show both read and written rows. [#43496](https://github.com/ClickHouse/ClickHouse/pull/43496) ([Ilya Yatsishin](https://github.com/qoega)).
+* Implement `aggregation-in-order` optimization on top of query plan. It is enabled by default (but works only together with `optimize_aggregation_in_order`, which is disabled by default). Set `query_plan_aggregation_in_order = 0` to use previous AST-based version. [#43592](https://github.com/ClickHouse/ClickHouse/pull/43592) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
+* Allow to send profile events with `trace_type = 'ProfileEvent'` to `system.trace_log` on each increment with current stack, profile event name and value of increment. It can be enabled by setting `trace_profile_events` and used to debug performance of queries. [#43639](https://github.com/ClickHouse/ClickHouse/pull/43639) ([Anton Popov](https://github.com/CurtizJ)).
+* Keeper improvement: requests are batched more often. The batching can be controlled with the new setting `max_requests_quick_batch_size`. [#43686](https://github.com/ClickHouse/ClickHouse/pull/43686) ([Antonio Andelic](https://github.com/antonio2368)).
+* Added possibility to use array as a second parameter for cutURLParameter function. Close [#6827](https://github.com/ClickHouse/ClickHouse/issues/6827). [#43788](https://github.com/ClickHouse/ClickHouse/pull/43788) ([Roman Vasin](https://github.com/rvasin)).
+* Implement referential dependencies and use them to create tables in the correct order while restoring from a backup. [#43834](https://github.com/ClickHouse/ClickHouse/pull/43834) ([Vitaly Baranov](https://github.com/vitlibar)).
+* Add a new setting `input_format_max_binary_string_size` to limit string size in RowBinary format. [#43842](https://github.com/ClickHouse/ClickHouse/pull/43842) ([Kruglov Pavel](https://github.com/Avogar)).
+* - Fix some incorrect logic in ast level optimization related. [#43873](https://github.com/ClickHouse/ClickHouse/pull/43873) ([Duc Canh Le](https://github.com/canhld94)).
+* Support query like `SHOW FULL TABLES ...`. [#43910](https://github.com/ClickHouse/ClickHouse/pull/43910) ([Filatenkov Artur](https://github.com/FArthur-cmd)).
+* When ClickHouse requests a remote HTTP server, and it returns an error, the numeric HTTP code was not displayed correctly in the exception message. Closes [#43919](https://github.com/ClickHouse/ClickHouse/issues/43919). [#43920](https://github.com/ClickHouse/ClickHouse/pull/43920) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Settings `merge_tree_min_rows_for_concurrent_read_for_remote_filesystem/merge_tree_min_bytes_for_concurrent_read_for_remote_filesystem` did not respect adaptive granularity. Fat rows did not decrease the number of read rows (as it is was done for `merge_tree_min_rows_for_concurrent_read/merge_tree_min_bytes_for_concurrent_read`, which could lead to high memory usage. [#43965](https://github.com/ClickHouse/ClickHouse/pull/43965) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
+* Support `optimize_if_transform_strings_to_enum` in new analyzer. [#43999](https://github.com/ClickHouse/ClickHouse/pull/43999) ([Antonio Andelic](https://github.com/antonio2368)).
+* This is to upgrade the new "DeflateQpl" compression codec which has been implemented on previous PR (details: https://github.com/ClickHouse/ClickHouse/pull/39494). This patch improves codec on below aspects: 1. QPL v0.2.0 to QPL v0.3.0 [Intel® Query Processing Library (QPL)](https://github.com/intel/qpl) 2. Improve CMake file for fixing QPL build issues for QPL v0.3.0。 3. Link the QPL library with libaccel-config at build time instead of runtime loading on QPL v0.2.0 (dlopen) 4. Fixed log print issue in CompressionCodecDeflateQpl.cpp. [#44024](https://github.com/ClickHouse/ClickHouse/pull/44024) ([jasperzhu](https://github.com/jinjunzh)).
+* Follow-up to https://github.com/ClickHouse/ClickHouse/pull/43834 Fix review issues; dependencies from `Distributed` table engine and from `cluster()` function are also considered now; as well as dependencies of a dictionary defined without host & port specified. [#44158](https://github.com/ClickHouse/ClickHouse/pull/44158) ([Vitaly Baranov](https://github.com/vitlibar)).
+
+#### Bug Fix
+* Fix mutations not making progress when checksums do not match between replicas (e.g. caused by a change in data format on an upgrade). [#36877](https://github.com/ClickHouse/ClickHouse/pull/36877) ([nvartolomei](https://github.com/nvartolomei)).
+* fix skip_unavailable_shards does not work using hdfsCluster table function. [#43236](https://github.com/ClickHouse/ClickHouse/pull/43236) ([chen](https://github.com/xiedeyantu)).
+* fix s3 support question mark wildcard. Closes [#42731](https://github.com/ClickHouse/ClickHouse/issues/42731). [#43253](https://github.com/ClickHouse/ClickHouse/pull/43253) ([chen](https://github.com/xiedeyantu)).
+* - Fix functions arrayFirstOrNull and arrayLastOrNull or null when array is Nullable. [#43274](https://github.com/ClickHouse/ClickHouse/pull/43274) ([Duc Canh Le](https://github.com/canhld94)).
+* - we create a new zk path called "async_blocks" for replicated tables in [#43304](https://github.com/ClickHouse/ClickHouse/issues/43304) . However, for tables created in older versions, this path does not exist and will cause error when doing partition operations. This PR will create this node when initializing replicated tree. - This PR created a flag `async_insert_deduplicate` with `false` default value to control whether to use this function. As mentioned in [#38075](https://github.com/ClickHouse/ClickHouse/issues/38075) , this function is not yet fully finished. I would turn off it by default. [#44223](https://github.com/ClickHouse/ClickHouse/pull/44223) ([Han Fei](https://github.com/hanfei1991)).
+
+#### Build/Testing/Packaging Improvement
+* Add support for FreeBSD/powerpc64le. [#40422](https://github.com/ClickHouse/ClickHouse/pull/40422) ([pkubaj](https://github.com/pkubaj)).
+* Bump Testcontainers for Go to v0.15.0. [#43278](https://github.com/ClickHouse/ClickHouse/pull/43278) ([Manuel de la Peña](https://github.com/mdelapenya)).
+* ... Enable base64 on s390x > Information about CI checks: https://clickhouse.com/docs/en/development/continuous-integration/. [#43352](https://github.com/ClickHouse/ClickHouse/pull/43352) ([Suzy Wang](https://github.com/SuzyWangIBMer)).
+* Shutdown will be much faster if do not call clearOldPartsFromFilesystem. Especially this is right for tests with zero-copy due to single thread deletion parts. clearOldPartsFromFilesystem is unnecessary after https://github.com/ClickHouse/ClickHouse/pull/41145. [#43760](https://github.com/ClickHouse/ClickHouse/pull/43760) ([Sema Checherinda](https://github.com/CheSema)).
+* Integrate skim into the client/local. [#43922](https://github.com/ClickHouse/ClickHouse/pull/43922) ([Azat Khuzhin](https://github.com/azat)).
+* Allow clickhouse to use openssl as a dynamic library and in-tree for development purposes. [#43991](https://github.com/ClickHouse/ClickHouse/pull/43991) ([Boris Kuschel](https://github.com/bkuschel)).
+* Closes [#43912](https://github.com/ClickHouse/ClickHouse/issues/43912). [#43992](https://github.com/ClickHouse/ClickHouse/pull/43992) ([Nikolay Degterinsky](https://github.com/evillique)).
+* Bring sha512 sums back to the building step. [#44017](https://github.com/ClickHouse/ClickHouse/pull/44017) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Kill stress tests after 2.5h in case of hanging process. [#44214](https://github.com/ClickHouse/ClickHouse/pull/44214) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+
+#### Bug Fix (user-visible misbehavior in official stable or prestable release)
+
+* Fixed unable to log in (because of failure to create session_log entry) in rare case of messed up setting profiles. ... [#42641](https://github.com/ClickHouse/ClickHouse/pull/42641) ([Vasily Nemkov](https://github.com/Enmk)).
+* Fix incorrect UserTimeMicroseconds/SystemTimeMicroseconds accounting. [#42791](https://github.com/ClickHouse/ClickHouse/pull/42791) ([Azat Khuzhin](https://github.com/azat)).
+* Do not suppress exceptions in web disk. Fix retries for web disk. [#42800](https://github.com/ClickHouse/ClickHouse/pull/42800) ([Azat Khuzhin](https://github.com/azat)).
+* Fixed race condition between inserts and dropping MVs. [#43161](https://github.com/ClickHouse/ClickHouse/pull/43161) ([AlfVII](https://github.com/AlfVII)).
+* Fixed bug which could lead to deadlock while using asynchronous inserts. [#43233](https://github.com/ClickHouse/ClickHouse/pull/43233) ([Anton Popov](https://github.com/CurtizJ)).
+* Additional check on zero uncompressed size is added to `CompressionCodecDelta`. [#43255](https://github.com/ClickHouse/ClickHouse/pull/43255) ([Nikita Taranov](https://github.com/nickitat)).
+* An issue with the following exception has been reported while trying to read a Parquet file from S3 into ClickHouse:. [#43297](https://github.com/ClickHouse/ClickHouse/pull/43297) ([Arthur Passos](https://github.com/arthurpassos)).
+* Fix bad cast from LowCardinality column when using short circuit function execution. Proper fix of https://github.com/ClickHouse/ClickHouse/pull/42937. [#43311](https://github.com/ClickHouse/ClickHouse/pull/43311) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fixed queries with `SAMPLE BY` with prewhere optimization on tables using `Merge` engine. [#43315](https://github.com/ClickHouse/ClickHouse/pull/43315) ([Antonio Andelic](https://github.com/antonio2368)).
+* Fix `DESCRIBE` for `deltaLake` and `hudi` table functions. [#43323](https://github.com/ClickHouse/ClickHouse/pull/43323) ([Antonio Andelic](https://github.com/antonio2368)).
+* Check and compare the content of `format_version` file in `MergeTreeData` so tables can be loaded even if the storage policy was changed. [#43328](https://github.com/ClickHouse/ClickHouse/pull/43328) ([Antonio Andelic](https://github.com/antonio2368)).
+* Fix possible (very unlikely) "No column to rollback" logical error during INSERT into Buffer. [#43336](https://github.com/ClickHouse/ClickHouse/pull/43336) ([Azat Khuzhin](https://github.com/azat)).
+* Fix a bug that allowed FucntionParser to parse an unlimited amount of round brackets into one function if `allow_function_parameters` is set. [#43350](https://github.com/ClickHouse/ClickHouse/pull/43350) ([Nikolay Degterinsky](https://github.com/evillique)).
+* MaterializeMySQL support ddl: drop table t1,t2 and Compatible with most of MySQL drop ddl. [#43366](https://github.com/ClickHouse/ClickHouse/pull/43366) ([zzsmdfj](https://github.com/zzsmdfj)).
+* Fix possible `Cannot create non-empty column with type Nothing` in functions if/multiIf. Closes [#43356](https://github.com/ClickHouse/ClickHouse/issues/43356). [#43368](https://github.com/ClickHouse/ClickHouse/pull/43368) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fix a bug when row level filter uses default value of column. [#43387](https://github.com/ClickHouse/ClickHouse/pull/43387) ([Alexander Gololobov](https://github.com/davenger)).
+* Query with DISTINCT + LIMIT BY + LIMIT can return fewer rows than expected. Fixes [#43377](https://github.com/ClickHouse/ClickHouse/issues/43377). [#43410](https://github.com/ClickHouse/ClickHouse/pull/43410) ([Igor Nikonov](https://github.com/devcrafter)).
+* Fix sumMap() for Nullable(Decimal()). [#43414](https://github.com/ClickHouse/ClickHouse/pull/43414) ([Azat Khuzhin](https://github.com/azat)).
+* Fix date_diff() for hour/minute on macOS. Close [#42742](https://github.com/ClickHouse/ClickHouse/issues/42742). [#43466](https://github.com/ClickHouse/ClickHouse/pull/43466) ([zzsmdfj](https://github.com/zzsmdfj)).
+* Fix incorrect memory accounting because of merges/mutations. [#43516](https://github.com/ClickHouse/ClickHouse/pull/43516) ([Azat Khuzhin](https://github.com/azat)).
+* Substitute UDFs in `CREATE` query to avoid failures during loading at the startup. Additionally, UDFs can now be used as `DEFAULT` expressions for columns. [#43539](https://github.com/ClickHouse/ClickHouse/pull/43539) ([Antonio Andelic](https://github.com/antonio2368)).
+* Correctly report errors in queries even when multiple JOINs optimization is taking place. [#43583](https://github.com/ClickHouse/ClickHouse/pull/43583) ([Salvatore](https://github.com/tbsal)).
+* Fixed primary key analysis with conditions involving `toString(enum)`. [#43596](https://github.com/ClickHouse/ClickHouse/pull/43596) ([Nikita Taranov](https://github.com/nickitat)).
+* - Ensure consistency when copier update status and `attach_is_done` in keeper after partition attach is done. [#43602](https://github.com/ClickHouse/ClickHouse/pull/43602) ([lizhuoyu5](https://github.com/lzydmxy)).
+* During recovering of the lost replica there could a situation where we need to atomically swap two table names (use EXCHANGE), but instead previously we tried to use two RENAME queries. Which was obviously failed and moreover failed the whole recovery process of the database replica. [#43628](https://github.com/ClickHouse/ClickHouse/pull/43628) ([Nikita Mikhaylov](https://github.com/nikitamikhaylov)).
+* fix s3Cluster function returns NOT_FOUND_COLUMN_IN_BLOCK error. Closes [#43534](https://github.com/ClickHouse/ClickHouse/issues/43534). [#43629](https://github.com/ClickHouse/ClickHouse/pull/43629) ([chen](https://github.com/xiedeyantu)).
+* Optimized number of List requests to ZooKeeper when selecting a part to merge. Previously it could produce thousands of requests in some cases. Fixes [#43647](https://github.com/ClickHouse/ClickHouse/issues/43647). [#43675](https://github.com/ClickHouse/ClickHouse/pull/43675) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Fix posssible logical error 'Array sizes mismatched' while parsing JSON object with arrays with same key names but with different nesting level. Closes [#43569](https://github.com/ClickHouse/ClickHouse/issues/43569). [#43693](https://github.com/ClickHouse/ClickHouse/pull/43693) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fixed possible exception in case of distributed group by with an alias column among aggregation keys. [#43709](https://github.com/ClickHouse/ClickHouse/pull/43709) ([Nikita Taranov](https://github.com/nickitat)).
+* Fix bug which can lead to broken projections if zero-copy replication is enabled and used. [#43764](https://github.com/ClickHouse/ClickHouse/pull/43764) ([alesapin](https://github.com/alesapin)).
+* - Fix using multipart upload for large S3 objects in AWS S3. [#43824](https://github.com/ClickHouse/ClickHouse/pull/43824) ([ianton-ru](https://github.com/ianton-ru)).
+* Fixed `ALTER ... RESET SETTING` with `ON CLUSTER`. It could be applied to one replica only. Fixes [#43843](https://github.com/ClickHouse/ClickHouse/issues/43843). [#43848](https://github.com/ClickHouse/ClickHouse/pull/43848) ([Elena Torró](https://github.com/elenatorro)).
+* * Fix logical error in right storage join with using. [#43963](https://github.com/ClickHouse/ClickHouse/pull/43963) ([Vladimir C](https://github.com/vdimir)).
+* Keeper fix: throw if interserver port for Raft is already in use. Fix segfault in Prometheus when Raft server failed to initialize. [#43984](https://github.com/ClickHouse/ClickHouse/pull/43984) ([Antonio Andelic](https://github.com/antonio2368)).
+* Fix order by positional arg in case unneeded columns pruning. Closes [#43964](https://github.com/ClickHouse/ClickHouse/issues/43964). [#43987](https://github.com/ClickHouse/ClickHouse/pull/43987) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* * Fix bug with wrong order of keys in Storage Join. [#44012](https://github.com/ClickHouse/ClickHouse/pull/44012) ([Vladimir C](https://github.com/vdimir)).
+* Fixed exception when subquery contains having but doesn't contain actual aggregation. [#44051](https://github.com/ClickHouse/ClickHouse/pull/44051) ([Nikita Taranov](https://github.com/nickitat)).
+* Fix race in s3 multipart upload. This race could cause the error `Part number must be an integer between 1 and 10000, inclusive. (S3_ERROR)` while restoring from a backup. [#44065](https://github.com/ClickHouse/ClickHouse/pull/44065) ([Vitaly Baranov](https://github.com/vitlibar)).
+* Fix undefined behavior in the `quantiles` function, which might lead to uninitialized memory. Found by fuzzer. This closes [#44066](https://github.com/ClickHouse/ClickHouse/issues/44066). [#44067](https://github.com/ClickHouse/ClickHouse/pull/44067) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Prevent dropping nested column if it creates empty part. [#44159](https://github.com/ClickHouse/ClickHouse/pull/44159) ([Antonio Andelic](https://github.com/antonio2368)).
+* Fix `LOGICAL_ERROR` in case when fetch of part was stopped while fetching projection to the disk with enabled zero-copy replication. [#44173](https://github.com/ClickHouse/ClickHouse/pull/44173) ([Anton Popov](https://github.com/CurtizJ)).
+* Fix possible Bad cast from type DB::IAST const* to DB::ASTLiteral const*. Closes [#44191](https://github.com/ClickHouse/ClickHouse/issues/44191). [#44192](https://github.com/ClickHouse/ClickHouse/pull/44192) ([Kruglov Pavel](https://github.com/Avogar)).
+* Prevent `ReadonlyReplica` metric from having negative values. [#44220](https://github.com/ClickHouse/ClickHouse/pull/44220) ([Antonio Andelic](https://github.com/antonio2368)).
+
+#### Build Improvement
+
+* Fixed Endian issues in hex string conversion on s390x (which is not supported by ClickHouse). [#41245](https://github.com/ClickHouse/ClickHouse/pull/41245) ([Harry Lee](https://github.com/HarryLeeIBM)).
+* ... toDateTime64 conversion generates wrong time on z build, add bit_cast swap fix to support toDateTime64 on s390x platform. [#42847](https://github.com/ClickHouse/ClickHouse/pull/42847) ([Suzy Wang](https://github.com/SuzyWangIBMer)).
+* ... s390x support for ip coding functions. [#43078](https://github.com/ClickHouse/ClickHouse/pull/43078) ([Suzy Wang](https://github.com/SuzyWangIBMer)).
+* Fix byte order issue of wide integers for s390x. [#43228](https://github.com/ClickHouse/ClickHouse/pull/43228) ([Harry Lee](https://github.com/HarryLeeIBM)).
+* Fixed endian issue in bloom filter serialization for s390x. [#43642](https://github.com/ClickHouse/ClickHouse/pull/43642) ([Harry Lee](https://github.com/HarryLeeIBM)).
+* Fixed setting TCP_KEEPIDLE of client connection for s390x. [#43850](https://github.com/ClickHouse/ClickHouse/pull/43850) ([Harry Lee](https://github.com/HarryLeeIBM)).
+* Fix endian issue in StringHashTable for s390x. [#44049](https://github.com/ClickHouse/ClickHouse/pull/44049) ([Harry Lee](https://github.com/HarryLeeIBM)).
+
+#### NO CL ENTRY
+
+* NO CL ENTRY: 'Revert "Revert "S3 request per second rate throttling""'. [#43335](https://github.com/ClickHouse/ClickHouse/pull/43335) ([Sergei Trifonov](https://github.com/serxa)).
+* NO CL ENTRY: 'Update version after release'. [#43348](https://github.com/ClickHouse/ClickHouse/pull/43348) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* NO CL ENTRY: 'Revert "Add table_uuid to system.parts"'. [#43571](https://github.com/ClickHouse/ClickHouse/pull/43571) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* NO CL ENTRY: 'Revert "Fix endian issue in integer hex string conversion"'. [#43613](https://github.com/ClickHouse/ClickHouse/pull/43613) ([Vladimir C](https://github.com/vdimir)).
+* NO CL ENTRY: 'Update replication.md'. [#43643](https://github.com/ClickHouse/ClickHouse/pull/43643) ([Peignon Melvyn](https://github.com/melvynator)).
+* NO CL ENTRY: 'Revert "Temporary files evict fs cache"'. [#43883](https://github.com/ClickHouse/ClickHouse/pull/43883) ([Vladimir C](https://github.com/vdimir)).
+* NO CL ENTRY: 'Update html interface doc'. [#44064](https://github.com/ClickHouse/ClickHouse/pull/44064) ([San](https://github.com/santrancisco)).
+* NO CL ENTRY: 'Revert "Add function 'age'"'. [#44203](https://github.com/ClickHouse/ClickHouse/pull/44203) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* NO CL ENTRY: 'Revert "Builtin skim"'. [#44227](https://github.com/ClickHouse/ClickHouse/pull/44227) ([Azat Khuzhin](https://github.com/azat)).
+* NO CL ENTRY: 'Revert "Add information about written rows in progress indicator"'. [#44255](https://github.com/ClickHouse/ClickHouse/pull/44255) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+
+#### NOT FOR CHANGELOG / INSIGNIFICANT
+
+* Build libcxx and libcxxabi from llvm-project [#42730](https://github.com/ClickHouse/ClickHouse/pull/42730) ([Robert Schulze](https://github.com/rschu1ze)).
+* Allow release only from ready commits [#43019](https://github.com/ClickHouse/ClickHouse/pull/43019) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Add global flags to base/ libraries [#43082](https://github.com/ClickHouse/ClickHouse/pull/43082) ([Raúl Marín](https://github.com/Algunenano)).
+* Enable strict typing check in tests/ci [#43132](https://github.com/ClickHouse/ClickHouse/pull/43132) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Add server UUID for disks access checks (read/read-by-offset/write/delete) to avoid possible races [#43143](https://github.com/ClickHouse/ClickHouse/pull/43143) ([Azat Khuzhin](https://github.com/azat)).
+* Do not include libcxx library for C [#43166](https://github.com/ClickHouse/ClickHouse/pull/43166) ([Azat Khuzhin](https://github.com/azat)).
+* Followup fixes for FuseFunctionsPass [#43217](https://github.com/ClickHouse/ClickHouse/pull/43217) ([Vladimir C](https://github.com/vdimir)).
+* Fix bug in replication queue which can lead to premature mutation finish [#43231](https://github.com/ClickHouse/ClickHouse/pull/43231) ([alesapin](https://github.com/alesapin)).
+* Support `CREATE / ALTER / DROP NAMED COLLECTION` queries under according access types [#43252](https://github.com/ClickHouse/ClickHouse/pull/43252) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Fix race in `IColumn::dumpStructure` [#43269](https://github.com/ClickHouse/ClickHouse/pull/43269) ([Anton Popov](https://github.com/CurtizJ)).
+* Sanitize thirdparty libraries for public flags [#43275](https://github.com/ClickHouse/ClickHouse/pull/43275) ([Azat Khuzhin](https://github.com/azat)).
+* stress: increase timeout for server waiting after TERM [#43277](https://github.com/ClickHouse/ClickHouse/pull/43277) ([Azat Khuzhin](https://github.com/azat)).
+* Fix cloning of ASTIdentifier [#43282](https://github.com/ClickHouse/ClickHouse/pull/43282) ([Nikolay Degterinsky](https://github.com/evillique)).
+* Fix race on write in `ReplicatedMergeTree` [#43289](https://github.com/ClickHouse/ClickHouse/pull/43289) ([Antonio Andelic](https://github.com/antonio2368)).
+* Cancel lambda api url [#43295](https://github.com/ClickHouse/ClickHouse/pull/43295) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fixed: Typo [#43312](https://github.com/ClickHouse/ClickHouse/pull/43312) ([Raevsky Rudolf](https://github.com/lanesket)).
+* Analyzer small fixes [#43321](https://github.com/ClickHouse/ClickHouse/pull/43321) ([Maksim Kita](https://github.com/kitaisreal)).
+* Fix: make test_read_only_table more stable [#43326](https://github.com/ClickHouse/ClickHouse/pull/43326) ([Igor Nikonov](https://github.com/devcrafter)).
+* Make insertRangeFrom() more exception safe [#43338](https://github.com/ClickHouse/ClickHouse/pull/43338) ([Azat Khuzhin](https://github.com/azat)).
+* Analyzer added indexes support [#43341](https://github.com/ClickHouse/ClickHouse/pull/43341) ([Maksim Kita](https://github.com/kitaisreal)).
+* Allow to "drop tables" from s3_plain disk (so as from web disk) [#43343](https://github.com/ClickHouse/ClickHouse/pull/43343) ([Azat Khuzhin](https://github.com/azat)).
+* Add --max-consecutive-errors for clickhouse-benchmark [#43344](https://github.com/ClickHouse/ClickHouse/pull/43344) ([Azat Khuzhin](https://github.com/azat)).
+* Add [#43072](https://github.com/ClickHouse/ClickHouse/issues/43072) [#43345](https://github.com/ClickHouse/ClickHouse/pull/43345) ([Nikita Taranov](https://github.com/nickitat)).
+* Suggest users installation troubleshooting [#43346](https://github.com/ClickHouse/ClickHouse/pull/43346) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Update version_date.tsv and changelogs after v22.11.1.1360-stable [#43349](https://github.com/ClickHouse/ClickHouse/pull/43349) ([robot-clickhouse](https://github.com/robot-clickhouse)).
+* Provide full stacktrace in case of uncaught exception during server startup [#43364](https://github.com/ClickHouse/ClickHouse/pull/43364) ([Azat Khuzhin](https://github.com/azat)).
+* Update SECURITY.md on new stable tags [#43365](https://github.com/ClickHouse/ClickHouse/pull/43365) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Splitting checks in CI more [#43373](https://github.com/ClickHouse/ClickHouse/pull/43373) ([alesapin](https://github.com/alesapin)).
+* Update version_date.tsv and changelogs after v22.8.9.24-lts [#43393](https://github.com/ClickHouse/ClickHouse/pull/43393) ([robot-clickhouse](https://github.com/robot-clickhouse)).
+* Fix mess with signed sizes in SingleValueDataString [#43401](https://github.com/ClickHouse/ClickHouse/pull/43401) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Add a comment [#43403](https://github.com/ClickHouse/ClickHouse/pull/43403) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Avoid race condition for updating system.distribution_queue values [#43406](https://github.com/ClickHouse/ClickHouse/pull/43406) ([Azat Khuzhin](https://github.com/azat)).
+* Fix flaky 01926_order_by_desc_limit [#43408](https://github.com/ClickHouse/ClickHouse/pull/43408) ([Azat Khuzhin](https://github.com/azat)).
+* Fix possible heap-use-after-free in local if history file cannot be created [#43409](https://github.com/ClickHouse/ClickHouse/pull/43409) ([Azat Khuzhin](https://github.com/azat)).
+* Fix flaky test [#43435](https://github.com/ClickHouse/ClickHouse/pull/43435) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Fix backward compatibility check [#43436](https://github.com/ClickHouse/ClickHouse/pull/43436) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Fix typo [#43446](https://github.com/ClickHouse/ClickHouse/pull/43446) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Remove noise from logs about NetLink in Docker [#43447](https://github.com/ClickHouse/ClickHouse/pull/43447) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Modify test slightly [#43448](https://github.com/ClickHouse/ClickHouse/pull/43448) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Set run_passes to 1 by default [#43451](https://github.com/ClickHouse/ClickHouse/pull/43451) ([Dmitry Novik](https://github.com/novikd)).
+* Do not reuse jemalloc memory in test_global_overcommit [#43453](https://github.com/ClickHouse/ClickHouse/pull/43453) ([Dmitry Novik](https://github.com/novikd)).
+* Fix createTableSharedID again [#43458](https://github.com/ClickHouse/ClickHouse/pull/43458) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Use smaller buffer for small files [#43460](https://github.com/ClickHouse/ClickHouse/pull/43460) ([Alexander Gololobov](https://github.com/davenger)).
+* Merging [#42064](https://github.com/ClickHouse/ClickHouse/issues/42064) [#43461](https://github.com/ClickHouse/ClickHouse/pull/43461) ([Anton Popov](https://github.com/CurtizJ)).
+* Use all parameters with prefixes from ssm [#43467](https://github.com/ClickHouse/ClickHouse/pull/43467) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Avoid possible DROP hung due to attached web disk [#43489](https://github.com/ClickHouse/ClickHouse/pull/43489) ([Azat Khuzhin](https://github.com/azat)).
+* Improve fuzzy search in clickhouse-client/clickhouse-local [#43498](https://github.com/ClickHouse/ClickHouse/pull/43498) ([Azat Khuzhin](https://github.com/azat)).
+* check ast limits for create_parser_fuzzer [#43504](https://github.com/ClickHouse/ClickHouse/pull/43504) ([Sema Checherinda](https://github.com/CheSema)).
+* Add another test for SingleDataValueString [#43514](https://github.com/ClickHouse/ClickHouse/pull/43514) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Move password reset message from client to server [#43517](https://github.com/ClickHouse/ClickHouse/pull/43517) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Sync everything to persistent storage to avoid writeback affects perf tests [#43530](https://github.com/ClickHouse/ClickHouse/pull/43530) ([Azat Khuzhin](https://github.com/azat)).
+* bump lib for diag [#43538](https://github.com/ClickHouse/ClickHouse/pull/43538) ([Dale McDiarmid](https://github.com/gingerwizard)).
+* Temporarily disable `test_hive_query` [#43542](https://github.com/ClickHouse/ClickHouse/pull/43542) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Analyzer SumIfToCountIfPass fix [#43543](https://github.com/ClickHouse/ClickHouse/pull/43543) ([Maksim Kita](https://github.com/kitaisreal)).
+* Analyzer UniqInjectiveFunctionsEliminationPass [#43547](https://github.com/ClickHouse/ClickHouse/pull/43547) ([Maksim Kita](https://github.com/kitaisreal)).
+* Disable broken 00176_bson_parallel_parsing [#43550](https://github.com/ClickHouse/ClickHouse/pull/43550) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Add benchmark for query interpretation with JOINs [#43556](https://github.com/ClickHouse/ClickHouse/pull/43556) ([Raúl Marín](https://github.com/Algunenano)).
+* Analyzer table functions untuple fix [#43572](https://github.com/ClickHouse/ClickHouse/pull/43572) ([Maksim Kita](https://github.com/kitaisreal)).
+* Prepare CI for universal runners preallocated pool [#43579](https://github.com/ClickHouse/ClickHouse/pull/43579) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Iterate list without index-based access [#43584](https://github.com/ClickHouse/ClickHouse/pull/43584) ([Alexander Gololobov](https://github.com/davenger)).
+* Remove code that I do not understand [#43593](https://github.com/ClickHouse/ClickHouse/pull/43593) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Add table_uuid to system.parts (resubmit) [#43595](https://github.com/ClickHouse/ClickHouse/pull/43595) ([Azat Khuzhin](https://github.com/azat)).
+* Move perf tests for Aarch64 from PRs to master [#43623](https://github.com/ClickHouse/ClickHouse/pull/43623) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Fix flaky 01175_distributed_ddl_output_mode_long [#43626](https://github.com/ClickHouse/ClickHouse/pull/43626) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Speedup backup config loading [#43627](https://github.com/ClickHouse/ClickHouse/pull/43627) ([Alexander Gololobov](https://github.com/davenger)).
+* Fix [#43478](https://github.com/ClickHouse/ClickHouse/issues/43478) [#43636](https://github.com/ClickHouse/ClickHouse/pull/43636) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
+* Do not checkout submodules recursively [#43637](https://github.com/ClickHouse/ClickHouse/pull/43637) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Optimize binary-builder size [#43654](https://github.com/ClickHouse/ClickHouse/pull/43654) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix flaky `KeeperMap` integration tests [#43658](https://github.com/ClickHouse/ClickHouse/pull/43658) ([Antonio Andelic](https://github.com/antonio2368)).
+* Fix data race in `Keeper` snapshot [#43663](https://github.com/ClickHouse/ClickHouse/pull/43663) ([Antonio Andelic](https://github.com/antonio2368)).
+* Use docker images cache from merged PRs in master and release branches [#43664](https://github.com/ClickHouse/ClickHouse/pull/43664) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Update AsynchronousReadIndirectBufferFromRemoteFS.cpp [#43667](https://github.com/ClickHouse/ClickHouse/pull/43667) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Fix pagination issue in GITHUB_JOB_ID() [#43681](https://github.com/ClickHouse/ClickHouse/pull/43681) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Try fix flaky test 00176_bson_parallel_parsing [#43696](https://github.com/ClickHouse/ClickHouse/pull/43696) ([Kruglov Pavel](https://github.com/Avogar)).
+* Fix log messages in clickhouse-copier [#43707](https://github.com/ClickHouse/ClickHouse/pull/43707) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* try to remove clickhouse if already exists [#43728](https://github.com/ClickHouse/ClickHouse/pull/43728) ([Yakov Olkhovskiy](https://github.com/yakov-olkhovskiy)).
+* Fix 43622 [#43731](https://github.com/ClickHouse/ClickHouse/pull/43731) ([Amos Bird](https://github.com/amosbird)).
+* Fix example of colored prompt in client [#43738](https://github.com/ClickHouse/ClickHouse/pull/43738) ([Azat Khuzhin](https://github.com/azat)).
+* Minor fixes in annoy index documentation [#43743](https://github.com/ClickHouse/ClickHouse/pull/43743) ([Robert Schulze](https://github.com/rschu1ze)).
+* Terminate lost runners [#43756](https://github.com/ClickHouse/ClickHouse/pull/43756) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Update README.md [#43759](https://github.com/ClickHouse/ClickHouse/pull/43759) ([Tyler Hannan](https://github.com/tylerhannan)).
+* Fix included_elements calculation in AggregateFunctionNullVariadic [#43763](https://github.com/ClickHouse/ClickHouse/pull/43763) ([Dmitry Novik](https://github.com/novikd)).
+* Migrate runner_token_rotation_lambda to zip-package deployment [#43766](https://github.com/ClickHouse/ClickHouse/pull/43766) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Analyzer compound expression crash fix [#43768](https://github.com/ClickHouse/ClickHouse/pull/43768) ([Maksim Kita](https://github.com/kitaisreal)).
+* Migrate termination lambda to zip-package [#43769](https://github.com/ClickHouse/ClickHouse/pull/43769) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix flaky `test_store_cleanup` [#43770](https://github.com/ClickHouse/ClickHouse/pull/43770) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Attempt to fix StyleCheck condition [#43773](https://github.com/ClickHouse/ClickHouse/pull/43773) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Rerun PullRequestCI on changed description body [#43777](https://github.com/ClickHouse/ClickHouse/pull/43777) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Yet another fix for AggregateFunctionMinMaxAny [#43778](https://github.com/ClickHouse/ClickHouse/pull/43778) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Add google benchmark to contrib [#43779](https://github.com/ClickHouse/ClickHouse/pull/43779) ([Nikita Taranov](https://github.com/nickitat)).
+* Fix EN doc as in [#43765](https://github.com/ClickHouse/ClickHouse/issues/43765) [#43780](https://github.com/ClickHouse/ClickHouse/pull/43780) ([Alexander Gololobov](https://github.com/davenger)).
+* Detach threads from thread group [#43781](https://github.com/ClickHouse/ClickHouse/pull/43781) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Try making `test_keeper_zookeeper_converter` less flaky [#43789](https://github.com/ClickHouse/ClickHouse/pull/43789) ([Antonio Andelic](https://github.com/antonio2368)).
+* Polish UDF substitution visitor [#43790](https://github.com/ClickHouse/ClickHouse/pull/43790) ([Antonio Andelic](https://github.com/antonio2368)).
+* Analyzer ConstantNode refactoring [#43793](https://github.com/ClickHouse/ClickHouse/pull/43793) ([Maksim Kita](https://github.com/kitaisreal)).
+* Update Poco [#43802](https://github.com/ClickHouse/ClickHouse/pull/43802) ([Alexander Gololobov](https://github.com/davenger)).
+* Add another BC check suppression [#43810](https://github.com/ClickHouse/ClickHouse/pull/43810) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* tests: fix 01676_long_clickhouse_client_autocomplete flakiness [#43819](https://github.com/ClickHouse/ClickHouse/pull/43819) ([Azat Khuzhin](https://github.com/azat)).
+* Use disk operation to serialize and deserialize meta files of StorageFilelog [#43826](https://github.com/ClickHouse/ClickHouse/pull/43826) ([flynn](https://github.com/ucasfl)).
+* Add constexpr [#43827](https://github.com/ClickHouse/ClickHouse/pull/43827) ([zhanglistar](https://github.com/zhanglistar)).
+* Do not postpone removal of in-memory tables [#43833](https://github.com/ClickHouse/ClickHouse/pull/43833) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Increase some logging level for keeper client. [#43835](https://github.com/ClickHouse/ClickHouse/pull/43835) ([Nikolai Kochetov](https://github.com/KochetovNicolai)).
+* FuseFunctionsPass small fix [#43837](https://github.com/ClickHouse/ClickHouse/pull/43837) ([Maksim Kita](https://github.com/kitaisreal)).
+* Followup fixes for XML helpers [#43845](https://github.com/ClickHouse/ClickHouse/pull/43845) ([Alexander Gololobov](https://github.com/davenger)).
+* Hold ProcessListEntry a bit longer in case of exception from Interpreter [#43847](https://github.com/ClickHouse/ClickHouse/pull/43847) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* A little improve performance of PODArray [#43860](https://github.com/ClickHouse/ClickHouse/pull/43860) ([zhanglistar](https://github.com/zhanglistar)).
+* Change email for robot-clickhouse to immutable one [#43861](https://github.com/ClickHouse/ClickHouse/pull/43861) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Rerun DocsCheck on edited PR description [#43862](https://github.com/ClickHouse/ClickHouse/pull/43862) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Temporarily disable misc-* slow clang-tidy checks [#43863](https://github.com/ClickHouse/ClickHouse/pull/43863) ([Robert Schulze](https://github.com/rschu1ze)).
+* do not leave tmp part on disk, do not go to the keeper for remove it [#43866](https://github.com/ClickHouse/ClickHouse/pull/43866) ([Sema Checherinda](https://github.com/CheSema)).
+* do not read part status just for logging [#43868](https://github.com/ClickHouse/ClickHouse/pull/43868) ([Sema Checherinda](https://github.com/CheSema)).
+* Analyzer Context refactoring [#43884](https://github.com/ClickHouse/ClickHouse/pull/43884) ([Maksim Kita](https://github.com/kitaisreal)).
+* Analyzer CTE resolution fix [#43893](https://github.com/ClickHouse/ClickHouse/pull/43893) ([Maksim Kita](https://github.com/kitaisreal)).
+* Improve release script [#43894](https://github.com/ClickHouse/ClickHouse/pull/43894) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Use only PRs to our repository in pr_info on push [#43895](https://github.com/ClickHouse/ClickHouse/pull/43895) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Join engine works with analyzer [#43897](https://github.com/ClickHouse/ClickHouse/pull/43897) ([Vladimir C](https://github.com/vdimir)).
+* Fix reports [#43904](https://github.com/ClickHouse/ClickHouse/pull/43904) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix vim settings (and make it compatible with neovim) [#43909](https://github.com/ClickHouse/ClickHouse/pull/43909) ([Azat Khuzhin](https://github.com/azat)).
+* Fix clang tidy errors introduced in [#43834](https://github.com/ClickHouse/ClickHouse/issues/43834) [#43911](https://github.com/ClickHouse/ClickHouse/pull/43911) ([Nikita Taranov](https://github.com/nickitat)).
+* Fix BACKUP TO S3 for Google Cloud Storage [#43940](https://github.com/ClickHouse/ClickHouse/pull/43940) ([Azat Khuzhin](https://github.com/azat)).
+* Fix tags workflow [#43942](https://github.com/ClickHouse/ClickHouse/pull/43942) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Generate missed changelogs for latest releases [#43944](https://github.com/ClickHouse/ClickHouse/pull/43944) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix typo in tests/ci/bugfix_validate_check.py [#43973](https://github.com/ClickHouse/ClickHouse/pull/43973) ([Vladimir C](https://github.com/vdimir)).
+* Remove test logging of signal "EINTR" [#44001](https://github.com/ClickHouse/ClickHouse/pull/44001) ([Kruglov Pavel](https://github.com/Avogar)).
+* Some cleanup of isDeterministic(InScopeOfQuery)() [#44011](https://github.com/ClickHouse/ClickHouse/pull/44011) ([Robert Schulze](https://github.com/rschu1ze)).
+* Try to keep runners alive for longer [#44015](https://github.com/ClickHouse/ClickHouse/pull/44015) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix relaxed "too many parts" threshold [#44021](https://github.com/ClickHouse/ClickHouse/pull/44021) ([Sergei Trifonov](https://github.com/serxa)).
+* Correct CompressionCodecGorilla exception message [#44023](https://github.com/ClickHouse/ClickHouse/pull/44023) ([Duc Canh Le](https://github.com/canhld94)).
+* Fix exception message [#44034](https://github.com/ClickHouse/ClickHouse/pull/44034) ([Nikolay Degterinsky](https://github.com/evillique)).
+* Update version_date.tsv and changelogs after v22.8.11.15-lts [#44035](https://github.com/ClickHouse/ClickHouse/pull/44035) ([robot-clickhouse](https://github.com/robot-clickhouse)).
+* do not hardlink serialization.json in new part [#44036](https://github.com/ClickHouse/ClickHouse/pull/44036) ([Sema Checherinda](https://github.com/CheSema)).
+* Fix tracing of profile events [#44045](https://github.com/ClickHouse/ClickHouse/pull/44045) ([Anton Popov](https://github.com/CurtizJ)).
+* Slightly better clickhouse disks and remove DiskMemory [#44050](https://github.com/ClickHouse/ClickHouse/pull/44050) ([alesapin](https://github.com/alesapin)).
+* Assign release PRs [#44055](https://github.com/ClickHouse/ClickHouse/pull/44055) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Merging [#36877](https://github.com/ClickHouse/ClickHouse/issues/36877) [#44059](https://github.com/ClickHouse/ClickHouse/pull/44059) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* add changelogs [#44061](https://github.com/ClickHouse/ClickHouse/pull/44061) ([Dan Roscigno](https://github.com/DanRoscigno)).
+* Fix the CACHE_PATH creation for default value [#44079](https://github.com/ClickHouse/ClickHouse/pull/44079) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix aspell [#44090](https://github.com/ClickHouse/ClickHouse/pull/44090) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix another bug in AggregateFunctionMinMaxAny [#44091](https://github.com/ClickHouse/ClickHouse/pull/44091) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Analyzer aggregate function lambda crash fix [#44098](https://github.com/ClickHouse/ClickHouse/pull/44098) ([Maksim Kita](https://github.com/kitaisreal)).
+* Fix -Wshorten-64-to-32 on FreeBSD and enable -Werror [#44121](https://github.com/ClickHouse/ClickHouse/pull/44121) ([Azat Khuzhin](https://github.com/azat)).
+* Fix flaky test `02497_trace_events_stress_long` [#44124](https://github.com/ClickHouse/ClickHouse/pull/44124) ([Anton Popov](https://github.com/CurtizJ)).
+* Minor file renaming [#44125](https://github.com/ClickHouse/ClickHouse/pull/44125) ([Robert Schulze](https://github.com/rschu1ze)).
+* Fix typo [#44127](https://github.com/ClickHouse/ClickHouse/pull/44127) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Better descriptions of signals [#44129](https://github.com/ClickHouse/ClickHouse/pull/44129) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* make calls to be sure that parts are deleted [#44156](https://github.com/ClickHouse/ClickHouse/pull/44156) ([Sema Checherinda](https://github.com/CheSema)).
+* Ignore "session expired" errors after BC check [#44157](https://github.com/ClickHouse/ClickHouse/pull/44157) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Fix incorrect assertion [#44160](https://github.com/ClickHouse/ClickHouse/pull/44160) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Close GRPC channels in tests [#44184](https://github.com/ClickHouse/ClickHouse/pull/44184) ([Antonio Andelic](https://github.com/antonio2368)).
+* Remove misleading message from logs [#44190](https://github.com/ClickHouse/ClickHouse/pull/44190) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Minor clang-tidy fixes in fromUnixTimestamp64() [#44194](https://github.com/ClickHouse/ClickHouse/pull/44194) ([Igor Nikonov](https://github.com/devcrafter)).
+* Hotfix for "check_status.tsv doesn't exists" in stress tests [#44197](https://github.com/ClickHouse/ClickHouse/pull/44197) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Fix documentation after [#42438](https://github.com/ClickHouse/ClickHouse/issues/42438) [#44200](https://github.com/ClickHouse/ClickHouse/pull/44200) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+* Fix an assertion in transactions [#44202](https://github.com/ClickHouse/ClickHouse/pull/44202) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Add log message [#44237](https://github.com/ClickHouse/ClickHouse/pull/44237) ([Alexander Tokmakov](https://github.com/tavplubix)).
+
diff --git a/docs/changelogs/v22.9.7.34-stable.md b/docs/changelogs/v22.9.7.34-stable.md
new file mode 100644
index 00000000000..042347b3815
--- /dev/null
+++ b/docs/changelogs/v22.9.7.34-stable.md
@@ -0,0 +1,37 @@
+---
+sidebar_position: 1
+sidebar_label: 2022
+---
+
+# 2022 Changelog
+
+### ClickHouse release v22.9.7.34-stable (613fe09ca2e) FIXME as compared to v22.9.6.20-stable (ef6343f9579)
+
+#### Bug Fix
+* Backported in [#43099](https://github.com/ClickHouse/ClickHouse/issues/43099): Updated normaliser to clone the alias ast. resolves [#42452](https://github.com/ClickHouse/ClickHouse/issues/42452) Implementation: * Updated QueryNormalizer to clone alias ast, when its replaced. Previously just assigning the same leads to exception in LogicalExpressinsOptimizer as it would be the same parent being inserted again. * This bug is not seen with new analyser (allow_experimental_analyzer), so no changes for it. I added a test for the same. [#42827](https://github.com/ClickHouse/ClickHouse/pull/42827) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
+
+#### Build/Testing/Packaging Improvement
+* Backported in [#44111](https://github.com/ClickHouse/ClickHouse/issues/44111): Bring sha512 sums back to the building step. [#44017](https://github.com/ClickHouse/ClickHouse/pull/44017) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+
+#### Bug Fix (user-visible misbehavior in official stable or prestable release)
+
+* Backported in [#43612](https://github.com/ClickHouse/ClickHouse/issues/43612): Fix bad inefficiency of `remote_filesystem_read_method=read` with filesystem cache. Closes [#42125](https://github.com/ClickHouse/ClickHouse/issues/42125). [#42129](https://github.com/ClickHouse/ClickHouse/pull/42129) ([Kseniia Sumarokova](https://github.com/kssenii)).
+* Backported in [#43526](https://github.com/ClickHouse/ClickHouse/issues/43526): Fix incorrect UserTimeMicroseconds/SystemTimeMicroseconds accounting. [#42791](https://github.com/ClickHouse/ClickHouse/pull/42791) ([Azat Khuzhin](https://github.com/azat)).
+* Backported in [#43518](https://github.com/ClickHouse/ClickHouse/issues/43518): Fix rare possible hung on query cancellation. [#42874](https://github.com/ClickHouse/ClickHouse/pull/42874) ([Azat Khuzhin](https://github.com/azat)).
+* Backported in [#43752](https://github.com/ClickHouse/ClickHouse/issues/43752): An issue with the following exception has been reported while trying to read a Parquet file from S3 into ClickHouse:. [#43297](https://github.com/ClickHouse/ClickHouse/pull/43297) ([Arthur Passos](https://github.com/arthurpassos)).
+* Backported in [#43618](https://github.com/ClickHouse/ClickHouse/issues/43618): Fix sumMap() for Nullable(Decimal()). [#43414](https://github.com/ClickHouse/ClickHouse/pull/43414) ([Azat Khuzhin](https://github.com/azat)).
+* Backported in [#43887](https://github.com/ClickHouse/ClickHouse/issues/43887): Fixed `ALTER ... RESET SETTING` with `ON CLUSTER`. It could be applied to one replica only. Fixes [#43843](https://github.com/ClickHouse/ClickHouse/issues/43843). [#43848](https://github.com/ClickHouse/ClickHouse/pull/43848) ([Elena Torró](https://github.com/elenatorro)).
+* Backported in [#44145](https://github.com/ClickHouse/ClickHouse/issues/44145): Fix undefined behavior in the `quantiles` function, which might lead to uninitialized memory. Found by fuzzer. This closes [#44066](https://github.com/ClickHouse/ClickHouse/issues/44066). [#44067](https://github.com/ClickHouse/ClickHouse/pull/44067) ([Alexey Milovidov](https://github.com/alexey-milovidov)).
+
+#### NO CL ENTRY
+
+* NO CL ENTRY: 'Fix multipart upload for large S3 object, backport to 22.9'. [#44219](https://github.com/ClickHouse/ClickHouse/pull/44219) ([ianton-ru](https://github.com/ianton-ru)).
+
+#### NOT FOR CHANGELOG / INSIGNIFICANT
+
+* Yet another fix for AggregateFunctionMinMaxAny [#43778](https://github.com/ClickHouse/ClickHouse/pull/43778) ([Alexander Tokmakov](https://github.com/tavplubix)).
+* Use only PRs to our repository in pr_info on push [#43895](https://github.com/ClickHouse/ClickHouse/pull/43895) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix tags workflow [#43942](https://github.com/ClickHouse/ClickHouse/pull/43942) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Assign release PRs [#44055](https://github.com/ClickHouse/ClickHouse/pull/44055) ([Mikhail f. Shiryaev](https://github.com/Felixoid)).
+* Fix another bug in AggregateFunctionMinMaxAny [#44091](https://github.com/ClickHouse/ClickHouse/pull/44091) ([Alexander Tokmakov](https://github.com/tavplubix)).
+
diff --git a/docs/en/development/build.md b/docs/en/development/build.md
index 8982a3bc0a4..01b246326cf 100644
--- a/docs/en/development/build.md
+++ b/docs/en/development/build.md
@@ -33,6 +33,13 @@ On Ubuntu/Debian you can use the automatic installation script (check [official
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
```
+Note: in case of troubles, you can also use this:
+
+```bash
+sudo apt-get install software-properties-common
+sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+```
+
For other Linux distribution - check the availability of the [prebuild packages](https://releases.llvm.org/download.html) or build clang [from sources](https://clang.llvm.org/get_started.html).
#### Use the latest clang for Builds
diff --git a/docs/en/engines/table-engines/mergetree-family/summingmergetree.md b/docs/en/engines/table-engines/mergetree-family/summingmergetree.md
index 5a2c0718610..49f90d1c292 100644
--- a/docs/en/engines/table-engines/mergetree-family/summingmergetree.md
+++ b/docs/en/engines/table-engines/mergetree-family/summingmergetree.md
@@ -34,7 +34,7 @@ For a description of request parameters, see [request description](../../../sql-
`columns` - a tuple with the names of columns where values will be summarized. Optional parameter.
The columns must be of a numeric type and must not be in the primary key.
- If `columns` not specified, ClickHouse summarizes the values in all columns with a numeric data type that are not in the primary key.
+ If `columns` is not specified, ClickHouse summarizes the values in all columns with a numeric data type that are not in the primary key.
### Query clauses
diff --git a/docs/en/engines/table-engines/special/buffer.md b/docs/en/engines/table-engines/special/buffer.md
index ba2381d3c01..8950d9b1aef 100644
--- a/docs/en/engines/table-engines/special/buffer.md
+++ b/docs/en/engines/table-engines/special/buffer.md
@@ -8,6 +8,10 @@ sidebar_label: Buffer
Buffers the data to write in RAM, periodically flushing it to another table. During the read operation, data is read from the buffer and the other table simultaneously.
+:::note
+A recommended alternative to the Buffer Table Engine is enabling [asynchronous inserts](/docs/en/guides/best-practices/asyncinserts.md).
+:::
+
``` sql
Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)
```
@@ -24,7 +28,7 @@ Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_
#### num_layers
-`num_layers` – Parallelism layer. Physically, the table will be represented as `num_layers` of independent buffers. Recommended value: 16.
+`num_layers` – Parallelism layer. Physically, the table will be represented as `num_layers` of independent buffers.
#### min_time, max_time, min_rows, max_rows, min_bytes, and max_bytes
@@ -34,11 +38,11 @@ Conditions for flushing data from the buffer.
#### flush_time, flush_rows, and flush_bytes
-Conditions for flushing data from the buffer, that will happen only in background (omitted or zero means no `flush*` parameters).
+Conditions for flushing data from the buffer in the background (omitted or zero means no `flush*` parameters).
Data is flushed from the buffer and written to the destination table if all the `min*` conditions or at least one `max*` condition are met.
-Also, if at least one `flush*` condition are met flush initiated in background, this is different from `max*`, since `flush*` allows you to configure background flushes separately to avoid adding latency for `INSERT` (into `Buffer`) queries.
+Also, if at least one `flush*` condition is met, a flush is initiated in the background. This differs from `max*` since `flush*` allows you to configure background flushes separately to avoid adding latency for `INSERT` queries into Buffer tables.
#### min_time, max_time, and flush_time
@@ -52,48 +56,54 @@ Condition for the number of rows in the buffer.
Condition for the number of bytes in the buffer.
-During the write operation, data is inserted to a `num_layers` number of random buffers. Or, if the data part to insert is large enough (greater than `max_rows` or `max_bytes`), it is written directly to the destination table, omitting the buffer.
+During the write operation, data is inserted into one or more random buffers (configured with `num_layers`). Or, if the data part to insert is large enough (greater than `max_rows` or `max_bytes`), it is written directly to the destination table, omitting the buffer.
The conditions for flushing the data are calculated separately for each of the `num_layers` buffers. For example, if `num_layers = 16` and `max_bytes = 100000000`, the maximum RAM consumption is 1.6 GB.
Example:
``` sql
-CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 16, 10, 100, 10000, 1000000, 10000000, 100000000)
+CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 1, 10, 100, 10000, 1000000, 10000000, 100000000)
```
-Creating a `merge.hits_buffer` table with the same structure as `merge.hits` and using the Buffer engine. When writing to this table, data is buffered in RAM and later written to the ‘merge.hits’ table. 16 buffers are created. The data in each of them is flushed if either 100 seconds have passed, or one million rows have been written, or 100 MB of data have been written; or if simultaneously 10 seconds have passed and 10,000 rows and 10 MB of data have been written. For example, if just one row has been written, after 100 seconds it will be flushed, no matter what. But if many rows have been written, the data will be flushed sooner.
+Creating a `merge.hits_buffer` table with the same structure as `merge.hits` and using the Buffer engine. When writing to this table, data is buffered in RAM and later written to the ‘merge.hits’ table. A single buffer is created and the data is flushed if either:
+- 100 seconds have passed since the last flush (`max_time`) or
+- 1 million rows have been written (`max_rows`) or
+- 100 MB of data have been written (`max_bytes`) or
+- 10 seconds have passed (`min_time`) and 10,000 rows (`min_rows`) and 10 MB (`min_bytes`) of data have been written
-When the server is stopped, with `DROP TABLE` or `DETACH TABLE`, buffer data is also flushed to the destination table.
+For example, if just one row has been written, after 100 seconds, it will be flushed, no matter what. But if many rows have been written, the data will be flushed sooner.
+
+When the server is stopped, with `DROP TABLE` or `DETACH TABLE`, buffered data is also flushed to the destination table.
You can set empty strings in single quotation marks for the database and table name. This indicates the absence of a destination table. In this case, when the data flush conditions are reached, the buffer is simply cleared. This may be useful for keeping a window of data in memory.
When reading from a Buffer table, data is processed both from the buffer and from the destination table (if there is one).
-Note that the Buffer tables does not support an index. In other words, data in the buffer is fully scanned, which might be slow for large buffers. (For data in a subordinate table, the index that it supports will be used.)
+Note that the Buffer table does not support an index. In other words, data in the buffer is fully scanned, which might be slow for large buffers. (For data in a subordinate table, the index that it supports will be used.)
If the set of columns in the Buffer table does not match the set of columns in a subordinate table, a subset of columns that exist in both tables is inserted.
If the types do not match for one of the columns in the Buffer table and a subordinate table, an error message is entered in the server log, and the buffer is cleared.
-The same thing happens if the subordinate table does not exist when the buffer is flushed.
+The same happens if the subordinate table does not exist when the buffer is flushed.
:::warning
-Running ALTER on the Buffer table in releases made before 26 Oct 2021 will cause a `Block structure mismatch` error (see [#15117](https://github.com/ClickHouse/ClickHouse/issues/15117) and [#30565](https://github.com/ClickHouse/ClickHouse/pull/30565)), so deleting the Buffer table and then recreating is the only option. It is advisable to check that this error is fixed in your release before trying to run ALTER on the Buffer table.
+Running ALTER on the Buffer table in releases made before 26 Oct 2021 will cause a `Block structure mismatch` error (see [#15117](https://github.com/ClickHouse/ClickHouse/issues/15117) and [#30565](https://github.com/ClickHouse/ClickHouse/pull/30565)), so deleting the Buffer table and then recreating is the only option. Check that this error is fixed in your release before trying to run ALTER on the Buffer table.
:::
If the server is restarted abnormally, the data in the buffer is lost.
-`FINAL` and `SAMPLE` do not work correctly for Buffer tables. These conditions are passed to the destination table, but are not used for processing data in the buffer. If these features are required we recommend only using the Buffer table for writing, while reading from the destination table.
+`FINAL` and `SAMPLE` do not work correctly for Buffer tables. These conditions are passed to the destination table but are not used for processing data in the buffer. If these features are required, we recommend only using the Buffer table for writing while reading from the destination table.
-When adding data to a Buffer, one of the buffers is locked. This causes delays if a read operation is simultaneously being performed from the table.
+When adding data to a Buffer table, one of the buffers is locked. This causes delays if a read operation is simultaneously being performed from the table.
-Data that is inserted to a Buffer table may end up in the subordinate table in a different order and in different blocks. Because of this, a Buffer table is difficult to use for writing to a CollapsingMergeTree correctly. To avoid problems, you can set `num_layers` to 1.
+Data that is inserted into a Buffer table may end up in the subordinate table in a different order and in different blocks. Because of this, a Buffer table is difficult to use for writing to a CollapsingMergeTree correctly. To avoid problems, you can set `num_layers` to 1.
If the destination table is replicated, some expected characteristics of replicated tables are lost when writing to a Buffer table. The random changes to the order of rows and sizes of data parts cause data deduplication to quit working, which means it is not possible to have a reliable ‘exactly once’ write to replicated tables.
Due to these disadvantages, we can only recommend using a Buffer table in rare cases.
-A Buffer table is used when too many INSERTs are received from a large number of servers over a unit of time and data can’t be buffered before insertion, which means the INSERTs can’t run fast enough.
+A Buffer table is used when too many INSERTs are received from a large number of servers over a unit of time, and data can’t be buffered before insertion, which means the INSERTs can’t run fast enough.
-Note that it does not make sense to insert data one row at a time, even for Buffer tables. This will only produce a speed of a few thousand rows per second, while inserting larger blocks of data can produce over a million rows per second (see the section “Performance”).
+Note that it does not make sense to insert data one row at a time, even for Buffer tables. This will only produce a speed of a few thousand rows per second while inserting larger blocks of data can produce over a million rows per second.
[Original article](https://clickhouse.com/docs/en/engines/table-engines/special/buffer/)
diff --git a/docs/en/getting-started/install.md b/docs/en/getting-started/install.md
index 391d3a3f59a..53f885e3963 100644
--- a/docs/en/getting-started/install.md
+++ b/docs/en/getting-started/install.md
@@ -6,10 +6,11 @@ slug: /en/install
# Installing ClickHouse
-You have two options for getting up and running with ClickHouse:
+You have three options for getting up and running with ClickHouse:
-- **[ClickHouse Cloud](https://clickhouse.com/cloud/):** the official ClickHouse as a service, - built by, maintained, and supported by the creators of ClickHouse
-- **[Self-managed ClickHouse](https://github.com/ClickHouse/ClickHouse):** ClickHouse can run on any Linux, FreeBSD, or Mac OS X with x86_64, AArch64, or PowerPC64LE CPU architecture
+- **[ClickHouse Cloud](https://clickhouse.com/cloud/):** The official ClickHouse as a service, - built by, maintained and supported by the creators of ClickHouse
+- **[Self-managed ClickHouse](#self-managed-install):** ClickHouse can run on any Linux, FreeBSD, or Mac OS X with x86-64, ARM, or PowerPC64LE CPU architecture
+- **[Docker Image](https://hub.docker.com/r/clickhouse/clickhouse-server/):** Read the guide with the official image in Docker Hub
## ClickHouse Cloud
@@ -22,73 +23,49 @@ The quickest and easiest way to get up and running with ClickHouse is to create
Once your Cloud service is provisioned, you will be able to [connect to it](/docs/en/integrations/connect-a-client.md) and start [inserting data](/docs/en/integrations/data-ingestion.md).
-:::note
-The [Quick Start](/docs/en/quick-start.mdx) walks through the steps to get a ClickHouse Cloud service up and running, connecting to it, and inserting data.
-:::
-
-## Self-Managed Requirements
-
-### CPU Architecture
-
-ClickHouse can run on any Linux, FreeBSD, or Mac OS X with x86_64, AArch64, or PowerPC64LE CPU architecture.
-
-Official pre-built binaries are typically compiled for x86_64 and leverage SSE 4.2 instruction set, so unless otherwise stated usage of CPU that supports it becomes an additional system requirement. Here’s the command to check if current CPU has support for SSE 4.2:
-
-``` bash
-$ grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"
-```
-
-To run ClickHouse on processors that do not support SSE 4.2 or have AArch64 or PowerPC64LE architecture, you should [build ClickHouse from sources](#from-sources) with proper configuration adjustments.
-
-ClickHouse implements parallel data processing and uses all the hardware resources available. When choosing a processor, take into account that ClickHouse works more efficiently at configurations with a large number of cores but a lower clock rate than at configurations with fewer cores and a higher clock rate. For example, 16 cores with 2600 MHz is preferable to 8 cores with 3600 MHz.
-
-It is recommended to use **Turbo Boost** and **hyper-threading** technologies. It significantly improves performance with a typical workload.
-
-### RAM {#ram}
-
-We recommend using a minimum of 4GB of RAM to perform non-trivial queries. The ClickHouse server can run with a much smaller amount of RAM, but it requires memory for processing queries.
-
-The required volume of RAM depends on:
-
-- The complexity of queries.
-- The amount of data that is processed in queries.
-
-To calculate the required volume of RAM, you should estimate the size of temporary data for [GROUP BY](/docs/en/sql-reference/statements/select/group-by.md#select-group-by-clause), [DISTINCT](/docs/en/sql-reference/statements/select/distinct.md#select-distinct), [JOIN](/docs/en/sql-reference/statements/select/join.md#select-join) and other operations you use.
-
-ClickHouse can use external memory for temporary data. See [GROUP BY in External Memory](/docs/en/sql-reference/statements/select/group-by.md#select-group-by-in-external-memory) for details.
-
-### Swap File {#swap-file}
-
-Disable the swap file for production environments.
-
-### Storage Subsystem {#storage-subsystem}
-
-You need to have 2GB of free disk space to install ClickHouse.
-
-The volume of storage required for your data should be calculated separately. Assessment should include:
-
-- Estimation of the data volume.
-
- You can take a sample of the data and get the average size of a row from it. Then multiply the value by the number of rows you plan to store.
-
-- The data compression coefficient.
-
- To estimate the data compression coefficient, load a sample of your data into ClickHouse, and compare the actual size of the data with the size of the table stored. For example, clickstream data is usually compressed by 6-10 times.
-
-To calculate the final volume of data to be stored, apply the compression coefficient to the estimated data volume. If you plan to store data in several replicas, then multiply the estimated volume by the number of replicas.
-
-### Network {#network}
-
-If possible, use networks of 10G or higher class.
-
-The network bandwidth is critical for processing distributed queries with a large amount of intermediate data. Besides, network speed affects replication processes.
-
-### Software {#software}
-
-ClickHouse is developed primarily for the Linux family of operating systems. The recommended Linux distribution is Ubuntu. The `tzdata` package should be installed in the system.
## Self-Managed Install
+1. The simplest way to download ClickHouse locally is to run the following command. If your operating system is supported, an appropriate ClickHouse binary will be downloaded and made runnable:
+ ```bash
+ curl https://clickhouse.com/ | sh
+ ```
+
+1. Run the `install` command, which defines a collection of useful symlinks along with the files and folders used by ClickHouse - all of which you can see in the output of the install script:
+ ```bash
+ sudo ./clickhouse install
+ ```
+
+1. At the end of the install script, you are prompted for a password for the `default` user. Feel free to enter a password, or you can optionally leave it blank:
+ ```response
+ Creating log directory /var/log/clickhouse-server.
+ Creating data directory /var/lib/clickhouse.
+ Creating pid directory /var/run/clickhouse-server.
+ chown -R clickhouse:clickhouse '/var/log/clickhouse-server'
+ chown -R clickhouse:clickhouse '/var/run/clickhouse-server'
+ chown clickhouse:clickhouse '/var/lib/clickhouse'
+ Enter password for default user:
+ ```
+ You should see the following output:
+ ```response
+ ClickHouse has been successfully installed.
+
+ Start clickhouse-server with:
+ sudo clickhouse start
+
+ Start clickhouse-client with:
+ clickhouse-client
+ ```
+
+1. Run the following command to start the ClickHouse server:
+ ```bash
+ sudo clickhouse start
+ ```
+
+:::tip
+The [Quick Start](/docs/en/quick-start.mdx/#step-1-get-clickhouse) walks through the steps to download and run ClickHouse, connect to it, and insert data.
+:::
+
## Available Installation Options {#available-installation-options}
### From DEB Packages {#install-from-deb-packages}
@@ -278,50 +255,16 @@ For production environments, it’s recommended to use the latest `stable`-versi
To run ClickHouse inside Docker follow the guide on [Docker Hub](https://hub.docker.com/r/clickhouse/clickhouse-server/). Those images use official `deb` packages inside.
-### Single Binary {#from-single-binary}
-
-You can install ClickHouse on Linux using a single portable binary from the latest commit of the `master` branch: [https://builds.clickhouse.com/master/amd64/clickhouse].
-
-``` bash
-curl -O 'https://builds.clickhouse.com/master/amd64/clickhouse' && chmod a+x clickhouse
-sudo ./clickhouse install
-```
-
-### From Precompiled Binaries for Non-Standard Environments {#from-binaries-non-linux}
-
-For non-Linux operating systems and for AArch64 CPU architecture, ClickHouse builds are provided as a cross-compiled binary from the latest commit of the `master` branch (with a few hours delay).
-
-- [MacOS x86_64](https://builds.clickhouse.com/master/macos/clickhouse)
- ```bash
- curl -O 'https://builds.clickhouse.com/master/macos/clickhouse' && chmod a+x ./clickhouse
- ```
-- [MacOS Aarch64 (Apple Silicon)](https://builds.clickhouse.com/master/macos-aarch64/clickhouse)
- ```bash
- curl -O 'https://builds.clickhouse.com/master/macos-aarch64/clickhouse' && chmod a+x ./clickhouse
- ```
-- [FreeBSD x86_64](https://builds.clickhouse.com/master/freebsd/clickhouse)
- ```bash
- curl -O 'https://builds.clickhouse.com/master/freebsd/clickhouse' && chmod a+x ./clickhouse
- ```
-- [Linux AArch64](https://builds.clickhouse.com/master/aarch64/clickhouse)
- ```bash
- curl -O 'https://builds.clickhouse.com/master/aarch64/clickhouse' && chmod a+x ./clickhouse
- ```
-
-Run `sudo ./clickhouse install` to install ClickHouse system-wide (also with needed configuration files, configuring users etc.). Then run `sudo clickhouse start` commands to start the clickhouse-server and `clickhouse-client` to connect to it.
-
-Use the `clickhouse client` to connect to the server, or `clickhouse local` to process local data.
-
### From Sources {#from-sources}
To manually compile ClickHouse, follow the instructions for [Linux](/docs/en/development/build.md) or [Mac OS X](/docs/en/development/build-osx.md).
-You can compile packages and install them or use programs without installing packages. Also by building manually you can disable SSE 4.2 requirement or build for AArch64 CPUs.
+You can compile packages and install them or use programs without installing packages.
- Client: programs/clickhouse-client
- Server: programs/clickhouse-server
+ Client: /programs/clickhouse-client
+ Server: /programs/clickhouse-server
-You’ll need to create a data and metadata folders and `chown` them for the desired user. Their paths can be changed in server config (src/programs/server/config.xml), by default they are:
+You’ll need to create data and metadata folders manually and `chown` them for the desired user. Their paths can be changed in server config (src/programs/server/config.xml), by default they are:
/var/lib/clickhouse/data/default/
/var/lib/clickhouse/metadata/default/
@@ -406,3 +349,42 @@ SELECT 1
**Congratulations, the system works!**
To continue experimenting, you can download one of the test data sets or go through [tutorial](/docs/en/tutorial.md).
+
+## Recommendations for Self-Managed ClickHouse
+
+ClickHouse can run on any Linux, FreeBSD, or Mac OS X with x86-64, ARM, or PowerPC64LE CPU architecture.
+
+ClickHouse uses all hardware resources available to process data.
+
+ClickHouse tends to work more efficiently with a large number of cores at a lower clock rate than with fewer cores at a higher clock rate.
+
+We recommend using a minimum of 4GB of RAM to perform non-trivial queries. The ClickHouse server can run with a much smaller amount of RAM, but queries will then frequently abort.
+
+The required volume of RAM generally depends on:
+
+- The complexity of queries.
+- The amount of data that is processed in queries.
+
+To calculate the required volume of RAM, you may estimate the size of temporary data for [GROUP BY](/docs/en/sql-reference/statements/select/group-by.md#select-group-by-clause), [DISTINCT](/docs/en/sql-reference/statements/select/distinct.md#select-distinct), [JOIN](/docs/en/sql-reference/statements/select/join.md#select-join) and other operations you use.
+
+To reduce memory consumption, ClickHouse can swap temporary data to external storage. See [GROUP BY in External Memory](/docs/en/sql-reference/statements/select/group-by.md#select-group-by-in-external-memory) for details.
+
+We recommend to disable the operating system's swap file in production environments.
+
+The ClickHouse binary requires at least 2.5 GB of disk space for installation.
+
+The volume of storage required for your data may be calculated separately based on
+
+- an estimation of the data volume.
+
+ You can take a sample of the data and get the average size of a row from it. Then multiply the value by the number of rows you plan to store.
+
+- The data compression coefficient.
+
+ To estimate the data compression coefficient, load a sample of your data into ClickHouse, and compare the actual size of the data with the size of the table stored. For example, clickstream data is usually compressed by 6-10 times.
+
+To calculate the final volume of data to be stored, apply the compression coefficient to the estimated data volume. If you plan to store data in several replicas, then multiply the estimated volume by the number of replicas.
+
+For distributed ClickHouse deployments (clustering), we recommend at least 10G class network connectivity.
+
+Network bandwidth is critical for processing distributed queries with a large amount of intermediate data. Besides, network speed affects replication processes.
diff --git a/docs/en/interfaces/formats.md b/docs/en/interfaces/formats.md
index 58998a6f491..b7ef859f974 100644
--- a/docs/en/interfaces/formats.md
+++ b/docs/en/interfaces/formats.md
@@ -1415,7 +1415,7 @@ Differs from [PrettySpaceNoEscapes](#prettyspacenoescapes) in that up to 10,000
## RowBinary {#rowbinary}
-Formats and parses data by row in binary format. Rows and values are listed consecutively, without separators.
+Formats and parses data by row in binary format. Rows and values are listed consecutively, without separators. Because data is in the binary format the delimiter after `FORMAT RowBinary` is strictly specified as next: any number of whitespaces (`' '` - space, code `0x20`; `'\t'` - tab, code `0x09`; `'\f'` - form feed, code `0x0C`) followed by exactly one new line sequence (Windows style `"\r\n"` or Unix style `'\n'`), immediately followed by binary data.
This format is less efficient than the Native format since it is row-based.
Integers use fixed-length little-endian representation. For example, UInt64 uses 8 bytes.
diff --git a/docs/en/operations/settings/constraints-on-settings.md b/docs/en/operations/settings/constraints-on-settings.md
index bb015f80834..4857bcd30c0 100644
--- a/docs/en/operations/settings/constraints-on-settings.md
+++ b/docs/en/operations/settings/constraints-on-settings.md
@@ -92,7 +92,7 @@ Code: 452, e.displayText() = DB::Exception: Setting force_index_by_date should n
**Note:** the `default` profile has special handling: all the constraints defined for the `default` profile become the default constraints, so they restrict all the users until they’re overridden explicitly for these users.
## Constraints on Merge Tree Settings
-It is possible to set constraints for [merge tree settings](merge-tree-settings.md). There constraints are applied when table with merge tree engine is created or its storage settings are altered. Name of merge tree setting must be prepended by `merge_tree_` prefix when referenced in `` section.
+It is possible to set constraints for [merge tree settings](merge-tree-settings.md). These constraints are applied when table with merge tree engine is created or its storage settings are altered. Name of merge tree setting must be prepended by `merge_tree_` prefix when referenced in `` section.
**Example:** Forbid to create new tables with explicitly specified `storage_policy`
diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md
index ddfaab02159..645a38a7f04 100644
--- a/docs/en/operations/settings/settings.md
+++ b/docs/en/operations/settings/settings.md
@@ -3588,6 +3588,31 @@ y Nullable(String)
z IPv4
```
+## schema_inference_make_columns_nullable {#schema_inference_make_columns_nullable}
+
+Controls making inferred types `Nullable` in schema inference for formats without information about nullability.
+If the setting is enabled, the inferred type will be `Nullable` only if column contains `NULL` in a sample that is parsed during schema inference.
+
+Default value: `false`.
+
+## input_format_try_infer_integers {#input_format_try_infer_integers}
+
+If enabled, ClickHouse will try to infer integers instead of floats in schema inference for text formats. If all numbers in the column from input data are integers, the result type will be `Int64`, if at least one number is float, the result type will be `Float64`.
+
+Enabled by default.
+
+## input_format_try_infer_dates {#input_format_try_infer_dates}
+
+If enabled, ClickHouse will try to infer type `Date` from string fields in schema inference for text formats. If all fields from a column in input data were successfully parsed as dates, the result type will be `Date`, if at least one field was not parsed as date, the result type will be `String`.
+
+Enabled by default.
+
+## input_format_try_infer_datetimes {#input_format_try_infer_datetimes}
+
+If enabled, ClickHouse will try to infer type `DateTime64` from string fields in schema inference for text formats. If all fields from a column in input data were successfully parsed as datetimes, the result type will be `DateTime64`, if at least one field was not parsed as datetime, the result type will be `String`.
+
+Enabled by default.
+
## date_time_input_format {#date_time_input_format}
Allows choosing a parser of the text representation of date and time.
diff --git a/docs/en/operations/system-tables/databases.md b/docs/en/operations/system-tables/databases.md
index cd90c94c480..8f0cc6e56d2 100644
--- a/docs/en/operations/system-tables/databases.md
+++ b/docs/en/operations/system-tables/databases.md
@@ -13,6 +13,7 @@ Columns:
- `metadata_path` ([String](../../sql-reference/data-types/enum.md)) — Metadata path.
- `uuid` ([UUID](../../sql-reference/data-types/uuid.md)) — Database UUID.
- `comment` ([String](../../sql-reference/data-types/enum.md)) — Database comment.
+- `engine_full` ([String](../../sql-reference/data-types/enum.md)) — Parameters of the database engine.
The `name` column from this system table is used for implementing the `SHOW DATABASES` query.
@@ -31,10 +32,12 @@ SELECT * FROM system.databases;
```
``` text
-┌─name───────────────┬─engine─┬─data_path──────────────────┬─metadata_path───────────────────────────────────────────────────────┬─uuid─────────────────────────────────┬─comment─┐
-│ INFORMATION_SCHEMA │ Memory │ /var/lib/clickhouse/ │ │ 00000000-0000-0000-0000-000000000000 │ │
-│ default │ Atomic │ /var/lib/clickhouse/store/ │ /var/lib/clickhouse/store/d31/d317b4bd-3595-4386-81ee-c2334694128a/ │ 24363899-31d7-42a0-a436-389931d752a0 │ │
-│ information_schema │ Memory │ /var/lib/clickhouse/ │ │ 00000000-0000-0000-0000-000000000000 │ │
-│ system │ Atomic │ /var/lib/clickhouse/store/ │ /var/lib/clickhouse/store/1d1/1d1c869d-e465-4b1b-a51f-be033436ebf9/ │ 03e9f3d1-cc88-4a49-83e9-f3d1cc881a49 │ │
-└────────────────────┴────────┴────────────────────────────┴─────────────────────────────────────────────────────────────────────┴──────────────────────────────────────┴─────────┘
+┌─name────────────────┬─engine─────┬─data_path────────────────────┬─metadata_path─────────────────────────────────────────────────────────┬─uuid─────────────────────────────────┬─engine_full────────────────────────────────────────────┬─comment─┐
+│ INFORMATION_SCHEMA │ Memory │ /data/clickhouse_data/ │ │ 00000000-0000-0000-0000-000000000000 │ Memory │ │
+│ default │ Atomic │ /data/clickhouse_data/store/ │ /data/clickhouse_data/store/f97/f97a3ceb-2e8a-4912-a043-c536e826a4d4/ │ f97a3ceb-2e8a-4912-a043-c536e826a4d4 │ Atomic │ │
+│ information_schema │ Memory │ /data/clickhouse_data/ │ │ 00000000-0000-0000-0000-000000000000 │ Memory │ │
+│ replicated_database │ Replicated │ /data/clickhouse_data/store/ │ /data/clickhouse_data/store/da8/da85bb71-102b-4f69-9aad-f8d6c403905e/ │ da85bb71-102b-4f69-9aad-f8d6c403905e │ Replicated('some/path/database', 'shard1', 'replica1') │ │
+│ system │ Atomic │ /data/clickhouse_data/store/ │ /data/clickhouse_data/store/b57/b5770419-ac7a-4b67-8229-524122024076/ │ b5770419-ac7a-4b67-8229-524122024076 │ Atomic │ │
+└─────────────────────┴────────────┴──────────────────────────────┴───────────────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────────────────────────────┴─────────┘
+
```
diff --git a/docs/en/sql-reference/data-types/float.md b/docs/en/sql-reference/data-types/float.md
index 8bf2e4007da..cd3905f54b2 100644
--- a/docs/en/sql-reference/data-types/float.md
+++ b/docs/en/sql-reference/data-types/float.md
@@ -6,6 +6,26 @@ sidebar_label: Float32, Float64
# Float32, Float64
+:::warning
+If you need accurate calculations, in particular if you work with financial or business data requiring a high precision you should consider using Decimal instead. Floats might lead to inaccurate results as illustrated below:
+
+```
+CREATE TABLE IF NOT EXISTS float_vs_decimal
+(
+ my_float Float64,
+ my_decimal Decimal64(3)
+)Engine=MergeTree ORDER BY tuple()
+
+INSERT INTO float_vs_decimal SELECT round(canonicalRand(), 3) AS res, res FROM system.numbers LIMIT 1000000; # Generate 1 000 000 random number with 2 decimal places and store them as a float and as a decimal
+
+SELECT sum(my_float), sum(my_decimal) FROM float_vs_decimal;
+> 500279.56300000014 500279.563
+
+SELECT sumKahan(my_float), sumKahan(my_decimal) FROM float_vs_decimal;
+> 500279.563 500279.563
+```
+:::
+
[Floating point numbers](https://en.wikipedia.org/wiki/IEEE_754).
Types are equivalent to types of C:
@@ -13,8 +33,6 @@ Types are equivalent to types of C:
- `Float32` — `float`.
- `Float64` — `double`.
-We recommend that you store data in integer form whenever possible. For example, convert fixed precision numbers to integer values, such as monetary amounts or page load times in milliseconds.
-
Aliases:
- `Float32` — `FLOAT`.
diff --git a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md
index aac0db208c6..bf88b9cedf2 100644
--- a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md
+++ b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md
@@ -607,3 +607,7 @@ dictGetString('prefix', 'asn', tuple(IPv6StringToNum('2001:db8::1')))
Other types are not supported yet. The function returns the attribute for the prefix that corresponds to this IP address. If there are overlapping prefixes, the most specific one is returned.
Data must completely fit into RAM.
+
+## Related Content
+
+- [Using dictionaries to accelerate queries](https://clickhouse.com/blog/faster-queries-dictionaries-clickhouse)
diff --git a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-lifetime.md b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-lifetime.md
index e4edad4d9a1..8e9dbd392aa 100644
--- a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-lifetime.md
+++ b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-lifetime.md
@@ -136,3 +136,7 @@ or
SOURCE(CLICKHOUSE(... update_field 'added_time' update_lag 15))
...
```
+
+## Related Content
+
+- [Using dictionaries to accelerate queries](https://clickhouse.com/blog/faster-queries-dictionaries-clickhouse)
diff --git a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md
index 4eb96fe80a2..c5d48945649 100644
--- a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md
+++ b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md
@@ -824,3 +824,7 @@ Setting fields:
:::note
The `table` or `where` fields cannot be used together with the `query` field. And either one of the `table` or `query` fields must be declared.
:::
+
+## Related Content
+
+- [Using dictionaries to accelerate queries](https://clickhouse.com/blog/faster-queries-dictionaries-clickhouse)
\ No newline at end of file
diff --git a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure.md b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure.md
index 881630167e3..8271a342941 100644
--- a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure.md
+++ b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure.md
@@ -176,3 +176,6 @@ Configuration fields:
- [Functions for working with dictionaries](../../../sql-reference/functions/ext-dict-functions.md).
+## Related Content
+
+- [Using dictionaries to accelerate queries](https://clickhouse.com/blog/faster-queries-dictionaries-clickhouse)
\ No newline at end of file
diff --git a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict.md b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict.md
index 76ca3ac978f..a923511ca5e 100644
--- a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict.md
+++ b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts-dict.md
@@ -52,3 +52,6 @@ LIFETIME(...) -- Lifetime of dictionary in memory
- [structure](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure.md) — Structure of the dictionary . A key and attributes that can be retrieved by this key.
- [lifetime](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-lifetime.md) — Frequency of dictionary updates.
+## Related Content
+
+- [Using dictionaries to accelerate queries](https://clickhouse.com/blog/faster-queries-dictionaries-clickhouse)
\ No newline at end of file
diff --git a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts.md b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts.md
index 9f922a2cccb..8621c68b428 100644
--- a/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts.md
+++ b/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts.md
@@ -79,3 +79,6 @@ You can convert values for a small dictionary by describing it in a `SELECT` que
- [Dictionary Key and Fields](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure.md)
- [Functions for Working with Dictionaries](../../../sql-reference/functions/ext-dict-functions.md)
+## Related Content
+
+- [Using dictionaries to accelerate queries](https://clickhouse.com/blog/faster-queries-dictionaries-clickhouse)
diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md
index 6cecc3f01da..6156a823d58 100644
--- a/docs/en/sql-reference/functions/date-time-functions.md
+++ b/docs/en/sql-reference/functions/date-time-functions.md
@@ -410,35 +410,35 @@ Converts a date with time to a certain fixed date, while preserving the time.
## toRelativeYearNum
-Converts a date or date with time to the number of the year, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the year, starting from a certain fixed point in the past.
## toRelativeQuarterNum
-Converts a date or date with time to the number of the quarter, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the quarter, starting from a certain fixed point in the past.
## toRelativeMonthNum
-Converts a date or date with time to the number of the month, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the month, starting from a certain fixed point in the past.
## toRelativeWeekNum
-Converts a date or date with time to the number of the week, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the week, starting from a certain fixed point in the past.
## toRelativeDayNum
-Converts a date or date with time to the number of the day, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the day, starting from a certain fixed point in the past.
## toRelativeHourNum
-Converts a date or date with time to the number of the hour, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the hour, starting from a certain fixed point in the past.
## toRelativeMinuteNum
-Converts a date or date with time to the number of the minute, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the minute, starting from a certain fixed point in the past.
## toRelativeSecondNum
-Converts a date or date with time to the number of the second, starting from a certain fixed point in the past.
+Converts a date with time or date to the number of the second, starting from a certain fixed point in the past.
## toISOYear
@@ -517,154 +517,6 @@ SELECT toDate('2016-12-27') AS date, toYearWeek(date) AS yearWeek0, toYearWeek(d
└────────────┴───────────┴───────────┴───────────┘
```
-## age
-
-Returns the `unit` component of the difference between `startdate` and `enddate`. The difference is calculated using a precision of 1 second.
-E.g. the difference between `2021-12-29` and `2022-01-01` is 3 days for `day` unit, 0 months for `month` unit, 0 years for `year` unit.
-
-
-**Syntax**
-
-``` sql
-age('unit', startdate, enddate, [timezone])
-```
-
-**Arguments**
-
-- `unit` — The type of interval for result. [String](../../sql-reference/data-types/string.md).
- Possible values:
-
- - `second` (possible abbreviations: `ss`, `s`)
- - `minute` (possible abbreviations: `mi`, `n`)
- - `hour` (possible abbreviations: `hh`, `h`)
- - `day` (possible abbreviations: `dd`, `d`)
- - `week` (possible abbreviations: `wk`, `ww`)
- - `month` (possible abbreviations: `mm`, `m`)
- - `quarter` (possible abbreviations: `qq`, `q`)
- - `year` (possible abbreviations: `yyyy`, `yy`)
-
-- `startdate` — The first time value to subtract (the subtrahend). [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) or [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `enddate` — The second time value to subtract from (the minuend). [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) or [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional). If specified, it is applied to both `startdate` and `enddate`. If not specified, timezones of `startdate` and `enddate` are used. If they are not the same, the result is unspecified. [String](../../sql-reference/data-types/string.md).
-
-**Returned value**
-
-Difference between `enddate` and `startdate` expressed in `unit`.
-
-Type: [Int](../../sql-reference/data-types/int-uint.md).
-
-**Example**
-
-Query:
-
-``` sql
-SELECT age('hour', toDateTime('2018-01-01 22:30:00'), toDateTime('2018-01-02 23:00:00'));
-```
-
-Result:
-
-``` text
-┌─age('hour', toDateTime('2018-01-01 22:30:00'), toDateTime('2018-01-02 23:00:00'))─┐
-│ 24 │
-└───────────────────────────────────────────────────────────────────────────────────┘
-```
-
-Query:
-
-``` sql
-SELECT
- toDate('2022-01-01') AS e,
- toDate('2021-12-29') AS s,
- age('day', s, e) AS day_age,
- age('month', s, e) AS month__age,
- age('year', s, e) AS year_age;
-```
-
-Result:
-
-``` text
-┌──────────e─┬──────────s─┬─day_age─┬─month__age─┬─year_age─┐
-│ 2022-01-01 │ 2021-12-29 │ 3 │ 0 │ 0 │
-└────────────┴────────────┴─────────┴────────────┴──────────┘
-```
-
-
-## date\_diff
-
-Returns the count of the specified `unit` boundaries crossed between the `startdate` and `enddate`.
-The difference is calculated using relative units, e.g. the difference between `2021-12-29` and `2022-01-01` is 3 days for day unit (see [toRelativeDayNum](#torelativedaynum)), 1 month for month unit (see [toRelativeMonthNum](#torelativemonthnum)), 1 year for year unit (see [toRelativeYearNum](#torelativeyearnum)).
-
-**Syntax**
-
-``` sql
-date_diff('unit', startdate, enddate, [timezone])
-```
-
-Aliases: `dateDiff`, `DATE_DIFF`.
-
-**Arguments**
-
-- `unit` — The type of interval for result. [String](../../sql-reference/data-types/string.md).
- Possible values:
-
- - `second` (possible abbreviations: `ss`, `s`)
- - `minute` (possible abbreviations: `mi`, `n`)
- - `hour` (possible abbreviations: `hh`, `h`)
- - `day` (possible abbreviations: `dd`, `d`)
- - `week` (possible abbreviations: `wk`, `ww`)
- - `month` (possible abbreviations: `mm`, `m`)
- - `quarter` (possible abbreviations: `qq`, `q`)
- - `year` (possible abbreviations: `yyyy`, `yy`)
-
-- `startdate` — The first time value to subtract (the subtrahend). [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) or [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `enddate` — The second time value to subtract from (the minuend). [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) or [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional). If specified, it is applied to both `startdate` and `enddate`. If not specified, timezones of `startdate` and `enddate` are used. If they are not the same, the result is unspecified. [String](../../sql-reference/data-types/string.md).
-
-**Returned value**
-
-Difference between `enddate` and `startdate` expressed in `unit`.
-
-Type: [Int](../../sql-reference/data-types/int-uint.md).
-
-**Example**
-
-Query:
-
-``` sql
-SELECT dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'));
-```
-
-Result:
-
-``` text
-┌─dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'))─┐
-│ 25 │
-└────────────────────────────────────────────────────────────────────────────────────────┘
-```
-
-Query:
-
-``` sql
-SELECT
- toDate('2022-01-01') AS e,
- toDate('2021-12-29') AS s,
- dateDiff('day', s, e) AS day_diff,
- dateDiff('month', s, e) AS month__diff,
- dateDiff('year', s, e) AS year_diff;
-```
-
-Result:
-
-``` text
-┌──────────e─┬──────────s─┬─day_diff─┬─month__diff─┬─year_diff─┐
-│ 2022-01-01 │ 2021-12-29 │ 3 │ 1 │ 1 │
-└────────────┴────────────┴──────────┴─────────────┴───────────┘
-```
-
## date\_trunc
Truncates date and time data to the specified part of date.
@@ -785,6 +637,80 @@ Result:
└───────────────────────────────────────────────┘
```
+## date\_diff
+
+Returns the difference between two dates or dates with time values.
+The difference is calculated using relative units, e.g. the difference between `2022-01-01` and `2021-12-29` is 3 days for day unit (see [toRelativeDayNum](#torelativedaynum)), 1 month for month unit (see [toRelativeMonthNum](#torelativemonthnum)), 1 year for year unit (see [toRelativeYearNum](#torelativeyearnum)).
+
+**Syntax**
+
+``` sql
+date_diff('unit', startdate, enddate, [timezone])
+```
+
+Aliases: `dateDiff`, `DATE_DIFF`.
+
+**Arguments**
+
+- `unit` — The type of interval for result. [String](../../sql-reference/data-types/string.md).
+ Possible values:
+
+ - `second`
+ - `minute`
+ - `hour`
+ - `day`
+ - `week`
+ - `month`
+ - `quarter`
+ - `year`
+
+- `startdate` — The first time value to subtract (the subtrahend). [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) or [DateTime64](../../sql-reference/data-types/datetime64.md).
+
+- `enddate` — The second time value to subtract from (the minuend). [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) or [DateTime64](../../sql-reference/data-types/datetime64.md).
+
+- `timezone` — [Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (optional). If specified, it is applied to both `startdate` and `enddate`. If not specified, timezones of `startdate` and `enddate` are used. If they are not the same, the result is unspecified. [String](../../sql-reference/data-types/string.md).
+
+**Returned value**
+
+Difference between `enddate` and `startdate` expressed in `unit`.
+
+Type: [Int](../../sql-reference/data-types/int-uint.md).
+
+**Example**
+
+Query:
+
+``` sql
+SELECT dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'));
+```
+
+Result:
+
+``` text
+┌─dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'))─┐
+│ 25 │
+└────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
+Query:
+
+``` sql
+SELECT
+ toDate('2022-01-01') AS e,
+ toDate('2021-12-29') AS s,
+ dateDiff('day', s, e) AS day_diff,
+ dateDiff('month', s, e) AS month__diff,
+ dateDiff('year', s, e) AS year_diff;
+```
+
+Result:
+
+``` text
+┌──────────e─┬──────────s─┬─day_diff─┬─month__diff─┬─year_diff─┐
+│ 2022-01-01 │ 2021-12-29 │ 3 │ 1 │ 1 │
+└────────────┴────────────┴──────────┴─────────────┴───────────┘
+```
+
## date\_sub
Subtracts the time interval or date interval from the provided date or date with time.
diff --git a/docs/en/sql-reference/functions/index.md b/docs/en/sql-reference/functions/index.md
index 840bcd583e4..22e79ec6623 100644
--- a/docs/en/sql-reference/functions/index.md
+++ b/docs/en/sql-reference/functions/index.md
@@ -296,3 +296,7 @@ Another example is the `hostName` function, which returns the name of the server
If a function in a query is performed on the requestor server, but you need to perform it on remote servers, you can wrap it in an ‘any’ aggregate function or add it to a key in `GROUP BY`.
+
+## Related Content
+
+- [User-defined functions in ClickHouse Cloud](https://clickhouse.com/blog/user-defined-functions-clickhouse-udfs)
diff --git a/docs/en/sql-reference/functions/string-functions.md b/docs/en/sql-reference/functions/string-functions.md
index cdbf29f3e6d..2e2b280d1d6 100644
--- a/docs/en/sql-reference/functions/string-functions.md
+++ b/docs/en/sql-reference/functions/string-functions.md
@@ -1159,4 +1159,40 @@ If s is empty, the result is 0. If the first character is not an ASCII character
+## concatWithSeparator
+Returns the concatenation strings separated by string separator. If any of the argument values is `NULL`, the function returns `NULL`.
+
+**Syntax**
+
+``` sql
+concatWithSeparator(sep, expr1, expr2, expr3...)
+```
+
+**Arguments**
+- sep — separator. Const [String](../../sql-reference/data-types/string.md) or [FixedString](../../sql-reference/data-types/fixedstring.md).
+- exprN — expression to be concatenated. [String](../../sql-reference/data-types/string.md) or [FixedString](../../sql-reference/data-types/fixedstring.md).
+
+**Returned values**
+- The concatenated String.
+
+**Example**
+
+Query:
+
+``` sql
+SELECT concatWithSeparator('a', '1', '2', '3', '4')
+```
+
+Result:
+
+``` text
+┌─concatWithSeparator('a', '1', '2', '3', '4')─┐
+│ 1a2a3a4 │
+└───────────────────────────────────┘
+```
+
+## concatWithSeparatorAssumeInjective
+Same as concatWithSeparator, the difference is that you need to ensure that concatWithSeparator(sep, expr1, expr2, expr3...) → result is injective, it will be used for optimization of GROUP BY.
+
+The function is named “injective” if it always returns different result for different values of arguments. In other words: different arguments never yield identical result.
diff --git a/docs/en/sql-reference/statements/create/function.md b/docs/en/sql-reference/statements/create/function.md
index 90be007bf43..80d20e8ccad 100644
--- a/docs/en/sql-reference/statements/create/function.md
+++ b/docs/en/sql-reference/statements/create/function.md
@@ -58,3 +58,7 @@ Result:
│ 2 │ even │
└────────┴──────────────────────────────────────┘
```
+
+## Related Content
+
+- [User-defined functions in ClickHouse Cloud](https://clickhouse.com/blog/user-defined-functions-clickhouse-udfs)
diff --git a/docs/en/sql-reference/syntax.md b/docs/en/sql-reference/syntax.md
index 837022a424f..0a2a832d2fc 100644
--- a/docs/en/sql-reference/syntax.md
+++ b/docs/en/sql-reference/syntax.md
@@ -77,8 +77,9 @@ Numeric literal tries to be parsed:
Literal value has the smallest type that the value fits in.
For example, 1 is parsed as `UInt8`, but 256 is parsed as `UInt16`. For more information, see [Data types](../sql-reference/data-types/index.md).
+Underscores `_` inside numeric literals are ignored and can be used for better readability.
-Examples: `1`, `18446744073709551615`, `0xDEADBEEF`, `01`, `0.1`, `1e100`, `-1e-100`, `inf`, `nan`.
+Examples: `1`, `10_000_000`, `0xffff_ffff`, `18446744073709551615`, `0xDEADBEEF`, `01`, `0.1`, `1e100`, `-1e-100`, `inf`, `nan`.
### String
diff --git a/docs/ru/interfaces/formats.md b/docs/ru/interfaces/formats.md
index e4665ff0c3e..59c77d082cf 100644
--- a/docs/ru/interfaces/formats.md
+++ b/docs/ru/interfaces/formats.md
@@ -948,7 +948,7 @@ $ watch -n1 "clickhouse-client --query='SELECT event, value FROM system.events F
## RowBinary {#rowbinary}
-Форматирует и парсит данные по строкам, в бинарном виде. Строки и значения уложены подряд, без разделителей.
+Форматирует и парсит данные по строкам, в бинарном виде. Строки и значения уложены подряд, без разделителей. Так как данные представлены в бинарном виде, разделитель после `FORMAT RowBinary` строго определен в следующем виде: любое количество пробелов (`' '` - space, код `0x20`; `'\t'` - tab, код `0x09`; `'\f'` - form feed, код `0x0C`), следующая за этим одна последовательность конца строки (Windows style `"\r\n"` или Unix style `'\n'`), и непосредственно следующие за этим бинарные данные.
Формат менее эффективен, чем формат Native, так как является строковым.
Числа представлены в little endian формате фиксированной длины. Для примера, UInt64 занимает 8 байт.
diff --git a/docs/ru/sql-reference/functions/date-time-functions.md b/docs/ru/sql-reference/functions/date-time-functions.md
index 8fbcaf9568b..f430f5cae51 100644
--- a/docs/ru/sql-reference/functions/date-time-functions.md
+++ b/docs/ru/sql-reference/functions/date-time-functions.md
@@ -424,23 +424,23 @@ WITH toDateTime64('2020-01-01 10:20:30.999', 3) AS dt64 SELECT toStartOfSecond(d
## toRelativeYearNum {#torelativeyearnum}
-Переводит дату или дату-с-временем в номер года, начиная с некоторого фиксированного момента в прошлом.
+Переводит дату-с-временем или дату в номер года, начиная с некоторого фиксированного момента в прошлом.
## toRelativeQuarterNum {#torelativequarternum}
-Переводит дату или дату-с-временем в номер квартала, начиная с некоторого фиксированного момента в прошлом.
+Переводит дату-с-временем или дату в номер квартала, начиная с некоторого фиксированного момента в прошлом.
## toRelativeMonthNum {#torelativemonthnum}
-Переводит дату или дату-с-временем в номер месяца, начиная с некоторого фиксированного момента в прошлом.
+Переводит дату-с-временем или дату в номер месяца, начиная с некоторого фиксированного момента в прошлом.
## toRelativeWeekNum {#torelativeweeknum}
-Переводит дату или дату-с-временем в номер недели, начиная с некоторого фиксированного момента в прошлом.
+Переводит дату-с-временем или дату в номер недели, начиная с некоторого фиксированного момента в прошлом.
## toRelativeDayNum {#torelativedaynum}
-Переводит дату или дату-с-временем в номер дня, начиная с некоторого фиксированного момента в прошлом.
+Переводит дату-с-временем или дату в номер дня, начиная с некоторого фиксированного момента в прошлом.
## toRelativeHourNum {#torelativehournum}
@@ -456,7 +456,7 @@ WITH toDateTime64('2020-01-01 10:20:30.999', 3) AS dt64 SELECT toStartOfSecond(d
## toISOYear {#toisoyear}
-Переводит дату или дату-с-временем в число типа UInt16, содержащее номер ISO года. ISO год отличается от обычного года, потому что в соответствии с [ISO 8601:1988](https://en.wikipedia.org/wiki/ISO_8601) ISO год начинается необязательно первого января.
+Переводит дату-с-временем или дату в число типа UInt16, содержащее номер ISO года. ISO год отличается от обычного года, потому что в соответствии с [ISO 8601:1988](https://en.wikipedia.org/wiki/ISO_8601) ISO год начинается необязательно первого января.
**Пример**
@@ -479,7 +479,7 @@ SELECT
## toISOWeek {#toisoweek}
-Переводит дату или дату-с-временем в число типа UInt8, содержащее номер ISO недели.
+Переводит дату-с-временем или дату в число типа UInt8, содержащее номер ISO недели.
Начало ISO года отличается от начала обычного года, потому что в соответствии с [ISO 8601:1988](https://en.wikipedia.org/wiki/ISO_8601) первая неделя года - это неделя с четырьмя или более днями в этом году.
1 Января 2017 г. - воскресение, т.е. первая ISO неделя 2017 года началась в понедельник 2 января, поэтому 1 января 2017 это последняя неделя 2016 года.
@@ -503,7 +503,7 @@ SELECT
```
## toWeek(date\[, mode\]\[, timezone\]) {#toweek}
-Переводит дату или дату-с-временем в число UInt8, содержащее номер недели. Второй аргументам mode задает режим, начинается ли неделя с воскресенья или с понедельника и должно ли возвращаемое значение находиться в диапазоне от 0 до 53 или от 1 до 53. Если аргумент mode опущен, то используется режим 0.
+Переводит дату-с-временем или дату в число UInt8, содержащее номер недели. Второй аргументам mode задает режим, начинается ли неделя с воскресенья или с понедельника и должно ли возвращаемое значение находиться в диапазоне от 0 до 53 или от 1 до 53. Если аргумент mode опущен, то используется режим 0.
`toISOWeek() ` эквивалентно `toWeek(date,3)`.
@@ -569,132 +569,6 @@ SELECT toDate('2016-12-27') AS date, toYearWeek(date) AS yearWeek0, toYearWeek(d
└────────────┴───────────┴───────────┴───────────┘
```
-## age
-
-Вычисляет компонент `unit` разницы между `startdate` и `enddate`. Разница вычисляется с точностью в 1 секунду.
-Например, разница между `2021-12-29` и `2022-01-01` 3 дня для единицы `day`, 0 месяцев для единицы `month`, 0 лет для единицы `year`.
-
-**Синтаксис**
-
-``` sql
-age('unit', startdate, enddate, [timezone])
-```
-
-**Аргументы**
-
-- `unit` — единица измерения времени, в которой будет выражено возвращаемое значение функции. [String](../../sql-reference/data-types/string.md).
- Возможные значения:
-
- - `second` (возможные сокращения: `ss`, `s`)
- - `minute` (возможные сокращения: `mi`, `n`)
- - `hour` (возможные сокращения: `hh`, `h`)
- - `day` (возможные сокращения: `dd`, `d`)
- - `week` (возможные сокращения: `wk`, `ww`)
- - `month` (возможные сокращения: `mm`, `m`)
- - `quarter` (возможные сокращения: `qq`, `q`)
- - `year` (возможные сокращения: `yyyy`, `yy`)
-
-- `startdate` — первая дата или дата со временем, которая вычитается из `enddate`. [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) или [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `enddate` — вторая дата или дата со временем, из которой вычитается `startdate`. [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) или [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `timezone` — [часовой пояс](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (необязательно). Если этот аргумент указан, то он применяется как для `startdate`, так и для `enddate`. Если этот аргумент не указан, то используются часовые пояса аргументов `startdate` и `enddate`. Если часовые пояса аргументов `startdate` и `enddate` не совпадают, то результат не определен. [String](../../sql-reference/data-types/string.md).
-
-**Возвращаемое значение**
-
-Разница между `enddate` и `startdate`, выраженная в `unit`.
-
-Тип: [Int](../../sql-reference/data-types/int-uint.md).
-
-**Пример**
-
-Запрос:
-
-``` sql
-SELECT age('hour', toDateTime('2018-01-01 22:30:00'), toDateTime('2018-01-02 23:00:00'));
-```
-
-Результат:
-
-``` text
-┌─age('hour', toDateTime('2018-01-01 22:30:00'), toDateTime('2018-01-02 23:00:00'))─┐
-│ 24 │
-└───────────────────────────────────────────────────────────────────────────────────┘
-```
-
-Запрос:
-
-``` sql
-SELECT
- toDate('2022-01-01') AS e,
- toDate('2021-12-29') AS s,
- age('day', s, e) AS day_age,
- age('month', s, e) AS month__age,
- age('year', s, e) AS year_age;
-```
-
-Результат:
-
-``` text
-┌──────────e─┬──────────s─┬─day_age─┬─month__age─┬─year_age─┐
-│ 2022-01-01 │ 2021-12-29 │ 3 │ 0 │ 0 │
-└────────────┴────────────┴─────────┴────────────┴──────────┘
-```
-
-## date\_diff {#date_diff}
-
-Вычисляет разницу указанных границ `unit` пересекаемых между `startdate` и `enddate`.
-
-**Синтаксис**
-
-``` sql
-date_diff('unit', startdate, enddate, [timezone])
-```
-
-Синонимы: `dateDiff`, `DATE_DIFF`.
-
-**Аргументы**
-
-- `unit` — единица измерения времени, в которой будет выражено возвращаемое значение функции. [String](../../sql-reference/data-types/string.md).
- Возможные значения:
-
- - `second` (возможные сокращения: `ss`, `s`)
- - `minute` (возможные сокращения: `mi`, `n`)
- - `hour` (возможные сокращения: `hh`, `h`)
- - `day` (возможные сокращения: `dd`, `d`)
- - `week` (возможные сокращения: `wk`, `ww`)
- - `month` (возможные сокращения: `mm`, `m`)
- - `quarter` (возможные сокращения: `qq`, `q`)
- - `year` (возможные сокращения: `yyyy`, `yy`)
-
-- `startdate` — первая дата или дата со временем, которая вычитается из `enddate`. [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) или [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `enddate` — вторая дата или дата со временем, из которой вычитается `startdate`. [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) или [DateTime64](../../sql-reference/data-types/datetime64.md).
-
-- `timezone` — [часовой пояс](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (необязательно). Если этот аргумент указан, то он применяется как для `startdate`, так и для `enddate`. Если этот аргумент не указан, то используются часовые пояса аргументов `startdate` и `enddate`. Если часовые пояса аргументов `startdate` и `enddate` не совпадают, то результат не определен. [String](../../sql-reference/data-types/string.md).
-
-**Возвращаемое значение**
-
-Разница между `enddate` и `startdate`, выраженная в `unit`.
-
-Тип: [Int](../../sql-reference/data-types/int-uint.md).
-
-**Пример**
-
-Запрос:
-
-``` sql
-SELECT dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'));
-```
-
-Результат:
-
-``` text
-┌─dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'))─┐
-│ 25 │
-└────────────────────────────────────────────────────────────────────────────────────────┘
-```
-
## date_trunc {#date_trunc}
Отсекает от даты и времени части, меньшие чем указанная часть.
@@ -815,6 +689,60 @@ SELECT date_add(YEAR, 3, toDate('2018-01-01'));
└───────────────────────────────────────────────┘
```
+## date\_diff {#date_diff}
+
+Вычисляет разницу между двумя значениями дат или дат со временем.
+
+**Синтаксис**
+
+``` sql
+date_diff('unit', startdate, enddate, [timezone])
+```
+
+Синонимы: `dateDiff`, `DATE_DIFF`.
+
+**Аргументы**
+
+- `unit` — единица измерения времени, в которой будет выражено возвращаемое значение функции. [String](../../sql-reference/data-types/string.md).
+ Возможные значения:
+
+ - `second`
+ - `minute`
+ - `hour`
+ - `day`
+ - `week`
+ - `month`
+ - `quarter`
+ - `year`
+
+- `startdate` — первая дата или дата со временем, которая вычитается из `enddate`. [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) или [DateTime64](../../sql-reference/data-types/datetime64.md).
+
+- `enddate` — вторая дата или дата со временем, из которой вычитается `startdate`. [Date](../../sql-reference/data-types/date.md), [Date32](../../sql-reference/data-types/date32.md), [DateTime](../../sql-reference/data-types/datetime.md) или [DateTime64](../../sql-reference/data-types/datetime64.md).
+
+- `timezone` — [часовой пояс](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) (необязательно). Если этот аргумент указан, то он применяется как для `startdate`, так и для `enddate`. Если этот аргумент не указан, то используются часовые пояса аргументов `startdate` и `enddate`. Если часовые пояса аргументов `startdate` и `enddate` не совпадают, то результат не определен. [String](../../sql-reference/data-types/string.md).
+
+**Возвращаемое значение**
+
+Разница между `enddate` и `startdate`, выраженная в `unit`.
+
+Тип: [Int](../../sql-reference/data-types/int-uint.md).
+
+**Пример**
+
+Запрос:
+
+``` sql
+SELECT dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'));
+```
+
+Результат:
+
+``` text
+┌─dateDiff('hour', toDateTime('2018-01-01 22:00:00'), toDateTime('2018-01-02 23:00:00'))─┐
+│ 25 │
+└────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
## date\_sub {#date_sub}
Вычитает интервал времени или даты из указанной даты или даты со временем.
diff --git a/docs/zh/getting-started/example-datasets/uk-price-paid.mdx b/docs/zh/getting-started/example-datasets/uk-price-paid.mdx
index 058f0ae421a..ecfdcddbbe2 100644
--- a/docs/zh/getting-started/example-datasets/uk-price-paid.mdx
+++ b/docs/zh/getting-started/example-datasets/uk-price-paid.mdx
@@ -41,7 +41,7 @@ ORDER BY (postcode1, postcode2, addr1, addr2);
我们将使用 `url` 函数将数据流式传输到 ClickHouse。我们需要首先预处理一些传入的数据,其中包括:
- 将`postcode` 拆分为两个不同的列 - `postcode1` 和 `postcode2`,因为这更适合存储和查询
-- 将`time` 字段转换为日期为它只包含 00:00 时间
+- 将`time` 字段转换为日期因为它只包含 00:00 时间
- 忽略 [UUid](/docs/zh/sql-reference/data-types/uuid.md) 字段,因为我们不需要它进行分析
- 使用 [transform](/docs/zh/sql-reference/functions/other-functions.md#transform) 函数将 `Enum` 字段 `type` 和 `duration` 转换为更易读的 `Enum` 字段
- 将 `is_new` 字段从单字符串(` Y`/`N`) 到 [UInt8](/docs/zh/sql-reference/data-types/int-uint.md#uint8-uint16-uint32-uint64-uint256-int8-int16-int32-int64 -int128-int256) 字段为 0 或 1
diff --git a/packages/clickhouse-server.service b/packages/clickhouse-server.service
index 1581b95213e..a1602482073 100644
--- a/packages/clickhouse-server.service
+++ b/packages/clickhouse-server.service
@@ -11,8 +11,8 @@ Wants=time-sync.target
[Service]
Type=notify
-# Switching off watchdog is very important for sd_notify to work correctly.
-Environment=CLICKHOUSE_WATCHDOG_ENABLE=0
+# NOTE: we leave clickhouse watchdog process enabled to be able to see OOM/SIGKILL traces in clickhouse-server.log files.
+# If you wish to disable the watchdog and rely on systemd logs just add "Environment=CLICKHOUSE_WATCHDOG_ENABLE=0" line.
User=clickhouse
Group=clickhouse
Restart=always
diff --git a/programs/client/Client.cpp b/programs/client/Client.cpp
index 115f76174bd..9923b8b365a 100644
--- a/programs/client/Client.cpp
+++ b/programs/client/Client.cpp
@@ -16,6 +16,8 @@
#include
+#include
+
#include "config_version.h"
#include
#include
@@ -258,6 +260,10 @@ try
if (is_interactive && !config().has("no-warnings"))
showWarnings();
+ /// Set user password complexity rules
+ auto & access_control = global_context->getAccessControl();
+ access_control.setPasswordComplexityRules(connection->getPasswordComplexityRules());
+
if (is_interactive && !delayed_interactive)
{
runInteractive();
diff --git a/programs/local/LocalServer.cpp b/programs/local/LocalServer.cpp
index 33d11091660..1614fb1a8b4 100644
--- a/programs/local/LocalServer.cpp
+++ b/programs/local/LocalServer.cpp
@@ -37,7 +37,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp
index 574e9bfa62e..f98b33c7f87 100644
--- a/programs/server/Server.cpp
+++ b/programs/server/Server.cpp
@@ -60,7 +60,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -70,6 +70,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include "MetricsTransmitter.h"
@@ -287,7 +289,6 @@ namespace ErrorCodes
extern const int MISMATCHING_USERS_FOR_PROCESS_AND_DATA;
extern const int NETWORK_ERROR;
extern const int CORRUPTED_DATA;
- extern const int SYSTEM_ERROR;
}
@@ -661,51 +662,6 @@ static void sanityChecks(Server & server)
}
}
-#if defined(OS_LINUX)
-/// Sends notification to systemd, analogous to sd_notify from libsystemd
-static void systemdNotify(const std::string_view & command)
-{
- const char * path = getenv("NOTIFY_SOCKET"); // NOLINT(concurrency-mt-unsafe)
-
- if (path == nullptr)
- return; /// not using systemd
-
- int s = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
-
- if (s == -1)
- throwFromErrno("Can't create UNIX socket for systemd notify.", ErrorCodes::SYSTEM_ERROR);
-
- SCOPE_EXIT({ close(s); });
-
- const size_t len = strlen(path);
-
- struct sockaddr_un addr;
-
- addr.sun_family = AF_UNIX;
-
- if (len < 2 || len > sizeof(addr.sun_path) - 1)
- throw Exception(ErrorCodes::SYSTEM_ERROR, "NOTIFY_SOCKET env var value \"{}\" is wrong.", path);
-
- memcpy(addr.sun_path, path, len + 1); /// write last zero as well.
-
- size_t addrlen = offsetof(struct sockaddr_un, sun_path) + len;
-
- /// '@' meass this is Linux abstract socket, per documentation it must be sun_path[0] must be set to '\0' for it.
- if (path[0] == '@')
- addr.sun_path[0] = 0;
- else if (path[0] == '/')
- addrlen += 1; /// non-abstract-addresses should be zero terminated.
- else
- throw Exception(ErrorCodes::SYSTEM_ERROR, "Wrong UNIX path \"{}\" in NOTIFY_SOCKET env var", path);
-
- const struct sockaddr *sock_addr = reinterpret_cast (&addr);
-
- if (sendto(s, command.data(), command.size(), 0, sock_addr, static_cast (addrlen)) != static_cast (command.size()))
- throw Exception("Failed to notify systemd.", ErrorCodes::SYSTEM_ERROR);
-
-}
-#endif
-
int Server::main(const std::vector & /*args*/)
try
{
@@ -748,8 +704,8 @@ try
else
{
const String config_path = config().getString("config-file", "config.xml");
- const auto config_dir = std::filesystem::path{config_path}.remove_filename();
- setenv("OPENSSL_CONF", config_dir.string() + "openssl.conf", true);
+ const auto config_dir = std::filesystem::path{config_path}.replace_filename("openssl.conf");
+ setenv("OPENSSL_CONF", config_dir.string(), true);
}
#endif
@@ -761,6 +717,8 @@ try
registerDisks(/* global_skip_access_check= */ false);
registerFormats();
registerRemoteFileMetadatas();
+ registerSchedulerNodes();
+ registerResourceManagers();
CurrentMetrics::set(CurrentMetrics::Revision, ClickHouseRevision::getVersionRevision());
CurrentMetrics::set(CurrentMetrics::VersionInteger, ClickHouseRevision::getVersionInteger());
@@ -1335,6 +1293,11 @@ try
global_context->getDistributedSchedulePool().increaseThreadsCount(new_pool_size);
}
+ if (config->has("resources"))
+ {
+ global_context->getResourceManager()->updateConfiguration(*config);
+ }
+
if (!initial_loading)
{
/// We do not load ZooKeeper configuration on the first config loading
@@ -1861,6 +1824,9 @@ try
}
#if defined(OS_LINUX)
+ /// Tell the service manager that service startup is finished.
+ /// NOTE: the parent clickhouse-watchdog process must do systemdNotify("MAINPID={}\n", child_pid); before
+ /// the child process notifies 'READY=1'.
systemdNotify("READY=1\n");
#endif
diff --git a/programs/server/config.xml b/programs/server/config.xml
index deebb434120..0cbc3d9339e 100644
--- a/programs/server/config.xml
+++ b/programs/server/config.xml
@@ -466,6 +466,30 @@
1
1
+
+
+
time
+ * ^ ^ ^ ^ ^ ^
+ * | | | | | |
+ * enqueue wait dequeue execute consume finish
+ *
+ * 1) Request is enqueued using ISchedulerQueue::enqueueRequest().
+ * 2) Request competes with others for access to a resource; effectively just waiting in a queue.
+ * 3) Scheduler calls ISchedulerNode::dequeueRequest() that returns the request.
+ * 4) Callback ResourceRequest::execute() is called to provide access to the resource.
+ * 5) The resource consumption is happening outside of the scheduling subsystem.
+ * 6) request->constraint->finishRequest() is called when consumption is finished.
+ *
+ * Steps (5) and (6) can be omitted if constraint is not used by the resource.
+ *
+ * Request can be created on stack or heap.
+ * Request ownership is done outside of the scheduling subsystem.
+ * After (6) request can be destructed safely.
+ *
+ * Request cancelling is not supported yet.
+ */
+class ResourceRequest
+{
+public:
+ /// Cost of request execution; should be filled before request enqueueing.
+ /// NOTE: If cost is not known in advance, credit model can be used:
+ /// NOTE: for the first request use 1 and
+ ResourceCost cost;
+
+ /// Request outcome
+ /// Should be filled during resource consumption
+ bool successful = true;
+
+ /// Scheduler node to be notified on consumption finish
+ /// Auto-filled during request enqueue/dequeue
+ ISchedulerConstraint * constraint = nullptr;
+
+ /// Timestamps for introspection
+ ResourceNs enqueue_ns = 0;
+ ResourceNs execute_ns = 0;
+ ResourceNs finish_ns = 0;
+
+ explicit ResourceRequest(ResourceCost cost_ = 1)
+ : cost(cost_)
+ {}
+
+ virtual ~ResourceRequest() = default;
+
+ /// Callback to trigger resource consumption.
+ /// IMPORTANT: is called from scheduler thread and must be fast,
+ /// just triggering start of a consumption, not doing the consumption itself
+ /// (e.g. setting an std::promise or creating a job in a thread pool)
+ virtual void execute() = 0;
+};
+
+}
diff --git a/src/IO/S3Common.cpp b/src/IO/S3Common.cpp
index 91f575d5097..c03f7f07310 100644
--- a/src/IO/S3Common.cpp
+++ b/src/IO/S3Common.cpp
@@ -851,8 +851,12 @@ namespace S3
quoteString(bucket), !uri.empty() ? " (" + uri.toString() + ")" : "");
}
+ bool isNotFoundError(Aws::S3::S3Errors error)
+ {
+ return error == Aws::S3::S3Errors::RESOURCE_NOT_FOUND || error == Aws::S3::S3Errors::NO_SUCH_KEY;
+ }
- S3::ObjectInfo getObjectInfo(std::shared_ptr client_ptr, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3)
+ Aws::S3::Model::HeadObjectOutcome headObject(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool for_disk_s3)
{
ProfileEvents::increment(ProfileEvents::S3HeadObject);
if (for_disk_s3)
@@ -865,7 +869,12 @@ namespace S3
if (!version_id.empty())
req.SetVersionId(version_id);
- Aws::S3::Model::HeadObjectOutcome outcome = client_ptr->HeadObject(req);
+ return client.HeadObject(req);
+ }
+
+ S3::ObjectInfo getObjectInfo(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3)
+ {
+ auto outcome = headObject(client, bucket, key, version_id, for_disk_s3);
if (outcome.IsSuccess())
{
@@ -874,16 +883,34 @@ namespace S3
}
else if (throw_on_error)
{
- throw DB::Exception(outcome.GetError().GetMessage(), ErrorCodes::S3_ERROR);
+ const auto & error = outcome.GetError();
+ throw DB::Exception(ErrorCodes::S3_ERROR,
+ "Failed to HEAD object: {}. HTTP response code: {}",
+ error.GetMessage(), static_cast(error.GetResponseCode()));
}
return {};
}
- size_t getObjectSize(std::shared_ptr client_ptr, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3)
+ size_t getObjectSize(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3)
{
- return getObjectInfo(client_ptr, bucket, key, version_id, throw_on_error, for_disk_s3).size;
+ return getObjectInfo(client, bucket, key, version_id, throw_on_error, for_disk_s3).size;
}
+ bool objectExists(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool for_disk_s3)
+ {
+ auto outcome = headObject(client, bucket, key, version_id, for_disk_s3);
+
+ if (outcome.IsSuccess())
+ return true;
+
+ const auto & error = outcome.GetError();
+ if (isNotFoundError(error.GetErrorType()))
+ return false;
+
+ throw S3Exception(error.GetErrorType(),
+ "Failed to check existence of key {} in bucket {}: {}",
+ key, bucket, error.GetMessage());
+ }
}
}
diff --git a/src/IO/S3Common.h b/src/IO/S3Common.h
index c68d76ece41..73dc51b980f 100644
--- a/src/IO/S3Common.h
+++ b/src/IO/S3Common.h
@@ -13,20 +13,17 @@
#include
#include
#include
+#include
#include
#include
#include
#include
-namespace Aws::S3
-{
- class S3Client;
-}
-
namespace DB
{
+
namespace ErrorCodes
{
extern const int S3_ERROR;
@@ -130,16 +127,22 @@ struct ObjectInfo
time_t last_modification_time = 0;
};
-S3::ObjectInfo getObjectInfo(std::shared_ptr client_ptr, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3);
+bool isNotFoundError(Aws::S3::S3Errors error);
-size_t getObjectSize(std::shared_ptr client_ptr, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3);
+Aws::S3::Model::HeadObjectOutcome headObject(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id = "", bool for_disk_s3 = false);
+
+S3::ObjectInfo getObjectInfo(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3);
+
+size_t getObjectSize(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id, bool throw_on_error, bool for_disk_s3);
+
+bool objectExists(const Aws::S3::S3Client & client, const String & bucket, const String & key, const String & version_id = "", bool for_disk_s3 = false);
}
#endif
namespace Poco::Util
{
-class AbstractConfiguration;
+ class AbstractConfiguration;
};
namespace DB::S3
diff --git a/src/IO/SchedulerNodeFactory.h b/src/IO/SchedulerNodeFactory.h
new file mode 100644
index 00000000000..5c31534a9b8
--- /dev/null
+++ b/src/IO/SchedulerNodeFactory.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include
+#include
+
+#include
+
+#include
+
+#include
+
+#include
+#include
+#include
+
+namespace DB
+{
+
+namespace ErrorCodes
+{
+ extern const int INVALID_SCHEDULER_NODE;
+}
+
+class SchedulerNodeFactory : private boost::noncopyable
+{
+public:
+ static SchedulerNodeFactory & instance()
+ {
+ static SchedulerNodeFactory ret;
+ return ret;
+ }
+
+ SchedulerNodePtr get(const String & name, EventQueue * event_queue, const Poco::Util::AbstractConfiguration & config, const String & config_prefix)
+ {
+ std::lock_guard lock{mutex};
+ if (auto iter = methods.find(name); iter != methods.end())
+ return iter->second(event_queue, config, config_prefix);
+ throw Exception(ErrorCodes::INVALID_SCHEDULER_NODE, "Unknown scheduler node type: {}", name);
+ }
+
+ template
+ void registerMethod(const String & name)
+ {
+ std::lock_guard lock{mutex};
+ methods[name] = [] (EventQueue * event_queue, const Poco::Util::AbstractConfiguration & config, const String & config_prefix)
+ {
+ return std::make_shared(event_queue, config, config_prefix);
+ };
+ }
+
+private:
+ std::mutex mutex;
+ using Method = std::function;
+ std::unordered_map methods;
+};
+
+}
diff --git a/src/IO/SchedulerRoot.h b/src/IO/SchedulerRoot.h
new file mode 100644
index 00000000000..f9af2099b8c
--- /dev/null
+++ b/src/IO/SchedulerRoot.h
@@ -0,0 +1,250 @@
+#pragma once
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include
+#include